事务特性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
https://www.slideshare.net/mryufeng/mysqlio-12891332
http://www.zhdba.com/mysqlops/2012/04/06/innodb-log1/
网友评论