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_ENGINE=ha_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_table,performance_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 */
"ENGINE=PERFORMANCE_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 能够实现 TP+AP 混合负载,剖析性能晋升 10 倍以上显著晋升,不须要进行数据迁徙,也无需与其余 AP 集成,补救 MySQL 剖析畛域的空白。
开源仓库
https://github.com/stoneatom/stonedb
退出 StoneDB 社区
Github: https://github.com/stoneatom/stonedb
Gitee: https://gitee.com/StoneDB/stonedb
社区官网: https://stonedb.io/
哔哩哔哩: https://space.bilibili.com/1154290084
Twitter: https://twitter.com/StoneDataBase
Linkedin: https://www.linkedin.com/in/stonedb/