基于语句复制的优点
从 MySQL 3.23 起就已经支持基于语句复制了
不用把大量的数据写进日志文件。当删除或者更新大量的数据时,日志的储存空间增长速度不会很快
日志记录了那些数据更改的SQL语句,保证数据库的一致。
基于语句复制的缺点
- 基于语句的复制中,以下语句是不安全的。使用基于语句的复制中,并非所有的修改数据(例如 INSERT DELETE, UPDATE和 REPLACE语句)语句都可以成功被复制。在使用基于语句的复制中,任何不确定的行为是难以复制的。诸如这类数据修改语言(Data Modification Language),还有以下这些
- 依赖于一个UDF(用户定义的函数)或存储的程序的语句是不确定的。因为返回的值是通过一个UDF或存储程序或依赖于其他以外的因素而不是提供给它的参数。(但是,基于行的复制,简单地复制UDF或存储程序的返回值,在主服务器和从从服务器上表中那些受影响的行和数据是相同的)。
DELETE
和UPDATE
语句中使用一个LIMIT
子句但没有ORDER BY
语句是不确定的。- 使用基于语句的复制,语句使用以下函数不能正常地复制:
- 在基于行的复制中,对于 INSERT ... SELECT 的 SQL 语句,需要行级别的锁定。
- 在需要进行表扫描(因为 WHERE 子句中没有用到索引)的UPDATE 语句中,在基于行的复制中必须锁定行
- 对于使用InnoDB引擎的:一个使用 AUTO_INCREMENT 的 INSERT 语句,会阻塞其他不冲突的 INSERT 语句。
- 对于复杂的语句,语句必须先被从服务器识别和执行,再进行更新或插入操作。基于行的复制,从服务器只会修改受影响的行,不执行所有语句。
- 在从服务器上在识别出现错误的话,特别是在执行复杂的语句时,基于语句的复制会随着时间的推移,那些受影响的行可能会慢慢增加误差。
- 存储函数调用语句时会执行相同的 NOW()值。
- 用户自定义的函数功能必须是唯一确定的,才能适用于从服务器
- 在主服务器和从服务器之间,表的定义必须保持一致
基于行复制的优点
- 所有的改变都能被复制,这在复制中是最安全的一种方式。
mysql 数据库不会被复制, mysql 数据库不会被看作一个节点特定的数据库。但是,基于语句的复制会复制这些信息,包括 GRANT、REVOKE 还有触发器,存储过程和视图,都会被从服务器复制。
对于这些语句 CREATE TABLE ... SELECT,用 CREATE 语句创建表,都是用基于语句的复制的格式。而数据的插入则是使用 行复制。
对于下面的语句,在主服务器上只要很少的行锁定,能支持高并发。
INSERT ... SELECT
带有 AUTO_INCREMENT 的 INSERT 语句
UPDATE or DELETE statements with WHERE clauses that do not use keys or do not change most of the examined rows.
Row-Based 日志和复制的用法
- RBL,非事务表和停止从服务器。 如果用 row-based 记录时,当从服务器在更新一个非事务表时,从服务器忽然被停止了,从服务器的数据库的可能会处于非一致的状态。所以当用 row-based 记录时,推荐用支持事务的引擎,如 InnoDB。
- 数据库级别的复制选项。这些 --replicate-do-db, --replicate-ignore-db, 和 --replicate-rewrite-db 选项在基于 row-based 和 statement-based 来记录时,区别是很大的。基于这一点,尽量避免使用数据库级别的选项而改用表级别的选项,诸如 --replicate-do-table 和 --replicate-ignore-table
- 不支持过滤 server ID 系统变量。经常会遇到这样一个场景:在 UPDATE 或者 DELETE 语句中通过 WHERE 中用 @@server_id <> id_value 语句来过滤掉从服务器的改变。如 WHERE @@server_id <> 1 。这个在用 row-based 来记录时,不能正常的工作。如果你一定要用 server_id 系统变量来声明过滤,要有 --binlog_format=STATEMENT.你也可以在 CHANGE MASTER TO 语句中 用IGNORE_SERVER_IDS 选项来过掉server_id 系统变量的影响。
- 二进制日志缺乏校验
- 当系统变量 slave_exec_mode 的值是 IDEMPOTENT 时,未能将更改应用于row-based 记录。因为无法找到原来的行不触发一个错误或会导致复制失败。这意味着更新不能成功的应用于从服务器上。所以主服务器和从服务器不会再同步。