17.1.2.1 Advantages and Disadvantages of Statement-Based and Row-Based Replication 基于语句复制和基于行复制的
优势和劣势
每个binary logging 格式有优点也有缺点,对于大多数用户,mixed 复制格式应该提供最好的
数据完整性和性能的组合。但是,你想利用特定的功能对于基于语句的或者基于行的复制格式 ,当执行某个任务时,
你可以使用这个章节的信息,它提供了一个相对的优缺点的总结,可能适合你的需求。
Advantages of statement-based replication 基于语句复制的优势
Disadvantages of statement-based replication 基于语句复制的缺点
Advantages of row-based replication 基于行复制的优点
Disadvantages of row-based replication 基于行复制的缺点
基于语句复制的优势:
1.成熟的及时在MySQL 3.23就已经出现了
2.更少的数据写入日志文件,当更新或者删除影响很多行的时候,
这个会导致更少的空间需要用于日志文件。这也意味着从备份执行恢复可以更快的完成。
日志文件包含了所有改变的语句,也可以用于审计数据库:
基于语句复制的缺点:
语句对于SBR是不安全的,不是所有的语句修改数据的(比如 INSERT,DELETE,UPDATE和REPLACE语句)
可以被复制使用基于语句的复制。任何不确定的行为是很难被复制的当使用基于语句的复制
比如下面的DML语句包括如下:
一个语句依赖一个UDF或者存储的程序是不确定的, 是有UDF或者存储的程序返回的值或者
依赖因素相比提供的参数 (基于行的复制,然而, 简单的复制UDF或者存储程序返回的值,
因此它在表记录的影响和数据 在master和slave上是相同的)
DELETE和UPDATE 语句使用一个LIMIT字句没有一个ORDER BY 是不确定的
语句使用下面的函数不能被复制在使用基于语句复制的时候:
LOAD_FILE()
UUID(), UUID_SHORT()
USER()
FOUND_ROWS()
SYSDATE() (unless both the master and the slave are started with the –sysdate-is-now option)
GET_LOCK()
IS_FREE_LOCK()
IS_USED_LOCK()
MASTER_POS_WAIT()
RAND()
RELEASE_LOCK()
SLEEP()
VERSION()
然而,所有其他的函数可以正确的复制使用基于语句的复制,包括NOW()
语句不能被正确的复制使用基于语句复制是被记录为一个告警,如下所示:
[Warning] Statement is not safe to log in statement format.
在这种情况下,还法术了类似的警告,客户端可以使用SHOW WARNINGS 来显示:
INSERT … SELECT 需要更多的行锁 相比基于行的复制
UPDATE 语句需要一个表扫描(因为where 条件没有使用索引)必须锁住更多的数据 相比基于行的复制
对于InnoDB:一个INSERT 语句使用 AUTO_INCREMENT堵塞其他不冲突的INSERT语句
对于复杂的语句, 语句必须被评估和执行在salve上在行被更新和插入前。
在基于行复制的环境,slave 只需要修改影响的行,不执行全局的语句。
如果这里有一个错误在评估时在slave上, 特别是在执行复杂的语句,基于语句的复制可能有慢慢的增加错误的边缘
随着时间的推移。See Section 17.4.1.28, “Slave Errors During Replication”.
基于行复制的优点:
所有的改变可以被复制,这是最安全的复制形势:
注意:
语句更新数据库的信心—比如GRANT,REVOKE 和触发器的操作,存储程序(包括存储过程),
视图都被复制到salves使用语句语句的复制
对于语句复制比如CREATE TABLE … SELECT,从表定义和复制使用基于语句的格式生成语句,而行插入则以行为基础的格式复制
该技术是和很多其他数据库管理系统相同的, 从其他数据库转换到MySQL的。
master 需要更少的锁, 从而提高了并发性,用下面语句的类型:
INSERT … SELECT
INSERT statements with AUTO_INCREMENT
UPDATE 或者DELETE 语句带WHERE 条件,但是不使用索引或者你改变很好行的。
基于行复制的缺点:
RBR 可以得到更多必须被记录的数据,来复制一个DML语句(比如 一个UPDATE或者DELETE 语句),
基于语句的复制只写一条语句到binary log.相比之下,基于行的复制写每个改变行到binarylog.
如果语句改变了很多行, 基于行复制的可能写更多的数据到binarylog,
这是真实的,即使是回滚的语句。 这意味着执行一个从备份恢复需要更多的时间。
此外, binary log 是被锁住很长时间用于写数据,可能会导致冲突问题。
确定的UDFs 产生大的BLOB 花费很长来复制,在基于行的复制,相比基于语句的复制。
这是因为BLOB 列是被记录的,相比语句生成数据。
你不能看到在salve 从master接收到的语句被执行,然而, 你可以哪些数据被改变在使用
mysqlbinlog 加上选择 –base64-output=DECODE-ROWS and –verbose.