目录:

一、Mysql Replication介绍

二、Mysql Replication架构

(一)Master-MultiSlave(单主到多从)
(二)Master-DistributedMaster-Slave(单主到从到多从)
(三)Tree(单主到多从再到多从)
(四)Master-Master(双主)

三、Mysql Replication配置测试

(一)Master-MultiSlave(单主到多从)
(二)Master-DistributedMaster-Slave(单主到从到多从)
(三)Master-Master(双主)

四、Mysql Replication性能测试

(一)测试环境
(二)准备工作
(三)测试方式
(四)性能测试
(五)测试结果

五、问题排除

(一)出现Slave_IO_Running: No
(二)出现Error: ‘Host ’192.168.7.129′ is not allowed to connect to this MySQL server’ errno: 1130 retry-time: 60 retries: 86400
(三)出现Error: ‘Host ’192.168.7.1′ is not allowed to connect to this MySQL server’
(四)出现Could not initialize master info structure

一、 Mysql Replication介绍

MySQL支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
如果想要设置链式复制服务器,从服务器本身也可以充当主服务器。
请注意当进行复制时,所有对复制中的表的更新必须在主服务器上进行。否则,必须要小心,以避免用户对主服务器上的表进行的更新与对从服务器上的表所进行的更新之间的冲突。
单向复制有利于健壮性、速度和系统管理:
1、主服务器/从服务器设置增加了健壮性。主服务器出现问题时,可以切换到从服务器作为备份。
2、通过在主服务器和从服务器之间切分处理客户查询的负荷,可以得到更好的客户响应时间。SELECT查询可以发送到从服务器以降低主服务器的查询处理负荷。但修改数据的语句仍然应发送到主服务器,以便主服务器和从服务器保持同步。如果非更新查询为主,该负载均衡策略很有效,但一般是更新查询。
3、使用复制的另一个好处是可以使用一个从服务器执行备份,而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。

二、 Mysql Replication架构

在实际应用中,可以根据具体的情况灵活地将主/从结构进行变化组合,下面将介绍一些常见的复制架构,万变不离其宗。
在进行各种部署之前,还需要遵守这么几条规则:
1. 一个从服务器只能有一个主服务器。
2. 一个主服务器可以有多个从服务器。
3. 无论是主服务器还是从服务器,都要确保各自的Server ID唯一。
4. 一个从服务器可以将其从主服务器获得的更新事件,传递给其它的从服务器;同时,这个从服务器也可以成为其他从服务器的主服务器。
(一)Master-MultiSlave(单主到多从)
这种架构是最基础的主从结构的水平扩展,所有的Slave之间没有任何联系,它们都各自独立的与唯一的Master进行连接。这种架构适用于读操作频繁写操作相对比较少的应用。
架构图如图1所示:
Mysql Replication架构部署一_mysql备份
图1 M-MSS架构
(二)Master-DistributedMaster-Slave(单主到从到多从)
这种架构其实是源于上面的Master-MutilSlave架构,在这个基础上又加入了一个具有特殊功能Master,是一种带有分布式功能的Master-MutilSlave架构。实际生产环境中,如果Master后面的Slave的数量相当多,这样就会给Master系统带来很大的负担,因为它要将每次的更新同步到下面的许许多多的Slave上,这样就会影响其对外提供服务的性能。如果我们将Master的每次更新先同步到一个Master上,然后再由其完成所有Slave的更新。这个特殊的Master使用一种叫做blackhole的存储引擎,使其具有很强的分发更新的能力。
架构图如图2所示:
Mysql Replication架构部署一_mysql备份_02
图2 分布式M-MSS架构
(三)Tree(单主到多从再到多从)
Tree架构,即M-SS-SS,是一个Master后面有一个庞大的Slave群,于是就将这些Slave按照树形结构将它们依次排开,基于上面分布式M-MSS架构。这种架构可以降低Master端的负载,但是它的缺点也是显而易见的,Slave间的关联性很强,如果与Master连接的Slave发生故障,那么和这个Slave相关联的所有Slave都将不能正常更新。
架构图如图3所示:
Mysql Replication架构部署一_mysql备份_03
图3 树形 M-SS-SS架构
(四)Master-Master(双主)
这种架构实现了Mysql双向备份。原则上说,作为从服务器的数据库版本可以高于主服务器的数据库版本,但不可以低于主服务器的数据库版本。所以在这种架构模式下,两台服务器的数据库版本必须一致。
架构图如图4所示:
Mysql Replication架构部署一_Mysql Replication_04
图4 M-M架构
基于这种架构,还可以给每一台主机附加从服务器(即DualMaster-Slave架构),提供一种额外的安全冗余,也就是说发生故障时除了Master间的切换,也可以在Master和Slave之间切换,同时Slave还可以对外提供读操作,减轻Master的负担。
架构图如图5所示:
Mysql Replication架构部署一_mysql主从复制_05
图5 MS-MS架构
以上介绍的几种架构都是在实际生产环境中常会遇到的架构模式,可以根据企业内部的具体情况,合理地采用这些架构,以保证应用高效可靠的运行。

