Mysql主从复制
mysql 主从复制技术原理介绍
MySQL支持单向、异步(async)复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。同步复制需要使用ndbcluster(各集群节点都可读可写)或者drbd(网络raid)这些技术,或者是新版mysql的半同步复制。通过 把主上的二进制日志(bin-log)的内容传到从上的一个新的日志叫relay-bin-log
从上的 IO 线程 负责传输
从上的 SQL 线程 负责从服务器解析日志
复制的过程:
1. slave端的IO线程连上master端,请求
2. master端返回给slave端,bin log文件名和位置信息
3. IO线程把master端的bin log内容依次写到slave端relay bin log里,并把master端的bin-log文件名和位置记录到master.info里
4. salve端的sql线程,检测到relay bin log中内容更新,就会解析relay log里更新的内容,并执行这些操作;也就是说salve执行和master一样的操作而达到数据同步的目的
mysql AB复制开始搭建
-
主从数据必须要同步
-
主:要启用二进制日志
-
主和从都要设置 server-id值,并且两边要不一样
-
需要建立一个用来复制的用户,并授于相应权限
master(2.2.2.128) -- slave(2.2.2.129 ) 用rpm版的mysql5.6来做:
第一步:在主从上安装mysql
yum install mysql* -y
service mysqld restart
service iptables stop
第二步:改配置文件
master:2.2.2.128 上添加2行
vim /etc/my.cnf
[mysqld] --在mysqld参数组下添加2行
log-bin=mysql-bin --指定二进制日志的名字
server-id=2 --指定id,id值任意
slave,2.2.2.129 上添加1行
vim /etc/my.cnf
[mysqld] --在mysqld参数组下添加1行
server-id=3 --指定id,id值任意,与主不一样
然后重启服务
master,2.2.2.128 上重启:
/etc/init.d/mysqld restart
slave,2.2.2.129 上重启:
/etc/init.d/mysqld restart
第三步:授权
在master上做授权,super和replication slave都是复制要用的权限
mysql> grant super,replication slave on *.* to 'slave1'@'2.2.2.129' identified by '123';
mysql> flush privileges;
在slave上最好使用刚才授权的用户是远程登录一下主去验证一下
mysql -u slave1 -h 2.2.2.128 -p123
第四步:
查看master的正在写的二进制文件名和位置
flush tables with read lock; #--先加锁,防止两边数据不一致;如果业务还未上线,这个就没有必要了
show master status; --只有打开二进制日志,这句命令才有结果,表示当前数据库的二进制日志写到什么位置
±-----------------±---------±-------------±-----------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
±-----------------±---------±-------------±-----------------+
| mysql-bin.000003 | 336 | | |
±-----------------±---------±-------------±-----------------+
slave端的配置:
mysql
slave stop;
change master to master_user='slave1', master_password='123', master_host='2.2.2.128', master_port=3306, master_log_file='mysql-bin.000003', master_log_pos=336;
start slave;
mysql> change master to
-> master_user=‘slave1’,
-> master_password=‘123’,
-> master_host=‘2.2.2.128’, --主的IP
-> master_port=3306, --端口,如果为3307就要换成3307
-> master_log_file=‘mysql-bin.000003’, --主上面查到的文件名
-> master_log_pos=336; --主上面查到的位置号
show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 2.2.2.128
Master_User: li
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 681
Relay_Log_File: mysql55-relay-bin.000002
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes --这里两个YES,表示两个线程OK
Replicate_Do_DB:
Replicate_Ignore_DB:
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: 681
Relay_Log_Space: 411
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
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 2
1 row in set (0.00 sec)
…
回到master端解锁:
unlock tables;
进行测试
1,先比较主,从的数据目录文件的不同
#ls /var/lib/mysql/ --master
ibdata1 ib_logfile1 mysql-bin.000001 mysql-bin.000003 mysql.sock
ib_logfile0 mysql mysql-bin.000002 mysql-bin.index test
#ls /var/lib/mysql/ --slave
ibdata1 ib_logfile1 mysql mysqld-relay-bin.000002 mysql.sock test
ib_logfile0 master.info mysqld-relay-bin.000001 mysqld-relay-bin.index relay-log.info
#cat /var/lib/mysql/master.info
#cat /var/lib/mysql/relay-log.info
#mysqlbinlog /var/lib/mysql/mysqld-relay-bin.000002
验证2:只有master写,slave可以看到;slave写,master看不到
如果复制出现问题
(要模拟问题的话,在从上创建一个库,然后在主上也创建这个库,就会冲突,造成复制出现问题),重做复制集群只需要重新在从上执行stop slave; change master to … ; start slave;
验证3:把从重启后,再上去查看状态,还是连接的,没什么影响
把主重启后,再去slave上去查看状态,发现重试时间为60秒,等60秒后又自动连接OK了