mysql的日志文件

了解个大概吧。

上回说到数据库的备份与恢复,日志文件在其中占有很重要的位置。

但是,我查了下资料,发现想搞懂这个数据库日志其实并不容易。包括网上许多文章,说了许多,但我越看越糊涂。只有一些mysql的日志文件原理介绍,相对好一些。mysql因为应用广泛,使用者众,作为数据库的学习对象,也算有代表性。

一、MySQL的日志文件

MySQL中有七种日志文件,分别是:

重做日志(redo log)
回滚日志(undo log)
二进制日志(binlog)
错误日志(errorlog)
慢查询日志(slow query log)
一般查询日志(general log)
中继日志(relay log)

其中重做日志和回滚日志与事务操作息息相关,二进制日志也与事务操作有一定的关系,这三种日志,对理解MySQL中的事务操作有着重要的意义。

二、RedoLog(重做日志)

用于崩溃恢复。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。redo log 是物理日志,记录的是“在某个数据页上做了什么修改”。

现在的数据库,为了提高性能,更改数据时,是先更改内存中的数据,然后等积攒了一定数量的更改记录才一起持久化到磁盘。很明显,这样就会有数据丢失的风险。幸而,数据库秉承修改数据先写日志的原则,数据修改时分别写RedoLog和UndoLog,其中RedoLog记录修改信息,而UndoLog是该修改的逆操作,比如,我们做的操作是INSERT,则UndoLog生成一条DELETE语句。所以说,RedoLog上记录的是物理格式,而UndoLog记录的是逻辑格式。

这个Redo文件其实也是先写到内存,但它持久化的频率比较密。比如当事务提交的时候就会持久化到磁盘。
在这里插入图片描述

回到上面提到的问题,当操作数据写到内存,事务提交后数据库出故障,由于RedoLog已经持久化,则数据库就可以根据RedoLog上的信息重放,保证用户的操作数据不丢失。

redolog文件大小是固定的,循环往复地使用。

三、UndoLog(回滚日志)

如前所述,undo log 叫做回滚日志,记录数据被修改前的信息,为了在发生错误时回滚之前的操作。

redo log记录的是物理日志,undo是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。

当执行rollback时,就可以用undo log中的逻辑记录进行回滚。有时候应用到行版本控制的时候,也是通过undo log来实现的:当读取的某一行被其他事务锁定时,它可以从undo log中分析出该行记录以前的数据是什么,从而提供该行版本信息,让用户实现非锁定一致性读取(MVCC,多版本并发控制)。

四、BinLog(二进制日志)

4.1 概述

用于主从复制和数据恢复。

MySQL二制进日志(binlog),也叫做变更日志(update log),是 MySQL 中非常重要的日志。二进制日志(binlog)中记录了对MySQL数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其它额外信息,但是它不记录select、show等那些不修改数据的SQL语句。二进制日志(binlog)主要用于数据库恢复和主从复制,以及审计操作。如果 MySQL 数据库意外停止,可以通过二进制日志文件来查看用户执行了哪些操作,对数据库服务器文件做了哪些修改,然后根据二进制日志文件中的记录来恢复数据库服务器。

【主从复制】
从库生成两个线程,一个I/O线程,一个SQL线程;

从库I/O线程请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;而主库则会生成一个log dump线程,用来给从库I/O线程传binlog;

从库SQL线程读取relay log文件中的日志,并解析成sql语句逐一执行。

【数据恢复】
如果数据库误操作, 可以找到距离误操作最近的时间节点的bin log,重放到临时数据库里,然后选择误删的数据节点,恢复到线上数据库。

binlog 是逻辑日志,记录的是这个语句的原始逻辑,即SQL语句。

binlog通过追加的方式记录日志,当文件尺寸大于给配置值后,后续的日志会记录到新的文件上。

4.2 BinLog参数

4.2.1 sync_binlog

sync_binlog用于控制cache的数据commit多少次才刷到磁盘上,默认是0,也就是让数据库自己决定同步的频率。如设置成1的话,则每commit一次就会将cache的数据同步到磁盘上,这样做最安全,但是性能最差。

sync_binlog=0,当事务提交后,Mysql仅仅是将binlog_cache中的数据写入binlog文件,但不执行fsync之类的磁盘同步指令通知文件系统将缓存刷新到磁盘,而是让Filesystem自行决定什么时候来做同步。
MySQL中默认的设置是 sync_binlog=0,即不作任何强制性的磁盘刷新指令,这个设置性能是最好的,但风险也是最大的。一旦系统崩溃(Crash),在文件系统缓存中的所有二进制日志信息都会丢失。从而带来数据不完整问题。

sync_binlog=n,在进行n次事务提交以后,Mysql将执行一次fsync之类的磁盘同步指令,同时文件系统将Binlog文件缓存刷新到磁盘。
可以适当的调整sync_binlog, 在牺牲一定的一致性下,获取更高的并发和性能。

mysql> show variables like 'sync_binlog';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 0     |
+---------------+-------+
1 row in set (0.00 sec)

4.2.2 binlog_format

指定二进制日志的类型。分别有STATEMENT、ROW、MIXED三种值。MySQL 5.7.6之前默认为STATEMENT模式,MySQL 5.7.7之后默认为ROW模式。

mysql> show variables like 'binlog_format';
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)

4.2.3 log_bin = /mysql/bin_log/mysql_binlog

开启 Binlog 并指定存放日志的位置;默认使用的设置是“log-bin=mysql-bin”,一般是放在data目录中。

4.2.4 expire_logs_days = 10

expire_logs_day 定义了 MySQL 清除过期日志的时间、二进制日志自动删除的天数。默认值为 0,表示“没有自动删除”。当 MySQL 启动或刷新二进制日志时可能删除。

4.2.5 max_binlog_size = 1​00M

max_binlog_size 定义了单个文件的大小限制,如果二进制日志写入的内容大小超出给定值,日志就会发生滚动(关闭当前文件,重新打开一个新的日志文件)。不能将该变量设置为大于 1GB 或小于 4096B(字节),其默认值是 1GB。

五、各日志写入时机

在这里插入图片描述

参考资料:
数据库原理四—MySQL日志
MySQL二进制日志(binlog)总结

posted on 2022-03-24 21:51  左直拳  阅读(3)  评论(0)    收藏  举报  来源

导航