关于MySQL主从复制的过滤,例如通过binlog-ignore-db、replicate-do-db、replicate-wild-do-table等。如果不好好研究过这些过滤选项就用的话,是有可能造成主从数据不一致问题的。本文将参考MySQL-5.5官方文档并结合实验,和各位一起探讨下这里的各个设置。

以下内容参考5.5官方文档

binlog_format的设置会导致一些复制执行上的差异。

格式有三种(STATEMENT,ROW,MIXED,5.5默认为STATEMENT)

当使用MIXED格式时,binlog绝大多数情况也是以STATEMENT格式记录,只有在下列情况下才会切换到ROW格式:

1、 当时用UUID()函数时

2、 当一个或多个拥有AUTO_INCREMENT列的表被更新同时有‘trigger’或者‘stored function’被调用时

# MIXED对于‘trigger’和‘stored function’总是使用statement-based

3、 执行INSERT DELAYED时

4、 当视图里的某一部分需要row-based复制(例如UUID())时,创建该视图的语句被改为row-based

5、 使用用户自定义函数(UDF)时

6、 当某语句被判定为row-based,并且执行它的session需要用到临时表,则session下的所有子语句都将以ROW格式记录

7、 当使用USER(),CURRENT_USER()或者 CURRENT_USER

8、 当语句引用了一个或多个system variables。

9、 当使用LOAD_FILE()

下面几点要注意

1.所有DDL语句都是基于statements,不论binlog_format如何设置

2.复制双方binlog_format需一致,否则复制无法进行

3.Binlog格式影响到以下‘复制过滤’配置的行为

--binlog-do-db
--binlog-ignore-db=ljk     #黑名单,这个库的修改不记录二进制日志。
该选项的行为取决于binlog格式
对于Statement-based logging:当use ljk后(即当前库为ljk时),所有的语句不被记录进binlog
当登陆mysql后不使用use或者use ljk之外的库,执行update ljk.table 依然会记录近binlog并复制[只对ljk库生效]
对于Row-based format:告诉服务器不记录任何ljk库下表的更改,无论当前在哪个库(即无论有无use语句,是否使用use  ljk)
--replicate-do-db = ljk             #白名单,允许复制哪个库
该选项的行为取决于binlog格式
对于Statement-based replication:只有主库在use ljk 之后执行的语句才会被从库复制,没有用use语句或者use其他库后执行的语句均不被复制

对于Row-based replication:只有ljk库的更改会被复制(无论use哪个库或者是否use)
无论是否use或use哪个库,ljk库之外的变更都不会被复制
--replicate-ignore-db

总结:Statement-based跟当前use的库有关,Row-based更直接,只关心指定的库‘做或不做’。

还有以下两种参数可‘过滤复制’
以下两种选项只对表的更改有影响,库的复制不受这些参数影响(但是类似ljk.%这种,也会对库起作用)

--replicate-do-table

这两个选项在我的实验里跟描述不太一致,详细见下文实验结果

--replicate-ignore-table

--replicate-wild-do-table = ljk.%   >>>>严格限定复制
无论use ljk或use 其他库或不use,对ljk库的更新都能被复制,同时,其他任何库在任何情况下均不会复制(包括建库建表操作)
--replicate-wild-ignore-table   

根据以上,综合建议:对复制的过滤,采用replicate-wild-do-table/ replicate-wild-ignore-table,比较严格和明确

下面是实验过程(MySQL-5.5.39)
一、 主库添加“binlog-ignore-db = mysql”,从库不加过滤

库操作:
    1. 主库不use,执行建库语句
    mysql> create database kai;
    从库复制
    2. 主库use  mysql,再执行
    mysql> create database kai;
    从库复制

在kai数据库执行建表操作:
    1. 没有use
    create table kai.li (id int,name char(15));
    从库复制
    2. use mysql;
    create table kai.li (id int,name char(15));
    从库不复制
    3. use 其他库;
    create table kai.li (id int,name char(15));
    从库复制

对表内容修改:
    1. 主库不use,向li表增加数据
    insert into kai.li values('1','ljk');
    从库复制
    2. 主库 use mysql,向li表增加数据
    从库不复制
    3. 主库use 其他库,更新li库(即跨库更新)
    mysql> use picture;
    mysql> insert into kai.li values('2','lhy');
    从库复制

对mysql库进行更改:
    1. 不 use
    mysql> create table mysql.ljk (id int,name varchar(15));
    从库复制
    2. Use 其他库
    mysql> drop table mysql.ljk;
    从库复制

 总结:对于主库使用binlog-ignore-db来说:只有在use db执行后才会生效

二、从库添加“replicate-ignore-db = mysql”,主库不加过滤

库操作
    1. 主库不use,执行建库语句
    mysql> create database kai;
    从库复制
    2. 主库use  mysql,再执行
    mysql> create database kai;
    从库复制

