Mysql Replication(复制)
Replication可以实现将数据从一台数据库服务器(master)复制到一台或多台数据库服务器(slave)
默认情况下属于异步复制,无需持续长连接
通过配置,可以复制所有库或几个库,或者库中的一些表
是MySQL内建的,本身自带的
Replication原理:
master将数据库的改变写入二进制日志,slave同步这些二进制日志,并根据这些二进制日志进行数据操作
Replication作用:
1、Fail Over 故障切换
2、Backup Server 备份服务,无法对SQL语句执行产生的故障恢复,有限的备份
3、High Performance 高性能,可以多台slave,实现读写分离
Replication工作原理:
整体上来说,复制有3个步骤:
1、master将改变记录到二进制日志,这些记录叫做二进制日志事件(binary log events)。
2、slave将master的二进制日志(binary log events)拷贝到他的中继日志(relay log),若已执行完成master产生的所有事件,slave会睡眠并等待master产生新的事件。
3、slave读取中继日志中的事件并重新执行,更新slave上的数据,使其与master中的数据一致。
Replication常见方案:
1、One master and Muti slave 一主多备
一般用来做读写分离,master写,其它slave读,这种架构最大问题是I/O压力集中在Master上(多台同步,影响IO)
2、M-S-S
使用一台slave做为中继,分担master的压力,slave中继需要开启bin-log,并配置log-slave-updates
slave中继可使用black-hole存储引擎,不会把数据存储到磁盘,只记录二进制日志。
3、M-M 双主互备(互为主从)
很多人误以为这样可以做到MySQL负载均衡,实际没什么好处,每个数据库需要做同样的同步更新,破坏了事务的隔离性和数据的一致性。
4、M-M-M 3M监控三台机器互相做对方的master
天生的缺陷:复制延迟,slave上同步要慢于master,大并发情况同步延迟更严重,mysql在5.6已经自身可以实现fail over故障切换
开启二进制日志,存放增删改操作
配置主服务器master,打开配置文件my.cnf,添加以下配置:
log-bin = /var/log/mysql/mysql-bin-master #开启二进制日志,并设置文件名
server-id = 1 #设置主从或集群等,唯一的值
binlog-do-db = DX #要同步的数据库
binlog-ignore-db=mysql #要忽略的数据库
创建用户,用于从库连接主库:
create user 'slave'@'%' identified by '123456';
授权(从库连接权):
GRANT REPLICATION slave ON *.* TO 'slave'@'%';
注意授权的用户信息,要和创建用户时的信息保持一致。
创建需要同步的数据库
create database DX;
use DX;
创建测试表
create table user(id int primary key auto_increment,name varchar(100));
查看主库状态(这些信息对于MySQL复制非常重要)
show master status;
查看二进制日志的事件信息
show binlog events\G;
show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
(1)IN 'log_name':指定要查询的binlog文件名(如果省略此参数,则默认指定第一个binlog文件);
(2)FROM pos:指定从哪个pos起始点开始查起(如果省略此参数,则从整个文件的第一个pos点开始算);
(3)LIMIT [offset]:偏移量(默认为0);
(4)row_count:查询总条数(如果省略,则显示所有行)。
查看二进制日志文件位置
show variables like '%log_bin%';
查看二进制日志文件
ls /var/log/mysql/
查看Mysql版本
show variables like "%version%";
查看Mysql线程
show processlist \G
从库配置:(版本不低于主库)
测试从库能否连接主库
mysql -h 主库IP -u 主库用户 -p
修改从库配置文件:
从库服务器没必要开启bin-log日志,只需打开从库配置文件,加入server-id
server-id=2 #从数据库ID号,不要和主库ID相同,如果设置多个从库,每个从库必须有唯一的server-id值。可将server-id理解为IP地址,这些id具有唯一性,能够在集群中识别每个实例。
重启服务并登录,修改从库
change master to master_host='10.168.1.150',master_user='slave',master_password='123456';
启动从库服务
start slave;
查看状态
show slave status\G
Slave_IO_Running:负责与Master主机的IO通信
Slave_SQL_Running:负责自己的slave mysql进程
两个Yes说明成功,从库配置完成。
主从复制可能遇到的错误及解决方案
在从库中使用show slave status\G查看状态
当 Slave_IO_Running 和 Slave_SQL_Running 不都为yes时,说明出现错误
这时可以再向下看 Last_Error 和 Last_SQL_Error 给出的错误原因
1、在从库更新主库信息,若报错:
ERROR 3021 (HY000): This operation cannot be performed with a running replica io thread; run STOP REPLICA IO_THREAD FOR CHANNEL '' first.
⑴ 停止从服务器的I/O线程
STOP REPLICA IO_THREAD;
注意:mysql8.0+中,SLAVE关键字已经被废弃,应该使用REPLICA关键字。在mysql5.7及之前版本中,可以使用STOP SLAVE IO_THREAD;
⑵ 等待I/O线程停止,可以通过检查从服务器的状态确认
SHOW SLAVE STATUS \G;
2、出现错误:
Last_IO_Error: Error connecting to source 'slave@10.168.1.150:3306'. This was attempt 1/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
尝试在从库数据使用主从复制的账号,远程登录一下主数据库,然后再使用本地账号登录,重启一下slave。
3、假设主库有10条数据,从库只有9条,对主库库所有数据进行修改,因为从库缺失一条,所以从库不会进行任何操作(数据不变),并报错:
Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at source log mysql-bin.003691, end_log_pos 71305213. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
所以这种错误,就是表明日志同步错误,也就是主库进行update或delete操作,而从库缺失这条数据,导致从库操作失败。
从库出现这种错误后,会停止后面的同步行为,直到我们手动处理了此错误。
解决办法:重新启动同步
⑴ 登录主库,查看master信息
show master status \G
获取到File与Position。
⑵ 查看从库信息
show slave status \G
⑶ 停止从库
stop slave。
⑷ 重新指定主库二进制文件,在从库中输入以下命令
CHANGE MASTER TO MASTER_HOST='x.x.x.x', MASTER_USER='user', MASTER_PASSWORD='密码', MASTER_LOG_FILE='对应主库中File名称', MASTER_LOG_POS=对应主库中Position;
⑸ 如果出现
ERROR 1802 (HY000): CHANGE REPLICATION SOURCE cannot be executed when the replica was stopped with an error or killed in MTA mode. Consider using RESET REPLICA or START REPLICA UNTIL.
表明从库需要重置 输入以下指令:
RESET REPLICA;
注意需要先stop,再执行。
⑹ 主库刷新bin,使用:
flush logs;
⑺ 以上方法使用后,还可能出现因为数据不同步导致的同步失败,可以对错误进行跳过使用以下指令(需要先执行stop slave):
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 100;
100为跳过错误次数,可自行更改。
⑻ 再次查看从库状态
show slave status \G