2台阿里云服务器centOS系统下mysql进行主主同步

项目背景:

原有的项目是在一台服务器上运行,服务器一旦宕机,系统就无法使用。为了让系统不间断运行,至少要2台服务器集群部署,一个宕机了另一个还能运行。那么这时候就涉及到一个问题,项目部署到2台服务器上每个服务器上的数据库如何同步呢,这时候就想到主从同步了,但是主从同步是主服务器的数据进行修改后,从服务器的数据库进行更新,从服务器的数据库并不能进行修改操作。为了让2个服务器的数据库都能读写数据,就要实现主主同步。

服务器环境:

第一台服务器:阿里云centOS6.8 32位   MySQL5.1   公网IP 47.99.91.1(IP假的哈,举例而已)

第二台服务器:阿里云centOS7.8 64位   MySQL5.7   公网IP 47.99.91.2(IP假的哈,举例而已)

具体实现步骤:

步骤1:在服务器1中修改my.cnf配置

输入命令:vi /etc/my.cnf 

2台阿里云服务器centOS系统下mysql进行主主同步

然后按i键进入编辑模式,在文件最后面添加以下内容:

server-id = 1       #这个是mysql的id要唯一,每个服务器上的不一样,可以从1开始 

log-bin = mysql-bin  #这个配置意思是开启二进制日志,只有开启了,别的服务器上传的mysql才能同步

binlog-do-db = mms  #这个是配置需要同步的数据库,如果有多个需要同步,多写几行

sync_binlog = 1  #这个默认为0,表示异步同步,性能好但是数据有丢失的可能性。设置为1表示同步同步,性能低但是数据不会丢失

binlog_format = mixed  #这个是为了保证主键不重复

auto-increment-increment = 2    

auto-increment-offset = 1   

slave-skip-errors = all  #跳过所有的错误,继续执行复制操作

关于以上参数的一些具体提示:

1.sync_binlog这个参数是对于MySQL系统来说是至关重要的,他不仅影响到Binlog对MySQL所带来的性能损耗,而且还影响到MySQL中数据的完整性。对于"sync_binlog"参数的各种设置的说明如下:

sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。

sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

在MySQL中系统默认的设置是sync_binlog=0,也就是不做任何强制性的磁盘刷新指令,这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。而当设置为“1”的时候,是最安全但是性能损耗最大的设置。因为当设置为1的时候,即使系统Crash,也最多丢失binlog_cache中未完成的一个事务,对实际数据没有任何实质性影响。

2.在做主主同步前,提醒下需要特别注意的一个问题:

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