在kai数据库执行建表操作
    1. 没有使用use
    create table kai.li (id int,name char(15));
    从库复制
    2. use mysql;
    create table kai.li (id int,name char(15));
    从库不复制
    3. use 其他库;
    create table kai.li (id int,name char(15));
    从库复制

对表内容修改:
    1. 主库不use,向li表增加数据
    insert into kai.li values('1','ljk');
    从库复制
    2. 主库 use mysql,向li表增加数据
    从库不复制
    3. 主库use 其他库,更新li库(即跨库更新)
    mysql> use picture;
    mysql> insert into kai.li values('2','lhy');
    从库复制

对mysql库进行更改
    1. 不 use
    mysql> create table mysql.ljk (id int,name varchar(15));
    从库不复制,且从库状态正常????
    2. Use 其他库
    mysql> drop table mysql.ljk;
    从库复制
    3. Use mysql
    mysql> create table ljk (id int,name varchar(15));
    从库不复制

 总结对于从库设定replicate-ignore-db 来说,基本上只有在主库使用use db时才会生效。

三、从库添加“replicate-ignore-table = mysql.%”,主库不加过滤

注:这条规则加完在任何库下执行任何语句均复制;相反,在从库添加replicate-do-table = mysql.%后,在任何库下执行任何sql都不会被复制。不知道是不是bug

库操作:
    1. 主库不use,执行建库语句
    mysql> create database kai;
    从库复制
    2. 主库use  mysql,再执行    
    mysql> create database kai;
    从库复制

在kai数据库执行建表操作
    1. 不use
    create table kai.li (id int,name char(15));
    从库复制
    2. use mysql;
    create table kai.li (id int,name char(15));
    从库复制   ????
    3. use 其他库;
    create table kai.li (id int,name char(15));
    从库复制

对表内容修改:
    1. 主库不use,向li表增加数据
    insert into kai.li values('1','ljk');
    从库复制
    2. 主库 use mysql,向li表增加数据
    从库复制
    3. 主库use 其他库,更新li库(即跨库更新)
    mysql> use picture;
    mysql> insert into kai.li values('2','lhy');
    从库复制

对mysql库进行更改
    1. 不 use
    mysql> create table mysql.ljk (id int,name varchar(15));
    从库复制
    2. Use 其他库
    mysql> drop table mysql.ljk;
    从库复制
    3. Use mysql
    mysql> create table ljk (id int,name varchar(15));
    从库复制

 总结:好像有bug,应该来说在use db后,并在对应的库下创建表应该会忽略同步。

四、 从库添加“replicate-wild-ignore-table = mysql.%”,主库不加过滤

库操作:
    1. 主库不use,执行建库语句
    mysql> create database kai;
    从库复制
    2. 主库use  mysql,再执行
    mysql> create database kai;
    从库复制

在kai数据库执行建表操作
    1. 不use
    create table kai.li (id int,name char(15));
    从库复制
    2. use mysql;
    create table kai.li (id int,name char(15));
    从库复制
    3. use 其他库;
    create table kai.li (id int,name char(15));
    从库复制

对表内容修改:
    1. 主库不use,向li表增加数据
    insert into kai.li values('1','ljk');
    从库复制
    2. 主库 use mysql,向li表增加数据
    从库复制
    3. 主库use 其他库,更新li库(即跨库更新)
    mysql> use picture;
    mysql> insert into kai.li values('2','lhy');
    从库复制

对mysql库进行更改
    1. 不 use
    mysql> create table mysql.ljk (id int,name varchar(15));
    从库不复制
    2. Use 其他库
    mysql> drop table mysql.ljk;
    从库不复制
    3. Use mysql
    mysql> create table ljk (id int,name varchar(15));
    从库不复制

总结:使用replicate-wild-ignore-table之后,所有对于mysql库下的表级别的任何操作都被忽略同步

综上参考官方文档以及实验,可得出结论:

对于每一个添加的‘复制过滤’配置,应从两方面考虑:

1. 不用use语句引用库,或者use xxx引用其他库之后再执行sql(又分两部分:对‘过滤的库/表’ 或 ‘对其他库/表’)会怎样

2. use xxx引用‘过滤的库/表’,再执行sql(也分两部分:对‘过滤的库/表’ 或 ‘对其他库/表’)会怎样

除replicate-wild-do-table=/replicate-wild-ignore-table=外,其他过滤规则会受到“binlog_format”以及“当前所在库”的影响(即所谓的跨库问题)

建议使用
replicate-wild-ignore-table=mysql.%
因为replicate-ignore-db 是通过use db来确定是否过滤的。
而wild-ignore是通过真实被修改的表进行过滤的,更为准确。

实验也验证了上文提到的“对复制的过滤,采用replicate-wild-do-table/ replicate-wild-ignore-table,比较严格和明确

