几十年来我们一直从服务器系统文件中读取MySQL错误日志,如果MySQL出现任何问题或发生任何未知的重启,一般我们都会查看mysql错误日志。
默认情况下,MySQL 错误日志可以在默认路径/var/log/mysqld.log 中找到,或者可以使用变量显式配置log_error。
使用 MySQL 错误日志作为 FILE 的几个缺点
- 在阅读冗长的信息时可能会遗漏真正的错误。
- 过滤特定日期和时间范围的错误。
- 由于担心误操作 DB 服务器,无法向开发人员提供 DB 服务器访问权限。
为了克服上述问题,从MySQL 8.0.22 开始,我们可以从表中访问错误日志。performance_schema.error_log
授予 表的 SELECT 权限 error_log将为开发团队使用简单的 SQL 查询提供对错误日志内容的读取访问权限。
出于演示目的,我在我们的测试环境中安装了最新的 MySQL 8.0.23。
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.23 |
+-----------+
1 row in set (0.00 sec)
表结构
mysql> show create table performance_schema.error_log\G
*************************** 1. row ***************************
Table: error_log
Create Table: CREATE TABLE `error_log` (
`LOGGED` timestamp(6) NOT NULL,
`THREAD_ID` bigint unsigned DEFAULT NULL,
`PRIO` enum('System','Error','Warning','Note') NOT NULL,
`ERROR_CODE` varchar(10) DEFAULT NULL,
`SUBSYSTEM` varchar(7) DEFAULT NULL,
`DATA` text NOT NULL,
PRIMARY KEY (`LOGGED`),
KEY `THREAD_ID` (`THREAD_ID`),
KEY `PRIO` (`PRIO`),
KEY `ERROR_CODE` (`ERROR_CODE`),
KEY `SUBSYSTEM` (`SUBSYSTEM`)
) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
列概述
LOGGED
LOGGED 对应time 错误事件发生的 字段,存储在错误日志表中的时间值log_timestamps 默认根据系统变量即UTC显示 。
我们可以通过log_timestamps根据我们的时区更改变量来更改时间戳值。
THREAD_ID
它是一个类似于 的 MySQL 线程 ID PROCESSLIST_ID,对于前台 MySQL 线程发生的事件显示 thread_id,对于后台线程,该值为 0。
PRIO
允许值为System、 Error、 Warning、 的事件优先级 Note。
ERROR_CODE
显示 MySQL 错误代码。
SUBSYSTEM
发生事件的子系统,例如 SERVER、INNODB。
DATA
错误事件的文本表示。
控制错误日志的变量
下面是控制错误日志的主要变量,它定义了错误日志的输出。
mysql> show global variables like 'log_error%';
+----------------------------+----------------------------------------+
| Variable_name | Value |
+----------------------------+----------------------------------------+
| log_error | /var/log/mysqld.log |
| log_error_services | log_filter_internal; log_sink_internal |
| log_error_suppression_list | |
| log_error_verbosity | 2 |
+----------------------------+----------------------------------------+
- log_error – 该变量定义了 MySQL 错误日志的路径。
- log_error_services– 此变量控制为错误记录启用哪些日志组件,默认情况下,这些值设置为log_filter_internal和log_sink_internal。
- log_filter_internal:此值提供基于日志事件优先级和错误代码log_error_verbosity 以及 log_error_suppression_list 系统变量的错误日志过滤 。
- log_sink_internal: 这个值定义了传统的错误日志输出格式。
- log_error_suppression_list – 此变量有助于过滤或忽略不值得或在错误日志中产生不必要噪音的错误、信息和警告。
我们可以列出一个或多个逗号分隔的值,指示我们需要抑制的错误代码。错误代码可以以符号或数字形式指定。
例子:
假设我们坚持从错误日志中过滤掉以下警告消息:
2021-03-26T09:40:40.109075Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
log_error_suppression_list根据log_error_verbosity定义的值生效
mysql> set global log_error_suppression_list='MY-010068';
Query OK, 0 rows affected (0.00 sec)
mysql> show global variables like 'log_error%';
+----------------------------+----------------------------------------+
| Variable_name | Value |
+----------------------------+----------------------------------------+
| log_error | /var/log/mysqld.log |
| log_error_services | log_filter_internal; log_sink_internal |
| log_error_suppression_list | MY-010068 |
| log_error_verbosity | 2 |
+----------------------------+----------------------------------------+
4 rows in set (0.00 sec)
To persist the value in CNF
[mysqld]
log_error_verbosity=2 # error and warning messages only #
log_error_suppression_list='MY-010068'
log_error_verbosity
此变量指定将记录在错误日志中的事件的详细程度,允许值从 1 到 3。默认值为 2。
| log_error_verbosity 值 | 允许的消息优先级 |
|---|---|
| 1 | ERROR |
| 2 | ERROR, WARNING |
| 3 | ERROR, WARNING, INFORMATION |
现在让我们查询表performance_schema.error_log
mysql> SELECT * FROM performance_schema.error_log\G
*************************** 1. row ***************************
LOGGED: 2021-01-18 09:56:33.800985
THREAD_ID: 0
PRIO: System
ERROR_CODE: MY-013169
SUBSYSTEM: Server
DATA: /usr/sbin/mysqld (mysqld 8.0.23) initializing of server in progress as process 6335
*************************** 2. row ***************************
LOGGED: 2021-01-18 09:56:33.818823
THREAD_ID: 1
PRIO: System
ERROR_CODE: MY-013576
SUBSYSTEM: InnoDB
DATA: InnoDB initialization has started.
*************************** 3. row ***************************
LOGGED: 2021-01-18 09:56:40.454929
THREAD_ID: 0
PRIO: System
ERROR_CODE: MY-011323
SUBSYSTEM: Server
DATA: X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
*************************** 4. row ***************************
LOGGED: 2021-02-15 06:00:28.384059
THREAD_ID: 0
PRIO: System
ERROR_CODE: MY-013172
SUBSYSTEM: Server
DATA: Received SHUTDOWN from user <via user signal>. Shutting down mysqld (Version: 8.0.23).
*************************** 5. row ***************************
LOGGED: 2021-02-15 06:00:29.583157
THREAD_ID: 0
PRIO: System
ERROR_CODE: MY-010910
SUBSYSTEM: Server
DATA: /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.23) MySQL Community Server - GPL.
*************************** 6. row ***************************
LOGGED: 2021-03-25 06:48:20.350948
THREAD_ID: 376
PRIO: Error
ERROR_CODE: MY-012640
SUBSYSTEM: InnoDB
DATA: Error number 28 means 'No space left on device'
*************************** 7. row ***************************
LOGGED: 2021-03-25 06:48:20.416039
THREAD_ID: 376
PRIO: Warning
ERROR_CODE: MY-012145
SUBSYSTEM: InnoDB
DATA: Error while writing 4194304 zeroes to ./sbtest/sbtest5.ibd starting at offset 1107296256
*************************** 8. row ***************************
LOGGED: 2021-03-25 06:48:20.434689
THREAD_ID: 376
PRIO: Error
ERROR_CODE: MY-013132
SUBSYSTEM: Server
DATA: The table 'sbtest5' is full!
通过简单的 SQL 查询,我们可以根据优先级过滤日志
mysql> SELECT * FROM performance_schema.error_log WHERE PRIO='error'\G
*************************** 1. row ***************************
LOGGED: 2021-03-26 10:12:42.947343
THREAD_ID: 0
PRIO: Error
ERROR_CODE: MY-000067
SUBSYSTEM: Server
DATA: unknown variable 'innodb_flush_log_at_trx_t=1'.
*************************** 2. row ***************************
LOGGED: 2021-03-26 10:12:42.947766
THREAD_ID: 0
PRIO: Error
ERROR_CODE: MY-010119
SUBSYSTEM: Server
DATA: Aborting
当新事件需要空间时,来自 error_log 的旧事件会自动清除。
可以从SHOW STATUS变量监视 error_log 表状态。
mysql> show global status like '%error_log%';
+---------------------------+------------------+
| Variable_name | Value |
+---------------------------+------------------+
| Error_log_buffered_bytes | 8368 |
| Error_log_buffered_events | 62 |
| Error_log_expired_events | 0 |
| Error_log_latest_write | 1616753905924032 |
+---------------------------+------------------+
4 rows in set (0.00 sec
error_log 表的限制
- error_log 表上不允许使用 TRUNCATE TABLE。
- 该表不能是 index ,默认情况下每列都已被索引。
最后,在 MySQL 8 中引入 error_log 表使错误可读性更加方便和容易,现在可以从远程客户端以及很少的简单 SQL 查询来访问错误日志,而无需访问物理系统文件。
MySQL 错误日志表功能有利于使用 MySQL shell 进行远程连接,并将在 AWS RDS、AZURE MySQL、Google Cloud SQL 平台等 DBaaS 中受益很多。错误日志需要控制台并且日志保留很复杂。
原文链接:https://mydbops.wordpress.com/2021/03/28/mysql-8-0-22-error-log-table-explained/




