错误日志 Error Log
mysql> show variables like 'log_error';
+---------------+---------------------------+
| Variable_name | Value |
+---------------+---------------------------+
| log_error | /var/log/mysql/mysqld.log |
+---------------+---------------------------+
1 row in set (0.00 sec)
cat /var/log/mysql/mysqld.log
2021-05-29T04:34:31.333904Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/lib/mysql/mysqlx.sock
2021-05-29T04:34:31.596739Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2021-05-29T04:34:31.596920Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2021-05-29T04:34:31.598120Z 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: Address already in use
2021-05-29T04:34:31.598287Z 0 [ERROR] [MY-010257] [Server] Do you already have another mysqld server running on port: 3306 ?
2021-05-29T04:34:31.598755Z 0 [ERROR] [MY-010119] [Server] Aborting
Error Log记录了MySQL运行过程中的系统信息[System]、警告信息[Warning]、错误信息[ERROR]。
通用日志 General Log
mysql> show variables like '%general_log%';
+------------------+--------------------------------------------+
| Variable_name | Value |
+------------------+--------------------------------------------+
| general_log | ON |
| general_log_file | /var/lib/mysql/iZm5ebzz76jb4bnhkzg6i3Z.log |
+------------------+--------------------------------------------+
2 rows in set (0.00 sec)
cat /var/lib/mysql/iZm5ebzz76jb4bnhkzg6i3Z.log
usr/libexec/mysqld, Version: 8.0.21 (Source distribution). started with:
Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock
Time Id Command Argument
2021-05-29T04:50:30.120882Z 10 Query show variables like '%general_log%'
2021-05-29T04:51:40.803937Z 10 Quit
General Log默认是关闭的,这里使用了SET GLOBAL general_log = ON;手动开启。General Log记录了MySQL运行过程中收到的所有请求信息。
变量log_output可以控制日志格式,有FILE(默认)和TABLE两种。
慢查询日志 Slow Query Log
mysql> show variables like '%slow_query_log%';
+---------------------+-------------------------------------------------+
| Variable_name | Value |
+---------------------+-------------------------------------------------+
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/iZm5ebzz76jb4bnhkzg6i3Z-slow.log |
+---------------------+-------------------------------------------------+
2 rows in set (0.01 sec)
cat /var/lib/mysql/iZm5ebzz76jb4bnhkzg6i3Z-slow.log
Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock
Time Id Command Argument
# Time: 2021-05-29T05:02:27.120937Z
# User@Host: root[root] @ localhost [] Id: 12
# Query_time: 0.000149 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0
SET timestamp=1622264547;
SET long_query_time = 0;
Slow Query Log默认是关闭的,这里使用了SET GLOBAL slow_query_log = ON;手动开启。Slow Query Log记录了查询时间超过long_query_time的命令。这里使用SET long_query_time = 0;修改了慢查询阈值,默认为10。
变量log_output可以控制日志格式,有FILE(默认)和TABLE两种。变量log_queries_not_using_indexes默认关闭,开启后若查询未使用索引会显示在慢查询日志中。
二进制日志 Bin Log
Bin Log记录了对MySQL执行的所有修改,主要用于恢复和复制。
mysql> show variables like '%bin%';
+------------------------------------------------+-----------------------------+
| Variable_name | Value |
+------------------------------------------------+-----------------------------+
| binlog_format | ROW |
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/binlog |
| log_bin_index | /var/lib/mysql/binlog.index | |
| sync_binlog | 1 |
+------------------------------------------------+-----------------------------+
37 rows in set (0.00 sec)
- binlog_format: STATEMENT(记录SQL) | ROW(记录行变动) | MIXED(前两种混合使用)。
- log_bin: 是否开启二进制日志。
- log_bin_basename: Bin Log文件名前缀,例如binlog.000001。
- log_bin_index: Bin Log索引文件名,里面保存了所有的Bin Log文件名。
- sync_binlog: 0 | 1表示每个事务执行完毕是否立即刷盘,N表示每N个事务刷盘一次。
使用mysqlbinlog工具可以查看Bin Log文件,mysqlbinlog binlog.000001。
中继日志 Relay Log
应用在主从复制中,master -> bin log -> relay log -> slave。
mysql> show variables like '%relay%';
+---------------------------+--------------------------------------------------------+
| Variable_name | Value |
+---------------------------+--------------------------------------------------------+
| relay_log | iZm5ebzz76jb4bnhkzg6i3Z-relay-bin |
| relay_log_basename | /var/lib/mysql/iZm5ebzz76jb4bnhkzg6i3Z-relay-bin |
| relay_log_index | /var/lib/mysql/iZm5ebzz76jb4bnhkzg6i3Z-relay-bin.index |
| relay_log_info_file | relay-log.info |
+---------------------------+--------------------------------------------------------+
11 rows in set (0.01 sec)
- relay_log: 日志文件名,空为不开启。
- relay_log_info_file: 记录日志文件的相关信息。
事务日志 Transaction Log
事务的实现基于innodb存储引擎,事务有ACID四大特性。其中隔离性通过锁来实现,原子性、一致性、持久性则通过Transaction Log(redo log、undo log)实现。
redo log用于实现事务的持久性,undo log用于实现事务的原子性。保证了隔离性、持久性、原子性,才能够保证事务的一致性。
redo log
随着事务不断地修改数据页的内容,redo log会记录对某一页上某个位置的修改。当MySQL实例crash后,加载硬盘中crash前的数据,并根据redo log重做该数据页。
1个innodb引擎至少包含1个redo log group,1个redo log group至少包含2个redo log。redo log会先写入ib_logfile1,到达文件末尾后会写入ib_logfile2,到达文件末尾后会再写入ib_logfile1,如此循环写入。
变量 | 含义 |
---|---|
innodb_log_group_home_dir | 记录了redo log存在的路径 |
innodb_log_files_in_group | 记录了redo log的数量,默认为2个(ib_logfile0, ib_logfile1) |
innodb_log_file_size | redo log的大小 |
innodb_log_buffer_size | redo log缓存区的大小 |
redo log的刷盘策略:
变量 | 含义 |
---|---|
innodb_flush_log_at_timeout | 默认为1,主线程每秒刷盘一次 |
innodb_flush_log_at_trx_commit | 默认为1,控制提交事务的刷盘策略:(0)不刷盘,(1)刷盘,(2)交给系统缓冲区 |
innodb_flush_method | 默认为fsync,刷盘时也要将系统缓冲区flush到磁盘上 |
redo log & bin log
bin log | redo log | |
---|---|---|
日志层级 | 系统日志 | 引擎日志 |
写入时机 | 事务提交 | 事务执行过程中 |
幂等性 | 否 | 是 |
双一写入?innodb_flush_log_at_trx_commit与sync_binlog都置1,这样做会导致性能较差,但是安全性更高。
redo log两阶段提交
redo log的写入分为prepare和commit两个阶段,写入顺序为:①redo log(标记为prepare阶段);②bin log;③redo log(更新为commit阶段)。
这也是为什么事务没有提交,redo log也会刷盘的原因,如果redo log中处于prepare阶段,但bin log中没有相应的内容,则会丢弃此次变更。
undo log
undo log不像是传统的日志,更像是数据备份,即在事务未提交前备份数据。
MySQL5.6之前,undo log存放于共享表空间中,也可以通过开启innodb_file_per_table变量让undo log存放于每个表的独立表空间中。
mysql> show variables like '%innodb_undo%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_undo_directory | ./ |
| innodb_undo_log_encrypt | OFF |
| innodb_undo_log_truncate | ON |
| innodb_undo_tablespaces | 2 |
+--------------------------+-------+
4 rows in set (0.01 sec)
MySQL5.6之后,可以通过innodb_undo_directory变量指定undo log表空间存储位置。innodb_undo_tablespaces表示undo log的数量(undo_001, undo_002)。