带从服务器的MySql主主复制之二
博客已经搬家,请访问如下地址:http://www.czhphp.com
本文将介绍主动被动模式下的MySql主主复制,和前一篇讲的主动主动模式下的主主复制相比,最大的差别就是,其中一台主服务器是只读的被动服务器(不是固定的,动态切换),因此很好的解决了主动主动模式下的冲突问题以及同时插入数据可能产生的数据错误(高性能MySql那本书上有详细的分析),并且一台主服务器挂了也不影响数据的写入,从而实现高可用性(不能算是完全的)。
要实现这种结构,我们需要使用Google的开源项目MySql-MMM(其实这个工具是perl脚本),他把服务器的角色抽象成writer和reader,并混合了固定IP和虚拟浮动IP,当监控机发现一台Master服务器故障时,会自动通过浮动IP把writer角色切换到另外一台master服务器,从而实现角色的变化,而且这个工具在一定程度上实现了读操作的负载均衡。
好了,进入正题,我们一边阅读官网的说明一边进行配置。
我们的结构是1台监控机monitor,2台Master,2台slave,结构图大概如下(点击图片查看大图):
各机器各种设定信息约定:
1
2
3
4
5
6
|
主机名 固定ip地址 MySql服务器ID monitor 192.168.0.100 监控机,不需要安装MySql服务器 master1 192.168.0.101 101 master2 192.168.0.102 102 slave1 192.168.0.103 103 slave2 192.168.0.104 104 |
虚拟IP及读写角色约定(当我们配置完MySql-MMM后,程序读写数据时用的IP):
1
2
3
4
5
6
|
虚拟IP 角色 192.168.0.200 writer(MySql写入操作时使用的IP) 192.168.0.201 reader(MySql读操作时使用的IP,下同) 192.168.0.202 reader 192.168.0.203 reader 192.168.0.204 reader |
测试系统OS:CentOS5.6
第一步,在4台MySql服务器里分别安装MySql,并配置好设定文件:
1.安装MySql服务器,我们使用官方提供的my-medium.cnf作为初期设定文件。
1
2
|
[root@m /m/s/s ~] # yum -y install mysql mysql-server [root@m /m/s/s ~] # \cp -f /usr/share/doc/mysql-server-*/my-medium.cnf /etc/my.cnf |
2.修改/etc/my.cnf,在[mysqld]域后追加如下内容:
特别注意:如果配置文件已经有了该配置参数,一定要先删除后,再追加我们的设定!
1
2
3
4
5
6
7
8
9
|
server_id = 101 /102/103/104 <-每台服务器要分别设置我们确定的对应server_id log_bin = mysql-bin log_bin_index = mysql-bin.index log_slave_updates = 1 relay_log = mysql-relay-bin relay_log_index = mysql-relay-bin.index sync_binlog = 1 max_binlog_size = 200M slave-skip-errors = 1062,1053 |
第二步,创建用于监控,复制,和管理的MySql用户,并开启复制:
1.启动MySql并设置root初期密码,在4台MySql服务器上分别执行:
1
2
|
[root@m /m/s/s ~] # /etc/init.d/mysqld start [root@m /m/s/s ~] # /usr/bin/mysqladmin -u root password 'mysql_password' |
2.追加3个用户,在4台MySql服务器上分别执行(或者在一台上执行,然后导出数据库,用scp上传到另外3台,再导入数据):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
[root@m /m/s/s ~] # mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.77-log Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> GRANT REPLICATION CLIENT ON *.* TO 'mmm_monitor' @ '192.168.0.%' IDENTIFIED BY 'mmm_monitor_pass' ; Query OK, 0 rows affected (0.05 sec) mysql> GRANT SUPER, REPLICATION CLIENT, PROCESS ON *.* TO 'mmm_agent' @ '192.168.0.%' IDENTIFIED BY 'mmm_agent_pass' ; Query OK, 0 rows affected (0.02 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO 'repli_user' @ '192.168.0.%' IDENTIFIED BY ' repli_user_pass'; Query OK, 0 rows affected (0.03 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.01 sec) |
mmm_monitor 用于monitor机监控4台MySql服务器的状态
mmm_agent 用于MySql服务器自身改变读写状态和复制主服务器对象(比如原先从A复制,现在要从B复制)
repli_user 用于复制的用户
特别注意:下面的各种命令和配置文件中使用到的用户名和密码,必须和我们刚刚追加的一致。
3.开启复制(在这一步里用到的IP千万别用我们前面约定的虚拟IP):
在master1上执行:
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@master1 ~] # mysql -uroot -p Enter password: mysql> CHANGE MASTER TO MASTER_HOST= '192.168.0.102' , -> MASTER_PORT=3306, -> MASTER_USER= 'repli_user' , -> MASTER_PASSWORD= 'repli_user_pass' , -> MASTER_LOG_FILE= 'mysql-bin.000001' , -> MASTER_LOG_POS=0; Query OK, 0 rows affected (0.20 sec) mysql> START SLAVE; Query OK, 0 rows affected (0.00 sec) mysql> SHOW SLAVE STATUS\G |
在master2/slave1/slave2上分别执行:
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@master2 /slave1/slave2 ~] # mysql -uroot -p Enter password: mysql> CHANGE MASTER TO MASTER_HOST= '192.168.0.101' , -> MASTER_PORT=3306, -> MASTER_USER= 'repli_user' , -> MASTER_PASSWORD= 'repli_user_pass' , -> MASTER_LOG_FILE= 'mysql-bin.000001' , -> MASTER_LOG_POS=0; Query OK, 0 rows affected (0.20 sec) mysql> START SLAVE; Query OK, 0 rows affected (0.00 sec) mysql> SHOW SLAVE STATUS\G |
到此为止,复制关系已经配置完成,你可以分别在2个master服务器里插入一些数据测试一下。
特别提示:
在这里,我们默认把slave1和slave2的复制master机都设成了master1(192.168.0.101),其实把slave1和slave2的复制master机无论设成master1(192.168.0.101)还是master2(192.168.0.102),都没有太大的关系,因为当2个master中的一个挂掉时,mysql-mmm会自动帮我们把slave的复制master切换到另外一台正常的master上。
第三步,装并配置MySql-MMM
1.因为标准的yum源里没有该软件,所以我们先装一下EPEL的yum源,在5台机器里分别执行:
1
2
|
[root@m /m/m/s/s ~] # wget http://download.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm [root@m /m/m/s/s ~] # rpm -ivh epel-release-5-4.noarch.rpm |
如果你的系统是RHEL6.x或者CentOS6.x,那么下载安装:
http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm
2.使用yum安装MySql-MMM的相关组件(其他一些依赖的组件会自动安装)。
A.在monitor里需要安装mysql-mmm和mysql-mmm-monitor:
1
|
yum -y install mysql-mmm mysql-mmm-monitor |
B.在4台MySql服务器上需要安装mysql-mmm和mysql-mmm-agent
1
|
yum -y install mysql-mmm-common mysql-mmm-agent |
3.在5台机器上配置/etc/mysql-mmm/mmm_common.conf文件,内容完全一样,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
active_master_role writer <host default> cluster_interface eth0 pid_path /var/run/mysql-mmm/mmm_agentd .pid bin_path /usr/libexec/mysql-mmm/ replication_user repli_user replication_password repli_user_pass agent_user mmm_agent agent_password mmm_agent_pass < /host > <host master1> ip 192.168.0.101 mode master peer master2 < /host > <host master2> ip 192.168.0.102 mode master peer master1 < /host > <host slave1> ip 192.168.0.103 mode slave < /host > <host slave2> ip 192.168.0.104 mode slave < /host > <role writer> hosts master1, master2 ips 192.168.0.200 mode exclusive < /role > <role reader> hosts master1, master2, slave1, slave2 ips 192.168.0.201, 192.168.0.202, 192.168.0.203, 192.168.0.204 mode balanced < /role > |
*如果你嫌在5台机器都配置一遍麻烦,也为了保证配置文件一致,你可以在monitor(192.168.0.100)里配置完了,让后用下面的scp命令把文件复制到MySql服务器上的相应目录(当然了前提是可以相互ssh登录)。
1
2
3
4
|
scp /etc/mysql-mmm/mmm_common .conf root@192.168.0.101: /etc/mysql-mmm/mmm_common .conf scp /etc/mysql-mmm/mmm_common .conf root@192.168.0.102: /etc/mysql-mmm/mmm_common .conf scp /etc/mysql-mmm/mmm_common .conf root@192.168.0.103: /etc/mysql-mmm/mmm_common .conf scp /etc/mysql-mmm/mmm_common .conf root@192.168.0.104: /etc/mysql-mmm/mmm_common .conf |
4.在4台MySql服务器上分别配置/etc/mysql-mmm/mmm_agent.conf,内容如下:
1
2
|
include mmm_common.conf this master1 /master2/slave1/slave2 <--各自用各自的 hostname |
5.在监控服务器monitor上配置/etc/mysql-mmm/mmm_mon.conf,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
include mmm_common.conf <monitor> ip 127.0.0.1 pid_path /var/run/mysql-mmm/mmm_mond .pid bin_path /usr/libexec/mysql-mmm status_path /var/lib/mysql-mmm/mmm_mond .status ping_ips 192.168.0.1, 192.168.0.101, 192.168.0.102, 192.168.0.103, 192.168.0.104 # auto_set_online 10 < /monitor > <host default> monitor_user mmm_monitor monitor_password mmm_monitor_pass < /host > debug 0 |
需要注意的是,上面的ping_ips那个配置参数的作用是从监控机检查对应的ip是否能ping通,有助于我们了解我们的环境网络状况,在这里我设置的网关ip和4台MySql服务器的固定ip。
第四步,启动MySql-MMM
1.首先在4台MySql服务上启动mysql-mmm-agent,并添加到开机自动启动:
1
2
3
|
[root@m /m/s/s ~] # /etc/init.d/mysql-mmm-agent start Starting MMM Agent Daemon: [ OK ] [root@m /m/s/s ~] # chkconfig mysql-mmm-agent on |
2.在监控机monitor上启动mysql-mmm-monitor,并添加到开机自动启动:
1
2
3
|
[root@monitor ~] # /etc/init.d/mysql-mmm-monitor start Starting MMM Monitor Daemon: [ OK ] [root@monitor ~] # chkconfig mysql-mmm-monitor on |
第五步,在monitor里确认我们的集群情况,然后将MySql服务器置于ONLINE状态:
1.稍微等会儿,查看状况:
1
2
3
4
5
|
[root@monitor ~] # mmm_control show master1(192.168.0.101) master /AWAITING_RECOVERY . Roles: master2(192.168.0.102) master /AWAITING_RECOVERY . Roles: slave1(192.168.0.103) slave /AWAITING_RECOVERY . Roles: slave2(192.168.0.104) slave /AWAITING_RECOVERY . Roles: |
2.设置ONLINE状态,先设置master1,因为默认情况下slave1和slave2的master机都是master1:
1
2
3
4
5
6
7
8
|
[root@monitor ~] # mmm_control set_online master1 OK: State of 'master1' changed to ONLINE. Now you can wait some time and check its new roles! [root@monitor ~] # mmm_control set_online master2 OK: State of 'master2' changed to ONLINE. Now you can wait some time and check its new roles! [root@monitor ~] # mmm_control set_online slave1 OK: State of 'slave1' changed to ONLINE. Now you can wait some time and check its new roles! [root@monitor ~] # mmm_control set_online slave2 OK: State of 'slave2' changed to ONLINE. Now you can wait some time and check its new roles! |
更多的一些操作,比如改变role等,执行mmm_control help查看帮助信息。
特别注意:现在解释一下monitor机上/etc/mysql-mmm/mmm_mon.conf里我注释掉的那句auto_set_online参数:
不设置该参数:MySql服务器挂掉的时间超过60秒的话,服务器恢复后会一直处于AWAITING_RECOVERY的状态,需要我们手动set_online把他设置为ONLINE状态,如果低于60秒,且非Flapping状态,会自动设置为ONLINE状态。
设置了该参数:服务器恢复到AWAITING_RECOVERY状态后,会等待我们设置的秒数,然后自动设置为ONLINE状态(还要考虑Flapping状态)。
因此,设置与不设置auto_set_online参数根据你的需求了,我偏向于不设置。
接下来,你可以去主服务器master里创建一个你要使用的用户,然后分别去链接一下我们的writer role和reader role来测试了。
如果你在配置或者测试过程中遇到问题,请仔细检查你设置的各项参数,以及各个地方同一参数的引用是否一致。更详细的配置参数和帮助请参阅官方的说明文档。