MySQL中的常见日志:
MySQL日志主要包括:错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。其中,比较重要的是二进制日志 binlog(归档日志)和事务日志redo log(重做日志)和undo log(回滚日志)。
慢查询日志的作用:
慢查询日志可以记录所有执行的SQL语句,包括执行时间、扫描的行数等信息,我们可以通过分析这些信息来了解数据库的使用情况,检测数据库是否正常运行,避免出现数据库宕机等问题,总之慢查询日志是一个非常重要的工具,它可以帮助我们发现问题、优化性能、监控健康状态等,保障数据库的稳定和高效运行。
binlog的作用:
binlog文件是记录了所有数据库表结构变更和表数据修改的日志,不会记录查询类的操作,比如select和show操作
redo log保证事务持久性的方式:
使用redo log,当数据发生修改时,先在redo log里面记录本次操作,然后再修改缓冲区中的数据。在事务提交时或提交前,调用fsync接口对redo log进行刷盘。
如果MySQL数据库宕机了,重启的时候,只需要读取redo log里面的数据,就可以对数据库进行恢复。由于redo log是WAL(Write Ahead Log)日志,也就是预写日志,在修改前,先写到日志里,所以保证了数据不会因为MySQL宕机而丢失数据,从而满足了持久性的要求。
redo log刷盘时机:
InnoDB存储引擎为redo log的刷盘策略提供了innodb_flush_log_at_trx_commit参数,它支持三种策略:
- 0:设置为0的时候,表示每次事务提交时不进行刷盘操作
- 1:设置为1的时候,表示每次事务提交时都将进行刷盘操作(默认值)
- 2:设置为2的时候,表示每次事务提交时都只把redo log buffer内容写入page cache
innodb_flush_log_at_trx_commit参数默认为1,也就是说当事务提交时会调用fsync对redo log进行刷盘。另外,InnoDB存储引擎有一个后台线程,每隔一秒,就会把redo log buffer中的内容写到文件系统缓存(page cache),然后调用fsync刷盘。
页修改后不直接刷盘的原因:
- 数据页大小是16KB,刷盘比较耗时,可能就修改了数据页里的几Byte数据,没必要把完整的数据页刷盘。而且数据页是随机写,因为一个数据页对应的位置可能在硬盘文件的随机位置,所以性能很差
- 如果是写redo log,一行记录可能就占几十Byte,只包含表空间号、数据页号、磁盘文件偏移量、更新值,再加上是顺序写,所以刷盘速度很快
redo log和binlog的区别:
- redo log是在InnoDB存储引擎层产生,而binlog是MySQL数据库的上层产生的,并且二进制日志不仅仅针对InnoDB存储引擎,MySQL数据库中的任何存储引擎对于数据库的修改都会产生二进制日志
- 两种日志记录的内容形式不同。MySQL的binlog是逻辑日志,其记录是对应的SQL语句。而binlog存储引擎的重做日志是物理日志
- 两种日志记录写入磁盘的时间点不同,二进制日志只在事务提交完成后进行一次写入。而binlog存储引擎的重做日志在事务进行中不断地被写入,并且日志不是随事务提交的顺序写入的
- binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件,redo log是循环使用
- binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用
undo log保证事务的原子性:
对事务进行一些列的修改之前,都会把其历史数据保存到undo log,然后把更新的数据记录到redo log日志里。当我们的事务进行commit后可以通过redo log日志来保证只要commit后的事务数据都会全部同步修改到数据库。当事务进行rollback时,我们可以通过undo log记录的历史版本来对整个事务关联的修改的数据进行回滚。