Mysql事务的实现原理

核心日志

1、Redo Log

2、Undo Log

3、BinLog


redoLog,保持继续执行恢复没有写入的功能日志,物理日志,innoDB独有。

undoLog,回滚操作,生成与执行相反的逻辑日志,且提前会有快照放在undoLog里面,有备份。

BinLog,二进制日志,mysql自身日志,主要是主从复制,数据恢复(使用mysqlbinlog)。

1、事务的实现原理

继续解析:

Mysql的事务实现,离不开RedoLog和UndoLog.

ACID

A(原子性 Atomicity),D(持久性 Durability),是由redoLog实现的

C(一致性,Consistency)是有undoLog执行的,保证失败可以回滚。

I(隔离性,isolation):隔离性是由锁和MVCC机制实现的。 一个悲观锁,一个乐观锁,每个都能找到相应的原数据。

1.1 RedoLog:

1、基本原理:

redoLogBuffer ->持久化,redoLog file ->(已经提交,还没写入IBD文件的数据)

2、刷盘规则:

Redo Log Buffer(是存放在操作系统的用户空间中) ->通过操作系统的内核空间缓冲区(OS buffer)-> fsync()->logfile

有一个O_DIRECT标志位,可以不通过OS BUFFER。但是redoLog没有使用。

物理日志,顺序循环,最后一个文件写满会向第一个文件写数据,也就是覆盖写。

3、RedoLog的LSN机制

log sequence number(日志的逻辑序列号,8字节的存储空间,单调递增)

1)RedoLog写入数据的总量

2)检查点位置

3)数据页版本相关的信息

机制

每个数据页,表头有一个fil_page_lsn,记录当前最终的LSN值。

将数据页的LSN与RedoLog的LSN值比较,如果数据页小于log,就是表示丢失了一部分数据,这个时候就用redolog来恢复数据,不然就不恢复。

1.2 Undo Log

作用:

  • 回滚事务

  • 多版本并发事务(MVCC)

发生:

启动事务之前,修改的数据记录存储到UndoLog中,如果事务回滚或MySql数据库崩溃,可以利用 UndoLog对没有提交的事务进行回滚,保证数据库的数据一致性。

UndoLog消失

undoLog产生于事务开始前,提交不会立刻删除,会放到待删除列表,让purge thread进行删除处理

undoLog机制

逻辑日志,

1)数据库执行insert,undoLog记录一条Delete;

2)数据库执行一条Delete,UndoLog会记录一条对应的Insert语句;

3)当数据库执行一条update语句时,undoLog会记录一条相反的update语句。???

UndoLog需要持久化,会产生redoLog。

undoLog的可靠性和完整性需要RedoLog来保证;

因此数据库崩溃先做RedoLog数据恢复,然后做UndoLog回滚。

1.2.1 UndoLog基本原理

都需要经过OS Buffer持久化。

如果日志中,设置了O_DIRECT的标志位,可以不经过OS BUFFER。

1.2.2 实现MVCC机制

多版本控制(MVCC)

1、提交之前,向UndoLog保存事务当前的数据,这些保存到UndoLog的旧版本数据可以作为快照供其他并发事务进行快照读。

2、select语句查询的数据被其他事务锁定,可以从UndoLog分析出当前数据之前的版本,从而向客户端返回之前的数据。

undo 回滚段,分为 insert 和 update;

1)insert undo log:事务对插入新记录产生的undo log,只在事务回滚时需要,在事务提交后可以立即丢弃。(但是没有丢吧?有点问题)

2)update undo log:进行删除和更新操作产生的undoLog,不仅回滚需要,一致性读也需要,因此不能随便删除,只有当数据库所使用的快照不涉及该日志记录,对应的回滚日志才会被purge线程删除。

可重复读隔离级别:MVVC

数据库每行数据后面添加了3个字段,

  • 6字节的事务id(DB_TRX_ID)字段;记录最后一次修改本行记录的事务id

  • 7字节的回滚指针(DB_ROLL_PTR)字段, 指向上一个版本的行记录(通过undo 找到相应的数据)

  • 6字节的DB_ROW_ID字段。(聚集索引行id)

1.3 BinLog

binlog,二进制日志。

记录mysql所有数据库表结构变更和表数据变更的二进制日志。

  • 不会记录注入select和show这类查询操作的日志 。

  • 同时,以事件形式记录相关变更操作的,并且包含语句执行消耗的时间。

1.3.1 重要使用场景

  • 主从复制:开启BinLog,主数据库把BinLog发送到从数据库,从数据库获取BinLog,

通过IO线程将日志写到中继日志,也就是RelayLog。通过sql线程将relayLog中的数据同步到从数据库,达到主从数据库的一致性。

  • 数据恢复:mysql数据库故障或者崩溃, BinLog进行数据恢复,例如可以使用mysqlbinlog等工具进行数据恢复

1.3.2 BinLog记录模式

1)Row

记录每一行,非常清楚记录每一行的修改情况。

  • 优点:完全实现主从同步和数据恢复

  • 缺点: 大批量操作,二进制内容日志暴涨,影响主从数据库的同步性能

