1.mysql事务日志的分类

innodb事务日志包括redo log 和 undo log ,redo log是重做日志,提供前滚操作,undo是回滚日志,提供回滚操作。

2.redo log—redo日志

redo是重做日志,记录的是新数据的备份,在事务提交前,只需要将redo log持久化即可,当系统崩溃时,虽然数据没有持久化,但是redo log已经持久化拉,系统可以根据redo log的内容,将所有数据恢复到最新状态。redo log保证了事务的持久性。

2.1为什么要用redo log

1、事务提交后,必须将事务对数据的修改刷(fsyn)到磁盘上,才能保证事务的ACID特性。
2、这个刷盘是一个随机写,随机写性能较低,如果每次事务提交都刷盘,会极大的影响数据建库的性能。

2.1.1日志刷盘的规则

默认情况下事务每次提交的时候都会刷事务日志到磁盘中, 这是因为变量 innodb_flush_log_at_trx_commit 的值为1。但是innodb不仅仅只会在有commit动作后才会刷日志到磁盘,这只是innodb存储引擎刷日志的规则之一。
刷日志到磁盘的规则:
1.发出commit动作时。已经说明过,commit发出后是否刷日志由变量 innodb_flush_log_at_trx_commit 控制。
2.每秒刷一次。这个刷日志的频率由变量 innodb_flush_log_at_timeout 值决定,默认是1秒。要注意,这个刷日志频率和commit动作无关。
3.当log buffer中已经使用的内存超过一半时。
4.当有checkpoint时,checkpoint在一定程度上代表了刷到磁盘时日志所处的LSN位置。

2.2随机写性能差的优化方案

1、先写日志,将随机写优化为顺序写
2、将每次写优化为批量写

2.3redo日志的三层架构

image.png
image.png

2.4日志落盘的步骤

  • 事务提交时,会写入log buffer,这里调用的是mysql自己的函数writeRedoLog
  • 只有当mysql发起系统调用写文件write时,log buffer里的数据,才会写到OS cache,注意:mysql系统调用完write之后,就认为文件已经写完,至于什么时候落盘,由操作系统决定。
  • 操作系统将 OS cache里的数据,刷到磁盘上(mysql也可以主动去刷)

image.png
优缺点:

  • 将每次写优化为批量写,提高性能
  • 可能会造成数据丢失

事务提交时,将redo log写入log buffer,认为事务提交成功,如果write OS cache之前或者是刷盘之前,系统 崩溃则会造成数据丢失。

2.5刷盘的三种策略

image.png
注意:mysql通过innodb flush log at trx commit 参数设置redo log的刷盘策略
策略一:innodb_flush_log_at_trx_commit =0(性能最佳)
每隔1秒,将log buffer中的数据批量写到OS Cache中,同时mysql主动刷盘。如果数据库崩溃,有一秒的数据丢失

策略二:innodb_flush_log_at_trx_commit =1(强一致)
每次事务提交,都将log buffer中的数据write入OS Cache中,同时mysql主动刷盘,将数据写入磁盘,这种策略是mysql默认的策略,为的是保证ACID特性。

策略三:innodb_flush_log_at_trx_commit = 2
每次事务提交,都将log buffer中的数据写入os cache中,每隔一秒,mysql做一次刷盘,如果操作系统崩溃,会有一秒数据丢失

问:高并发业务,行业最佳实践,是使用第三种折中配置(=2)
配置为2和配置为0,性能差异并不大,因为将数据从log buffer拷贝到os cache,虽然跨越用户态与内核态,但毕竟是内存数据拷贝,速度很快
配置为2和配置为0,安全性差异巨大,操作系统崩溃的概率相比mysql应用程序崩溃的概率,小的多,设置为2,只要操作系统不崩溃,数据就不会丢失

3.undo log—redo日志

undo log是回滚日志,是为了实现事务的原子性,记录了事务的操作行为;在mysql数据库innodb存储引擎中,还用undo log来实现多版本的并发控制—mvcc
除了回滚操作,undo的另一个作用是MVCC,即在innodb存储引擎中MVCC的实现是通过undo来完成。当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过undo读取之前的行版本信息,来实现非锁定读取。

3.1事务的原子性

事务中的所有操作,要么全部成功,要么不做任何操作,如果在执行过程中发生了错误,要回滚到事务开始前的状态,就像这个事务从来没有执行过。

3.2事务的持久性

事务一旦完成,该事务对数据库所做的所有修改都会持久的保存到数据库中,为了保证持久性,数据库系统会将修改后的数据完全的记录到持久的存储上。

3.3简易流程

假如数据库有一条数据A=1

  • 开启事务
  • 记录A=1到undo日志中
  • 修改A=3
  • 将undo日志写到磁盘中
  • 事务提交

3.4undo log 的存储方式

innodb存储引擎对undo的管理采用段方式:rollback segment成为回滚段,每个回滚段中有1024个undo segment