- A+
目录:
1. MySQL binlog三种模式及设置方法
1.1 Row Level(行模式)
日志中会记录成每一行数据被修改的情况,然后在slave端再对相同的数据进行修改。
优点:在row level情况下,bin-log中可以不记录执行的sql语句上下文相关的信息,仅仅只需要记录那一条记录被修改了,修改成说明样子。所以row level的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解,而且不会出现某些特点情况下的存储过程或function,以及trigget的电泳和触发无法被正确复制的问题。
缺点:row level下,所有的执行语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如会产生大量的binlog日志。
1.2 Statement Level(默认)清单模式
每一条被修改的数据的sql语句都会记录到master的binlog中,slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行。
优点:解决了行模式的缺点,它不需要记录每一行数据的变化,减少binlog日志量,节约磁盘IO,提高性能,因为他只需要记录在Master上所执行的语句的细节,以及执行语句时候的上下文的信息。
缺点:由于它是记录的执行语句,所以,为了让这些语句在slave端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端被执行的时候能够得到和在master端执行时候相同的结果,另外就是,由于MaSQL现在发展比较快,很多新功能不断的加入,使MySQL的复制遇到了不小的挑战。容易造成主从数据不一致。
1.3 Mixed
实际上就是前两种模式的结合,在mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Staterment和row行模式之间选一种,当他认为数据可能会造成不一致的情况时,他就会悬着行模式,当他认为这是一百万条记录只需要一条就搞定了,就会悬着选择statement模式
2. 企业如何选择binlog的模式
1. 互联网公司,使用MySQL的功能相对少(存储过程、触发器、函数)。
选择默认的语句模式,statement level(默认)。
2. 公司如果用到使用MySQL的特殊功能(存储过程、触发器、函数)。
则选择Mined模式。
3. 公司如果用到使用MySQL特殊功能(存储过程、触发器、函数),又希望数据最大化一致,此时最好Row level模式。
2.1 设置MySQL binlog的格式
查看当前binlog模式,命令如下:
mysql> show global variables like "binlog_format%"; +---------------+-----------+ | Variable_name | Value | +---------------+-----------+ | binlog_format | STATEMENT | #<== 模式的STATEMENT清单模式 +---------------+-----------+ 1 row in set (0.00 sec)
在配置文件中参数如下:
log-bin=mysql-bin #binlog_format = "STATEMENT" #binlog_format = "ROW" binlog_format = "MIXED"
运行时在线修改如下命令(临时生效)
调整为ROW模式
mysql> set global binlog_format = "ROW"; #<== 调整为ROW模式 Query OK, 0 rows affected (0.00 sec) mysql> show global variables like "binlog_format%"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | ROW | #<== 修改成功 +---------------+-------+ 1 row in set (0.00 sec)
想要永久生效修改配置文件,如下:
[root@db01 ~]# vim /data/3306/my.cnf [mysqld] binlog_format = "ROW" #<== 在mysqld模块下更改
测试查看行模式的行记录:
查看test表中当前数据
mysql> select * from test; +----+------+ | id | age | +----+------+ | 1 | 呵呵 | | 2 | kaka | +----+------+ 2 rows in set (0.00 sec)
修改数据:
mysql> update test set age='ttttt'; Query OK, 0 rows affected (0.00 sec) Rows matched: 2Changed: 0 Warnings: 0
不加where指定条件时修改全部
mysql> select * from test; +----+-------+ | id | age | +----+-------+ | 1 | ttttt | | 2 | ttttt | +----+-------+ 2 rows in set (0.00 sec)
修改后解析binlog日志查看:
[root@db01 3306]# mysqlbinlog --base64-output=decode-rows -v mysql-bin.000016 ### UPDATE `oldboy`.`test` #<== 行级解析后的形式 ### WHERE ### @1=1 ### @2='ttttoiot' ### SET ### @1=1 ### @2='tttttttt' ### UPDATE `oldboy`.`test` ### WHERE ### @1=2 ### @2='ttttoiot' ### SET ### @1=2 ### @2='tttttttt'