欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【mysql】-- Mysql的undo log、redo log、bin log日志

程序员文章站 2022-07-08 14:23:59
...

一、mysql的日志文件

Mysql有七种日志文件:
重做日志(redo log)
回滚日志(undo log)
二进制日志(bin log)
错误日志(error log)
慢查询日志(slow query log)
一般查询日志(general log)
中继日志(relay log)

二、undo log日志–InnoDB特有

2.1、undo log日志介绍

Undo log作用:提供回滚【保证原子性】和MVCC。
Undo log中存储的是老版本数据,当一个事务需要读取记录行时,如果当前记录行不可见,可以通过回滚指针顺着undo log链找到满足其可见性条件的记录行版本。
Undo log是逻辑日志【如当delete一条记录时,undo log记录是对应insert记录。】。
对应的物理文件
Mysql5.7之前,undo表空间位于系统表空间的回滚段中,默认记录在系统表空间的ibdata1的系统数据文件。
Mysql5.7之后,undo表空间可独立配置。
存储方式
Undo log的存储由InnoDB存储引擎实现,数据保存在InnoDB的数据文件中,innodb存储引擎对undo的管理采用段(segment)的方式,具体来说是一种命名为回滚段(rollback segment)的数据结构。
能支持128个rollback segment,每个回滚段(rollback segment)中有1024个undo log segment。
查询undo相关参数show VARIABLES like '%innodb_undo%';

innodb_undo_directory:定义存储的目录路径,默认值./
innodb_undo_log_truncate:参数设置为ON,即开启在线回收(收缩)undo log日志文件,支持动态设置,默认是关闭的
innodb_undo_logs:这个参数是指前面介绍的rollback segment的数量,Mysql5.5版本之后默认设置为128
innodb_undo_tablespaces:该变量默认值为0,表示undo log全部写入一个表空间文件,可以设置这个变量,平均分配到多少个文件中。

2.2、undo log原理

为了满足事务的原子性,在操作任何数据之前,首先将数据备份到undo log,然后进行数据修改,如果出现错误或rollback,系统利用undo log中备份的数据恢复到事务开始之前状态。事务完成后,undo log记录也不会立即删除。

 例如对表A两行进行操作
(1)事务开始
(2)记录行1数据到undo log
(3)修改行1新数据
(4)记录行2数据到undo log
(5)修改行2新数据
(6)将undo log写到磁盘
(7)数据存在buffer pool,合适机会刷入磁盘
(8)事务提交

------ undo log必须先于数据持久化到磁盘,但不需要立即持久化到磁盘,因为每个undo log操作都会有一个redo log记录。

2.3、insert操作的内部机制

insert undo log : 事务对insert新记录时产生的undo log, 只在事务回滚时需要, 并且在事务提交后就可以立即丢弃。

2.4、delete/update操作的内部机制

在InnoDB当中,UPDATE和DELETE操作产生的Undo log都属于同一类型:update_undo log------------事务对记录进行delete和update操作时产生的undo log,不仅在事务回滚时需要,快照读也需要,只有当数据库所使用的快照中不涉及该日志记录,对应的回滚日志才会被purge线程删除。
Delete操作实际上不会直接删除,而是在delete对象上打delete flg,标记为删除,最终的删除操作是purge线程完成。
Update操作分为两种:
如果更新的不是主键列,在undo log反向记录如何update。
如果更新的是主键列,update是先删除该行,再插入一行目标行。

三、redo log日志–InnoDB特有

3.1、redo log文件存在意义

背景
Mysql每次事务提交时,并不会把每次的修改实时同步到磁盘,而是存放在buffer pool中,在合适时机同步到磁盘。
存在现实问题
如果还没同步数据时,mysql出现断电崩溃,那么怎么保证数据的一致性

-----------针对上面的问题,引入redo log:只记录成功事务对数据页做的哪些修改,同时redo log会持久化到磁盘,系统重启后可以读取redo log恢复最新数据【恢复数据的保障,保障了持久性】。

