MYSQL复制的几种模式

MySQL 5.1 中,在复制方面的改进就是引进了新的复制技术:基于行的复制。

MYSQL复制的几种模式

MySQL 5.1 中,在复制方面的改进就是引进了新的复制技术:基于行的复制。
简言之,这种新技术就是关注表中发生变化的记录,而非以前的照抄 binlog 模式。
从 MySQL 5.1.12 开始,可以用以下三种模式来实现:
-- 基于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表时【NDB为分布式所创】
. 当函数中包含 UUID() 时
. 2个及以上包含 AUTO_INCREMENT 字段的表被更新时
. 行任何 INSERT DELAYED 语句时
. 用 UDF 时
. 视图中必须要求使用 RBR 时,例如创建视图是使用了 UUID() 函数

设定主从复制模式的方法非常简单,只要在以前设定复制配置的基础上,再加一个参数:
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 模式后,能解决很多原先出现的主键重复问题。

实例: 
对于insert into db_allot_ids select * from db_allot_ids 这个语句: 
在BINLOG_FORMAT=STATEMENT 模式下: 
BINLOG日志信息为: 
-----------------------------------------
BEGIN
/*!*/;
# at 173
#090612 16:05:42 server id 1 end_log_pos 288 Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1244793942/*!*/;
insert into db_allot_ids select * from db_allot_ids 
/*!*/;
-----------------------------------------

在BINLOG_FORMAT=ROW 模式下:
BINLOG日志信息为:
-----------------------------------------
BINLOG '
hA0yShMBAAAAMwAAAOAAAAAAAA8AAAAAAAAAA1NOUwAMZGJfYWxsb3RfaWRzAAIBAwAA
hA0yShcBAAAANQAAABUBAAAQAA8AAAAAAAEAAv/8AQEAAAD8AQEAAAD8AQEAAAD8AQEAAAA=
'/*!*/;
-----------------------------------------
确实看不懂里面记的是啥.

二、Replication 实现级别

  由于MySQL Replication 是基于 Binary Log 实现的,所以Replication 的实现级别实际上是由Binary Log 的存储格式所决定。Binary Log 中记录 Eent 的方式可以是基于一条语句(Statement Level),也可以是基于一条记录(Row level),这可以在 MySQL 的配置参数(—binlog-format)中设定这个格式。

  1. Row Level:Binary Log 中会记录成每一行数据被修改的形式,然后在 Slave 端再对相同的数据进行修改。

  优点:在 Row Level 模式下,Binary Log 中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条记录被修改了,修改成什么样了。所以 Row Level 的日志内容会非常清楚的记录下每一行数据修改的细节,非常容易理解。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题。

  缺点:Row Level下,所有的执行的语句当记录到 Binary Log 中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如有这样一条update语句:UPDATE group_message SET group_id = 1 where group_id = 2,执行之后,日志中记录的不是这条update语句所对应的事件(MySQL以事件的形式来记录 Binary Log 日志),而是这条语句所更新的每一条记录的变化情况,这样就记录成很多条记录被更新的很多个事件。自然,Binary Log 日志的量就会很大。尤其是当执行ALTER TABLE 之类的语句的时候,产生的日志量是惊人的。因为MySQL对于 ALTER TABLE 之类的 DDL 变更语句的处理方式是重建整个表的所有数据,也就是说表中的每一条记录都需要变动,那么该表的每一条记录都会被记录到日志中。

  2. Statement Level:每一条会修改数据的 Query 都会记录到 Master的 Binary Log 中。Slave在复制的时候 SQL 线程会解析成和原来 Master 端执行过的相同的 Query 来再次执行。

  优点:Statement Level下的优点首先就是解决了Row Level下的缺点,不需要记录每一行数据的变化,减少 Binary Log 日志量,节约了 IO 成本,提高了性能。因为他只需要记录在Master上所执行的语句的细节,以及执行语句时候的上下文的信息。

缺点:由于他是记录的执行语句,所以,为了让这些语句在slave端也能正确执行,那么他还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,以保证所有语句在slave端杯执行的时候能够得到和在master端执行时候相同的结果。另外就是,由于Mysql现在发展比较快,很多的新功能不断的加入,使mysql得复制遇到了不小的挑战,自然复制的时候涉及到越复杂的内容,bug也就越容易出现。在statement level下,目前已经发现的就有不少情况会造成mysql的复制出现问题,主要是修改数据的时候使用了某些特定的函数或者功能的时候会出现,比如:sleep()函数在有些版本中就不能真确复制,在存储过程中使用了last_insert_id()函数,可能会使slave和master上得到不一致的id等等。由于row level是基于每一行来记录的变化,所以不会出现类似的问题。

  3. Mixed Level: 从 5.1.8 版本开始,MySQL 提供了除Statement Level和Row Level之外的第三种 Mixed Level,实际上就是前两种模式的结合。在Mixed模式下,MySQL会根据执行的每一条具体的 Query 语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。除了MySQL认为通过STATEMENT方式可能造成复制过程中Master与Slave之间产生不一致数据(如特殊Procedure和Function的使用,UUID()函数的使用等特殊情况)的时候MySQL会选择ROW的模式来记录变更之外,都会使用STATEMENT模式来记录变更。当然,这里需要排除的特殊情况并不仅仅只有上面所描述的这几种,具体请参考 MySQL 官方的详细手册。

  老版本的 MySQL 一直都只有基于 Statement 的复制模式,直到5.1.5版本的 MySQL 才开始支持Row Level的复制。从5.0开始,MySQL 的复制已经解决了大量老版本中出现的无法正确复制的问题。但是由于存储过程的出现,给 MySQL 的复制又带来了更大的新挑战。另外,看到官方文档说,从5.1.8版本开始,MySQL 开始提供 Mixed Level,新版本中的Statment level还是和以前一样,仅仅记录执行的语句。而新版本的Mysql中队Row Level模式也被做了优化,并不是所有的修改都会以Row Level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果 Query 语句确实就是 UPDATE 或者 DELETE 等修改数据的语句,那么还是会记录所有行的变更。

