东莞网站运营知名乐云seo,上海建站,做网站怎么找客户联系方式,宁波网络公司选哪家StoneDB开源地址 
https://github.com/stoneatom/stonedb 设计#xff1a;小艾 
审核#xff1a;丁奇、李浩 
编辑#xff1a;宇亭 作者#xff1a;王若添 中国科学技术大学-软件工程-在读硕士、StoneDB 内核研发实习生 performance_schema 简介 
MySQL 启动后会自动创建四… StoneDB开源地址 
https://github.com/stoneatom/stonedb 设计小艾 
审核丁奇、李浩 
编辑宇亭 作者王若添 中国科学技术大学-软件工程-在读硕士、StoneDB 内核研发实习生 performance_schema 简介 
MySQL 启动后会自动创建四个 database 
mysql show databases;
--------------------
| Database           |
--------------------
| information_schema |
| mysql              |
| performance_schema |
| sys                |
--------------------其中的 performance schema 用于监控 MySQL server 在一个较低级别的运行过程中的资源消耗、资源等待等情况。它提供了一种在数据库运行时实时检查 server 的内部执行情况的方法该数据库主要关注数据库运行过程中的性能相关的数据与更为常见的 information_schema 不同information_schema 主要关注 server 运行过程中的元数据信息。 
performance_schema 中的事件只记录在本地 server 的 performance_schema 中其表中数据发生变化时不会被写入 binlog 中也不会通过复制机制被复制到其他 server 中。 表的分类 
可以将 performance_schema 库下的表按照监视不同的纬度就行分组。 语句事件记录表这些表记录了语句事件信息  
mysql show tables like %statement%;
----------------------------------------------------
| Tables_in_performance_schema (%statement%)         |
----------------------------------------------------
| events_statements_current                          |
| events_statements_histogram_by_digest              |
| events_statements_history                          |
| events_statements_summary_by_digest                |
| events_statements_summary_by_host_by_event_name    |
| ...                                                |等待事件记录表与语句事件类型的相关记录表类似  
mysql show tables like %wait%;
-----------------------------------------------
| Tables_in_performance_schema (%wait%)         |
-----------------------------------------------
| data_lock_waits                               |
| events_waits_current                          |
| events_waits_history                          |
| events_waits_history_long                     |
| ...                                           |事务事件记录表记录事务相关的事件的表  
mysql show tables like %transaction%;
------------------------------------------------------
| Tables_in_performance_schema (%transaction%)         |
------------------------------------------------------
| binary_log_transaction_compression_stats             |
| events_transactions_current                          |
| events_transactions_history                          |
| ...                                                  |使用场景 
对于语句事件记录表中的 events_statements_summary_by_digest 表举例这个表记录了基于 SQL 语句摘要的统计信息。如果我们想要了解该 stonedb 进程上执行过的所有类型 SQL 的频次我们可以使用 SELECT DIGEST_TEXT,COUNT_STAR FROM events_statements_summary_by_digest 查询该表其中 DIGEST_TEXT: 这个列是 SQL 语句的标准化版本即删除了 SQL 语句中的特定数据例如具体的值、表名、列名等后的 SQL 语句。所有逻辑上相同的 SQL 语句即使具体的值不同都会有相同的 DIGEST_TEXT。这使得我们可以统计和分析相同逻辑 SQL 语句的执行情况。  COUNT_STAR: 这个列是每个 SQL 语句摘要的执行次数。这可以帮助我们识别哪些 SQL 语句被执行的次数最多可能对系统的性能影响最大。  
这个查询返回的结果就是每种 SQL 语句的标准化版本及其执行次数。这可以帮助我们理解哪些类型的 SQL 语句最常被执行进而可以对这些 SQL 语句进行优化以提高系统的性能。 创建新的元数据表 
如果我们希望在 performance_schema 库中新增加一个描述列式二级引擎列相关信息的元数据表 mock_columns用来描述加载到 mock_columns 的列式数据情况比如被加载到了 mock 引擎中的列名列号所属表名ndv(number of disctinct value)等信息。 
以 t1 表为例 
create table t1 (c1 int PRIMAEY_KEY);
// 安装二级引擎mock的动态链接库
INSTALL PLUGIN mock SONAME ha_mock.so;
// 指定t1的二级引擎为mock
ALTER TABLE t1 SECONDARY_ENGINEha_mock;执行下面的 sql 可以将 innodb 中数据 load 到二级引擎 mock 中 
ALTER TABLE t1 SECONDARY_LOAD;在代码层面我们需要在加载 innodb 表到 mock 引擎(sql_table.cc 中的 secondary_engine_load_table 函数)的同时将各列的元数据信息存起来比如可以存在一个全局的 meta_column_columns 映射表中以便之后执行器在查询中可以读到这些列信息。 
函数调用栈如下图 查询元数据表 
将 t1 表加载到 mock 引擎中后我们就可以执行 SELECT * FROM mock_columns 进行查询。 
代码实现上简单来说我们需要新建一个类 table_mock_columns 实现 PFS_engine_table 这个抽象类在深入细节之前先了解下 MySQL 中存储引擎 handler 接口的基本概念 
MySQL 架构可分为 SQL 层和存储引擎层而且支持插件式存储引擎不同的存储引擎只需实现 handler 这个抽象类包含的方法即可作为 MySQL 的引擎进行数据存取常见的存储引擎有 innodb、myisam 等(上文提到的 mock 引擎也是一种存储引擎)。而负责 MySQL 元数据信息的引擎是 perfschema 引擎。显然 ha_perfschema 需要继承 handler 抽象类ha_perfschema 类主要的成员变量 PFS_engine_table *m_tableperformance_schema 中所有的 table 类都需要继承该抽象类(也可以理解该类的一个主要作用是充当读取记录的游标详细信息见后文)。 PFS_engine_table 的初始化 
PFS_engine_table 中的存在一个类型为 PFS_engine_table_share *的成员变量 m_table_share 其数据被所有打开该表的句柄共享的。其中包含一些回调函数如打开表 m_open_table写操作 m_write_row 和删除所有行 m_delete_all_rows 等。 
还包含一个 Plugin_table 类型的代表表定义的变量 m_table_def(类似于 CREATE TABLE 类型 SQL 的形式包括表名列名及列类型等信息)。我们需要做的就是在创建 PFS_engine_table 类型的 column 表时填充这些变量和函数。如定义表 mock_columns 的表结构 
Plugin_table table_mock_columns::s_table_def(/* Schema name */performance_schema,/* Name */mock_columns,/* Definition */  TABLE_ID int unsigned NOT NULL,\\n  TABLE_NAME VARCHAR(64) NOT NULL,\\n  COLUMN_ID int unsigned NOT NULL,\\n  NDV bigint unsigned NOT NULL,\\n  ENCODING varchar(64) DEFAULT NULL,\\n/* Options */ ENGINEPERFORMANCE_SCHEMA CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,/* Tablespace */nullptr);
)实现相关虚函数 
PFS_engine_table 中主要的虚函数有以下三个(暂时不关注索引相关的读取函数): 
int rnd_init(bool scan)
int rnd_next(void)
int read_row_values(TABLE *table, unsigned char *buf, Field **fields, bool read_all)如果我们希望在 performance_schema 库下新增一张元数据表需要重载以上三个方法rnd_init 函数做一些初始化工作rnd_next 函数从全局映射表 meta_column_columns 中将下一条记录取到 m_table 游标中read_row_values 函数负责将 m_table 游标中存储的数据读出并返回。 
查询该表时候MySQL 执行器中的函数调用链如下 (参数已省略)TableScanIterator::Read()→handler::ha_rnd_next()→ha_perfschema::rnd_next()→table_mock_columns::rnd_next(), 执行后会将下一条记录取出到 m_table 游标中暂存然后 ha_perfschema::rnd_next()会调用 read_row_values()函数, 将 m_table 中的一行数据读出填充到 Field 列表字段查询结束。 
最后的查询结果如下 
mysql SELECT * FROM mock_columns;
---------------------------------------------------
| TABLE_ID | TABLE_NAME |  COLUMN_ID | NDV |  ENCODING  |
----------------------------------------------------
|       87 |         t1 |          0 |   0 | dictionary |
----------------------------------------------------
1 row in set (4.68 sec)删除元数据表 
performance_schema 中的表是不进行持久化的这些表主要用来收集和存储 MySQL 服务器的实时性能数据以便于用户进行性能分析和问题诊断。这些数据存储在内存中并且在 MySQL 服务器重启后会被清空。这种设计是有意为之的因为 performance_schema 中的数据主要用于实时性能分析而不是长期存储。如果需要长期保留这些数据我们需要自己定期收集并存储这些数据。 
用户也可以执行如下 SQL 将从 innodb 主引擎中加载到二级引擎 mock 的表卸手动载掉 
ALTER TABLE t1 SECONDARY_UNLOAD;执行表卸载的时候需要自动把加载到二级引擎 mock 上的表中对应的列信息删除掉对应到源码层面就是当用户执行该 SQL 时mock 引擎将之前加载到 meta_mock_columns 映射表中需要被卸载表的数据清除掉。 结束语 
经过对 performance_schema 相关表的介绍和源码探索我们已对如何在 performance_schema 库中创建一张我们需要的元数据表有了较为详细的理解。希望这篇分析能为您在深入研究或进行二次开发时提供有益的参考。 
❝ 本文基于 MySQL 8.0.33 源码进行分析 ❞ StoneDB 介绍 
StoneDB 是石原子科技自主设计研发的国内首款完全兼容于 MySQL 生态的开源 一体化实时 HTAP 数据库产品具备行列混存、智能索引等核心特性为 MySQL 数据库提供在线数据实时就近分析服务能够高效解决 MySQL 数据库在分析型应用场景中面临的能力问题。同时StoneDB 使用多存储引擎架构的设计事务引擎具有数据强一致特性具备完整的事务并发处理能力使得 StoneDB 可以替代 MySQL 数据库满足在线事务处理场景的需求使用 MySQL 的用户通过 StoneDB 可以实现 TPAP 混合负载分析性能提升 10 倍以上显著提升不需要进行数据迁移也无需与其他 AP 集成弥补 MySQL 分析领域的空白。 
开源仓库 
https://github.com/stoneatom/stonedb