当前位置: 移动技术网 > IT编程>数据库>Mysql > 为什么有时候binlog文件会很大于max_binlog_size以及max_binlog_cache_size

为什么有时候binlog文件会很大于max_binlog_size以及max_binlog_cache_size

2019年01月31日  | 移动技术网IT编程  | 我要评论

问题描述

线上一个很有意思的现象,发现binlog文件大小是15g,查看了参数是1073741824[1g], max_binlog_cache_size是21474836480[20g]。那么为什么会文件大小会超过max_binlog_file_size的设置。这个问题比较好理解,如果是大事务呢?那么这里有一个小问题,binlog里面是以event为单位来记录的,那么事务有可能跨binlog吗?使用begin;***;***;commit进行测试

第二个问题,以上面的设置为例,在文件快到1g的时候,如果来了一个大事务,这个大事务接近20g,那么是不是可以任务binlog文件的最大可能值是接近1g+20g=21g呢,因为超过max_binlog_cache_size就会报错了。这个也是可以测试下的。

实验证明

  问题1:实验测试

root@test10:39:24>set global max_binlog_size=4096;

root@test10:48:23>begin;
query ok, 0 rows affected (0.00 sec)

root@test10:48:39>insert into testb select * from testa limit 32;
query ok, 32 rows affected (0.00 sec)
records: 32  duplicates: 0  warnings: 0

root@test10:49:05>insert into testb select * from testa limit 32;
query ok, 32 rows affected (0.00 sec)
records: 32  duplicates: 0  warnings: 0

root@test10:49:10>insert into testb select * from testa limit 32;
query ok, 32 rows affected (0.00 sec)
records: 32  duplicates: 0  warnings: 0

root@test10:49:14>insert into testb select * from testa limit 32;
query ok, 32 rows affected (0.00 sec)
records: 32  duplicates: 0  warnings: 0

root@test10:49:18>commit;
query ok, 0 rows affected (0.00 sec)

# at 3994  -- 上一个event结束的地方
#190130 10:49:14 server id 21036055 end_log_pos 4064 crc32 0x64e8a1c6 rows_query
# insert into testb select * from testa limit 32
# at 4064
#190130 10:49:14 server id 21036055 end_log_pos 4113 crc32 0x7ef21b8c table_map: `test`.`testb` mapped to number 11496
# at 4113
#190130 10:49:14 server id 21036055 end_log_pos 4692 crc32 0xfc3f78bd write_rows: table id 11496 flags: stmt_end_f  -- 这已经是下一个insert 语句了,在一个binlog文件中,说明binlog是以事务为单位来进行切割的,不是事务里面的单个sql语句,这也是比较好理解的,因为事务只有执行完了, 才能在内存中生成完整的binlog,才存在刷盘的操作。

 

 问题2:实验测试

root@test11:01:52>set global  max_binlog_cache_size=4096;
root@test11:15:20>insert into testb select * from testb limit 200; -- 3.9k jan 30 11:15 mysql-bin.003691
root@test11:15:28>insert into testb select * from testb limit 460; -- 12k jan 30 11:16 mysql-bin.003691
root@test11:17:34>insert into testb select * from testb limit 470; -- 最大就是在460到470之间
error 1197 (hy000): multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again
这个实验说明binlog文件最大应该是max_binlog_size + max_binlog_cache_size的和,但是max_binlog_cache_size在文件大小上可能比实际设置的值要大,见下问题。所有严格来讲应该是大于两者的和的。

 

在实验的过程中遇见一个新问题

root@test11:07:21>insert into testb select * from testb limit 400;

# at 331
#190130 11:07:32 server id 21036055 end_log_pos 402 crc32 0x62bb0a5e rows_query
# insert into testb select * from testb limit 400
# at 402
#190130 11:07:32 server id 21036055 end_log_pos 451 crc32 0x3177b22e table_map: `test`.`testb` mapped to number 11496
# at 451
#190130 11:07:32 server id 21036055 end_log_pos 7286 crc32 0x35efff16 write_rows: table id 11496 flags: stmt_end_f  

能正常插入证明内存中产生的binlog应该是小于4096的,但是实际在binlog中看见的确实7286,明显是比4094大的,为啥会这样呢,在从内存中把binlog落盘的过程中做了什么处理吗?

 

root@test11:21:01>show create table testb\g
*************************** 1. row ***************************
       table: testb
create table: create table `testb` (
  `a` bigint(20) default null,
  `b` bigint(20) default null
) engine=innodb default charset=utf8mb4 collate=utf8mb4_unicode_ci
1 row in set (0.00 sec)

root@test11:24:10>select version();
+---------------+
| version() |
+---------------+
| 5.7.21-21-log |
+---------------+
1 row in set (0.00 sec)

 以上是表结构以及mysql的版本

 

如有任何问题,欢迎指正。

参考文献:

https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html#sysvar_max_binlog_size

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网