三、 Mysql Replication配置测试

首先,在每台服务器上安装Mysql数据库:
[root@bogon ~]# yum install mysql*
默认安装的Mysql包含一个空密码的root用户和一个匿名用户,存在安全隐患,需要手动删除匿名用户,加密root帐号。如下操作:
启动Mysql服务:
[root@bogon ~]# service mysqld start
进入Mysql控制台:
[root@bogon ~]# mysql
选择mysql数据库:
mysql> use mysql
删除匿名用户:
mysql> delete from user where user=’ ‘;
设置root用户密码:
mysql> update user set password=password(‘qqing99′) where user=’root’;
以上操作重启mysql后生效。
然后针对上面介绍的几种架构模式分别进行测试其功能。分析以上几种架构模式,明显的可以看出第三种Tree架构模式是基于第二种 Master-DistributedMaster-Slave架构模式,所以测试时只测试第二种架构模式。
(一)Master-MultiSlave(单主到多从)
1、测试环境
Master Slave1 Slave2 Slave3
OS CentOS release 5.6 (Final) CentOS release 5.4 (Final) CentOS release 5.4 (Final) CentOS release 5.4 (Final)
Hostname bogon repli1 repli12 repli13
IP 192.168.41.189 192.168.7.128 192.168.7.129 192.168.7.130
Mysql-Version 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77
2、主服务器授权
在Master(bogon)上创建一个用户并授权从服务器可以连接主服务器并可以进行更新。
mysql> grant replication slave on *.* to repli@’192.168.7.128′ identified by ‘qqing99′;
mysql> grant replication slave on *.* to repli@’192.168.7.129′ identified by ‘qqing99′;
mysql> grant replication slave on *.* to repli@’192.168.7.130′ identified by ‘qqing99′;
然后退出mysql控制台,停止mysql服务:
mysql> \q
[root@bogon ~]#
service mysqld stop
3、配置Mysql主配置文件/etc/my.cnf
yum方式安装mysql,其默认主配置文件为/etc/my.cnf
在/etc/my.cnf配置文件[mysqld]模块添加如下参数
Master(bogon):
[root@bogon ~]# vim /etc/my.cnf
server-id = 1 #指定服务器的ID(ID唯一)
log-bin = mysql-bin #指定产生binlog日志文件的前缀
binlog-do-db = discuz #指定日志文件只对discuz数据库进行操作(可选)
binlog-ignore-db = mysql #指定日志文件不对mysql数据库进行操作(可选)
Slave1(repli1):
[root@repli1 ~]# vim /etc/my.cnf
server-id = 2 #指定服务器的ID
master-host = 192.168.41.189 #主服务器IP地址
master-user = repli #主服务器上创建授权给从服务器的用户
master-password = “qqing99″ #用戶密码
master-port = 3306 #连接端口
master-connect-retry = 60 #重试连接的时间
replicate-ignore-db = mysql #忽略同步备份的数据库
replicate-do-db = discuz #需要同步备份的数据库(如有多个,可添加 多条记录)
Slave2(repli2)和Slave3(repli3)的配置除server-id不同外,其它的和Slave1(repli1)的配置相同。
4、数据复制
确保要同步的Master和Slave的数据库相同,如果不同则要先把Master的数据库复制到Slave中。可以用mysqldump工具导出数据库再导入到Slave中,也可以直接打包Master的数据库再上传到Slave。如果数据库较大,则推荐使用第二种方式。但不管是使用哪种方式,在同步前都要先锁定Master的数据。
启动mysql服务:
[root@bogon ~]# service mysqld start
锁定数据,禁止更新:
mysql> flush tables with read lock;
打包数据:
[root@bogon mysql]# tar zcf discuz.tar.gz discuz
上传数据:
[root@bogon mysql]# scp discuz.tar.gz root@slave:/var/lib/mysql (slave表示从服务器的IP)
在从服务器上解压:
[root@repli1 mysql]# tar -zxvf discuz.tar.gz
解除锁定:
mysql> unlock tables;
5、查看同步状态
启动Slave服务器,进入mysql控制台,查看同步状态。
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.41.189
Master_User: repli
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000015
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000015
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: discuz
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
正常状态下,看到上面的两行加粗处,即Slave_IO_Running和Slave_SQL_Running的参数都为 Yes,就说明主从同步运行正常。
6、同步测试
在master上写入数据:
Master:
mysql> select * from repli;
+—-+——+——+
| id | name | sex |
+—-+——+——+
| 1 | Tom | boy |
| 2 | Mary | girl |
| 3 | John | boy |
| 4 | Lucy | girl |
+—-+——+——+
4 rows in set (0.00 sec)
mysql> insert into repli values(5,’Lily’,'girl’);
Query OK, 1 row affected (0.00 sec)
在slave上查看结果:
mysql> select * from repli;
+—-+——+——+
| id | name | sex |
+—-+——+——+
| 1 | Tom | boy |
| 2 | Mary | girl |
| 3 | John | boy |
| 4 | Lucy | girl |
| 5 | Lily | girl |
+—-+——+——+
5 rows in set (0.00 sec)
(二)Master-DistributedMaster-Slave(单主到从到多从)
1、测试环境
Master Master1/Slave1 Slave2 Slave3
OS CentOS release 5.6 (Final) CentOS release 5.4 (Final) CentOS release 5.4 (Final) CentOS release 5.4 (Final)
Hostname bogon repli1 repli12 repli13
IP 192.168.41.189 192.168.7.128 192.168.7.129 192.168.7.130
Mysql-Version 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77
2、主服务器授权
在master(bogon)上创建一个用户,授权从服务器Master1/Slave1(repli2)可以连接主服务器并可以进行更新。
mysql> grant replication slave on *.* to repli@’192.168.7.128′ identified by ‘qqing99′;
在Master1/Slave1(repli1)上创建一个用户,授权从服务器Slave2(repli2)和Slave3(repli3)可以连接主服务器并可以进行更新。
mysql> grant replication slave on *.* to srepli@’192.168.7.129′ identified by ‘qqing99′;
mysql> grant replication slave on *.* to srepli@’192.168.7.130′ identified by ‘qqing99′;
然后退出mysql控制台,停止mysql服务:
mysql> \q
[root@bogon ~]#
service mysqld stop
3、配置Mysql主配置文件/etc/my.cnf
在/etc/my.cnf配置文件[mysqld]模块添加如下参数
Master(bogon):
[root@bogon ~]# vim /etc/my.cnf
server-id = 1 #指定服务器的ID(ID唯一)
log-bin = mysql-bin #指定产生binlog日志文件的前缀
binlog-do-db = discuz #指定日志文件只对discuz数据库进行操作(可选)
binlog-ignore-db = mysql #指定日志文件不对mysql数据库进行操作(可选)
Master1/Slave1(repli1):
[root@repli1 ~]# vim /etc/my.cnf
server-id = 2
log-bin = mysql-bin
binlog-do-db = discuz
binlog-ignore-db = mysql
master-host = 192.168.41.189
master-user = repli
master-password = “qqing99″
master-port = 3306
master-connect-retry = 60
replicate-ignore-db = mysql
replicate-do-db = discuz
log-slave-updates
PS:当配置为A->B->C架构模式时,即B既是A的从服务器又是C的主服务器时,除了需要打开log-bin之外,还需要打开log-slave-updtes。否则,A的更新只能同步到B后无法同步到C。
可以通过在B上使用“show variables like ‘log%’ ”来确认是否已经生效。
mysql> show variables like ‘log%’;
+———————————+——-+
| Variable_name | Value |
+———————————+——-+
| log | OFF |
| log_bin | ON |
| log_bin_trust_function_creators | OFF |
| log_error | |
| log_queries_not_using_indexes | OFF |
| log_slave_updates | ON |
| log_slow_queries | OFF |
| log_warnings | 1 |
+———————————+——-+
8 rows in set (0.01 sec)
Slave2(repli2)和Slave3(repli3)的配置除server-id不同外,其它的都相同,做如下配置:
server-id = 3
master-host = 192.168.7.128
master-user = srepli
master-password = “qqing99″
master-port = 3306
master-connect-retry = 60
replicate-ignore-db = mysql
replicate-do-db = discuz
4、数据复制
分别在Master(bogon)和Master1/Slave1(repli1)上锁定数据,禁止更新:
mysql> flush tables with read lock;
打包数据:
[root@bogon mysql]# tar zcf discuz.tar.gz discuz
上传数据:
[root@bogon mysql]# scp discuz.tar.gz root@slave:/var/lib/mysql (slave表示从服务器的IP)
在从服务器上解压:
[root@repli1 mysql]# tar -zxvf discuz.tar.gz
分别在Master(bogon)和Master1/Slave1(repli1)上解除锁定:
mysql> unlock tables;
5、查看同步状态
启动Slave服务器,进入mysql控制台,查看同步状态。
在master1/Slave1(repli1)上查看:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.41.189
Master_User: repli
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000015
Read_Master_Log_Pos: 204
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000015
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: discuz
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 204
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
分别在Slave2和Slave3查看:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.7.1298
Master_User: srepli
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000016
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000016
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: discuz
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
看到Slave_IO_Running和Slave_SQL_Running的参数都为 Yes,就说明主从同步运行正常。
6、同步测试
在Master(bogon)上进行数据写入:
mysql> insert into repli values(6,’Jack’,'boy’);
Query OK, 1 row affected (0.00 sec)
在Master1/Slave1、Slave2和Slave3上查看结果:
mysql> select * from repli;
+—-+——+——+
| id | name | sex |
+—-+——+——+
| 1 | Tom | boy |
| 2 | Mary | girl |
| 3 | John | boy |
| 4 | Lucy | girl |
| 5 | Lily | girl |
| 6 | Jack | boy |
+—-+——+——+
6 rows in set (0.00 sec)
(三)Master-Master(双主)
1、测试环境
Master/Slave Master1/Slave1
OS CentOS release 5.6 (Final) CentOS release 5.4 (Final)
Hostname bogon repli1
IP 192.168.41.189 192.168.7.128
Mysql-Version 14.12 Distrib 5.0.77 14.12 Distrib 5.0.77
2、主服务器授权
分别在Master/Slave和Master1/Slave1上创建一个用户并授予相应权限。
mysql> grant replication slave on *.* to repli@’192.168.7.128′ identified by ‘qqing99′;
mysql> grant replication slave on *.* to srepli@’192.168.41.189′ identified by ‘qqing99′;
然后退出mysql控制台,停止mysql服务:
mysql> \q
[root@bogon ~]#
service mysqld stop
3、配置Mysql主配置文件/etc/my.cnf
在/etc/my.cnf配置文件[mysqld]模块添加如下参数
Master/Slave(bogon):
[root@bogon ~]# vim /etc/my.cnf
server-id = 1
log-bin = mysql-bin
binlog-do-db = discuz
binlog-ignore-db = mysql
master-host = 192.168.7.128
master-user = srepli
master-password = qqing99
master-port = 3306
replicate-ignore-db = mysql
replicate-do-db = discuz
Master1/Slave1(repli1):
[root@repli1 ~]# vim /etc/my.cnf
server-id = 2
log-bin = mysql-bin
binlog-do-db = discuz
binlog-ignore-db = mysql
master-host = 192.168.41.189
master-user = repli
master-password = qqing99
master-port = 3306
replicate-ignore-db = mysql
replicate-do-db = discuz
4、数据复制
分别在Master/Slave和Master1/Slave1上锁定数据,禁止更新:
mysql> flush tables with read lock;
打包数据:
[root@bogon mysql]# tar zcf discuz.tar.gz discuz
上传数据:
[root@bogon mysql]# scp discuz.tar.gz root@192.168.7.128:/var/lib/mysql
在服务器上解压:
[root@repli1 mysql]# tar -zxvf discuz.tar.gz
解除锁定:
mysql> unlock tables;
5、查看同步状态
启动Slave服务器,进入mysql控制台,查看同步状态。
在Master1/Slave1上查看
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.41.189
Master_User: repli
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000015
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000015
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: discuz
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
在master/Slave上查看:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.7.129
Master_User: srepli
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000017
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000017
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: discuz
Replicate_Ignore_DB: mysql
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
6、同步测试
在master/Slave上执行:
mysql> update repli set sex=’girl’ where id=6;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
在master1/Slave1上查看:
mysql> select * from repli;
+—-+——+——+
| id | name | sex |
+—-+——+——+
| 1 | Tom | boy |
| 2 | Mary | girl |
| 3 | John | boy |
| 4 | Lucy | girl |
| 5 | Lily | girl |
| 6 | Jack | girl |
+—-+——+——+
6 rows in set (0.00 sec)
在master1/Slave1上执行:
mysql> insert into repli values(7,’Tim’,'boy’);
Query OK, 1 row affected (0.01 sec)
在master/Slave上查看:
mysql> select * from repli;
+—-+——+——+
| id | name | sex |
+—-+——+——+
| 1 | Tom | boy |
| 2 | Mary | girl |
| 3 | John | boy |
| 4 | Lucy | girl |
| 5 | Lily | girl |
| 6 | Jack | girl |
| 7 | Tim | boy |
+—-+——+——+
7 rows in set (0.00 sec)