签到成功

知道了

CNDBA社区CNDBA社区

MySQL 日志系统 redo log 和 binlog 说明

2021-08-21 14:31 1726 0 转载 MySQL
作者: dave

1 重做日志(redo log)

redo log又称重做日志文件,用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。innodb 使用了WAL 技术(Write-Ahead Logging)即先写日志,再写磁盘。 这样可以保证数据的一致性,在实例和介质失败(media failure)时,redo log文件就能派上用场,如数据库掉电,InnoDB存储引擎会使用redo log恢复到掉电前的时刻,以此来保证数据的完整性。

每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组至少有2个重做日志文件,redo log 循环使用,如默认的ib_logfile0和ib_logfile1。大小由innodb_log_file_size 参数控制,默认是48M。 文件个数由 innodb_log_files_in_group 参数控制,默认是2个。 文件名由ib_logfile为前缀。 http://www.cndba.cn/cndba/dave/article/4672

http://www.cndba.cn/cndba/dave/article/4672

  • innodb_log_file_size:指定每个redo日志大小,默认值48MB
  • innodb_log_files_in_group:指定日志文件组中redo日志文件数量,默认为2
  • innodb_log_group_home_dir:指定日志文件组所在路劲,默认值./,指mysql的数据目录datadir
[dave@www.cndba.cn  mysql]# pwd
/var/lib/mysql
[dave@www.cndba.cn  mysql]# ll -lh|grep ib_logfile
-rw-r----- 1 root  root   48M Aug 21 13:32 ib_logfile0
-rw-r----- 1 root  root   48M Aug 20 03:13 ib_logfile1
[dave@www.cndba.cn  mysql]#


mysql> show variables like 'innodb_log%';
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| innodb_log_buffer_size      | 16777216 |
| innodb_log_checksums        | ON       |
| innodb_log_compressed_pages | ON       |
| innodb_log_file_size        | 50331648 |
| innodb_log_files_in_group   | 2        |
| innodb_log_group_home_dir   | ./       |
| innodb_log_write_ahead_size | 8192     |
+-----------------------------+----------+
7 rows in set (0.01 sec)

2 二进制日志(binlog)

在之前的博客,我们了解到MySQL 体系架构有2个层次,如下:

http://www.cndba.cn/cndba/dave/article/4672

MySQL Server 层 和 InnoDB 引擎层 体系结构
https://www.cndba.cn/dave/article/4671

  1. Server 层:主要做的是 MySQL 功能层面的事情;
  2. 引擎层: 负责存储相关的具体事宜。

redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(二进制日志)。

binlog记录了对MySQL数据库执行更改的所有操作,但是不包括SELECT和SHOW这类操作,如果想记录SELECT和SHOW操作,那只能使用查询日志—general_log[={0|1}] (1为启用)。http://www.cndba.cn/cndba/dave/article/4672

binlog 属于逻辑日志,是以二进制的形式记录的是这个语句的原始逻辑。从 5.1.8 版本开始,二进制日志 (binlog) 有 3 种不同的格式可选:Mixed,Statement,Row,默认格式是 Statement,而从5.7.7版本以上默认是ROW模式。

MySQL binlog日志格式 binlog_format
https://www.cndba.cn/dave/article/4664

http://www.cndba.cn/cndba/dave/article/4672

mysql> show variables like '%log_bin%';
+---------------------------------+--------------------------------+
| Variable_name                   | Value                          |
+---------------------------------+--------------------------------+
| log_bin                         | ON                             |
| log_bin_basename                | /var/lib/mysql/mysql-bin       |
| log_bin_index                   | /var/lib/mysql/mysql-bin.index |
| log_bin_trust_function_creators | OFF                            |
| log_bin_use_v1_row_events       | OFF                            |
| sql_log_bin                     | ON                             |
+---------------------------------+--------------------------------+
6 rows in set (0.01 sec)

mysql> show variables like '%binlog%';
+--------------------------------------------+----------------------+
| Variable_name                              | Value                |
+--------------------------------------------+----------------------+
| binlog_cache_size                          | 32768                |
| binlog_checksum                            | CRC32                |
| binlog_direct_non_transactional_updates    | OFF                  |
| binlog_error_action                        | ABORT_SERVER         |
| binlog_format                              | MIXED                |
| binlog_group_commit_sync_delay             | 0                    |
| binlog_group_commit_sync_no_delay_count    | 0                    |
| binlog_gtid_simple_recovery                | ON                   |
| binlog_max_flush_queue_time                | 0                    |
| binlog_order_commits                       | ON                   |
| binlog_row_image                           | FULL                 |
| binlog_rows_query_log_events               | OFF                  |
| binlog_stmt_cache_size                     | 32768                |
| binlog_transaction_dependency_history_size | 25000                |
| binlog_transaction_dependency_tracking     | COMMIT_ORDER         |
| innodb_api_enable_binlog                   | OFF                  |
| innodb_locks_unsafe_for_binlog             | OFF                  |
| log_statements_unsafe_for_binlog           | ON                   |
| max_binlog_cache_size                      | 18446744073709547520 |
| max_binlog_size                            | 1073741824           |
| max_binlog_stmt_cache_size                 | 18446744073709547520 |
| sync_binlog                                | 1                    |
+--------------------------------------------+----------------------+
22 rows in set (0.00 sec)

mysql>

[dave@www.cndba.cn  mysql]# ll -lh|grep mysql-bin
-rw-r----- 1 root  root   177 Oct 26  2019 mysql-bin.000001
-rw-r----- 1 root  root  1.1G Dec  8  2020 mysql-bin.000002
-rw-r----- 1 root  root  528M Aug 21 14:05 mysql-bin.000003
-rw-r----- 1 root  root    57 Dec  8  2020 mysql-bin.index
[dave@www.cndba.cn  mysql]#

redo log与binlog的区别

  1. redo log是在InnoDB存储引擎层产生,而binlog是MySQL数据库的上层产生的,并且二进制日志不仅仅针对INNODB存储引擎,MySQL数据库中的任何存储引擎对于数据库的更改都会产生二进制日志。
  2. 两种日志记录的内容形式不同。MySQL的binlog是逻辑日志,其记录是对应的SQL语句。而innodb存储引擎层面的重做日志是物理日志,记录的是在某个数据页上做了什么修改。
  3. 两种日志与记录写入磁盘的时间点不同,二进制日志只在事务提交完成后进行一次写入。而innodb存储引擎的重做日志在事务进行中不断地被写入,并日志不是随事务提交的顺序进行写入的。
  4. 二进制日志仅在事务提交时记录,并且对于每一个事务,仅在事务提交时记录,并且对于每一个事务,仅包含对应事务的一个日志。而对于innodb存储引擎的重做日志,由于其记录是物理操作日志,因此每个事务对应多个日志条目,并且事务的重做日志写入是并发的,并非在事务提交时写入,其在文件中记录的顺序并非是事务开始的顺序。
  5. binlog不是循环使用,在写满或者重启之后,会生成新的binlog文件,redo log是循环使用。
  6. binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

binlog有固定的格式:

  1. statement 格式的 binlog,最后会有 COMMIT
  2. row 格式的 binlog,最后会有一个 XID event

从MySQL 5.6.2开始,引入了 binlog_checksum参数,用来验证 binlog 内容的正确性。对于 binlog 日志由于磁盘原因,可能会在日志中间出错的情况,MySQL 可以通过校验 checksum 的结果来发现,保证了事务 binlog 的完整性。

http://www.cndba.cn/cndba/dave/article/4672

3 redo log 和 binlog 的数据一致性:两阶段提交(2PC)

MySQL 使用两阶段提交主要解决 binlog 和 redo log 的数据一致性的问题。

http://www.cndba.cn/cndba/dave/article/4672

redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。

两阶段提交过程如下:

  1. InnoDB redo log 写盘,完成后InnoDB 事务进入 prepare 状态。
  2. 如果前面 prepare 成功,那么开始binlog 写盘,将事务日志持久化到 binlog,如果持久化成功,那么 InnoDB 事务则进入 commit 状态(在 redo log 里面写一个 commit 记录),事务操作完成。如果有大量长事务在执行,那么这里就可能出现binlog 写入的等待,导致事务无法及时提交而出现阻塞。

每个事务 binlog 的末尾,会记录一个 XID event,标志着事务是否提交成功,也就是说,recovery 过程中,binlog 最后一个 XID event 之后的内容都应该被 purge。http://www.cndba.cn/cndba/dave/article/4672http://www.cndba.cn/cndba/dave/article/4672

在redo log 和 binlog 文件中有一个共同的数据字段:XID。崩溃恢复的时候,会按顺序扫描 redo log:http://www.cndba.cn/cndba/dave/article/4672

  1. 如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;
  2. 如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务,进行回滚。
用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2261
    原创
  • 3
    翻译
  • 578
    转载
  • 191
    评论
  • 访问:8017055次
  • 积分:4346
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