| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> MySQL事务 -> 正文阅读 |
|
[大数据]MySQL事务 |
目录 一、事务的特性????????事务有ACID特性:A原子性、C一致性、I隔离性、D持久性。InnoDB存储引擎中,redo log(重做日志文件,称为日志)实现原子性和持久性;锁实现隔离性;undo log(回滚日志)实现一致性。 ? ? ? ? 如下表所示,ACID特性的对比。事务的持久性则采用Force Log at Commit机制实现,即:事务提交时,必须先将该事务的所有日志写入到redo log(重做日志文件)进行持久化,然后事务提交后才算真正完成。
二、事务的分类????????InnoDB存储引擎支持扁平事务、保存点的扁平事务、链事务、分布式事务,原生不支持嵌套事务,下图事务分类总结。
1. 扁平事务????????扁平事务(Flat Transaction)指所有操作处于同一层次中,由BEGIN开始,COMMIT或ROLLBACK结束,实际生产中使用最频繁的事务。因此,扁平事务是应用程序成为原子操作的基本组成模块。 ? ? ? ? 如下图所示,扁平事务中的三种情况。看出,扁平事务的主要限制不能提交或回滚事务的一部分。 2. 带有保存点的扁平事务????????带有保存点的扁平事务(Flat Transaction?with Savepoint) 指事务执行过程中回滚到同一事务中较早的一个状态,也支持扁平事务。 ????????保存点(Savepoint)用来通知系统记住当前事务的状态,以便之后发生错误时,事务能回滚到保存点当时的状态。注意,保存点在事务内部是单调递增,即使回滚后再开始操作,也不影响保存点的计数。如下图所示。 ![]() ????????事务开始时,隐式地设置一个保存点。那么在扁平事务中,只有一个保存点,因此只能回滚到事务的开始状态。 3. 链事务????????链事务(Chained?Transaction)指当前事务提交和开始下一个事务合并为一个原子操作。在当前事务提交后,释放数据对象,将必要的处理上下文隐式地传给下一个事务,即:下一个事务会看到上个事务的处理结果。 ????????链事务与带有保存点的扁平事务的区别:
4. 嵌套事务????????嵌套事务(Nested Transaction)指事务中嵌套事务,顶层事务(父事务)控制着各个层次的事务(子事务)。 ? ? ? ? 嵌套事务的特点:
5. 分布式事务????????分布式事务(Distributed Transaction)指在多个独立的事务资源参与到一个全局事务中。InnoDB存储引擎对XA事务的支持。 ? ? ? ? XA事务由一个或多个资源管理器、一个事务管理器、一个应用程序组成:
????????XA分布式事务使用的是两阶段提交方式:
? ? ? ? MySQL数据库中还存在另外一种分布式事务,不同存储引擎之间的事务,称为内部XA事务。最常见的内部XA事务存在于binlog与InnoDB存储引擎之间。在事务提交时,先写二进制日志,再写InnoDB重做日志,两个写入要求是原子操作,否则主从数据库存在数据不一致。如下图所示,数据库宕机发生在①、②之后,③之前,则会导致主从数据库存在数据不一致。 ? ? ? ? 为了解决这个问题,如下图所示,采用XA事务。当事务提交时,InnoDB存储引擎会先做一个PREPARE操作,将事务xid写入。数据库发生宕机恢复后,先检查准备的UXID事务是否已经提交,若没有,InnoDB存储引擎层会再一次执行提交操作。 三、事务的实现1. 重做日志文件(redo log file)?? ? ? ? ①. 基本概念????????重做日志文件(redo log file)记录提交事务修改页的操作,是物理日志(默认数据目录下:ib_logfile0、ib_logfile1)。其目的:实现事务的原子、持久特性,数据库的恢复使用。 ? ? ? ? 事务由两部分组成:
? ? ? ? 事务日志的产生过程:
????????需要注意的是:step3写入磁盘执行时间最慢,磁盘的性能决定事务提交的性能,也决定DB的性能。参数innodb_flush_log_at_trx_commit控制重做日志刷新到磁盘的策略,默认1(事务提交同步一次fsync)?。 ????????事务的持久性则采用Force Log at Commit机制实现:事务提交时,必须先将该事务的所有日志写入到redo log file(重做日志文件)进行持久化,然后事务提交后才算真正完成,即:事务提交时,先写重做日志再提交事务。 ????????重做日志(redo log)与二进制日志(binlog)的区别,如下表所示。
? ? ? ? 如下图所示,二进制日志对每一个事务仅保存一个日志,且按事务提交的顺序写入;重做日志对每个事务则对应多个日志条目(不同的页修改操作)且事务并发写入,不是事务提交的顺序写入。 ![]() ? ? ? ? ②. 重做日志格式? ? ? ??重做日志格式组成如下图所示,可以看出redo log是记录页的修改操作。 ????????根据不同的重做日志类型,会有不同的redo log body,如下图所示。 ![]() ? ? ? ? ③. 日志块(log block)?????????InnoDB存储引擎中,重做日志以512字节(块)存储,即:重做日志缓存、重做日志文件都是以块的形式进行保存,称之为“重做日志块”(redo log block)。重做日志块大小与磁盘扇区大小一样都是512字节,因此重做日志写入可以保证原子性,无需doublewrite技术。若修改页的重做日志大于512字节,则需要分割多个重做日志块进行存储。 ????????重做日志块的组成:块512字节 = 头部12字节 + 内容 492(512-12-8)字节 + 尾部8字节,如下图所示。内容存储重做日志(重做日志格式见上小节)。 ????????注意:其中LOG_BLOCK_FIRST_REC_GROUP表示块中第一个事务开始位置的日志偏移量, 如下图所示。 ? ? ? ? ④. 日志组(log group)????????重做日志组(log group)是个逻辑概念,由多个重做日志文件组成。组内的文件大小相同,默认总大小512GB。默认情况下,一个InnoDB存储引擎只有一个日志组。 ????????重做日志文件存储的就是重做日志缓冲里面的重做日志块,也是以块的形式管理。InnoDB存储引擎运行过程中,重做日志缓存刷新到磁盘的时机如下:
? ? ? ? 日志块追加到重做日志文件的尾部,当文件被写满时,则写入下一个重做日志文件,即:采用round-robin方式写入。? ? ? ? ? ? ? ? ⑤. 日志序列编号(LSN)????????日志序列编号(Log Sequence Number _ LSN)表示写入重做日志的字节总数,占用8字节且单调递增。 ????????LSN不仅在重做日志,而且还在每个页中。LSN的含义如下:
????????⑥. 恢复????????InnoDB存储引擎启动时,不管上次是否正常关闭,则都会尝试进行恢复数据操作。读取重做日志文件,根据数据页Checkpoint的LSN与重做日志文件中修改页的LSN进行比较,来判定数据页是否需要恢复操作。 ? ? ? ? 重做日志是物理日志,则幂等。而二进制日志是逻辑日志,恢复慢。所以,重做日志恢复速度比二进制日志恢复快。 2. undo日志(undo log)????????①. 基本概念????????对数据库修改时,不仅会产生redo log,而且还会产生undo log。回滚日志(undo log)记录修改行的操作,是逻辑日志,存放在共享表空间的undo段(undo segment)。其目的:事务回滚,MVCC技术来实现事务一致性。 ? ? ? ? 当InnoDB存储引擎回滚时,实际做的事与先前相反的工作,如下所示。
????????MVCC技术是通过undo log完成,当读取行时,判断该行是否被其他事务占用,若是则当前事务通过undo读取之前的行版本信息,实现非锁定读。 ? ? ? ? 事务提交对undo log的处理:
????????需要注意的是,写入undo log日志的过程,也伴随着产生redo log,即:undo log也需要通过redo log来持久化。 ? ? ? ? ②. undo日志格式????????回滚日志格式分类,如下:
? ? ? ? 注意,对于INSERT操作回滚时,则直接删除,符合事务的隔离性(只对当前事务可见,其他事务不可见),而DELETE/UPDATE操作,则放入链表等purge操作真正删除或修改;undo log是逻辑日志,只是将数据逻辑的恢复之前的样子,则回滚被逻辑的取消,但是表空间大小不会因回滚而收缩。 ? ? ? ? ③. undo存储管理?? ? ? ? InnoDB存储引擎对undo segment的管理采用段的方式,支持同时在线的事务数量为:128 * 1024。 回滚段(rollback segment):一个undo段(undo segment)支持128个rollback segment undo日志段(undo log segment):每个rollback segment有1024个undo log segment,在该段中进行undo页的申请 ? ? ? ? 与rollback segment相关的参数有:
? ? ? ? 事务提交时,判定undo页是否重用:
3. purge操作????????当DELETE删除一条记录时,将记录delete flag设置为1,记录并没有删除,还存在于B+树中。所以DELETE和UPDATE操作并不直接删除或修改原有数据,而是“延迟”在purge操作中完成。因此purge用于完成DELETE、UPDATE操作。 ????????purge用于完成DELETE、UPDATE操作,这样的设计InnoDB存储引擎支持MVCC,若该行记录不被其他事务引用,则可以真正删除操作。根据之前undo log的介绍,一个undo页有多个事务的undo log存在,后面的事务总在最后,但不是事务提交顺序。因此,InnoDB存储引擎有个history list,目的是按事务提交的顺序,将undo log进行链接(先提交放在尾端)。 ![]() ? ? ? ? 如上图所示,?purge操作的过程如下。清除undo page,避免大量随机读取操作,提高purge效率。
? ? ? ? 与purge有关的相关参数,innodb_purge_batch_size越大,每次回收undo页就越大,但是太大会导致CPU和磁盘过于集中处理导致性能下降。
4. 组提交(group commit)????????对于非只读事务时,每次提交事务后需调用一次fsync操作,来保证redo日志已经写入磁盘,而对磁盘的操作效率很慢。因此MySQL提供组提交的功能,其目的是一次fsync刷新多个事务日志写入重做日志文件(提高磁盘fsync效率)。 ????????MySQL5.6版本之前,开启二进制日志后,group commit功能会失效,而MySQL5.6采用BLGC(Binary Log Group Commit)实现方式。提交顺序放入队列,第一个为leader,其他follower,leader控制follower的行为,如下图所示。BLGC的三个阶段:
![]() ????????当有一组事务在进行Commit阶段时,其他新事务可以进行Flush阶段,从而使group commit不断生效。参数binlog_max_flush_queue_time控制group commit时的flush阶段中等待时间,默认0(不等待),当一组事务完成提交,当前一组事务也不马上进入Sync阶段,而是等待一段时间。 三、事务的隔离级别????????SQL标准定义的四个隔离级别为:
????????REPEATABLE READ是2.9999?的隔离,没有幻读的保护;而SERIALIABLE称为隔离,或是3?的隔离。SQL和SQL2标准默认事务隔离级别是SERIALIABLE。 ? ? ? ? 需要注意的是InnoDB存储引擎默认事务隔离级别是REPEATABLE READ,与SQL标准不同的是,InnoDB存储引擎在该级别下使用Next-Key Lock锁的算法,避免的不可重复读,已经达到了事务的隔离性要求,即达到了SERIALIABLE的隔离性要求。 ? ? ? ? InnoDB存储引擎的隔离性是通过锁实现的。READ COMMITTED隔离级别,则采用Record Lock算法,关闭了Gap Lock;REPEATABLE READ隔离级别时,采用Next-Key Lock(Record Lock + Gap Lock);SERIALIABLE隔离级别时,对每个SELECT语句自动加上LOCK IN SHARE MODE,加共享锁,因此读占用了锁,对一致性非锁定读不支持,此时隔离级别符合数据库理论的要求。 四、隐式提交的SQL????????隐式提交是指执行完这些SQL语句后,会有一个隐式COMMIT操作。如下所示,列出隐式提交有哪些SQL语句。注意TRUNCATE TABLE与DELETE一样,但是不能回滚。 ![]() 五、参考资料 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年5日历 | -2025/5/11 5:13:27- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |