根据文档描述,在基于RBR的复制中,每一个数据行更改事件会包含两份影像(image)。
一份是“before”影像,是指被更改的数据行的那些列的原始记录,一份是“after”影像,是指被更改后的列(值)。
默认配置下,mysql会在“before”和“after”影像中记录更改数据行的所有列。
但是很明显,这不是必须的。
其实我们可以通过配置binlog_row_image参数来节省磁盘,内存以及网络资源。
因为其实仅仅只需要记录我们更改的那些列(值)。
当删除一条数据行时,仅仅只有“before”影像。
当插入一条数据行时,仅仅只有“after”影像。
所以只有当更新一条数据行时,才会同时记录“before”影像和“after”影像。
而对于“before”影像,其实仅仅需要记录我们更改的列值,以及能够唯一识别这些数据行的列值(比如主键)即可。
参数binlog_row_image有如下配置:
full:在“before”和“after”影像中,记录所有的列值;
minimal:在“before”和“after”影像中,仅仅记录被更改的以及能够唯一识别数据行的列值;
noblob:在“before”和“after”影像中,记录所有的列值,但是BLOB 与 TEXT列除外(如未更改)。
默认值是full。
下面试验看看full和minimal的binlog日志量的区别:
C:\>net start mysql57_3306
MySQL57_3306 服务正在启动 ..
MySQL57_3306 服务已经启动成功。
C:\>mysql -P3306
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.11-log MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select @@global.binlog_format,@@session.binlog_format;
+------------------------+-------------------------+
| @@global.binlog_format | @@session.binlog_format |
+------------------------+-------------------------+
| ROW | ROW |
+------------------------+-------------------------+
1 row in set (0.00 sec)
mysql> select @@global.binlog_row_image,@@session.binlog_row_image;
+---------------------------+----------------------------+
| @@global.binlog_row_image | @@session.binlog_row_image |
+---------------------------+----------------------------+
| FULL | FULL |
+---------------------------+----------------------------+
1 row in set (0.00 sec)
mysql> select @@global.max_binlog_cache_size;
+--------------------------------+
| @@global.max_binlog_cache_size |
+--------------------------------+
| 134217728 |
+--------------------------------+
1 row in set (0.00 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000031
Position: 194
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-7371
1 row in set (0.00 sec)
mysql> UPDATE cms.`b_business_record` tl
-> SET tl.`projectName` = 'test'
-> WHERE tl.`id` IS NOT NULL;
Query OK, 63 rows affected (1.41 sec)
Rows matched: 63 Changed: 63 Warnings: 0
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000031
Position: 38602 #在full下,日志量从194字节增大到38602字节,增加了38602 - 194 = 38408字节
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-7372
1 row in set (0.00 sec)
mysql> set @@session.binlog_row_image='minimal';
Query OK, 0 rows affected (0.00 sec)
mysql> select @@global.binlog_row_image,@@session.binlog_row_image;
+---------------------------+----------------------------+
| @@global.binlog_row_image | @@session.binlog_row_image |
+---------------------------+----------------------------+
| FULL | MINIMAL |
+---------------------------+----------------------------+
1 row in set (0.00 sec)
mysql> flush logs;
Query OK, 0 rows affected (0.27 sec)
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000032
Position: 194
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-7373
1 row in set (0.00 sec)
mysql> UPDATE cms.`b_business_record` tl
-> SET tl.`projectName` = 'sss'
-> WHERE tl.`id` IS NOT NULL;
Query OK, 63 rows affected (0.09 sec)
Rows matched: 63 Changed: 63 Warnings: 0
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000032
Position: 2564 #而在minimal下,binlog日志量只增大了 2564 - 194 = 2370字节
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: e2e2f927-e75c-11e5-ac89-5c260a17ccde:1-7374
1 row in set (0.00 sec)
mysql>
经过测试,minimal相比full,binlog日志量减少了93.83%。
这在节约磁盘空间和内存开销以及网络流量上,确实有着明显的优势。