MySQL日志详解
目录
1 redo日志
1.1 redo日志相关参数
1.2 redo日志写入过程分析
1.3 redo日志落盘机制
1.4 redo日志作用
2 binlog日志
2.1 binlog日志相关参数
2.2 查看binlog日志文件
2.3 删除binlog日志文件
2.4 binlog日志切换时机
2.5 binlog日志写入磁盘机制
2.6 binlog日志格式
3 undo日志
3.1 undo日志的类型
3.1.1 insert undo日志
3.1.2 update/delete undo 日志
3.2 undo日志的作用
3.2.1 事务回滚
3.2.2 多版本并发控制(MVCC)
3.3.3 崩溃恢复
3.3 回滚段
3.4 undo日志生命周期
3.4.1 生成阶段
3.4.2 提交/回滚处理
3.4.3 purge清理
3.5 undo日志参数
3.6 undo日志监控
3.7 undo日志优化
3.7.1 undo表空间膨胀
3.7.2 高并发事务undo slot不足
3.7.3 MVCC读性能下降
4 错误日志
5 慢查询日志
6 通用日志
1 redo日志
1.1 redo日志相关参数
- innodb_log_buffer_size:redo日志缓冲区大小。默认16MB
- innodb_log_group_home_dir:redo日志文件目录,默认在data目录下
- innodb_log_files_in_group:redo日志文件个数
- innodb_log_file_size:单个redo日志文件大小,默认48MB
- innodb_log_write_ahead_size:
- redo日志预写块大小
- 用于优化redo日志写入效率
- 默认为文件系统块大小
- 建议值最小为文件系统块大小或者其整数倍
1.2 redo日志写入过程分析
- redo日志从头开始写,写完一个文件继续写另外一个文件
- 写到最后一个文件后又回到第一个文件开头开始写
- write pos是当前记录的位置,一边写一边后移,写到3号文件末尾就回到0号文件开头开始写
- check point是当前要擦除的开始位置,这个位置开始到wirte pos之间的数据都是需要同步到数据文件里的数据
- write pos和check point之间的位置是可写区域,
- 当write pos追上check point时,代表redo日志写满了,需要进行擦除操作才能继续写入
- 当check point追上write pos时,表示redo数据已全部同步至数据文件
1.3 redo日志落盘机制
- innodb_flush_log_at_trx_commit:redo日志写入策略
- 设置为0:表示每次事务提交时都将redo日志写入redo日志缓冲区,数据库宕机时可能会丢失数据
- 设置为1时(默认值),表示每次事务时都会将redo日志持久化到磁盘,数据最安全,不会因为数据库或者系统宕机导致数据丢失,但是性能差一点
- 设置为2时,表示每次提交事务时都只是将redo日志写到操作系统缓存(page cache)中,这种情况数据库宕机不会丢失数据,操作系统宕机的话,如果page cache中的数据没来的及写入磁盘文件的话就会丢失数据
- 同时innodb有一个后台线程,每隔1秒会将redo日志缓冲区中的数据调用操作系统函数write写到文件系统的page cache,然后调用fsync函数将数据持久化到磁盘文件
1.4 redo日志作用
- redo记录已提交数据,将数据文件的随机写转换为redo日志的顺序写,提升了写入性能
- 当mysql异常宕机时,redo中的日志没来及的刷盘时
- 在mysql启动时,会从check point开始,按顺序重放redo日志,将数据写入数据文件中,确保了已提交的数据不丢失
2 binlog日志
- binlog日志记录保存了所有执行过的修改操作语句
- 不保存查询语句
- 启用binlog日志,会对性能有一定影响
- mysql8默认开启binlog
2.1 binlog日志相关参数
- log_bin:binlog开关,ON|1开启,OFF|0关闭
- log_bin_basename:binlog日志文件前缀,binlog日志文件名,后面跟着递增序列
- log_bin_index:binlog日志文件索引,里面记录着当前存在的binlog日志名
- max_binlog_size:binlog日志文件最大大小,超过该值时会自动切换binlog文件
- binlog_expire_logs_seconds:binlog过期时间,超过该时间binlog日志文件会被清理
2.2 查看binlog日志文件
- 查看binlog日志文件列表
- 查看第一个binlog日志事件
- 查看指定binlog日志事件
- 查看当前使用binlog日志文件
- mysqlbinlog解析binlog日志文件
mysqlbinlog --no-defaults -v --base64-output=decode-rows /var/lib/mysql/mysql-bin.000053
2.3 删除binlog日志文件
- 删除所有的binlog日志文件
- 删除指定日期前的binlog日志文件
purge master logs before '2025-04-28 19:12:00';
- 删除指定日志文件前的日志文件
purge master logs to 'mysql-bin.000006';
2.4 binlog日志切换时机
- 执行flush logs
- binlog日志文件达到配置大小
- 重启mysql服务
- mysql异常宕机
2.5 binlog日志写入磁盘机制
- sync_binlog参数
- 为0时(默认),表示每次提交事务只写到os 缓存page cache中,由操作系统自行判断什么时候执行fsync写入磁盘,服务器宕机时有可能丢失数据
- 为1时,表示每次提交事务都会执行fsync写入磁盘
- 当>1时,表示每次提交事务都写入到os缓存page cache中,当积累N个事务后调用fsync写入磁盘,服务其宕机时最多丢失N个事务
2.6 binlog日志格式
- binlog_format参数
- STATEMENT格式
- 基于SQL语句的复制,每一条修改SQL都会记录到binlog中
- 这种方式日志量小,节约IO开销,提升性能
- 但是存在一些执行过程中才能确定结果的函数,比如UUID(),SYSDATE()等函数,会造成主从数据不一致的问题
- ROW格式
- 基于行的复制,日志中会记录成每一行数据被修改的形式,然后再slave端再对相同的数据进行修改
- 记录下每一行数据修改的细节,可以解决函数,存储过程中在slave执行导致主从数据不一致的问题
- 但是这种方式日志量比较大,占用存储多,会影响MySQL性能
- MIXED格式,混合模式
- MySQL根据每一条具体的SQL语句来区分对待记录的日志形式
- 如果sql中有函数或者在执行时才知道结果的情况,就会选择ROW格式
- 否则选择STATEMENT格式
3 undo日志
3.1 undo日志的类型
3.1.1 insert undo日志
- 记录insert操作,仅用于事务回滚,事务提交后可直接删除(无MVCC依赖)
- 存储插入行的主键信息,用于回滚时删除该行
3.1.2 update/delete undo 日志
- 记录update/delete操作,需要长期保留,直接所有可能访问旧版本数据的事务完成
- 存储被修改前的数据内容(旧行数据),形成版本链
3.2 undo日志的作用
3.2.1 事务回滚
当执行rollback时,通过undo日志逆向操作,恢复数据到事务前的状态
3.2.2 多版本并发控制(MVCC)
其他事务读取数据时,通过undo日志链+read view读取可见数据,避免读写冲突
3.3.3 崩溃恢复
在数据库异常崩溃后,通过undo日志回滚未提交的事务,确保数据一致性
3.3 回滚段
- mysql管理undo日志采用回滚段方式
- 每个回滚段包含多个个undo slot,每个slot对应一个事务的undo日志
- 不同事务的undo日志分配到不同slot,避免冲突
- InnoDB默认创建128个回滚段,每个回滚段支持1024个undo slot
- 因此mysql理论上最大的事务并发数为128*1024=131072
3.4 undo日志生命周期
3.4.1 生成阶段
事务修改数据时,生成对应的undo日志并写入回滚段
3.4.2 提交/回滚处理
- 事务提交时
- insert undo日志:立即标记位可删除
- update/delete undo日志:保留至无活跃事务依赖其版本
- 事务回滚时,使用undo日志逆向恢复数据
3.4.3 purge清理
- 后台线程定期清理不再需要的undo日志
- 无活跃事务需要访问该undo日志才能清理
3.5 undo日志参数
- innodb_undo_directory:undo表空间存储路径,默认data目录
- innodb_undo_tablespaces:undo表空间数量,默认2
- innodb_max_undo_log_size:单个undo表空间的最大大小,默认1G
- innodb_undo_log_truncate:启用undo表空间自动收缩,默认off
3.6 undo日志监控
- 查看undo表空间使用情况
select * from information_schema.INNODB_TABLESPACES where SPACE_TYPE = 'Undo'\G
- 查看undo表空间文件
SELECT tablespace_name, file_name, status FROM information_schema.FILES WHERE file_type = 'UNDO LOG';
3.7 undo日志优化
3.7.1 undo表空间膨胀
- 原因:长事务活未及时提交事务导致undo日志无法清理
- 解决方案:
- 监控并终止长事务
- 启动undo表空间自动收缩
- 手动收缩undo表空间
3.7.2 高并发事务undo slot不足
- 现象:错误 ER_INNODB_TOO_MANY_CONCURRENT_TRXS
- 解决方案:
- 增加回滚段数量(innodb_rollback_segments)
- 增加undo日志文件数量(innodb_undo_tablespaces)
3.7.3 MVCC读性能下降
- 原因:undo版本链过长,遍历耗时
- 解决方案
- 优化事务提交频率,减少长事务
- 合理设置隔离级别,如使用 READ COMMITTED 替代 REPEATABLE READ
4 错误日志
记录MySQL数据启动,停止以及运行过程中的错误日志信息
5 慢查询日志
- 当查询sql执行时间超过long_query_time配置时,被记录在慢查询日志中
- 开启未使用索引查询sql写入慢查询日志
set global log_queries_not_using_indexes = on;
- mysqldumpslow命令分析慢查询日志
- 常用参数说明
-s 表示按照何种方式排序
c 访问次数
l 锁定时间
r 返回记录
t 查询时间
al 平均锁定时间
ar 平均返回记录数
at 平均查询时间
-t 返回前面多少条数据
-
- 查询返回记录集最多的SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/db2node1-slow.log
-
- 查询访问次数最多的SQL
mysqldumpslow -s c -t 10 /var/lib/mysql/db2node1-slow.log
-
- 查询耗时最多的SQL
mysqldumpslow -s t -t 10 /var/lib/mysql/db2node1-slow.log
6 通用日志
记录用户所有的操作,包括语法错误的sql语句