出现的问题(多主自增长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,当然如果服务器多的话,还可以自定义算法,只要不同就可以了

在下面例子中,在两台主主服务器上加入参数,以实现奇偶插入!

记住:在做主主同步时需要设置自增长的两个相关配置,如下:

auto_increment_offset     表示自增长字段从那个数开始,取值范围是1 .. 65535。这个就是序号。如果有n台mysql机器,则从第一台开始分为设1,2...n

auto_increment_increment    表示自增长字段每次递增的量,其默认值是1,取值范围是1 .. 65535。如果有n台mysql机器,这个值就设置为n。

在主主同步配置时,需要将两台服务器的:

auto_increment_increment     增长量都配置为2

auto_increment_offset        分别配置为1和2。这是序号,第一台从1开始,第二台就是2,以此类推.....

这样才可以避免两台服务器同时做更新时自增长字段的值之间发生冲突。(针对的是有自增长属性的字段)

2台阿里云服务器centOS系统下mysql进行主主同步

把这些参数设置好后,按esc键退出编辑模式,输入命令  :wq  保存文件

步骤2:在服务器1中创建用于同步的账号

mysql> grant replication slave on mms.* to 'repl01'@'47.99.91.2' identified by '123456';

mysql> flush privileges;

第一句话的意思:创建并授权账号repl01拥有mms数据库的所有权限,密码为123456,只能从ip为47.99.91.2来访问

第二句话的意思是刷新权限

步骤3:在服务器2中修改my.cnf配置

输入命令:vi /etc/my.cnf 

添加的内容和第一步基本一样,就是2处不一样

server-id = 2  

auto-increment-offset = 2

步骤4:在服务器2中创建用于同步的账号

mysql> grant replication slave on mms.* to 'repl02'@'47.99.91.1' identified by '456789';

mysql> flush privileges;

第一句话的意思:创建并授权账号repl02拥有mms数据库的所有权限,密码为456789,只能从ip为47.99.91.1来访问

第二句话的意思是刷新权限

步骤5:把服务器1和服务器2的数据调整一致(如果2个服务器都是新建的这一步可省略)

在同步之前把2个服务器中数据库内的数据都自己手动复制成一样的,那么开启同步后,所有数据都一样了。我这边手动同步是用MySQL-Front这个软件远程连接了2个服务器,然后把原先运行的那个服务器中mms库里数据导出为sql文件,然后又导入到新建的那个服务器的数据库中的。这一步你们也可以用其他方式。

步骤6:在服务器1中同步服务器2

先去服务器2中mysql中输入命令  show master status; 获取2个参数

mysql> show master status;

+------------------+----------+--------------+------------------+-------------------+

| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000001 |   256 |       |          |          |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

然后在服务器1中mysql中输入以下命令

mysql> change master to master_host='47.99.91.2',master_user='repl02',master_password='456798',master_log_file='mysql-bin.000001',master_log_pos=256;

这句命令设置的意义就在于,服务器1的mysql一旦开启了同步后,就从去服务器2的ip地址根据master_log_file和master_log_pos这2个参数读取服务器2的mysql的二进制日志文件,服务器1的mysql读取到了之后就更新数据。

输入命令开启同步

mysql> start slave;

mysql> show slave status \G;

*************************** 1. row ***************************

             Slave_IO_State: Waiting for master to send event

              Master_Host: 47.99.91.1

              Master_User: repl

              Master_Port: 3306

             Connect_Retry: 60

            Master_Log_File: mysql-bin.000001

          Read_Master_Log_Pos: 158

           nelay_Log_File: mysql-relay-bin.000003

             Relay_Log_Pos: 750

        Relay_Master_Log_File: mysql-bin.000001

            Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

            ..................

只要黄色2行是yes就表示服务器1的同步成功,这时你去修改、添加、删除服务器2的mysql数据时,服务器1的也会同步了

步骤7:在服务器2中同步服务器1

先去服务器1中mysql中输入命令  show master status; 获取2个参数

mysql> show master status;

+------------------+----------+--------------+------------------+-------------------+

| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000003 |   100 |       |          |          |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

然后在服务器2中mysql中输入以下命令

mysql> change master to master_host='47.99.91.1',master_user='repl01',master_password='4123465',master_log_file='mysql-bin.000003',master_log_pos=100;

这句命令设置的意义就在于,服务器2的mysql一旦开启了同步后,就从去服务器1的ip地址根据master_log_file和master_log_pos这2个参数读取服务器1的mysql的二进制日志文件,服务器2的mysql读取到了之后就更新数据。

输入命令开启同步

mysql> start slave;

mysql> show slave status \G;

*************************** 1. row ***************************

             Slave_IO_State: Waiting for master to send event

              Master_Host: 47.99.91.2

              Master_User: repl

              Master_Port: 3306

             Connect_Retry: 60

            Master_Log_File: mysql-bin.000001

          Read_Master_Log_Pos: 158

           nelay_Log_File: mysql-relay-bin.000003

             Relay_Log_Pos: 750

        Relay_Master_Log_File: mysql-bin.000001

            Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

            ..................

只要黄色2行是yes就表示服务器2的同步成功,这时你去修改、添加、删除服务器1的mysql数据时,服务器2的也会同步了

这样就实现了2台服务器的数据实时同步