目录
1.系统数据库的简介
2.performance_schema详解
2.1. 什么是performance_schema?
2.2 performance_schema 使用
2.2.1 检查当前数据库版本是否支持
2.2.2.performance_schema 表的分类
2.2.3.performance_schema 简单配置与使用
2.2.4.查看最近执行失败的 SQL 语句
2.2.5.查看最近的事务执行信息
3.总结
以下系统库的介绍,主要是扩展大家的知识面,因为系统库中的数据很重要, 没有对 MySQL 有全面通盘的了解,不宜去操作其下的数据,而且对系统库的管理维护是是 DBA 的职责。
MySQL 有几个系统数据库,这几个数据库包含了 MySQL 服务器运行过程中所需的一些信息以及一些运行状态信息,我们现在稍微了解一下。
performance_schema
这个数据库里主要保存 MySQL 服务器运行过程中的一些状态信息,算是对
MySQL 服务器的一个性能监控。包括统计最近执行了哪些语句,在执行过程的每个阶段都花费了多长时间,内存的使用情况等等信息。
sys
这个数据库主要是通过视图的形式把 information_schema 和performance_schema 结合起来,让程序员可以更方便的了解 MySQL 服务器的一些性能信息。
information_schema
这个数据库保存着 MySQL 服务器维护的所有其他数据库的信息,比如有哪些表、哪些视图、哪些触发器、哪些列、哪些索引。这些信息并不是真实的用户数据,而是一些描述性信息,有时候也称之为元数据。
mysql
这个数据库核心,它存储了 MySQL 的用户账户和权限信息,一些存储过程、事件的定义信息,一些运行过程中产生的日志信息,一些帮助信息以及时区信息等。
MySQL 的performance_schema 是运行在较低级别的用于监控MySQL Server运行过程中的资源消耗、资源等待等情况的一个功能特性,它具有以下特点。
过上面介绍,相信你对于什么是 performance_schema 这个问题了解得更清晰了。下面开始介绍 performance_schema 的使用。
performance_schema 被视为存储引擎,如果该引擎可用,则应该在 INFORMATION_SCHEMA.ENGINES 表或 show engines 语句的输出中可以看到它的 Support 字段值为 YES,如下所示。
当我们看到 performance_schema 对应的 Support 字段值为 YES 时,就表示当前的数据库版本是支持 performance_schema 的。但确认了数据库实例支持performance_schema 存储引擎就可以使用了吗?NO,很遗憾,performance_schema 在 MySQL 5.6 及之前的版本中默认没有启用,在 MySQL 5.7及之后的版本中才修改为默认启用。
启用performance_schema
如果要显式启用或关闭performance_schema,则需要使用参数
performance_schema=ON|OFF来设置,并在my.cnf中进行配置。
注意:该参数为 只读参数,需要在实例启动之前设置才生效
mysqld 启动之后,通过如下语句查看 performance_schema 启用是否生效(值为 ON 表示 performance_schema 已初始化成功且可以使用了;值为 OFF 表示在启用 performance_schema 时发生某些错误,可以查看错误日志进行排查)。
现在,可以通过查询 INFORMATION_SCHEMA.TABLES 表中与performance_schema 存储引擎相关的元数据,或者在 performance_schema 库下使用 show tables 语句来了解其存在哪些表。
使用 show tables 语句来查询有哪些 performance_schema 引擎表。
现在,我们知道了在当前版本中,performance_schema 库下一共有 87 个表, 那么这些表都用于存放什么数据呢?我们如何使用它们来查询数据呢?先来看看这些表是如何分类的。
performance_schema 库下的表可以按照监视的不同维度进行分组,例如: 按照不同的数据库对象进行分组、按照不同的事件类型进行分组,或者按照事件类型分组之后,再进一步按照账号、主机、程序、线程、用户等进行细分。
下面介绍按照事件类型分组记录性能事件数据的表。
语句事件记录表:记录语句事件信息的表,包括:events_statements_current(当前语句事件表)、events_statements_history(历史语句事件表)、events_statements_history_long(长语句历史事件表)以及一些 summary 表(聚合后的摘要表)。其中,summary 表还可以根据账号(account)、主机(host)、程序(program)、线程(thread)、用户(user)和全局(global) 再进行细分。
show tables like 'events_statement%';
等待事件记录表:与语句事件记录表类似。
show tables like 'events_wait%';
阶段事件记录表:记录语句执行阶段事件的表,与语句事件记录表类似。
show tables like 'events_stage%';
事务事件记录表:记录与事务相关的事件的表,与语句事件记录表类似。
show tables like 'events_transaction%';
监视文件系统层调用的表:
show tables like '%file%';
监视内存使用的表:
show tables like '%memory%';
动态对 performance_schema 进行配置的配置表:
show tables like '%setup%';
现在,我们已经大概知道了 performance_schema 中主要表的分类,但如何使用这些表来提供性能事件数据呢?
当数据库初始化完成并启动时,并非所有的 instruments(在采集配置项的配置表中,每一项都有一个开关字段,或为 YES,或为 NO)和 consumers(与采集配置项类似,也有一个对应的事件类型保存表配置项,为 YES 表示对应的表保存性能数据,为 NO 表示对应的表不保存性能数据)都启用了,所以默认不会收集所有的事件。
可能你想检测的事件并没有打开,需要进行设置。可以使用如下两条语句打开对应的 instruments 和 consumers,我们以配置监测等待事件数据为例进行说明。
打开等待事件的采集器配置项开关,需要修改 setup_instruments 配置表中对应的采集器配置项。
update setup_instruments set enabled='yes',timed='yes' where name like 'wait%';
打开等待事件的保存表配置项开关,修改 setup_consumers 配置表中对应的配置项。
update setup_consumers set enabled='yes' where name like 'wait%';
配置好之后,我们就可以查看 Server 当前正在做什么了。可以通过查询 events_waits_current 表来得知,该表中每个线程只包含一行数据,用于显示每个线程的最新监视事件(正在做的事情)。
*_current 表中每个线程只保留一条记录,且一旦线程完成工作,该表中就不会再记录该线程的事件信息了。*_history 表中记录每个线程已经执行完成的事件信息,但每个线程的事件信息只记录 10 条,再多就会被覆盖掉。*_history_long表中记录所有线程的事件信息,但总记录数量是 10000 行,超过会被覆盖掉。
summary 表提供所有事件的汇总信息。该组中的表以不同的方式汇总事件数据(如:按用户、按主机、按线程等汇总)。
使用代码对数据库的某些操作(比如:使用 Java 的 ORM 框架操作数据库) 报出语法错误,但是代码并没有记录 SQL 语句文本的功能,在 MySQL 数据库层能否查看到具体的 SQL 语句文本,看看是否哪里写错了?这个时候,大多数人首先想到的就是去查看错误日志。很遗憾,对于 SQL 语句的语法错误,错误日志并不会记录。
实际上,在 performance_schema 的语句事件记录表中针对每一条语句的执行状态都记录了较为详细的信息,例如:events_statements_表和events_statements_summary_by_digest 表(events_statements_表记录了语句所有的执行错误信息,而 events_statements_summary_by_digest 表只记录了语句在执行过程中发生错误的语句记录统计信息,不记录具体的错误类型,例如:不记录语法错误类的信息)。下面看看如何使用这两个表查询语句发生错误的语句信息。
首先,我们模拟一条语法错误的 SQL 语句,使用events_statements_history_long 表或者 events_statements_history 表查询发生语法错误的 SQL 语句:
然后,查询 events_statements_history 表中错误号为 1064 的记录
select * from events_statements_history where mysql_errno=1064\G
不知道错误号是多少,可以查询发生错误次数不为 0 的语句记录,在里边找到 SQL_TEXT 和 MESSAGE_TEXT 字段(提示信息为语法错误的就是它)。
我们可以通过慢查询日志查询到一条语句的执行总时长,但是如果数据库中存在着一些大事务在执行过程中回滚了,或者在执行过程中异常中止,这个时候慢查询日志就爱莫能助了,这时我们可以借助 performance_schema 的events_transactions_*表来查看与事务相关的记录,在这些表中详细记录了是否有事务被回滚、活跃(长时间未提交的事务也属于活跃事务)或已提交等信息。
首先需要进行配置启用,事务事件默认并未启用
update setup_instruments set enabled='yes',timed='yes' where name like 'transaction%';
update setup_consumers set enabled='yes' where name like '%transaction%';
开启一个新会话(会话 2)用于执行事务,并模拟事务回滚。
查询活跃事务,活跃事务表示当前正在执行的事务事件,需要从 events_transactions_current 表中查询。
会话 2 中回滚事务:
查询事务事件当前表和事务事件历史记录表,可以看到在两表中都记录了一行事务事件信息,线程ID 为49 的线程执行了一个事务,事务状态为ROLLED BACK。
但是当我们关闭会话 2 以后,事务事件当前表中的记录就消失了。
当然 performance_schema 的用途不止我们上面说到过的这些,它还能提供比如查看 SQL 语句执行阶段和进度信息、MySQL 集群下复制功能查看复制报错详情等等。更多的一些能力我们后面再详解