mysql 事务与日志
**************************
InnoDB 存储引擎事务功能实现
mysql innodb存储引擎的事务功能通过redo log以及undo log来实现,
redo log:实现事务的原子性、持久性,
undo log:实现事务的一致性,用来帮助事务回滚以及mvcc功能的实现
事务的隔离性通过mvcc以及锁来实现
**************************
redo log
redo log与二进制日志的区别:
redo log:在数据库引擎产生的,记录对页的修改,事务执行过程中写入
二进制日志:数据库上层产生的,记录sql语句,事务提交时写入
redo log 存储内容
redo 由两部分组成:redo log buffer、redo log file
事务提交时,redo log buffer刷盘写入事务日志文件(redo log file),完成事务持久化;
事务提交时,为提高事务执行效率,也可不将redo log buffer写入事务日志文件,但事务可能丢失
redo log存储形式:以块的形式保存
每个日志块的大小为512字节,重做日志头占用12字节、重做日志尾占用8字节,实际存储的数据量为492字节;
重做块可以重用,若一个重做块还有剩余空间,还可以继续写入内容
事务提交后,日志刷盘控制参数:innodb_flush_log_at_trx_commit
0:每隔1秒将缓冲内容刷新到事务日志文件
1:提交事务时刷新到事务日志文件,该值为默认值
2:只写入缓冲,由系统调用刷盘写入事务日志文件,若系统故障,可能会导致事务丢失
数据恢复:数据库启动时,会检查内存中的LSN(日志序列号)与日志文件中的LSN,
若内存中的LSN小于日志文件中的LSN,则加载日志中的数据到内存中;
若内存中的LSN大于日志文件中的LSN,表示还有部分数据未被刷盘到日志文件中,不需要做数据恢复
**************************
undo log:回滚时,通过undo log回滚到事务初始状态
事务回滚时,执行最初操作的反向操作:
insert 操作:回滚时删除插入的数据
delete 操作:回滚时执行insert操作
update 操作:回滚时执行反向的update操作
undo log可实现mvcc功能,若行记录被其他事务占用,可用undo log读取事务开始前的数据
undo log存储:undo segment
每个undo_tablespace可以创建128个rollbck segment,
每个rollback segment记录1024个undo log segment,
每个undo log segment进行undo页的申请
undo_tablespaces可以动态调整,可创建的rollback segment的数量为:undo_tablespaces * 128,
undo log segment的数量为:undo_tablespaces *128 * 1024
说明:undo log segment的数量表示同时支持的最大事务数量(事务并发度)
rollback segement相关参数:
innodb_undo_directory:rollback segment的存储位置,默认为存储引擎的数据目录
innodb_undo_log_encrypt:undo_tablespaces加密,默认off
innodb_undo_log_truncate:默认超过1g(innodb_max_undo_log_size),触发truncate
innodb_undo_tablespaces:共享表空间的数量,默认为2,可动态调整
事务回滚undo log处理:事务回滚,直接执行反向的undo log操作
事务提交undo log处理
insert操作:插入操作对其他事务不可见,事务提交时undo log可直接删除
update、delete操作:其他事务可能正在使用update、delete对应的行记录,需要根据undo log读取数据快照(MVCC);
因此在事务提交时,事务如果包含update、delete操作,则事务的undo log需加入history list中,由purge操作删除;
purge 操作(灰色表示事务仍在使用)
在history list上查找第一个需要被清理的事务(此处为trx1),trx1在undo page1上,删除trx1;
undo page可以重用,undo page存在多个事务,undo page1上的事务(trx3)可直接删除;
undo page1上的trx5还在使用,不能被删除,返回history list查找可删除的undo log;
history list尾端事务trx2可删除,trx2所在页为undo page2,undo page2上的事务trx6、trx4都已经提交,可直接删除
**************************
二进制日志组提交(BLGC)
binary log group commit:为提高事务的处理性能,二进制日志提交时使用组提交进行批量提交
数据库上层事务提交时,将事务按顺序放入队列中,队列中的第一个事务为leader,其余为follower,leader控制着folower的行为
flush 阶段:将事务的二进制写入缓存
sync 阶段:将缓存中的二进制日志刷新到二进制文件(若有多个事务,一次sync就可完成二进制日志的写入,这就是BLGC)
commit 阶段:leader按顺序调用存储引擎事务的提交(存储引擎本就支持组提交)
binlog_max_flush_queue_time:刷盘等待时间,默认为0
说明:该参数控制flush阶段等待一定时间后触发sync,以使group commit阶段有更多的事务提交,但会导致事务响应时间变慢,推荐设为0