本文永久更新链接地址http://www.linuxidc.com/Linux/2015-10/124181.htm

MySQL 5.5主从关于‘复制过滤’的深入探究的更多相关文章

  1. MySQL 5.7在线设置复制过滤【转】

    转自 MySQL 5.7在线设置复制过滤 - yayun - 博客园 https://www.cnblogs.com/gomysql/p/4991197.html 5.7也GA了,有许多新的特性,其中 ...

  2. MySQL数据库的主从同步复制配置

    一.主从同步机制原理 MYSQL主从同步是在MySQL主从复制(Master-Slave Replication)基础上实现的,通过设置在Master MySQL上的binlog(使其处于打开状态), ...

  3. MySQL(mariadb)主从复制模式与复制过滤

    在前一篇文章<mysql多实例与复制应用>中只对mysql的复制做了简单的介绍,本篇内容专门介绍一下mysql的复制. MySQL复制 mysql复制是指将主数据库的DDL和DML操作通过 ...

  4. MySQL 5.7在线设置复制过滤

    很久没有更新博客了,主要是公司事情比较多,最近终于闲下来了.然而5.7也GA了,有许多新的特性,其中现在可以进行在线设置复制过滤了.但是还是得停复制,不过不用重启实例了.方便了DBA们进行临时性的调整 ...

  5. mysql 5.7主从库复制设置

    先要修改配置文件,重启mysql服务 log-bin= mysql-binlog # 打开二进制日志 ,最好放在不同的硬盘上,减小 IO 消耗 expire_logs_day= # 设置二进制日志保存 ...

  6. MySQL/MariaDB数据库的主从级联复制

      MySQL/MariaDB数据库的主从级联复制 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.主从复制类型概述 1>.主从复制 博主推荐阅读: https://ww ...

  7. mysql主从延迟复制

    需求描述 正常情况下我们是不会有刻意延迟从库的需求的,因为正常的线上业务自然是延迟越低越好.但是针对测试场景,业务上偶尔需要测试延迟场景下业务是否能正常运行. 解决方案 针对这种场景mysql有一个叫 ...

  8. mysql主从服务器复制操作

    master主机ip:192.168.1.19  用户名sunzy 密码123456slave主机ip:192.168.1.20 1.配置master1)接下来对master进行配置,包括打开二进制日 ...

  9. MYSQL管理之主从同步管理

    原文地址:MYSQL管理之主从同步管理 作者:飞鸿无痕 MYSQL管理之主从同步管理 MYSQL主从同步架构是目前使用最多的数据库架构之一,尤其是负载比较大的网站,因此对于主从同步的管理也就显得非常重 ...

随机推荐

  1. Jmeter实现Basic Auth方式登录

    背景 在实际测试日常中,产品有两种登录方式,一种是普通登录方式,另一种则是Basic Auth方式登录.两种登录对应着产品中不同的操作,对权限进行了一个划分. Postman登录 使用Postman登 ...

  2. 博客第一篇 osi七层网络传输模型

  3. ASP.NET MVC 常用路由总结

    1.URL模式 路由系统用一组路由来实现它的功能,这些路由共同组成了应用系统URL架构或方案,这种URL架构是应用程序能够识别并能对之做出响应的一组URL,当处理一个输入 请求时,路由系统的工作是将这 ...

  4. python Event对象、队列和多进程基础

    Event对象 用于线程间通信,即程序中的其一个线程需要通过判断某个线程的状态来确定自己下一步的操作,就用到了event对象 event对象默认为假(Flase),即遇到event对象在等待就阻塞线程 ...

  5. Git 基本命令行操作

    一.本地仓库操作 1.初始化    git init 2.添加版本控制文件    git add README.md3.本地提交    git commit -m “1st commit”4.配置远程 ...

  6. Jenkins不同job之间传递参数

    有的时候不同job直接需要传递一个文件名或者路径,这个时候我们不需要传递文件实体,那这个路径如何传递呢?比如有如下两个项目,我想把A的工作目录传递给B,让B使用. A job配置 首先需要安装一个Pa ...

  7. DRF的视图

    DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们两个有什么不同呢~~~ urlpatterns = [    ...

  8. 在UnrealEngine中用Custom节点实现马赛克效果

    参考这位大神的Shaderhttp://blog.csdn.net/noahzuo/article/details/51316015 //input BaseUV 屏幕UV //intput Tili ...

  9. Ubuntu编译安装配置Redis以及基本使用

    1.首先下载redis curl -O http://download.redis.io/releases/redis-4.0.8.tar.gz 2.解压压缩包 .tar.gz 3.安装TCL测试工具 ...

  10. eclipse 导入android 项目重名解决方法

    在进行andoid 开发时会用到许多的开源框架,但有时候发现几天框架的项目名字都是 library. 解决方法: 1.如果项目中没有 .project 文件,直接修改项目文件夹的名字即可,注意在你引用 ...