天天看点

mysql事务与redo log undo logredo logundo log事务四大特性总结参考

redo log

redo log是基于磁盘数据结构记录的日志,用于在db崩溃时恢复由未完成的事务写入的正确数据。在正常操作期间,redo log会对SQL语句或低级API调用产生的更改表数据的请求进行编码。在意外关闭之前没有完成数据文件更新的修改将在初始化期间和连接被接受之前自动重放。关于redo log在崩溃恢复中的作用,请参见“InnoDB恢复”章节14.19.2 Section 14.19.2, “InnoDB Recovery”

默认redo log在磁盘上由两个文件表示 ib_logfile0 and ib_logfile1。MySQL以循环的方式写redo log文件。redo log中的数据根据受影响的记录进行编码;此数据统称为重做数据。通过redo log的数据通道由不断增加的LSN(log sequence number)值表示。

mysql事务与redo log undo logredo logundo log事务四大特性总结参考

undo log

undo log撤消日志是与单个读写事务关联的撤消日志记录的集合,一个undo log包含怎样撤销一个事务对聚簇索引(主键索引)记录最近的变更信息。如果另一个事务需要一致性读操作查看原始数据,从undo log记录中检索未发生变更的数据返回(事务未提交前)。Undo日志存在于Undo日志段中,Undo日志段包含在回滚段中。回滚段位于system表空间、undo表空间和临时表空间中。

位于临时表空间中的Undo logs用于用户定义的临时表数据变更的事务。这些undo logs不需要redo-logged,因为他们不需要崩溃恢复。他们仅用于服务运行时的rollback。这类undo log避免了redo日志I/O提高了性能。

InnoDB支持最大128的回滚段,其中32个被分配给临时表空间。这样就剩下96个回滚段可以分配给修改常规表中的数据的事务。The

innodb_rollback_segments

参数定义InnoDB使用回滚段的数量。

一个回滚段支持的事务数依赖于回滚段中undo slot的数量与每个事务需要的undo log数量。

根据InnoDB页面的大小,回滚段中的undo槽的数量是不同的。

InnoDB Page Size Number of Undo Slots in a Rollback Segment (InnoDB Page Size / 16)

4096 (4KB)

256

8192 (8KB)

512

16384 (16KB)

1024

32768 (32KB)

2048

65536 (64KB)

4096

一个事务被分配的最大4个undo log,每一个对应以下操作类型:

  1. INSERT

    操作在用户定义的表
  2. UPDATE

    and

    DELETE

    操作在用户定义的表
  3. INSERT

    操作在用户定义的临时表
  4. UPDATE

    and

    DELETE

    操作在用户定义的临时表

Undo log被按需分配。例如,一个事务执行

INSERT

,

UPDATE

, and

DELETE

操作常规表与临时表需要4个undo log全部分配。一个事务仅执行

INSERT

操作常规表需要一个undo log。常规表执行操作的事务由已分配的系统表空间或undo表空间的回滚段分配undo log。临时表执行操作的事务由已分配的临时表空间的回滚段分配undo log。

分配给事务的undo log在事务期间保持与事务绑定。例如,分配给常规表

INSERT

操作事务的undo log,用于该事务常规表上执行的所有

INSERT

操作。

考虑到上述因素,可以使用以下公式来估算InnoDB能够支持的并发读写事务的数量。

  • 如果每个事务执行一个

    INSERT

    或者 (一个

    UPDATE

    或者

    DELETE

    )操作,

    InnoDB

    能够支持的并发读写事务数量为:
(innodb_page_size / 16) * (innodb_rollback_segments - 32)
           
  • 如果每个事务执行一个

    INSERT

    与 (一个

    UPDATE

    或者

    DELETE

    )操作,

    InnoDB

    能够支持的并发读写事务数量为:
(innodb_page_size / 16 / 2) * (innodb_rollback_segments - 32)
           
  • 如果在临时表上操作的每个事务执行一个

    INSERT

    ,

    InnoDB

    能够支持的并发读写事务数量为:
(innodb_page_size / 16) * 32
           
  • 如果在临时表上操作的每个事务执行一个

    INSERT

    与 (一个

    UPDATE

    DELETE

    ),

    InnoDB

    能够支持的并发读写事务数量为:
mysql事务与redo log undo logredo logundo log事务四大特性总结参考

事务四大特性

ACID

atomicity, consistency, isolation, and durability首字母简写。这些属性在数据库系统中都是理想的,并且都与事务的概念密切相关。InnoDB的事务特性遵循了ACID原则。

A:事务是可提交或回滚的原子工作单元。当一个事务产生多个DB变更,要么所有变更全部成功在事务提交时,要么所有变更全部撤销在事务回滚时。

C:在事务每次提交或回滚后以及事务进行时,数据库始终保持一致性状态。如果相关数据变更横跨多张表,查询看到的要么全部是旧值,要么全部是新值,不会是混合的新旧值

I:所有进行中的事务彼此之间是相互保护(隔离的);他们不能相关干涉或者看到彼此未提交的数据。这种隔离是通过锁定机制实现的。有经验的用户可以调整隔离级别,在确保事务确实不会相互干扰的情况下,减少保护以提高性能和并发性。

D:事务的结果是持久性的;一旦提交操作成功,由事务产生的变更不会发生电源故障,系统崩溃,竞态条件,或许多非数据库应用程序容易受到的其他潜在危险。持久性通常涉及到对磁盘存储的写入,并具有一定的冗余,以防止在写操作期间断电或软件崩溃。(在InnoDB中,doublewrite缓冲区有助于提高持久性。)

总结

redo log与binlog区别

  1. redo log基于磁盘物理数据结构存储,binlog为逻辑日志结构(即使row模式也是记录行变更的数据值)
  2. redo log用于数据持久化(处理缓存与磁盘一致性问题,可复用),binlog用于主从复制(处理磁盘与磁盘一致性问题,不可复用,append only)
  3. redo log可以合并提交以降低IO成本(Group Commit for Redo Log Flushing)
  4. redo log是面向innoDB引擎,binlog面向DB(包含所有引擎表均会记录binlog日志)

mysql事务实现原理

原子性:基于undo log实现,undo log可以根据LSN进行撤销操作。要么全部成功,要么全部撤销

一致性:个人理解遵循了AID原则的数据库一定是具备一致性的

隔离性:基于数据库排它锁,共享锁机制实现,MVCC(undo log+read view)多版本并发控制机制可以实现无锁情况下避免脏读/不可重复读/幻读,但是不能解决更新丢失。

持久性:基于redo log + undo log实现,doublewrite缓存区即:redo log buffer,undo log buffer

注:DIO模式不经过linux内核缓存

mysql事务与redo log undo logredo logundo log事务四大特性总结参考

参考

https://dev.mysql.com/doc/refman/5.7/en/innodb-redo-log.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-undo-logs.html

https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_consistent_read