2)Statement

记录每一条修改数据的sql语句。

SQL进程将BinLog中的sql语句解析成和Mysql主数据库中执行过的sql语句相同的sql语句,然后在从数据库执行SQL进程解析出来的sql语句。

  • 优点:不记录数据的修改细节,只是记录数据表结构和数据变更的sql语句,产生日志小,减少IO操作,提高数据存储和恢复的效率。

  • 缺点:某些情况,主从不一致。比如主数据库使用了last_insert_id(),和now()等函数,会导致mysql主从数据库中的数据不一样。

3)Mixed

row和statement一起用。

使用Statement模式保存BinLog,存在state模式无法复制的操作,例如使用last_insert_id(),和now()等函数,会使用Row模式。

Mysql会根据执行的sql语句选择写入的记录模式

1.3.3 BinLog文件结构

各种更新操作。

修改操作:Log Event

Query Event,Row Event, Xid Event。

文件结构,

timestamp,type_code,server_id,event_length,next_position,flags,extra_headers

1.3.4 BinLog写入机制

先记录BinLog 二进制日志,再记录事务日志。

BinLog就是各种日志事件的集合。

操作:

1)根据记录的模式(Row,Statement,Mixed)和操作(create,drop,alter,insert,update)等触发事件,生成日志事件(事件触发执行机制)

2)将日志事件写入相应的缓冲区(binlog_cache_mngr),

这个数据结构有两个缓冲区,一个是stmt_cache,不支持事务的信息;

一个是trx_cache,用于存放支持事务的信息。

3)事务commit阶段,会将日志文件写入磁盘的BinLog中。

不同的事务会以串行的方式将日志事件写入BinLog,所以一个事务包含的日志事件在BinLog文件中是连续的,中间不会插入其他事务的日志事件。

综上,一个事务的BinLog是完整的,并且中间不会插入其他事务的BinLog

1.3.5 BinLog的组提交机制

提高Mysql日志刷盘的效率,Mysql数据库提供了组提交(group commit)的功能。

通过组提交功能,调用一次fsync()函数将多个事务的日志刷新到磁盘的日志文件中,而不是单个事务的日志单独刷新,提升刷盘效率。

提交事务。

两个阶段的操作:

  • 修改内存中的事务信息,并且写入相应的RedoLogBffer

  • 调用fsync(),将redo log buffer中的日志信息刷新到磁盘的Redo log文件中。

BinLog,5.6之前会失效,mysql需要保证binlog 和事务日志的一致性,使用了两阶段事务。

1)事务提交,Innodb 存储引擎需要进行prepare操作。

2)将更新写入BinLog操作。

3)将事务日志写入RedoLog。

保证一致性的话,prepare阶段,会启用一个prepare commit mutex锁,会导致开启二进制日志后 组提交功能 失效。

5.6之后。

会将事务按照一定的顺序放入一个队列当中,第一个事务称leader,其他事务叫follower.

移除了prepare commit mutex锁。

实现方式成为 二进制日志组提交(Binary Log Group Commit)BLGC.

1) flush,将每个事务的BinLog写入对应的内存缓冲区

2)sync,将内存缓冲区的binlog写入磁盘的binlog,如果队列有多个事务,此时只执行一次刷盘操作就可以将多个事务的binlog刷新到磁盘的binlog。

3)commit,leader事务根据队列中事务的顺序调用的存储引擎层事务的提交操作。

2 Mysql事务流程

2.1 mysql事务执行流程

MySQL Innodb Engine--DML操作时先生成Undo Log还是先生成Redo Log

答案:先生成Undo Log,再生成Redo Log。

在生成Undo Log并写入到Undo Space时,会产生Redo Log。

在故障恢复时,可以通过Redo Log来恢复Undo Log,再通过Undo Log来回滚事务。

2.2 Mysql事务恢复流程

事务提交之前GG,

会先使用RedoLog,先做恢复数据,然后使用undolog回滚数据,

事务提交之后GG,

会使用redoLog恢复数据。

先恢复看看,如果提交了就结束

没有提交就undo.

2.3 Mysql的XA事务

mysql5.0.3版本支持XA事务,只有Innodb支持。 connector/j 5.0.0版本之后支持XA事务。

2.4 XA事务的基本原理

XA事务支持不同数据库之间实现分布式事务。

XA事务其实是二阶段提交的分布式事务。

使用XA事务,数据库事务隔离级别需要设置成串行化。

XA事务组成:

  • 事务管理器 控制所有事务的协调者。

  • 资源管理器 所有数据库连接。

  • 应用程序

2.5 XA事务语法

查看存储引擎是否支持XA事务

show engines \G

XA STARTXA END xidXA PREPARE xidXA COMMIT xidXA ROLLBACK xidXA RECOVER (查询)

XA事务使用XID标识分布式事务,xid主要由以下几部分组成。

xid:gtrid [,bqual[,format Id]]

gtrid: 必须,字符串,表示全局事务标识符

bqual:可选,字符串,默认空串,表示分支限定符,

formatId:可选,默认1,用于标识gtrid和bqual值使用的格式,

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值