2012年11月26日星期一

MySQL 5.5 复制格式

基于语句复制的优点

从 MySQL 3.23 起就已经支持基于语句复制了

不用把大量的数据写进日志文件。当删除或者更新大量的数据时,日志的储存空间增长速度不会很快

日志记录了那些数据更改的SQL语句,保证数据库的一致。

基于语句复制的缺点

  • 基于语句的复制中,以下语句是不安全的。使用基于语句的复制中,并非所有的修改数据(例如 INSERT DELETE, UPDATE和 REPLACE语句)语句都可以成功被复制。在使用基于语句的复制中,任何不确定的行为是难以复制的。诸如这类数据修改语言(Data Modification Language),还有以下这些
  • 在基于行的复制中,对于 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 记录。因为无法找到原来的行不触发一个错误或会导致复制失败。这意味着更新不能成功的应用于从服务器上。所以主服务器和从服务器不会再同步。

没有评论:

发表评论