線上一個頗有意思的現象,發現binlog文件大小是15G,查看了參數max_binlog_size
是1073741824[1G], max_binlog_cache_size是21474836480[20G]。那麼爲何會文件大小會超過max_binlog_file_size的設置。這個問題比較好理解,若是是大事務呢?那麼這裏有一個小問題,binlog裏面是以event爲單位來記錄的,那麼事務有可能跨binlog嗎?使用BEGIN;***;***;commit進行測試html
第二個問題,以上面的設置爲例,在文件快到1G的時候,若是來了一個大事務,這個大事務接近20G,那麼是否是能夠任務binlog文件的最大可能值是接近1G+20G=21G呢,由於超過max_binlog_cache_size就會報錯了。這個也是能夠測試下的。mysql
問題1:實驗測試sql
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,才存在刷盤的操做。app
問題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在文件大小上可能比實際設置的值要大,見下問題。全部嚴格來說應該是大於二者的和的。
在實驗的過程當中碰見一個新問題ui
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 this
能正常插入證實內存中產生的binlog應該是小於4096的,可是實際在binlog中看見的確實7286,明顯是比4094大的,爲啥會這樣呢,在從內存中把binlog落盤的過程當中作了什麼處理嗎?spa
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)code
以上是表結構以及MySQL的版本
若有任何問題,歡迎指正。server
參考文獻:
https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html#sysvar_max_binlog_size