一、主从复制的基本原理和逻辑图
1、原理(过程)
1.从库开启一个 I/O 线程(I/O thread),连接主库发送请求到主库(传 pos,binlog event等参数)获取 binlog 日志。
2.主库会创建一个 log dump 线程(dump thread),检查 binlog event,根据从库要求,将 binlog 发送给从库 I/O 线程,从库 I/O 线程将 binlog 写入 relay log(中继日志)。
3.从库开启 SQL 线程(SQL thread),取 relay log 文件中的日志,并解析成具体操作执行,实现主从数据最终一致性;
2、逻辑图
3、常见的问题
1.主服务器如何知道从服务器已经有哪些数据了,需要从哪里开始拿?
和master-info有关,从服务器上有IO进程,每次读的时候,会查看这个文件
这个master-info文件记录了取日志结束的pos位置号,日志文件的名字
2.relay-log.info
告诉 SQL thread 读取中继器日志的时候,从那个文件开始,那个位置号结束
二、主从复制的作用和三种模式
1、主从复制的作用
1.数据备份--》必须使用延迟备份,延迟30分钟去复制二进制日志,master和slave30分钟的数据时间差
2.高可用
3.负载均衡
2、主从复制的三种模式
1、异步模式
缺点:有延迟,会丢失数据
2、半同步复制
3、同步复制
三、主从复制的相关复制操作
1、延迟备份
2、在线主从复制实现–》xtrabackup
难点:要获得mysqldump数据的时候的二进制日志文件和当时的位置号
3、主从切换
4、主主复制/一主多从架构
互为主从,可以是相同的库和表,也可以是不同的库和表
若主主双方都操作,最好设置auto-increment-offset(初始值)和auto-increment-increment(步长),用来避免冲突;
5、半同步:相对于异步模式,多了一个ack确认请求,如果超过10秒没有得到响应,会自动采取异步模式
6、同步复制:组复制,性能好,但是成本高
四、主从复制中异步模式的操作案例
1、安装好2台Mysql服务器,以及mysql软件,版本一致 --》环境一致
2、master上启动二进制日志功能,新建一个授权用户,同时将原始数据备份
1.创建用户
liuhongjie 123456
create user 'lhjrepl'@'192.168.243.134' identified by '123456';
grant replication slave on *.* to 'lhjrepl'@'192.168.243.134';
2.备份原数据
1.flush tables with read lock; #锁住所有表,不要别的会话写入
Query OK, 0 rows affected (0.00 sec)
2.show master status; #查看当前位置号
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 629 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
3.mysqldump -uroot -p123456 --all-databases --master-data > sc_dbdump.db
4.scp sc_dbdump.db root@192.168.243.134:/root
root@192.168.243.134's password:
sc_dbdump.db 100% 866KB 79.1MB/s 00:00
3、在slave上面操作:修改mysql配置文件,不需要开启二进制日志,但是需要指定server_id = 2
4、在slave上恢复master导出的原始数据:mysql -uroot -p123456 <sc_dbdump.db
5、解锁:unlock tables;
6、填写master信息
在mysql里操作:
change master to master_host='192.168.243.138',
MASTER_USER='lhjrepl',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=629;
7、到slave的/data/mysql目录下查看,是否有master.info和relay-log.info文件
8、在slave机器上,开启尝试连接主数据库–》start slave(sql语句)
查看是否连接上了
root@(none) 21:53 mysql>show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.243.138
Master_User: lhjrepl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 629
Relay_Log_File: nginx-kafka03-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes #两个都为yes表示已经连接上了
Slave_SQL_Running: Yes
9、对主机器上的数据库进行操作,看从里的数据库是否跟着改变
五、主从复制的延迟备份
1、在slave机器上面操作:
1.stop slave
2.change master to master_delay = 50; #延迟50秒
3.start slave
六、主从切换的实现
1.监控master和slave
2.选举新的master
1.stop slave
2.reset master
3.开启二进制日志
4.log-slave-updates=on
3.其他的slave马上把master切换到新的master
4.app马上写数据到新的master
4.1 直接修改web里的代码里的ip,换成新的master的ip
4.2 修改域名对应的ip为新的master的ip
七、半同步操作
1、在master上面操作
1.INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
2.SET GLOBAL rpl_semi_sync_master_enabled = 1;
3.show variables like "%semi_sync%";
2、在slave上面操作
1.INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
2.SET GLOBAL rpl_semi_sync_slave_enabled = 1;
3.show variables like "%semi_sync%";
3、重启slave
1.stop slave;
2.start slave;