MySQL双主复制,由于最近在完善之前写的文档,该加的加一点,该改的改一点,其实这个我是想和在主从同步的那篇文章下面简单写一下来着,想想之前做个高可用,今天也直接加上吧,哈哈,先说说原理,说白了就是两台MySQL都开启binlog,然后在my.cnf里面加一点参数,两台服务器之间互相主从,一般是配合keepalived实现双主热备,其实搭建起来也不是很困难,就算是建立到主从的基础之上了,再配合keepalived实现高可用,我指的不是使用lvs进行轮训,而是热备,如果一台宕了则切换到另一台,具体操作如下。
master1配置
修改my.cnf[root@rj-bai ~]# vim /etc/my.cnf
server-id=1 #定义serverID
log-bin=/data/mysql/mysql-bin #开启binlog
binlog_format = MIXED
sync_binlog=1
log-slave-updates
#auto_increment_increment=2
#auto_increment_offset=1
[root@rj-bai ~]# /etc/init.d/mysqld restart #重启mysqld
这里简单说一下吧,其实要做双主热备用前五个参数就可以了,如果是涉及到双主同时去写,而且双主后面还有从库,就需要开启后两个参数了,定义自增长字段及自增长字段每次递增的量,可以避免两个服务器在同时更新的时候发生冲突。
创建复制账号,按自己网段修改mysql> grant replication slave on *.* to 'ha'@'10.10.79.%' identified by 'Sowhat?';
master1首先锁表,查询状态。mysql> flush table with read lock ;
Query OK, 0 rows affected (0.03 sec)
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000012 | 423 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
导出数据到master2[root@rj-bai ~]# mysqldump -u root -p --events --ignore-table=mysql.events --all-databases > all.sql
[root@rj-bai ~]# scp all.sql root@10.10.79.129:/root
master2配置
1.修改my.cnf[root@rj-bai2 ~]# vim /etc/my.cnf
server-id=2 #serverID等于2,其他一致。
log-bin=/data/mysql/mysql-bin
binlog_format = MIXED
sync_binlog=1
log-slave-updates
#auto_increment_increment=2
#auto_increment_offset=2
2.导入master1的数据
master2服务器上 source 命令导入全部覆盖,导入完成以后记得重启一下服务。[root@rj-bai2 ~]# mysql -u root -p
Enter password:
mysql> source /root/all.sql
[root@rj-bai2 ~]# /etc/init.d/mysqld restart
在master2开始同步
执行语句,开始同步,并查看状态。mysql> CHANGE MASTER TO MASTER_HOST='10.10.79.128',MASTER_PORT=3306,MASTER_USER='ha',MASTER_PASSWO
RD='Sowhat?',MASTER_LOG_FILE='mysql-bin.000012',MASTER_LOG_POS=423;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
mysql> start slave ;
Query OK, 0 rows affected (0.04 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.79.128
Master_User: ha
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000012
Read_Master_Log_Pos: 423
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000012
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
最后,查询master2的状态,然后在master1执行同步即可。mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 656872 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在master1开始同步
开始同步mysql> UNLOCK TABLES; #解锁
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE MASTER TO MASTER_HOST='10.10.79.129',MASTER_PORT=3306,MASTER_USER='ha',MASTER_PASSWORD='Sowhat?',MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=120;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave ;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.79.129
Master_User: ha
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 120
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
最后的最后,看到的结果是这样的。
接来玩玩高可用
没错,用keepalived,搞个VIP出来,我在这里就不写了,有需要的可以去参考一下这篇文章,因为keepalived崩了以后vip才会飘走,而MySQL崩了和他一点关系没有,所以得写一个守护进程,盯着MySQL,如果MySQL崩了,我就把keepalived关掉,vip就会飘走了,然后写了个死循环脚本,具体如下。#!/bin/bash
while true
do
if [ `netstat -lntp | grep 3306 | wc -l` -ne 1 ];
then
/etc/init.d/keepalived stop
fi
sleep 5
done
注意,netstat 后面不要出现-a参数,-a是列出所有的当前连接,只要是有连接,保证不止是一个,而-l只列出监听中的连接,也就是占用3306端口的进程的MySQL,所以进程数只有一个,下面就开始做测试吧,先装一个blog出来吧。过程我就不写了,我的VIP地址是10.10.79.213。
创建完数据库之后看一下,数据是否同步过来了。
装完之后,把MySQL关了,不用干别的,刷新页面就行了,会爆出无法连接MySQL的错误,几秒钟后会回复正常。
最后看看服务器状态,以及一些后续操作。
VIP已切换到另一台服务器。
如果崩了发现的及时,先不要开启keepalived,先查找原因,尝试能不能将崩掉的服务器再次起来,如果起来了,然后尝试在两台服务器之见进行同步数据,如果能同步过来,就将keepalived再次开启,优先权高的会将VIP抢回去,如果发现同步不过来,或是距离崩掉的时间太长了,导致崩掉的服务器数据缺失太多,这种情况就没办法,master2服务器停止同步,继续使用,然后找一个夜深人静的时候,停掉业务,以该库数据为标准重做双主即可。