通过这篇文章可以了解到下面几个问题
总结以上的三个问题,其实就是关于MySQL innodb事务的流程;那么接下来,我将详细总结下一一一:MySQL innodb的事务流程:
1.接下来我就以update为例,讲解下MySQL5.6的innodb的事务流程,总结起来就是:
镇对update he set where id=5;
1)事务开始
2)对id=5这条数据上排他锁,并且给5两边的临近范围加gap锁,防止别的事务insert新数据;
3)将需要修改的数据页PIN到innodb_buffer_cache中;
4)记录id=5的数据到undo log. 5)记录修改id=5的信息到redo log.
6)修改id=5的name='liuwenhe'.
7)刷新innodb_buffer_cache中脏数据到底层磁盘,这个过程和commit无关;
8)commit,触发page cleaner线程把redo从redo buffer cache中刷新到底层磁盘,并且刷新innodb_buffer_cache中脏数据到底层磁盘也会触发对redo的刷新;
9)记录binlog (记录到binlog_buffer_cache中)
10)事务结束;
2.关于事务的四大特性ACID
事务的原子性(Atomicity):事务中的所有操作,要么全部完成,要么不做任何操作,不能只做部分操作。如果在执行的过程中发生了错误,要回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过。
事务的持久性(Durability):事务一旦完成,该事务对数据库所做的所有修改都会持久的保存到数据库中。为了保证持久性,数据库系统会将修改后的数据完全的记录到持久的存储上。
事务的隔离性:多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果
事务的一致性:一致性是指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。这是说数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
二:redo和undo保证MySQL innodb事务的原子性和持久性:
总起来概述可以认为:
undo用来保存数据更改之前的数据;保证原子性
redo用来保存数据更改之后的数据(注意是物理的修改信息),保证持久性
1)首先介绍Undo Log
Undo Log 主要是为了实现事务的原子性,在MySQL数据库InnoDB存储引擎中,还用Undo Log来实现多版本并发控制(简称:MVCC),之后的文章将会介绍mvcc;
Undo Log的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方
也就是 Undo Log,然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。
需要注意在MySQL 5.6之前,undo log是放在了共享表空间 ibdata1中的,MySQL5.6中开始支持把undo log分离到独立的表空间,并放到单独的文件目录下;采用独立undo表空间,再也不用担心undo会把 ibdata1 文件搞大。
undo log是为回滚而用,具体内容就是copy事务前的数据库内容(行)到innodb_buffer_pool中的undo buffer(或者叫undo page),在适合的时间把undo buffer中的内容刷新到磁盘。undo buffer与redo buffer一样,也是环形缓冲,但当缓冲满的时候,undo buffer中的内容也会被刷新到磁盘;并且innodb_purge_threads后台线程会清空undo页、清理“deleted”page,InnoDB将Undo Log看作数据,因此记录Undo Log的操作也会记录到redo log中。这样undo log就可以象数据一样缓存起来
2)接下来介绍 Redo Log,注意是先写redo,然后才修改buffer cache中的页,因为修改是以页为单位的,所以先写redo才能保证一个大事务commit的时候,redo已经刷新的差不多了。反过来说假如是先改buffer cache中的页,然后再写redo,就可能会有很多的redo需要写,因为一个页可能有很多数据行;而很多数据行产生的redo也可能比较多,那么commit的时候,就可能会有很多redo需要写;
和Undo Log相反,Redo Log记录的是新数据的备份。在事务提交前,只要将Redo Log持久化即可,
不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是Redo Log已经持久化。系统可以根据Redo Log的内容,将所有数据恢复到最新的状态。需要注意的是,事务过程中,先把redo写进redo log buffer中,然后MySQL后台进程page cleaner thread适当的去刷新redo到低层磁盘永久保存;
因为刷新buffer pool的脏数据之前,必须要先刷新redo(从redo log buffer到磁盘),所以触发刷新脏数据buffer pool的脏数据的条件也同时会触发刷新redo。还需要注意:MySQL 5.6版本之前都是master thread来完成刷脏数据的任务(包括buffer pool中的脏数据以及redo log buffer中的redo),MySQL 5.6版本,刷新操作放入到了单独的Page Cleaner Thread中;
Checkpoint(检查点)技术目的是解决以下几个问题:1、缩短数据库的恢复时间;2、缓冲池不够用时,将脏页刷新到磁盘;3、重做日志不可用时,刷新脏页。
在InnoDB存储引擎内部,有两种Checkpoint
分别为:Sharp Checkpoint、Fuzzy Checkpoint