来源:http://blog.csdn.net/adparking/article/details/7586054

转载于:https://blog.51cto.com/longzhiyi/903894

MYSQL复制的几种模式相关推荐

  1. mysql的几种模式_MYSQL复制的几种模式

    MySQL 5.1 中,在复制方面的改进就是引进了新的复制技术:基于行的复制. MYSQL复制的几种模式 MySQL 5.1 中,在复制方面的改进就是引进了新的复制技术:基于行的复制. 简言之,这种新 ...

  2. mysql复制模式有几种_MYSQL复制的几种模式

    MySQL 5.1 中,在复制方面的改进就是引进了新的复制技术:基于行的复制. MYSQL复制的几种模式 MySQL 5.1 中,在复制方面的改进就是引进了新的复制技术:基于行的复制. 简言之,这种新 ...

  3. MySQL binlog日志三种模式选择及配置

    在认识binlog日志三种模式前,先了解一下解析binlog日志的命令工mysqlbinlog.mysqlbinlog工具的作用是解析mysql的二进制binlog日志内容,把二进制日志解析成可以在M ...

  4. Mysql复制表两种方式(复制表结构、复制表结构和数据、复制表中的部分数据、复制表中的部分数据并起别名)

    需要完全的复制MySQL的数据表,包括表的结构,索引,默认值等. 如果仅仅使用CREATE TABLE - SELECT 命令,是无法实现的. 本章节将为大家介绍如何完整的复制MySQL数据表,步骤如 ...

  5. 设置MySQL复制时,replicate-ignore-db模式下如何正常工作

    在复制中,如果启用参数 replicate-ignore-db / replicate-do-db 后想要让复制正常运行,只需在连接数据库后不执行 "use db" 语句即可,如果 ...

  6. Mysql当前模式让不记录日志_MySQL日志binlog的三种模式

    1三种模式的介绍 二进制日志binlog作用: 1.以二进制形式记录更改数据库的SQL语句(insert,update,delete,create,drop,alter等) 2.用于Mysql主从复制 ...

  7. mysql主从同步的三种模式

    mysql 主从同步三种模式:异步复制.半同步复制.全同步复制 今天我们就来看下这三种同步模式的优势和劣势 异步复制 异步复制是mysql 默认的同步方式 在master为slave开通账号密码.ip ...

  8. mysql 复制数据文件_mysql数据库搬家,可以直接复制数据库文件吗

    诶?这项技术又是什么玩意(What)? 这项技术为什么会存在?我们已经有那么多解决方案(Method)了,我们为什么要用它(Why)? 如果这项技术那么好且我们正好有场景可以用到这项技术,且能使我们的 ...

  9. 以下关于mysql复制关系_MySQL 复制

    MySQL复制介绍 •MySQL复制允许将主实例(master)上的数据同步到一个或多个从实例(slave)上,默认情况下复制是异步进行的,从库也不需要一直连接到主库来同步数据 • MySQL复制的数 ...

最新文章

  1. HALCON标定助手使用实例
  2. [轉]俞老师在同济大学的演讲词:度过有意义的生命
  3. 随机森林与梯度提升树
  4. Linux移植随笔:让内核支持nor flash
  5. linux hosts和hostname
  6. c盘存放文件夹的功能
  7. 大型综合办公管理系统源码(OA+HR+CRM)源码免费分享
  8. HTML 标签参考手册 - 功能排序
  9. 物联网安全漏洞有哪些
  10. matlab+nnf.m,第6章_西安电子科技大学:工程线性代数(MATLAB版)_ppt_大学课件预览_高等教育资讯网...
  11. 解决 Minimum supported Gradle version is 5.1.1. Current version is 4.6
  12. zookeeper Session Expired
  13. java-poi实现生成word
  14. 数据分类分级 数据识别-实现部分敏感数据识别
  15. oracle exp query使用解决-LRM-00101: 未知的参数名
  16. html a标签设置背景,css利用A标签的背景可能作出很有意思的效果
  17. Google 出的C++轻量级日志库_GLog_了解_使用
  18. 微信引流方法之闲鱼引流
  19. Springboot使用Mapstruct拷贝对象,集成swagger2
  20. Codeforces 题目合集+分类+代码 【Updating...】【361 in total】

热门文章

  1. 《Hive编程指南》14.3 投影变换的实践出错原因分析
  2. JavaScript语义基础
  3. linux下安装oracle sqlplus以及imp、exp工具
  4. 构建Spring Boot程序有用的文章
  5. iOS开发- 蓝牙后台接收数据(BLE4.0)
  6. 如何获取组SPGroup的描述Description信息
  7. 使用V-chart时配置踩过的一些坑
  8. NSTimer不准确与GCDTimer详解
  9. IDEA微服务项目的application.yml没有绿色叶子的解决办法
  10. Codeforces Beta Round #1