Mysql-事务

作者: 01010100 | 来源:发表于2018-01-24 11:52 被阅读8次

    事务特性ACID

    原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。

    一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。

    隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。

    持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。

    事务的原子性、一致性、持久性是通过redo/undo log来实现的

    事务的隔离性是通过锁来实现的

    事务理解

    持久性理解

    首先来看一下事务的持久性,也许你会问,事务的持久性:难道不应该等待数据最终写到数据文件中完成持久化吗?

    是的,确实是这样,而且如果等数据最终写到数据文件中标志事务结束,这样绝对确保了事务的持久性,而且根本不需要什么redo log!

    按照上述理解,梳理一下事务的基本流程:

    1,事务开启

    2,先从磁盘中将需要变更的数据读入至内存

    3,在内存中将数据更新

    4,写binlog,并刷到磁盘中

    5,将内存中更改后的数据刷至数据文件

    6,事务提交成功

    这种流程的瓶颈在于第5步,由于数据写到数据文件是IO随机写,速度是非常慢的,所有事务的提交将阻塞在这个过程。可以理解假设update.. where id=1, update.. where id=999,这样两条数据之前是分布在不同的磁盘区域中,现在需要先进行查找再写入,这是非常慢的。

    于是innodb做了一系列优化,在第5步,这里不是等数据写回至数据文件,而是用写redo log来替代。redo log是一种物理日志,类似于内存快照,以追加的方式记录,是顺序IO,写入速度是非常快的。

    所以,真正的事务并不会等到数据真正写入数据中才返回,引入真正的事务提交过程:

    事务提交

    insert into values( ...);

    1、从数据库将需修改数据读入内存中Buffer Pool(下图中无需读入数据,已忽略)

    2、在内存中写undolog

    3、在内存中更新数据,产生脏页Dirty Page(此时与数据文件中的内容不一致)

    4、将事务过程中的变更写入redo log

    5、事务提交,写bin log

    6、redo log 第二阶段,如果5写入成功则commit(即写入提交成功的标志),否则rollback

    后台线程刷磁盘操作(undolog和数据文件的刷入):

    1、将undolog 写入磁盘

    2、将数据写入磁盘

    我们知道undo log用于事务的回滚的,理论上跟redo log一样,也必须在事务提交之前写入磁盘的,而且必须在redo log之前写入!但是仔细看下面淘宝丁奇大神的图,会发现undo log的写入并不需要在事务提交之前完成。这是为何?实际上Undo和Redo Log的这种关联,使得持久化变得复杂起来。

    于是innodb又又作了写优化:将Undo Log看作数据,因此记录Undo Log的操作也会记录到redo log中。这样undo log就可以象数据一样缓存起来,而不用在redo log之前写入磁盘了。

    包含Undo Log操作的Redo Log,看起来是这样的:

    记录1: trx1, Undo log insert undo_insert …

    记录2: trx1, insert …

    记录3: trx2, Undo log insert undo_update …

    记录4: trx2, update …

    记录5: trx3, Undo log insert undo_delete …

    记录6: trx3, delete …

    所以,undolog 由后台线程写入,不用在redo log之前写盘了,不过还是必须在数据写入磁盘之前写入。

    事务与日志

    binlog

    文件:mysql-bin.000001,mysql-bin.000002..

    目的:mysql server层的日志,属于逻辑日志,记录的是变更的sql语句,用于数据库宕机恢复,主备复制等

    log_bin=/var/lib/mysql/binlog/mysql-bin

    redo log

    文件:ib_logfile*文件,

    目的:持久性,参照事务提交过程

    innodb_log_group_home_dir=./logs/redolog(./是mysqlld根目录)

    undo log

    文件:默认存放在共享表空间内,ibdata*文件,磁盘上不存在单独的undo log文件,

          5.6以后也可以设置为独立的文件:innodb_undo_tablespaces

    目的:比较好理解,保存的是变更发生之前的数据,用于回滚

    参考:

    http://9i9icenter.com/huanqiuNews/599f30ca2277046518e85878

    http://www.ywnds.com/?p=8282

    https://www.slideshare.net/mryufeng/mysqlio-12891332

    http://www.zhdba.com/mysqlops/2012/04/06/innodb-log1/

    http://www.cnblogs.com/xinysu/p/6555082.html

    http://www.zhdba.com/mysqlops/2012/04/06/innodb-log1/

    相关文章

      网友评论

        本文标题:Mysql-事务

        本文链接:https://www.haomeiwen.com/subject/zgmyaxtx.html