内容
物理格式的内容,记录的是物理数据页面的修改的信息。物理日志,是数据页面的修改之后的物理记录。
redo log又称重做日志文件,InnoDB引擎产生的,用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。【如果数据库掉电,InnoDB存储引擎会使用redo log恢复到掉电前的时刻,以此来保证数据的完整性】。
什么时候产生
在事务执行过程中,便开始写入redo log文件。redo log是事务进行中不断写入,且不是顺序进行写入。Redo log是循环利用。
什么时候释放
对应的事务的脏页写入磁盘后,redo log可释放。 重做日志占用的空间是可以被覆盖。
对应的物理文件
默认情况下,对应的物理文件位于数据库的data目录下的ib_logfile1&ib_logfile2。

innodb_log_group_home_dir:指定日志文件组所在的路径,默认./ ,表示在数据库的数据目录下。
innodb_log_files_in_group:指定重做日志文件组中文件的数量,默认2。
innodb_log_file_size:重做日志文件的大小。
innodb_mirrored_log_groups:指定了日志镜像文件组的数量,默认1

3.2、redo log原理

原理:和undo log相反,redo log记录的是新数据备份。Redo log目的是系统崩溃后进行数据恢复。由于buffer pool池的脏页不是立即刷回磁盘,所以用redo log来保证。Redo log是将事务中每个sql语句单元操作进行记录,且在事务提交时刷入磁盘【可以参数来设置,保证事务操作记录不会丢失】。这样在系统崩溃恢复或重启时,只要根据redo log就可以恢复最新状态的数据。

例如对表A两行进行操作
(1)事务开始
(2)记录行1数据到undo log 【在redo log会插入“行1旧数据写入undo log”的记录】
(3)修改行1新数据
(4)新行1数据记录写入redo log
(5)记录行2数据到undo log 【在redo log会插入“行2旧数据写入undo log”的记录】
(6)修改行2新数据
(7)新行2数据记录写入redo log
(8)将undo log写到磁盘
(9) 准备提交事务,redo日志合适机会写入磁盘;
(10)准备提交事务,bin日志写入磁盘, redo日志改为commit标记;
(11)数据存在buffer pool,合适机会刷入磁盘
(12)事务提交

-----特点说明:
Redo log日志是先写入redo log buffer,随后以每秒将buffer数据写入到磁盘【有这个线程机制】;
Redo log是采用顺序追加的操作,所有并发事务共享存储空间,操作记录是交替记录;
如果一个事务回滚,Redo log之前的记录是不会删除的,像回滚操作的每步sql操作也会依次记录redo log;

3.3、write ahead Log策略

即当事务提交时,先写redo log重做日志,再修改页。这是由于发生宕机而导致数据丢失时,通过重做日志 redo log 来完成数据的恢复。

3.4、 redolog的覆盖和innodb_log_buffer刷入磁盘参数配置

按照redo log日志原理,只要对应buffer pool的脏页刷回磁盘,那么对应的redo log日志就没必要了,那么它占用的磁盘空间可以被后续的redo log日志重用。---------判断redo log日志占用的磁盘空间是否被覆盖,它的依据是对应的buffer pool脏页是否刷回磁盘。
【mysql】-- Mysql的undo log、redo log、bin log日志
按照上面图示分析,在checkpoint_lsn标注时间点的redo log都不能被覆盖。这是保证数据的一致性。对于innodb_log_buffer缓冲区是类似一个“闭环”的内存,从头开始写,写到末尾就又回到开头循环写。InnoDB 的 redo log 一个缓存区innodb_log_buffer【默认8M】,InnoDB先将重做日志写入innodb_log_buffer缓存区。
【mysql】-- Mysql的undo log、redo log、bin log日志
write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件【刷入磁盘】。如果write pos追上checkpoint,不能再执行新的更新,需要删除一些记录,checkpoint推进一下。

