MySQL-HA Keepalived Master-Master半同步
时间:2015-02-23 01:21 来源:linux.it.net.cn 作者:IT
1、前言
最近在总结研究下以前项目涉及的高可用方案的东西,已经完成了WEB的HA,这里开始准备总结下数据库的,所以先以以前使用的MYSQL入手,计划后面做POSTGRES,ORACLE的RAC。
2、方案
本案例先使用两台linux做双机MASTER-MASTER高可用(后续可以考虑加入只读SLAVER,用于提高查询性能),采用MYSQL5.6.x的半同步实现数据复制和同步,使用keepalived来监控MYSQL和提供VIP及浮动。
2.1、环境及软件
操作系统:RedHat 6.3
Keepalived:keepalived-1.2.2.tar.gz
MYSQL:MySQL-server-5.6.10-1.el6.x86_64.rpm MySQL-client-5.6.10-1.el6.x86_64.rpm
2.2、IP规划
名称
IP
备注
VIP
10.10.10.20
由KEEPALIVED产生的虚拟IP,也是前端客户端使用的IP
MYSQL_DB_MASTER1
10.10.10.21
数据库1服务器(默认主)
MYSQL_DB_MASTER2
10.10.10.22
数据库2服务器
3、安装设置MYSQL半同步
3.1、安装MYSQL
这里选择的是使用社区版的MYSQL,请在www.mysql.com上下载对应操作系统的安装文件,这里根据官方的建议使用RPM包方式安装。
安装
如果是默认Redhat6.3安装后,可能会有mysql-libs的冲突,请先卸载原有的mysql-libs相关包。
# yum -y remove mysql-libs*
# rpm -ivh MySQL-server-5.6.10-1.el6.x86_64.rpm
……
# rpm -ivh MySQL-client-5.6.10-1.el6.x86_64.rpm
……
默认安装是在/usr下面,所以my.cnf是在/usr/my.cnf,这里为了习惯用法,拷贝到/etc/目录下
# mv /usr/my.cnf /etc/
设置root用户初始密码
默认安装完成后,mysql的root初始密码保存在: ~/.mysql_secret
# cat ~/.mysql_secret
# The random password set for the root user at Tue Dec 17 19:31:29 2013 (local time): uQ8X91Ys
标准方式修改密码
# mysqladmin -u root -p oldPassword password
# New password:
# Confirm new password:
或
# mysqladmin -u root -p password newPassword
SQL直接更新方式修改密码:
初始化root密码常见问题及处理
error: 'Access denied for user 'root'@'localhost' (using password: NO)'
# /etc/init.d/mysql stop
# mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
# mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root';
mysql> FLUSH PRIVILEGES;
mysql> quit
# /etc/init.d/mysql restart
# mysql -uroot -p
Enter password: <输入新设的密码newpassword>
mysql>
设置网络访问权限
MYSQL的用户访问策略是需要指定用户从某IP可以访问那些权限。具体用法请参考grant命令。这里为了简单起见,直接设置root用户在整个局域内(10.10.10.*)都可以访问数据库。
# mysql -uroot -p
******
mysql> GRANT ALL PRIVILEGES ON *.* TO root@'10.10.10.%' IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql>FLUSH PRIVILEGES;
这样设置后,就可以通过内网的其他机器访问数据库了。
修改数据文件路径
mysql安装后,默认的数据存储路径在/var/lib/mysql下。这里修改为/data/mysql
# service mysql stop
# mkdir /data/mysql
# cp -r /var/lib/mysql/* /data/mysql
# chown -R mysql:mysql /data/mysql
vi /etc/my.cnf
-
[mysqld]
-
datadir = /data/mysql
-
socket = /data/mysql/mysql.sock
-
# 顺便配置下MYSQL使用mysql用户启动
-
user=mysql
保存退出
为/data/mysql/mysql.sock建立指向/var/lib/mysql/mysql.sock的软连接
# ln -s /data/mysql/mysql.sock /var/lib/mysql/mysql.sock
启动MYSQL并测试
# service mysql start
# mysql -uroot -p
******
mysql>
最可能出现的问题(如果你是Redhat6.x或CentOS6.x):selinux 照成服务无法正常启动,报错:
Starting MySQL. ERROR! The server quit without updating PID file (/data/mysql/xxxxx.pid).
验证问题方法:
# setenforce 0
# service mysql start
Starting MySQL. SUCCESS!
如果能正常启动,解决问题,就确定是selinux造成的问题了。
解决办法1:直接禁用
vim /etc/selinux/config
修改:SELINUX=disabled
保存后,重启操作系统生效
解决方案2:配置selinux支持mysql访问相关端口和文件系统
本人比较懒,给个连接自己研究哈(或者google: selinux mysql):
https://blogs.oracle.com/jsmyth/entry/selinux_and_mysql
如果出现问题,一般解决问题的方式是查看MYSQL的日志文件,一般提示会比较清楚,或者根据错误信息区GOOGLE都可以找到答案。日志文件: ${datadir}/${hostname}.err, 本例中修改了数据目录,所以日志文件是:/data/mysql/acooly1.err
OK,本节安装MYSQL完成,然后另外一台服务器的MYSQL安装完全相同(半同步的设置有小不同,那下面会说明)。请参照以上说明安装另外一台MYSQL服务(MYSQL_DB_MASTER2)。
3.2、设置MYSQL双向半同步
半同步复制及semi-sync replication,最开始是GOOGLE提出和实现,后来MYSQL在5.5后的版本中支持的复制功能。只要是通过类似“两阶段提交”的方式实现,只要有一台备机成功同步数据,主服务器的事务就提交,否则等待10秒后,转为传统的异步复制。
本方案中为了实现故障转移功能,在利用半同步复制能力的同时,对整体方案进行了调整如下:
-
MYSQL_DB_MASTER1和MYSQL_DB_MASTER2互为主备,即MYSQL_DB_MASTER1时MYSQL_DB_MASTER2的主,MYSQL_DB_MASTER2是MYSQL_DB_MASTER1的主,通过半同步实现双向的同步复制(注意:这里不会出现冲突,因为备机只会同步不是本机server_id的bin-log日志,通过两台机器的server_id隔离需要同步的bin-log)
-
通过Keepalived实现MYSQL服务器的监控和VIP的浮动,保证同一时间只有一台MYSQL服务器可用。
-
该方案中,可以兼容后期的扩容,加入多台SALVE与两台MASTER异步同步实现数据的只读查询,实现读写分离,提高整体性能。
配置/etc/my.cnf
分别修改/etc/my.cnf配置,打开bin-log功能和设置server_id
vi /etc/my.cnf
-
[mysqld]
-
# MYSQL_DB_MASTER1设置为1,MYSQL_DB_MASTER2设置为2
-
server_id=1
-
log_bin=mysql-bin
安装官方文档说明,主(MYSQL_DB_MASTER1)需要设置rpl_semi_sync_master_enabled=1和rpl_semi_sync_master_timeout=1000,备(MYSQL_DB_MASTER2)需要设置rpl_semi_sync_slave_enabled=1,这里因为是双向同步,我都没有设置,经测试,没有设置也没有关系(暂时没有深究,后续在研究下)。
配置MYSQL_DB_MASTER1与MYSQL_DB_MASTER2的主备同步
在MYSQL_DB_MASTER1上操作配置MYSQL_DB_MASTER1为MYSQL_DB_MASTER2的主。
-
<span style="font-size: 14px; font-family: 'Microsoft YaHei', 微软雅黑, SimHei, tahoma, arial, helvetica, sans-serif;"># mysql -uroot -p
-
Enter password:
-
......
-
-- 建立复制用户replication,允许内网内其他机器(访问本机所有数据库)
-
mysql > grant replication slave on *.* to 'replication'@'10.10.10.%' identified by 'replication';
-
Query OK, 0 rows affected (0.00 sec)
-
-- 查看master的bin-log状态,用户设置SLAVE同步的起点
-
mysql> show master status;
-
+------------------+----------+--------------+------------------+-------------------+
-
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
-
+------------------+----------+--------------+------------------+-------------------+
-
| mysql-bin.000013 | 120 | | | |
-
+------------------+----------+--------------+------------------+-------------------+
-
1 row in set (0.02 sec) </span>
这里注意记录下当前bin-log文件名称:mysql-bin.000013和位置:120,备机设置的时候需要用到。
在MYSQL_DB_MASTER2上操作配置
-
<span style="font-size: 14px; font-family: 'Microsoft YaHei', 微软雅黑, SimHei, tahoma, arial, helvetica, sans-serif;">--设置SLAVE的MASTER和开始同步的文件位置
-
mysql> change master to master_host='10.10.10.21',master_user='replication',master_password='replication',master_log_file='mysql-bin.000003',master_log_pos=120;
-
--启动同步
-
mysql> start slave;
-
mysql> show slave status\G;
-
*************************** 1. row ***************************
-
Slave_IO_State: Waiting for master to send event
-
Master_Host: 10.10.10.21
-
Master_User: replication
-
Master_Port: 3306
-
Connect_Retry: 10
-
Master_Log_File: mysql-bin.000013
-
Read_Master_Log_Pos: 120
-
Relay_Log_File: acooly2-relay-bin.000020
-
Relay_Log_Pos: 283
-
Relay_Master_Log_File: mysql-bin.000013
-
Slave_IO_Running: Yes
-
Slave_SQL_Running: Yes
-
……
-
1 row in set (0.02 sec)</span>
Slave_IO_Running: Yes和Slave_SQL_Running: Yes表示SLAVE已经正常启动并监听MASTER的数据发送事件,处理同步。
配置MYSQL_DB_MASTER2与MYSQL_DB_MASTER1的主备同步
所有配置操作与上一节,只是把主备关系交换。
OK
如果所有的配置成功,启动MASTER1和MASTER2两个数据库,分别从两端创建数据库,表和更新表数据,另外一边都会实时同步。
4、Keepalived实现MYSQL的高可用
前面已经完成MYSQL的双向实时同步的配置,本节使用Keepalived实现MYSQL双机的高可用,故障转移。通过VIP实现同时只有一台MYSQL提供服务。
4.1、配置KEEPALIVED
两台MYSQL服务器上的配置基本相同(除了keepalived.conf的个别配置外),具体操作配置如下:
安装Keepalived请参考:Keepalived + LVS(DR) 高可用负载均衡集群 的 3.3、Keepalived 安装配置
设置keepalived的主配置文件/etc/keepalived/keepalived.conf实现本机的MYSQL的监控和VIP浮动。
-
global_defs {
-
router_id Mysql-HA
-
}
-
-
# 定义MYSQL监控的脚本,每2秒监控一次,具体脚本请见下面
-
vrrp_script check_mysql {
-
script "/opt/keepalived/keepalived_check_mysql.sh"
-
interval 2
-
}
-
-
vrrp_sync_group VG1 {
-
group {
-
KEEPALIVED_MYSQL
-
}
-
}
-
-
vrrp_instance KEEPALIVED_MYSQL {
-
# 注意:两台MYSQL服务器都设置为BACKUP
-
state BACKUP
-
interface eth0
-
virtual_router_id 20
-
# MASTER1设置为100,则MASTER2设置为稍低,如:90
-
priority 100
-
advert_int 1
-
# 只有MASTER1设置不抢夺控制权
-
nopreempt
-
authentication {
-
auth_type PASS
-
auth_pass 111111
-
}
-
track_script {
-
check_mysql
-
}
-
virtual_ipaddress {
-
10.10.10.20
-
}
-
}
检查本机MYSQL服务是否正常,如果MYSQL服务不可用,则停止KEEPALIVED服务,由备机的KEEPALIVED接管并提供VIP(指向备机)
-
#!/bin/bash
-
-
MYSQL=/usr/bin/mysql
-
MYSQL_HOST=localhost
-
MYSQL_USER=root
-
MYSQL_PASSWORD=1qaz@WSX
-
# 日志文件
-
LOG_FILE=/opt/keepalived/check_mysql.log
-
# 检查次数
-
CHECK_TIME=3
-
-
#mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
-
MYSQL_OK=1
-
-
-
function check_mysql_helth (){
-
$MYSQL -h $MYSQL_HOST -u $MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
-
if [ $? = 0 ] ;then
-
MYSQL_OK=1
-
else
-
MYSQL_OK=0
-
fi
-
return $MYSQL_OK
-
}
-
-
while [ $CHECK_TIME -ne 0 ]
-
do
-
let "CHECK_TIME -= 1"
-
check_mysql_helth
-
if [ $MYSQL_OK = 1 ] ; then
-
CHECK_TIME=0
-
#echo `date --date=today +"%Y-%M-%d %H:%m:%S"` - [INFO] - mysql available: success[$MYSQL_OK] >> $LOG_FILE
-
exit 0
-
fi
-
if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
-
then
-
/etc/init.d/keepalived stop
-
echo `date --date=today +"%Y-%M-%d %H:%m:%S"` - [INFO] - mysql invaild. keepalived stop. >> $LOG_FILE
-
exit 1
-
fi
-
sleep 1
-
done
4.2、验证故障转移
配置完成后,分别启动两台服务器的mysql和keepalived服务
分别启动MYSQL_DB_MASTER1和MYSQL_DB_MASTER2
# service mysql start
Starting MySQL.......... SUCCESS!
# service keepalived start
Starting keepalived: [ OK ]
在MYSQL_DB_MASTER1查看VIP
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
……
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3b:be:91 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.21/24 brd 10.10.10.255 scope global eth0
inet 10.10.10.20/32 scope global eth0
inet6 fe80::250:56ff:fe3b:be91/64 scope link
valid_lft forever preferred_lft forever
停止MYSQL_DB_MASTER1的MYSQL服务,查看VIP
# service mysql stop
Shutting down MySQL..... SUCCESS!
# service keepalived status
keepalived is stopped
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
……
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:37:87:e4 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.21/24 brd 10.10.10.255 scope global eth0
inet6 fe80::20c:29ff:fe37:87e4/64 scope link
valid_lft forever preferred_lft forever
没有VIP(10.10.10.20)了
在MYSQL_DB_MASTER2上查看VIP
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
……
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3b:be:91 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.22/24 brd 10.10.10.255 scope global eth0
inet 10.10.10.20/32 scope global eth0
inet6 fe80::250:56ff:fe3b:be91/64 scope link
valid_lft forever preferred_lft forever
可以看到VIP已经切换到MYSQL_DB_MASTER2
从新启动MYSQL_DB_MASTER1的MYSQL服务和KEEPALIVED服务,但是这个时候是不会从新浮动到MASTER1的,因为我们配置KEEPALIVED的时候都是配置的BACKUP,而且MASTER1配置了不抢占。这余我们设计是相符的。(只有等MASTER2出现故障的情况才从新有MASTER1接管)
OK,本次记录到此,后续完善加入多个异步同步的SLAVE。
5、参考资料
http://dev.mysql.com/doc/
http://bbs.chinaunix.net/thread-1824528-1-1.html
http://blog.csdn.net/haier_jiang/article/details/8449013
http://www.9ai9.net/?p=131
(责任编辑:IT)
1、前言最近在总结研究下以前项目涉及的高可用方案的东西,已经完成了WEB的HA,这里开始准备总结下数据库的,所以先以以前使用的MYSQL入手,计划后面做POSTGRES,ORACLE的RAC。
|
名称 | IP | 备注 |
VIP | 10.10.10.20 | 由KEEPALIVED产生的虚拟IP,也是前端客户端使用的IP |
MYSQL_DB_MASTER1 | 10.10.10.21 | 数据库1服务器(默认主) |
MYSQL_DB_MASTER2 | 10.10.10.22 | 数据库2服务器 |
3、安装设置MYSQL半同步
3.1、安装MYSQL
这里选择的是使用社区版的MYSQL,请在www.mysql.com上下载对应操作系统的安装文件,这里根据官方的建议使用RPM包方式安装。
安装
如果是默认Redhat6.3安装后,可能会有mysql-libs的冲突,请先卸载原有的mysql-libs相关包。
# yum -y remove mysql-libs*
# rpm -ivh MySQL-server-5.6.10-1.el6.x86_64.rpm
……
# rpm -ivh MySQL-client-5.6.10-1.el6.x86_64.rpm
……
默认安装是在/usr下面,所以my.cnf是在/usr/my.cnf,这里为了习惯用法,拷贝到/etc/目录下
# mv /usr/my.cnf /etc/
设置root用户初始密码
默认安装完成后,mysql的root初始密码保存在: ~/.mysql_secret
# cat ~/.mysql_secret
# The random password set for the root user at Tue Dec 17 19:31:29 2013 (local time): uQ8X91Ys
标准方式修改密码
# mysqladmin -u root -p oldPassword password
# New password:
# Confirm new password:
或
# mysqladmin -u root -p password newPassword
SQL直接更新方式修改密码:
初始化root密码常见问题及处理 error: 'Access denied for user 'root'@'localhost' (using password: NO)' # /etc/init.d/mysql stop # mysqld_safe --user=mysql --skip-grant-tables --skip-networking & # mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root'; mysql> FLUSH PRIVILEGES; mysql> quit # /etc/init.d/mysql restart # mysql -uroot -p Enter password: <输入新设的密码newpassword> mysql> |
设置网络访问权限
MYSQL的用户访问策略是需要指定用户从某IP可以访问那些权限。具体用法请参考grant命令。这里为了简单起见,直接设置root用户在整个局域内(10.10.10.*)都可以访问数据库。
# mysql -uroot -p
******
mysql> GRANT ALL PRIVILEGES ON *.* TO root@'10.10.10.%' IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql>FLUSH PRIVILEGES;
这样设置后,就可以通过内网的其他机器访问数据库了。
修改数据文件路径
mysql安装后,默认的数据存储路径在/var/lib/mysql下。这里修改为/data/mysql
# service mysql stop
# mkdir /data/mysql
# cp -r /var/lib/mysql/* /data/mysql
# chown -R mysql:mysql /data/mysql
vi /etc/my.cnf
- [mysqld]
- datadir = /data/mysql
- socket = /data/mysql/mysql.sock
- # 顺便配置下MYSQL使用mysql用户启动
- user=mysql
保存退出
为/data/mysql/mysql.sock建立指向/var/lib/mysql/mysql.sock的软连接
# ln -s /data/mysql/mysql.sock /var/lib/mysql/mysql.sock
启动MYSQL并测试
# service mysql start
# mysql -uroot -p
******
mysql>
最可能出现的问题(如果你是Redhat6.x或CentOS6.x):selinux 照成服务无法正常启动,报错:
Starting MySQL. ERROR! The server quit without updating PID file (/data/mysql/xxxxx.pid).
验证问题方法:
# setenforce 0
# service mysql start
Starting MySQL. SUCCESS!
如果能正常启动,解决问题,就确定是selinux造成的问题了。
解决办法1:直接禁用
vim /etc/selinux/config
修改:SELINUX=disabled
保存后,重启操作系统生效
解决方案2:配置selinux支持mysql访问相关端口和文件系统
本人比较懒,给个连接自己研究哈(或者google: selinux mysql):
https://blogs.oracle.com/jsmyth/entry/selinux_and_mysql
如果出现问题,一般解决问题的方式是查看MYSQL的日志文件,一般提示会比较清楚,或者根据错误信息区GOOGLE都可以找到答案。日志文件: ${datadir}/${hostname}.err, 本例中修改了数据目录,所以日志文件是:/data/mysql/acooly1.err
OK,本节安装MYSQL完成,然后另外一台服务器的MYSQL安装完全相同(半同步的设置有小不同,那下面会说明)。请参照以上说明安装另外一台MYSQL服务(MYSQL_DB_MASTER2)。
3.2、设置MYSQL双向半同步
半同步复制及semi-sync replication,最开始是GOOGLE提出和实现,后来MYSQL在5.5后的版本中支持的复制功能。只要是通过类似“两阶段提交”的方式实现,只要有一台备机成功同步数据,主服务器的事务就提交,否则等待10秒后,转为传统的异步复制。
本方案中为了实现故障转移功能,在利用半同步复制能力的同时,对整体方案进行了调整如下:
- MYSQL_DB_MASTER1和MYSQL_DB_MASTER2互为主备,即MYSQL_DB_MASTER1时MYSQL_DB_MASTER2的主,MYSQL_DB_MASTER2是MYSQL_DB_MASTER1的主,通过半同步实现双向的同步复制(注意:这里不会出现冲突,因为备机只会同步不是本机server_id的bin-log日志,通过两台机器的server_id隔离需要同步的bin-log)
- 通过Keepalived实现MYSQL服务器的监控和VIP的浮动,保证同一时间只有一台MYSQL服务器可用。
- 该方案中,可以兼容后期的扩容,加入多台SALVE与两台MASTER异步同步实现数据的只读查询,实现读写分离,提高整体性能。
配置/etc/my.cnf
分别修改/etc/my.cnf配置,打开bin-log功能和设置server_id
vi /etc/my.cnf
- [mysqld]
- # MYSQL_DB_MASTER1设置为1,MYSQL_DB_MASTER2设置为2
- server_id=1
- log_bin=mysql-bin
配置MYSQL_DB_MASTER1与MYSQL_DB_MASTER2的主备同步
在MYSQL_DB_MASTER1上操作配置MYSQL_DB_MASTER1为MYSQL_DB_MASTER2的主。
- <span style="font-size: 14px; font-family: 'Microsoft YaHei', 微软雅黑, SimHei, tahoma, arial, helvetica, sans-serif;"># mysql -uroot -p
- Enter password:
- ......
- -- 建立复制用户replication,允许内网内其他机器(访问本机所有数据库)
- mysql > grant replication slave on *.* to 'replication'@'10.10.10.%' identified by 'replication';
- Query OK, 0 rows affected (0.00 sec)
- -- 查看master的bin-log状态,用户设置SLAVE同步的起点
- mysql> show master status;
- +------------------+----------+--------------+------------------+-------------------+
- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
- +------------------+----------+--------------+------------------+-------------------+
- | mysql-bin.000013 | 120 | | | |
- +------------------+----------+--------------+------------------+-------------------+
- 1 row in set (0.02 sec) </span>
这里注意记录下当前bin-log文件名称:mysql-bin.000013和位置:120,备机设置的时候需要用到。
在MYSQL_DB_MASTER2上操作配置
- <span style="font-size: 14px; font-family: 'Microsoft YaHei', 微软雅黑, SimHei, tahoma, arial, helvetica, sans-serif;">--设置SLAVE的MASTER和开始同步的文件位置
- mysql> change master to master_host='10.10.10.21',master_user='replication',master_password='replication',master_log_file='mysql-bin.000003',master_log_pos=120;
- --启动同步
- mysql> start slave;
- mysql> show slave status\G;
- *************************** 1. row ***************************
- Slave_IO_State: Waiting for master to send event
- Master_Host: 10.10.10.21
- Master_User: replication
- Master_Port: 3306
- Connect_Retry: 10
- Master_Log_File: mysql-bin.000013
- Read_Master_Log_Pos: 120
- Relay_Log_File: acooly2-relay-bin.000020
- Relay_Log_Pos: 283
- Relay_Master_Log_File: mysql-bin.000013
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
- ……
- 1 row in set (0.02 sec)</span>
Slave_IO_Running: Yes和Slave_SQL_Running: Yes表示SLAVE已经正常启动并监听MASTER的数据发送事件,处理同步。
配置MYSQL_DB_MASTER2与MYSQL_DB_MASTER1的主备同步
所有配置操作与上一节,只是把主备关系交换。
OK
如果所有的配置成功,启动MASTER1和MASTER2两个数据库,分别从两端创建数据库,表和更新表数据,另外一边都会实时同步。
4、Keepalived实现MYSQL的高可用
前面已经完成MYSQL的双向实时同步的配置,本节使用Keepalived实现MYSQL双机的高可用,故障转移。通过VIP实现同时只有一台MYSQL提供服务。
4.1、配置KEEPALIVED
两台MYSQL服务器上的配置基本相同(除了keepalived.conf的个别配置外),具体操作配置如下:
安装Keepalived请参考:Keepalived + LVS(DR) 高可用负载均衡集群 的 3.3、Keepalived 安装配置
设置keepalived的主配置文件/etc/keepalived/keepalived.conf实现本机的MYSQL的监控和VIP浮动。
- global_defs {
- router_id Mysql-HA
- }
- # 定义MYSQL监控的脚本,每2秒监控一次,具体脚本请见下面
- vrrp_script check_mysql {
- script "/opt/keepalived/keepalived_check_mysql.sh"
- interval 2
- }
- vrrp_sync_group VG1 {
- group {
- KEEPALIVED_MYSQL
- }
- }
- vrrp_instance KEEPALIVED_MYSQL {
- # 注意:两台MYSQL服务器都设置为BACKUP
- state BACKUP
- interface eth0
- virtual_router_id 20
- # MASTER1设置为100,则MASTER2设置为稍低,如:90
- priority 100
- advert_int 1
- # 只有MASTER1设置不抢夺控制权
- nopreempt
- authentication {
- auth_type PASS
- auth_pass 111111
- }
- track_script {
- check_mysql
- }
- virtual_ipaddress {
- 10.10.10.20
- }
- }
检查本机MYSQL服务是否正常,如果MYSQL服务不可用,则停止KEEPALIVED服务,由备机的KEEPALIVED接管并提供VIP(指向备机)
- #!/bin/bash
- MYSQL=/usr/bin/mysql
- MYSQL_HOST=localhost
- MYSQL_USER=root
- MYSQL_PASSWORD=1qaz@WSX
- # 日志文件
- LOG_FILE=/opt/keepalived/check_mysql.log
- # 检查次数
- CHECK_TIME=3
- #mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
- MYSQL_OK=1
- function check_mysql_helth (){
- $MYSQL -h $MYSQL_HOST -u $MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
- if [ $? = 0 ] ;then
- MYSQL_OK=1
- else
- MYSQL_OK=0
- fi
- return $MYSQL_OK
- }
- while [ $CHECK_TIME -ne 0 ]
- do
- let "CHECK_TIME -= 1"
- check_mysql_helth
- if [ $MYSQL_OK = 1 ] ; then
- CHECK_TIME=0
- #echo `date --date=today +"%Y-%M-%d %H:%m:%S"` - [INFO] - mysql available: success[$MYSQL_OK] >> $LOG_FILE
- exit 0
- fi
- if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
- then
- /etc/init.d/keepalived stop
- echo `date --date=today +"%Y-%M-%d %H:%m:%S"` - [INFO] - mysql invaild. keepalived stop. >> $LOG_FILE
- exit 1
- fi
- sleep 1
- done
4.2、验证故障转移
配置完成后,分别启动两台服务器的mysql和keepalived服务
分别启动MYSQL_DB_MASTER1和MYSQL_DB_MASTER2
# service mysql start
Starting MySQL.......... SUCCESS!
# service keepalived start
Starting keepalived: [ OK ]
在MYSQL_DB_MASTER1查看VIP
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
……
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3b:be:91 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.21/24 brd 10.10.10.255 scope global eth0
inet 10.10.10.20/32 scope global eth0
inet6 fe80::250:56ff:fe3b:be91/64 scope link
valid_lft forever preferred_lft forever
停止MYSQL_DB_MASTER1的MYSQL服务,查看VIP
# service mysql stop
Shutting down MySQL..... SUCCESS!
# service keepalived status
keepalived is stopped
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
……
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:37:87:e4 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.21/24 brd 10.10.10.255 scope global eth0
inet6 fe80::20c:29ff:fe37:87e4/64 scope link
valid_lft forever preferred_lft forever
没有VIP(10.10.10.20)了
在MYSQL_DB_MASTER2上查看VIP
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
……
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3b:be:91 brd ff:ff:ff:ff:ff:ff
inet 10.10.10.22/24 brd 10.10.10.255 scope global eth0
inet 10.10.10.20/32 scope global eth0
inet6 fe80::250:56ff:fe3b:be91/64 scope link
valid_lft forever preferred_lft forever
可以看到VIP已经切换到MYSQL_DB_MASTER2
从新启动MYSQL_DB_MASTER1的MYSQL服务和KEEPALIVED服务,但是这个时候是不会从新浮动到MASTER1的,因为我们配置KEEPALIVED的时候都是配置的BACKUP,而且MASTER1配置了不抢占。这余我们设计是相符的。(只有等MASTER2出现故障的情况才从新有MASTER1接管)
OK,本次记录到此,后续完善加入多个异步同步的SLAVE。
5、参考资料
http://dev.mysql.com/doc/
http://bbs.chinaunix.net/thread-1824528-1-1.html
http://blog.csdn.net/haier_jiang/article/details/8449013
http://www.9ai9.net/?p=131
(责任编辑:IT)