数据库核心技术深度剖析:事务、索引、锁与SQL优化实战指南(第八节)-----MySQL日志

MySQL日志

重做日志(redo log)、二进制日志(bin log)、回滚日志(undo log)、错误日志(error log)、慢查询日志(slow query log)、一般查询日志(general log)、中继日志(relay log)。

二进制日志(bin log)

binlog 用于记录数据库执行的写入性操作(不包括查询)信息,以二进制的形式保存在磁盘中。binlogmysql的逻辑日志(即SQL语句),并且由 Server 层进行记录,使用任何存储引擎的 mysql 数据库都会记录 binlog 日志。binlog 是通过追加的方式进行写入的,可以通过max_binlog_size 参数设置每个 binlog文件的大小,当文件大小达到给定值之后,会生成新的文件来保存日志。

作用

  • 主从复制:在主从复制中,从库利用主库上的binlog进行重播,实现主从同步
  • 数据恢复:通过使用mysqlbinlog`工具来实现数据库基于时间点的还原

刷盘时机

对于 InnoDB 存储引擎而言,只有在事务提交时才会记录biglog ,此时记录还在内存中,那么 biglog是什么时候刷到磁盘中的呢?mysql 通过 sync_binlog 参数控制 biglog 的刷盘时机,取值范围是 0-N

  • sync_binlog=0:不去强制要求,由系统自行判断何时写入磁盘
  • sync_binlog=1:每次 commit 的时候都要将 binlog 写入磁盘
  • sync_binlog=N(N>1):每N个事务,才会将 binlog 写入磁盘

从上面可以看出, sync_binlog 最安全的是设置是 1 ,这也是MySQL 5.7.7之后版本的默认值。但是设置一个大一些的值可以提升数据库性能,因此实际情况下也可以将值适当调大,牺牲一定的一致性来获取更好的性能。

日志格式

binlog 日志有三种格式,日志格式通过 binlog-format 指定。在 MySQL 5.7.7 之前,默认的格式是 STATEMENTMySQL 5.7.7 之后,默认值是 ROW

  • STATMENT:基于SQL语句复制(statement-based replication, SBR),每一条会修改数据的sql语句会记录到binlog
    • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,从而提高了性能
    • 缺点:在某些情况下会导致主从数据不一致,比如执行sysdate()、slepp() 等
  • ROW:基于行复制(row-based replication, RBR ),不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了。
    • 优点:不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题
    • 缺点:会产生大量的日志,尤其是alter table 的时候会让日志暴涨
  • MIXED:基于STATMENTROW 两种模式的混合复制(mixed-based replication, MBR ),一般的复制使用STATEMENT 模式保存 binlog ,对于 STATEMENT 模式无法复制的操作使用 ROW 模式保存 binlog

重做日志(redo log)

**重做日志是InnoDB引擎层日志,用来记录事务操作引起数据变化,记录的是数据页的物理修改。**包括两部分:

  • 内存中的日志缓冲(redo log buffer)
  • 磁盘上的日志文件(redo logfile)

MySQL 每执行一条 DML 语句,先将记录写入 redo log buffer,后续某个时间点再一次性将多个操作记录写到 redo log file,种先写日志再写磁盘的技术就是 WAL(Write-Ahead Logging) 技术。之后MySQL会在合适的时候将操作记录 flush 到磁盘上面,flush 的条件可能是系统比较空闲,或 redo log 空间不足时。redo log 文件的大小是固定的,如可以是由4个1GB文件组成的集合。

WAL(Write-Ahead Logging)

WAL(Write-Ahead Logging,预写式日志)是一种数据安全写入机制,即先写日志,再写磁盘,这样保证数据的安全性。先在内存中提交事务,然后写日志(在InnoDB中就是Redo Log,日志是为了防止宕机导致内存数据丢失),然后再后台任务中把内存中的数据异步刷到磁盘。

作用

  • 确保事务的持久性
  • 防止发生故障时,尚有脏页未写入磁盘。在重启mysql服务时,根据redo log进行重做,从而达到事务的持久性特性

写入流程

为了控制 redo log 的写入策略,innodb_flush_log_at_trx_commit 会有下面 3 中取值:

  • 0每次提交事务只写在 redo log buffer
  • 1每次提交事务持久化到磁盘
  • 2每次提交事务写到 文件系统的 page cache

刷盘场景

redo log 实际的触发 fsync 操作写盘包含以下几个场景:

  • 后台每隔 1 秒钟的线程轮询
  • innodb_flush_log_at_trx_commit 设置成 1 时,事务提交时触发
  • innodb_log_buffer_size 是设置 redo log 大小的参数。当 redo log buffer 达到 innodb_log_buffer_size / 2 时,也会触发一次 fsync

回滚日志(undo log)

回滚日志(undo log)主要存储的是数据的逻辑变化日志,用于回滚操作。比如我们要 insert 一条数据,那么 undo log 就会生成一条对应的 delete 日志。所以当需要回滚时,只需要利用undo log 就可以恢复都修改前的数据。

作用

  • 提供回滚操作。undo log实现事务的原子性,保存了事务发生之前的数据的一个版本,可以用于回滚
  • 提供多版本并发控制(MVCC)下的读。也即非锁定读

你可能感兴趣的:(数据库,sql,mysql)