innodb_flush_log_at_trx_commit这个参数是决定redolog是什么时候从log buffer中持久化到磁盘的。建议把这个参数的值设置为1,这样可以保证MySQL掉电等异常重启后数据不丢失。

(A)、设置为 0 的时候,表示每次事务提交时都只是把 redo log 留在redo log buffer。由主线程每秒一次执行刷选innodb_log_buffer到重做日志文件【若提交事务,Mysql崩溃,此时内存的数据会丢失】。
(B)、设置为 1 的时候,表示每次事务提交时都将 redo log 直接持久化到磁盘【建议设置】。
(C)、设置为 2 的时候,表示每次事务提交时都只是把 redo log 写到磁盘文件对应的OS cache,此时还不是进入磁盘文件,会有1秒后才会由OS cache进入磁盘文件。

另外,当重做日志缓存可用空间 < 50%,Mysql会暂停事务操作,将redo log buffer重做日志刷新到重做日志文件。

3.5、redolog的数据恢复策略

当数据库系统崩溃,我们需要恢复数据,此时就需要找到合适的时间点对于的redo log文件来恢复。
确定恢复的时间起点
按照checkPoint机制分析,checkPoint_lsn之前对应着脏页已经刷回磁盘。所以从checkpoint_lsn开始读取redo日志来恢复页面。

四、bin log日志–service特有

4.1、bin log文件存在意义

binLog日志是归档日志,逻辑格式的日志,以二进制的形式记录语句的原始逻辑,可以简单认为就是执行过的事务中的sql语句【事务提交完成后一次写入】。在server层实现,任何引擎都可以实现。binlog记录了对MySQL数据库执行更改的所有操作【insert、update、delete】。
主要用于数据库的主从复制与及增量恢复。
什么时候产生
事务提交的时候,一次性将事务中的sql语句(一个事务可能对应多个sql语句)按照一定的格式记录到binlog中。
什么时候释放
Binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件。可作为恢复数据使用。binlog的默认是保持时间由参数expire_logs_days配置天数后,会被自动删除。
参数show VARIABLES like '%expire_logs_days%';
【mysql】-- Mysql的undo log、redo log、bin log日志

对应的物理文件:show VARIABLES like '%log_bin_basename%';
【mysql】-- Mysql的undo log、redo log、bin log日志

当日志文件达到指定的最大的大小之后,进行滚动更新,生成新的日志文件。
对于每个binlog日志文件,通过一个统一的index文件来组织。

4.2、 binlog日志模式–row level、statement level(默认)、Mixed

Row level模式
记录的方式是行,即如果批量修改数据,记录的不是批量修改的SQL语句事件,而是每条记录被更改的SQL语句,因此,ROW模式的binlog日志文件会变得很“重”。

例如:update table1 set a=1 where b>=1 and b<=3,那么这个语句会变成
update table1 set a=1 where b=1
update table1 set a=1 where b=2
update table1 set a=1 where b=3

优点:row level的binlog日志内容会非常清楚的记录下每一行数据被修改的细节。
缺点:row level下,所有执行的语句当记录到日志中的时候,都以每行记录的修改来记录,这样可能会产生大量的日志内容,产生的binlog日志量是惊人的。

statement level(默认)
记录每一条修改数据的SQL语句。和书写的sql一致。
优点:大大减少了binlog日志量,节约磁盘IO,提高性能。
缺点:statement level下对一些特殊功能的复制效果不是很好,比如:函数、存储过程的复制。

Mixed
MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

4.3、binlog主从同步原理

原理:MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。
(A)、master服务器将数据的改变【增删改操作】记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
(B)、slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件;
©、同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中;接着,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。
主从复制用途
●实时灾备,用于故障切换
●读写分离,提供查询服务
●备份,避免影响业务

相关标签: mysql