核心日志
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值使用的格式,