暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

事务

MySQLDBA修炼之路 2019-05-17
207

事务数据库的事务,可以是一个非常简单的SQL,也可以是一组sql构成的,事务是访问或者更新数据库的一个单元。

begincommit一个事务内的语句,要么全部成功,要么全部失败不存在部分成功,部分失败的情况

事务的四个特性原子性:一个事务内的任务要么全部执行成功,要不全部不执行一致性:事务的整个执行过程中,数据库的完整性的约束不能被破坏隔离性:事务的隔离性要求当前事务的操作,不会受到其他事务的影响持久性:事务一旦提交那么结果是持久性的,即使宕机,也不影响

Redo的作用

1、持久化数据

在数据库commit的时候,必须要保证redo的安全性,必须要保证redo已经落盘,才能返回提交成功的结果。redo是记录了Innodb数据库所有的数据变化,所以只要redo能落盘,数据就已经持久化,如果发生了宕机,在重启数据库后,可以通过redo直接进行数据库的恢复操作。

比对redo的lsn和数据的lsn,如果数据页的lsn比redo小,那么就需要通过redo对数据页进行重做,保证事务的特性。

2、效率提高性能

为什么在落盘的时候是提交redo到硬盘,而不是直接刷新脏块,主要原因

redo效率

1、脏块的数据量比较大,落盘脏块的话,一个块16KB,我们即使只修改一条数据,那么也需要整个脏快落盘,对于系统的IO压力很大,而redo记录的是数据库的修改的数据页的变化情况,而且

a.redo的落盘操作是顺序IO,性能较好

b.redo只记录数据页的改变情况,数据量很小

c.redo的数据库和硬盘块是一样的,IO效率高

注意:

redo落盘是持续在事务执行的整个过程中的,并不是commit的时候才进行redo落盘的操作,这样的目的在于redo的落盘和脏块的落盘是完全两个过程。

1、DML操作导致的页面变化,均需要记录Redo日志(物理日志);

2、在页面修改完成之后,在脏页刷出磁盘之前,写入Redo日志;

3、日志先行(WAL),日志一定比数据页先写回磁盘;

4、 聚簇索引/二级索引/Undo页面修改,均需要记录Redo日志;

undo作用1、回滚事务2、保证mvcc多版本高并发控制innodb把undo分两类1、新增(insert))2、修改undo(update del)

insert在事务执行完成后,回滚记录就可以丢掉了。但是对于更新和删除操作而言,在完成事务后,还需要为MVCC提供服务,这些日志就被放到一个history list,用于MVCC以及等待purge。undo日志的正确性是通过redo来保证的,所以在数据库恢复的时候,需要先恢复redo,在所有数据块都保证一致性的情况下,在进行undo的逻辑操作。

检查点(checkpoint)

检查点解决的问题

1. 缩短数据库恢复时间

2. 缓冲池不够用的时候,刷新脏页到磁盘

3. 重做日志不够用的时候,刷新脏页

当数据库发生宕机的时候,数据库不需要恢复所有的页面,因为检查点之前的页面都已经刷新回磁盘了。故数据库只需要对检查点以后的日志进行恢复,这就大大减少了恢复时间。

检查点类型sharp和fuzzysharp,关闭数据库的时候设置innodb_fast_shutdown=1,在关闭数据库的时候,会刷新所有脏页到数据库内。fuzzy checkpoint在数据库运行的时候,进行页面的落盘操作,不是全部落盘,是落盘一部分数据

mysql两个阶段提交存储引擎+server层提交存储引擎 redoserver binlogredo binlog 在事务的提交过程中, 要保证两个日志的事务的顺序是一致的。

先写binlog落盘--重做缓存--redo

MySQL二阶段提交流程:事务的提交主要分三个主要步骤:

1、Storage Engine(InnoDB) transaction prepare阶段:此时SQL已经成功执行,并生成xid信息及redo和undo的内存日志。

2、Binary log日志提交:write()将binary log内存日志数据写入文件系统缓存。fsync()将binary log文件系统缓存日志数据永久写入磁盘。

3、Storage Engine(InnoDB)内部提交:修改内存中事务对应的信息,并且将日志写入重做日志缓冲。调用fsync将确保日志都从重做日志缓冲写入磁盘。

一旦步骤2中的操作完成,就确保了事务的提交,即使在执行步骤3时数据库发送了宕机。此外需要注意的是,每个步骤都需要进行一次fsync操作才能保证上下两层数据的一致性。步骤2的fsync参数由sync_binlog控制,步骤2的fsync由参数innodb_flush_log_at_trx_commit控制。

事务隔离级别

read uncommited 未提交读容易产生脏读的问题,就是本事务读取到其他事务没有提交的数据,读取其他事务在内存中的脏块的数据。

修改隔离级别session级别修改global 修改set session transaction isolation level read uncommited;set global transaction isolation level ****;mysql默认的事务是自动提交的关闭自动提交set autocommit=0;session级别的参数

set session transaction isolation level read uncommitted;set autocommit=0;show variables like '%iso%';

session2读到了sessionq1中没有提交的数据,脏读

RC隔离级别set session transaction isolation level read committed;避免了脏读

select 在session1没有提交的情况下,没有查询到新插入数据,没有造成脏读

但是session1 commit之后,session2读到了不一样的数据

脏读(Drity Read):事务T1修改了一行数据,事务T2在事务T1提交之前读到了该行数据。

不可重复读(Non-repeatable read): 事务T1读取了一行数据。 事务T2接着修改或者删除了改行数据,当T1再次读取同一行数据的时候,读到的数据时修改之后的或者发现已经被删除。

幻读(Phantom Read): 事务T1读取了满足某条件的一个数据集,事务T2插入了一行或者多行数据满足了T1的选择条件,导致事务T1再次使用同样的选择条件读取的时候,得到了比第一次读取更多的数据集。

幻读和可重复读的区别

幻读更多的是针对于insert来说,即在一个事务之中,先后的两次select查询到了新的数据,新的数据来自于另一个事务的insert,一般称之为幻读,通过gap_lock来防止产生幻读(虽然record可以避免数据行被修改,但是却无法阻止insert,gap_lock锁定索引间隙,防止了在事务查询的范围内的insert情况)而可重复读,一般是针对于update和delete来说,可重复读采用了mvcc多版本控制来实现数据查询结果本身的不变。

RR 模式下避免幻读set session transaction isolation level repeatable read;

RR 模式下避免幻读set session transaction isolation level repeatable read;session1                        session2begin                             begin                                      update t1 allinsert 1   阻塞(保证不会有新的数据对update t1的结果产生影响)                                       commit后,session1不再阻塞commit   

-----------------------------------------------------------

RR模式下避免不可重复读set session transaction isolation level repeatable read;session1                                  session2begin                                       begin                                                select t1 mayday(查询是mayday)update t1 cjr(更新数据为cjr)                                                select t1  mayday(查询还是mayday)commit                                                                select t1  mayday (依然mayday)                                                commit                                                select t1 cjr(再次查询是cjr了)

文章转载自MySQLDBA修炼之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论