推荐用mixed,默认使用statement,基于上下文。mysql
MySQL Replication复制能够是基于一条语句(Statement level),也能够是基于一条记录(Row level),能够在MySQL的配置参数中设定这个复制级别,不一样复制级别的设置会影响到Master端的bin-log记录成不一样的形式。sql
Row Level:日志中会记录成每一行数据被修改的形式,而后在slave端再对相同的数据进行修改。数据库
优势:在row level模式下,bin-log中能够不记录执行的sql语句的上下文相关的信息,仅仅只须要记录那一条记录被修改了,修改为什么样了。因此row level的日志内容会很是清楚的记录下每一行数据修改的细节,很是容易理解。并且不会出现某些特定状况下的存储过程,或function,以及trigger的调用和触发没法被正确复制的问题。安全
缺点:row level下,全部的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,好比有这样一条update语句:update product set owner_member_id = ‘b’ where owner_member_id = ‘a’,执行以后,日志中记录的不是这条update语句所对应额事件(MySQL以事件的形式来记录bin-log日志),而是这条语句所更新的每一条记录的变化状况,这样就记录成不少条记录被更新的不少个事件。天然,bin-log日志的量就会很大。尤为是当执行alter table之类的语句的时候,产生的日志量是惊人的。由于MySQL对于alter table之类的表结构变动语句的处理方式是整个表的每一条记录都须要变更,实际上就是重建了整个表。那么该表的每一条记录都会被记录到日志中。服务器
Statement Level:每一条会修改数据的sql都会记录到 master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行。多线程
优势:statement level下的优势首先就是解决了row level下的缺点,不须要记录每一行数据的变化,减小bin-log日志量,节约IO,提升性能。由于他只须要记录在Master上所执行的语句的细节,以及执行语句时候的上下文的信息。并发
缺点:因为他是记录的执行语句,因此,为了让这些语句在slave端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证全部语句在slave端杯执行的时候可以获得和在master端执行时候相同的结果。另外就是,因为MySQL如今发展比较快,不少的新功能不断的加入,使MySQL得复制遇到了不小的挑战,天然复制的时候涉及到越复杂的内容,bug也就越容易出现。在statement level下,目前已经发现的就有很多状况会形成MySQL的复制出现问题,主要是修改数据的时候使用了某些特定的函数或者功能的时候会出现,好比:sleep()函数在有些版本中就不能真确复制,在存储过程当中使用了last_insert_id()函数,可能会使slave和master上获得不一致的id等等。因为row level是基于每一行来记录的变化,因此不会出现相似的问题。函数
从官方文档中看到,以前的MySQL一直都只有基于statement的复制模式,直到5.1.5版本的MySQL才开始支持row level的复制。从5.0开始,MySQL的复制已经解决了大量老版本中出现的没法正确复制的问题。可是因为存储过程的出现,给MySQL Replication复制又带来了更大的新挑战。另外,看到官方文档说,从5.1.8版本开始,MySQL提供了除Statement Level和Row Level以外的第三种复制模式:Mixed,实际上就是前两种模式的结合。在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。新版本中的Statment level仍是和之前同样,仅仅记录执行的语句。而新版本的MySQL中队row level模式也被作了优化,并非全部的修改都会以row level来记录,像遇到表结构变动的时候就会以statement模式来记录,若是sql语句确实就是update或者delete等修改数据的语句,那么仍是会记录全部行的变动。性能
下面值得一读::优化
-- 基于SQL语句的复制(statement-based replication, SBR),
-- 基于行的复制(row-based replication, RBR),
-- 混合模式复制(mixed-based replication, MBR)。
相应地,binlog的格式也有三种:STATEMENT,ROW,MIXED。 MBR 模式中,SBR 模式是默认的。
在运行时能够动态改动 binlog的格式,除了如下几种状况:
. 存储流程或者触发器中间
. 启用了NDB
. 当前会话试用 RBR 模式,而且已打开了临时表
若是binlog采用了 MIXED 模式,那么在如下几种状况下会自动将binlog的模式由 SBR 模式改为 RBR 模式。
. 当DML语句更新一个NDB表时
. 当函数中包含 UUID() 时
. 2个及以上包含 AUTO_INCREMENT 字段的表被更新时
. 行任何 INSERT DELAYED 语句时
. 用 UDF 时
. 视图中必需要求运用 RBR 时,例如创建视图是运用了 UUID() 函数
设定主从复制模式:
log-bin=mysql-bin
#binlog_format="STATEMENT"
#binlog_format="ROW"
binlog_format="MIXED"
也能够在运行时动态修改binlog的格式。例如
mysql> SET SESSION binlog_format = 'STATEMENT';
mysql> SET SESSION binlog_format = 'ROW';
mysql> SET SESSION binlog_format = 'MIXED';
mysql> SET GLOBAL binlog_format = 'STATEMENT';
mysql> SET GLOBAL binlog_format = 'ROW';
mysql> SET GLOBAL binlog_format = 'MIXED';
两种模式各自的优缺点:
SBR 的优势:
历史悠久,技能成熟
binlog文件较小
binlog中包含了全部数据库修改信息,能够据此来审核数据库的安全等状况
binlog能够用于实时的还原,而不只仅用于复制
主从版本能够不同,从服务器版本能够比主服务器版本高
SBR 的缺点:
不是全部的UPDATE语句都能被复制,尤为是包含不肯定操做的时候。
调用具备不肯定因素的 UDF 时复制也可能出疑问
运用如下函数的语句也不能被复制:
* LOAD_FILE()
* UUID()
* USER()
* FOUND_ROWS()
* SYSDATE() (除非启动时启用了 --sysdate-is-now 选项)
INSERT ... SELECT 会产生比 RBR 更多的行级锁
复制需要执行 全表扫描(WHERE 语句中没有运用到索引)的 UPDATE 时,需要比 RBR 请求更多的行级锁
对于有 AUTO_INCREMENT 字段的 InnoDB表而言,INSERT 语句会阻塞其余 INSERT 语句
对于一些复杂的语句,在从服务器上的耗资源状况会更严重,而 RBR 模式下,只会对那个发生变化的记录产生影响
存储函数(不是存储流程 )在被调用的同时也会执行一次 NOW() 函数,这个能够说是坏事也多是好事
肯定了的 UDF 也需要在从服务器上执行
数据表必须几乎和主服务器保持一致才行,不然可能会致使复制出错
执行复杂语句若是出错的话,会消耗更多资源
RBR 的优势: 任何状况均可以被复制,这对复制来讲是最安全可靠的 和其余大多数数据库系统的复制技能同样 多数状况下,从服务器上的表若是有主键的话,复制就会快了不少 复制如下几种语句时的行锁更少: * INSERT ... SELECT * 包含 AUTO_INCREMENT 字段的 INSERT * 没有附带条件或者并无修改不少记录的 UPDATE 或 DELETE 语句 执行 INSERT,UPDATE,DELETE 语句时锁更少 从服务器上采用多线程来执行复制成为可能 RBR 的缺点: binlog 大了不少 复杂的回滚时 binlog 中会包含大量的数据 主服务器上执行 UPDATE 语句时,全部发生变化的记录都会写到 binlog 中,而 SBR 只会写一次,这会致使频繁发生 binlog 的并发写疑问 UDF 产生的大 BLOB 值会致使复制变慢 不能从 binlog 中看到都复制了写什么语句(加密过的) 当在非事务表上执行一段堆积的SQL语句时,最好采用 SBR 模式,不然很容易致使主从服务器的数据不一致状况发生 另外,针对系统库 mysql 里面的表发生变化时的处理准则以下: 若是是采用 INSERT,UPDATE,DELETE 直接操做表的状况,则日志格式根据 binlog_format 的设定而记录 若是是采用 GRANT,REVOKE,SET PASSWORD 等管理语句来作的话,那么不管如何 都采用 SBR 模式记录。 注:采用 RBR 模式后,能处理不少原先出现的主键重复问题。