双主双写、只备份某些表且要在建表ID自增

先展示下最终实现的配置

主1的配置(重要的,其他略)

log-bin = mysql-bin #必须要有binlog

auto_increment_offset = 1 #自增ID的初始值

auto_increment_increment = 2 #自增ID的步长(每次自动增加的数)

server-id=1 #server-id 主库从库要不同

replicate-do-db=haha #作为slave时(SQL线程)将要复制(同步)的数据库

replicate-wild-do-table=haha.user #作为slave时(SQL线程)将要复制(同步)的数据库的数据表

#以上两个配合使用,就指定只有该表同步了

master-host = 192.168.56.14 # 设置master的参数,略

master-user = rep

master-password = 123321

master-port = 3306


除此之外你的业务也要有相应的配置,也就是说(要同步的)数据库的表要设置自增ID,如

mysql> create table user(

    -> userid int(4) primary key not null auto_increment,

    -> username varchar(16) not null,

    -> userpassword varchar(32) not null

    -> );

如上例中的 auto_increment

主2的配置

log-bin = mysql-bin #必须要有binlog

auto_increment_offset = 2 #自增ID的初始值,注意和主区别

auto_increment_increment = 2 #自增ID的步长(每次自动增加的数)

server-id=2         #server-id 主库从库要不同

replicate-do-db=haha #作为slave时(SQL线程)将要复制(同步)的数控库

replicate-wild-do-table=haha.user         #作为slave时(SQL线程)将要复制(同步)的数控库

#以上两个配合使用,就指定只有该表同步了

#多个表就写多个,如haha.user123

master-host = 192.168.56.13 # 设置master的参数,略

master-user = rep

master-password = 123321

master-port = 3306

重启数据库,重启slave线程

测试,达到需求.

思想:

         不要在主库使用 --binlog-do-db 和 --binlog-ignore-db 来限制从库要复制库

要在从库使用replicate-do-db 和 replicate-wild-do-table 限制同步的库

详解

ID自增问题

多主互备和主从复制有一些区别,因为多主中都可以对服务器有写权限,所以设计到自增长重复问题

出现的问题(多主自增长ID重复)

1:首先我们通过A,B的test表结构

2:掉A,在B上对数据表test(存在自增长ID)执行插入操作,返回插入ID 为1

3:后停掉B,在A上对数据表test(存在自增长ID)执行插入操作,返回的插入ID也是1

4:然后 我们同时启动A,B,就会出现主键ID重复


解决方法:

我们只要保证两台服务器上插入的自增长数据不同就可以了

如:A 查奇数ID,B插偶数ID,当然如果服务器多的话,你可以定义算法,只要不同就可以了

在这里我们在A,B上加入参数,以实现奇偶插入


A:my.cnf上加入参数

auto_increment_offset = 1

auto_increment_increment = 2

这样A的auto_increment字段产生的数值是:1, 3, 5, 7, …等奇数ID了


B:my.cnf 上加入参数

auto_increment_offset = 2

auto_increment_increment = 2

这样B的auto_increment字段产生的数值是:2, 4, 6, 8, …等偶数ID了

可以看出,你的 auto_increment字段在不同的服务器之间绝对不会重复,所以Master-Master结构就没有任何问题了。当然,你还可以使用3台,4 台,或者N台服务器,只要保证auto_increment_increment = N 再设置一下auto_increment_offset为适当的初始值就可以了,那样,我们的MySQL可以同时有几十台主服务器,而不会出现自增长ID重复。

指定表的同步

我看到很多人用binlog-do-db, binlog-ignore-db, replicate-do-db, and replicate-ignore-db来过滤哪些库需要主从复制。虽然这4个参数确实能这样做,但我看来这样做是危险的。这4个参数被滥用了。在很多情 况下,这有更好安全的选择。

为什么危险很简单: 他们并不像你想的那样工作. 想象如下的场景: 你设置了 binlog-ignore-db = garbage, 所以garbage数据库(在slave上不存在这个数据库) 中的数据不会被复制。

现在请按操作:

  1. $ mysql
  2. mysql> delete from garbage.junk;
  3. mysql> use garbage;
  4. mysql> update production.users set disabled = 1 where user = "root";

复制会broke2次, 第一次,因为 slave尝试着去执行第一条语句,但是slave上并没有这样的表”garbage.junk” , 第二次, 隐含的, 因为对production.users表的操作不会被复制,所以root帐号并没有在slave上被禁用掉。

为什么? 因为 binlog-ignore-db 并不像你想的那样执行, 我之前说的, “garbage数据库上的数据不会被复制”是错的, 实际上(数据库)并没有这么做。事实上,他是通过“use 数据库”这种方式来过滤掉到哪些数据库操作不记录到binlog中去的。换句话说, 过滤不是基于查询的字符串的, 而是基于你used的数据库。

  1. mysql> use garbage;
  2. mysql> update production.users set disabled = 1 where user = "root";
像这里的,主库使用garbage,binlog就会忽略掉、不记录紧跟其后的操作,如这里的update production.users set disabled = 1 where user = “root”; 传给从库也就没有这行操作,导致从库没有更新root表。

我提到的其它配置选项也是类似. binlog-do-db 和 binlog-ignore-db 语句是特别危险的,因为它们不将指定的数据库操作写入到binary日志,导致你不能使用二进制日志从备份恢复指定时间的数据。

安全的替换方案是在 slave上配置过滤, 使用基于查询中真正涉及到的表的选项, 这些是: replicate-wild-* 选项, 例如, 避免复制 garbage数据库中的数据的安全的方案是 配置:  replicate-wild-ignore-table=garbage.%. 这样做仍然有一些特殊的情况, 不能正常工作,但可以在更多的情况下正常工作,并且会遇到更少的意外 (gotchas)。










posted @ 2016-05-19 22:19  曹小贱  阅读(699)  评论(0编辑  收藏  举报