目录
关于binlog,redo log,undo log的操作顺序
MySQL中的日志类型:
1,Error Log,错误日志。
2,General Query Log,查询日志,记录了每条sql的信息,包括查询和修改等,对性能影响比较大。
3,Slow Query Log,慢查询日志,记录查询比较慢的sql。可以设置阈值。
4,Binary Log,也就是binlog,二进制日志,归档日志,记录了数据库改动。包括建表,删表,数据修改等。
5,Redo Log,重做日志。用于恢复提交后的物理数据页。
6,Undo Log,回滚日志。用于回滚行记录到某个版本。
redo log和undo log篇
redo log和undo log属于事务日志。
redo log是重做日志。用于备份未提交的事务。是在事务执行的过程中写入,如果写入磁盘前发生故障,重启MySQL后会根据redo log重做。保证事务持久化。
undo log是回滚日志。用于回滚行记录到某个版本。在事务提交前写入,记录了事务的旧版本,可以给其他并发事务进行未锁定读取。保证事务的原子性和事务并发控制。
关于redo log
redo log存在的意义是保证事务持久化。
一,redo log的文件
redo log日志文件大小固定。
默认日志文件在mysql目录的data子目录下,ib_logfile1和ib_logfile2两个文件,大小相同,循环使用。
redo log是物理日志,记录数据页更新的内容。
redo log以块为单位存储,每块512字节,包括:
日志块头,12字节
日志块尾,8字节
日志主体,492字节
在redo log buffer和redo log文件中都是这样存储的。
二,redo log的写入
redo log在内存中有一个缓存区Innodb_log_buffer,记录redo log时,先将日志写入内存的缓存区,再刷到磁盘中。
redo log不是随着事务提交才写入文件的,而是从事务开始就逐步写入文件了(即使事务还没提交)。
三,redo log的删除
当事务提交并写入磁盘后,redo log就没用了,所以redo log的写入是循环写入的,先写ib_logfile1,再写ib_logfile2,ib_logfile2写满了就把ib_logfile1从头擦除继续写入。
四,查看redo log相关的配置
show global variables like "innodb_log%";
show global variables like "innodb_flush_log_at_trx_commit%";
其中:
innodb_log_file_size,是日志文件大小
innodb_log_group_home_dir,是日志组文件位置。默认./,会使日志文件存放在mysql目录的data子目录下。
innodb_log_files_in_group,是文件组个数,目录下会有相同大小的日志文件。
innodb_flush_log_at_trx_commit,事务日志刷盘策略
0表示每秒从log buffer刷到OS buffer,然后刷到磁盘文件。当系统崩溃时,会丢失1秒的数据。
1表示每次事务提交从log buffer刷到OS buffer,然后刷到磁盘文件。系统崩溃时不会丢数据,但性能较差。
2表示每次事务提交从log buffer刷到OS buffer,每秒刷到磁盘文件。
注:OS buffer是操作系统内核缓存
关于undo log
undo log的设计是为了保证事务的原子性和事务并发控制。
undo log是逻辑日志,记录数据库表的行信息。
举例:当delete一条记录时,undo log里会记录一条insert日志,update时也会记录一条相反的update日志。
undo log的日志文件保存在共享空间表中,在mysql目录的data子目录下的ibdata1文件。
当事务发生异常或显式回滚时,MySQL使用undo log回滚数据。
一,undo log的文件
undo log的日志文件默认保存在共享空间表中,位于mysql目录的data子目录下的ibdata1文件。5.6版本开始支持独立的表空间。
如果开启了innodb_file_per_table,将放在每个表的.ibd文件中。
innodb_undo_tablespaces变量可以控制rollback segment默认放在多少文件中,默认是0,表示都放在一个文件中。
二,undo log的写入
undo log在事务开始刚开始就会产生,保存事务开始前的数据。
undo log也会产生redo log。
mysql5.7之后有“独立undo表空间”
三,undo log的空间释放
当事务提交之后,undo log并不能立马被删除,而是由purge线程判断是否还有事务在使用undo log记录的信息,以此决定是否释放日志空间。
四,查看redo log相关的配置
show variables like "%undo%";
其中:
innodb_undo_directory,日志文件位置,默认是.,即mysql目录的data目录。
innodb_undo_logs,支持的rollback segment回滚段数。默认128。
innodb_undo_tablespaces,控制rollback segment默认放在多少文件中。默认0。
五,关于undo log的segment
undo log是用segment(段)方式来记录的,每个undo log占用一个undo log segment。
rollback segment称为回滚段,每个回滚段中有1024个undo log segment。
启用的回滚段数可由innodb_rollback_segments(5.6以前,默认是1)或innodb_undo_logs(5.6以后,默认是128)参数来修改。
redo log和undo log的协作
redo log和undo log一起保证了事务的持久性和原子性。
假设有A、B两个数据,值分别为1,2,在一个事务中把A改成3,把B改成4,操作顺序如下:
- 事务开始。
- 记录A=1到undo log。
- 修改A=3。
- 记录A=3到redo log。
- 记录B=2到undo log。
- 修改B=4。
- 记录B=4到redo log。
- 将redo log写入磁盘。
- 事务提交。
注:要先把redo log写入磁盘才能提交事务,否则无法保证持久性。
关于XA
XA是分布式事务的规范,定义了事务管理器和资源管理器间的接口。
XA把事务的提交分为了两个阶段,以此来实现分布式事务。
两个阶段分别是:
1,prepare阶段。事务管理器向相关数据库服务器发送prepare请求,数据库服务器接收到请求后修改数据,成功后把事务状态改为可以提交并返回。
2,commit阶段。如果prepare阶段所有数据库都返回成功,则向所有数据库服务器发送确认提交请求,否则发送回滚指令。
关于binlog,redo log,undo log的操作顺序
5.6版本以前:
1,开始提交事务
2,进入prepare阶段
3,写内存中的事务日志,写内存中的binlog
4,提交事务
5,将binlog和事务日志刷到磁盘。
5.6版本以后,引入事务队列,队列的第一个事务作为leader,其余事务为follower,操作步骤如下:
1,flush阶段。向内存中写入每个事务的二进制日志。
2,fsync阶段。将内存中的二进制日志刷盘。此过程还经过了操作系统内核空间缓存(OS buffer),若队列中有多个事务,那么仅一次fsync操作就完成了二进制日志的刷盘操作。
3,commit阶段:leader根据顺序调用存储引擎层事务的提交,事务状态改为completed。
本文完