MySQL-day10-主从复制

20 篇文章 0 订阅

文章目录

mysql的主从复制

一.mysql主从复制

负载均衡 热备 冗余 容灾

1.主库需操作

  • 主库要开启二进制日志
  • 主库的server_id和从库不同
  • 主库要有提供从库连接的用户
  • 主库确定binlog名称和位置点
  • 获取其他主库信息:ip,port,user,password

2.从库需操作

  • 需要配置与主库不同的server_id
  • 同步主库的所有数据
  • 填写主库信息进行同步(change master to)
  • 开启IO线程和SQL线程

3.主从复制原理

1.主库配置server_id和binlog
2.主库授权用户
3.主库查看binlog名字及位置点
4.通过change master to语句告诉从库主库的ip,port,user,password,file,pos
5.从库开启IO线程和SQL线程(start slave;)
6.从库通过IO线程和change master to获取的信息连接主库
7.从库连接主库后,会去询问主库的dump线程,是否有比change master to时更新的binlog文件和位置点
8.主库接收到从库请求后,比较一下binlog信息,如果有就将最新数据通过dump线程给从库IO线程(使用ACK)
9.从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中(使用ACK)
10.从库IO线程也会返回ACK更新master.info文件里面的binlog文件名和位置点(使用ACK)
11.TCP/IP缓存中的内容会存到relay-log中
12.SQL线程会读取relay-log.info,获取上一次执行到的位置点,与中继日志对比,执行最新的relay-log日志
13.SQL线程执行完relay-log最新的数据后,更新relay-log.info,记录本次更新到的位置点

4.主从涉及到的文件

1)主库
  • 主库binlog:记录主库发生过的修改事件
  • dump线程:对比binlog是否更新,并且将新数据的二进制日志传送给从库
2)从库
  • IO线程:连接主库,接收主库发来的新数据的binlog日志
  • SQL线程:执行主库传过来的新数据的binlog日志
  • relay-log(中继日志):存储所有主库传过来的binlog事件
  • master.info:记录上次请求到的主库binlog名字和位置点
  • relay-log.info:记录上一次执行relay-log到的位置,下次从记录的位置开始向下继续执行

二、主从复制搭建实战

1.主库操作

mysqladmin -uroot password '123'	# 给主库个密码
1)配置主库配置文件
#编辑mysql配置文件
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=1
#开启binlog日志
log_bin=mysql-bin
2)创建主从复制用户
#登录数据库
[root@db01 ~]# mysql -uroot -p123
#创建rep用户作为从库连接用的用户
mysql> grant replication slave on *.* to slave@'192.168.100.%' identified by 'oldboy123';
	这里必须 *.* 不能指定库授权,因为 replication slave 是全局的
3)查看主库binlog信息
mysql> show master status;

2. 从库操作

1)修改配置文件
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
#主库server-id为1,从库不等于1
server_id=2

#重启数据库
[root@db02 ~]# /etc/init.d/mysqld restart
2)配置主从同步
#登陆数据库
[root@db02 ~]# mysql -uroot -poldboy123

#执行change master to 语句
mysql> change master to
-> master_host='192.168.100.111',
-> master_user='slave',
-> master_password='oldboy123',
-> master_log_file='mysql-bin.000001',
-> master_log_pos=1357;

#开启IO和SQL线程
start slave;

3.添加数据库主从(数据库运行中做主从)

1)准备纯净的从库环境
2)主库全备数据
# 不打点备份
mysqldump -uroot -p123 --all-databases > /backup/full.sql

# 打点备份
mysqldump -uroot -p123  --triggers --master-data=2 --single-transaction --all-databases  > /backup/full2.sql
	 --master-data=2  备份文件中 change master 是有注释的 
	 --single-transaction  

PS:此选项会将隔离级别设置为:REPEATABLE READ。并且随后再执行一条START TRANSACTION语句,让整个数据在dump过程中保证数据的一致性,这个选项对InnoDB的数据表很有用,且不会锁表。
3)将热备数据传达从库
scp root@192.168.100.111:/backup/full.sql  /backup/
4)模拟主库运行,有数据写入
insert into .....
5)导入全备数据
  • 导入不打点的数据的话,接下来主从,位置点只能去主库查看 show master status; 这个是不准确的
  • 如果导入的是打点的数据,那么接下来主从的同步位置点可以从全被sql里面找到,是准确的
6)查看sql文件中的位置点(如果是打点备份的话)
[root@db02 scripts]# head -50 /backup/full2.sql | grep 'MASTER_LOG_POS' -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=786574;
7)从库配置主从
mysql> change master to
	-> master_host='192.168.100.111',
	-> master_user='slave',
	-> master_password='oldboy123',
	-> master_log_file='mysql-bin.000001',
	-> master_log_pos=786337;
8)开启SQL线程和IO线程
start slave;
9)查看主从状态
show slave status;

4.验证多个从库server_id相同,主从是否有问题

1)配置第二个从库
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
server_id=2
2)启动数据库
systemctl start mysql
3)将主库的全备发送到从库
scp root@192.168.100.111/backup/full2.sql  /backup
4)在从库执行sql文件
mysql < /backup/full2.sql
5)查看sql文件中的位置点
[root@db02 scripts]# head -50 /tmp/dadian.sql|grep 'MASTER_LOG_POS' -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=786574;
6)在从库上执行change master
change master to
	master_host='192.168.100.111',
	master_user='slave',
	master_password='oldboy123',
	master_log_file='mysql-bin.000001',
	master_log_pos=786574;
7)开启SQL线程和IO线程
start slave;
8)查看主从复制的状态
show slave status\G

三、主从复制基本故障处理

reset slave all;	# 清空主从配置

1.IO线程问题

1)检测网络
[root@db01 ~]# ping 192.168.100.111
2)检测端口
[root@db01 ~]# telnet 192.168.100.111 3307

#阿里云机器有的禁ping
[root@db01 ~]# tcping 192.168.100.111 3306
3)检测账号,密码:
#根据授权命令
grant replication slave on *.* to slave@'192.168.100.%' identified by 'oldboy123';

#连接测试
mysql -uslave -poldboy123 -h127.0.0.1 -P 3307
4)查看binlog是否存在
show master status;
5)反向解析
#没有跳过反向解析
ERROR 1045 (28000): Access denied for user 'root'@'db01' (using password: YES)

#配置
skip_name_resolve	

2.SQL线程问题

1)主库有的数据,从库没有
2)从库有的数据,主库没有
3)主库与从库数据库结构有差别
4)三种处理方法
处理方法一:临时奏效
	#临时停止同步
	mysql> stop slave;
	#将同步指针向下移动一个(可重复操作)解决不了根本问题
	mysql> set sql_slave_skip_counter=1;
	#开启同步
	mysql> start slave;
	
处理方法二:永久奏效
	#编辑配置文件
	[root@db01 ~]# vim /etc/my.cnf
	#在[mysqld]标签下添加以下参数
	slave-skip-errors=1032,1062,1007
	
处理方法三:直接配置从库为只读,没有写权限就不会有结构差别的问题
	1.要求,主从复制之前,主库和从库的数据保证一致.
	2.在从库上设置  只读:set read-only=1;
	(做读写分离时使用,但是做MHA会出现提升为主库时,主库只读,后面会讲专门做读写分离的Atlas)

四、延时从库

  • 用延时从库可以做备份,主库执行删除时,从库还没删除,可以把从库的表数据拿出来,予以恢复
  • 企业中一般会延时3-6小时

1.延时从库配置方法

1)已经有主从的情况下
mysql> stop slave;	# 停止主从
mysql> CHANGE MASTER TO MASTER_DELAY = 180;		# 设置延时为180秒
mysql> start slave;	# 开启主从
mysql> show slave status \G	# 查看状态
SQL_Delay: 180
主库创建数据,会看到从库值变化,创建的库没有创建
	SQL_Remaining_Delay: 170
2)没有主从复制的情况下
1.修改主库,从库配置文件
	server_id
	开启binlog

2.保证从库和主库的数据一致

3.执行change语句
	change master to
	master_host='192.168.100.111',
	master_user='slave',
	master_password='oldboy123',
	master_log_file='mysql-bin.000001',
	master_log_pos=2752,
	master_delay=180;
3)延时从库停止方法
1.停止主从
mysql> stop slave;

2.设置延时为0
mysql> CHANGE MASTER TO MASTER_DELAY = 0;

3.开启主从
mysql> start slave;

#注:做延时从库只是为了备份,不提供服务

2.思考:延时到底是在哪里延时的?

思考:IO线程还是SQL线程做的手脚?

# 去主库创建一个库
create database ttt;

#查看从库的relaylog看看有没有内容
mysqlbinlog --base64-output=decode-rows -vvv db03-relay-bin.000002

总结:
	延时从库是在SQL线程做的手脚,IO线程已经把数据放到relay-log里了.
	SQL线程在执行的时候,会延迟你设定的时间长度.

3.使用延时从库恢复数据

1)场景
总数据量级500G,正常备份去恢复需要1.5-2小时

1)配置延时3600秒
mysql> CHANGE MASTER TO MASTER_DELAY = 3600;

2)主库
drop database db;

3)怎么利用延时从库,恢复数据?
2)环境准备
1.进行每日的全备
	mysqldump -uroot -p123 -A -R --triggers --master-data=2 –single-transaction > /backup/full.sql

2.调整延时从库延时时间为10分钟
	stop slave;
	CHANGE MASTER TO MASTER_DELAY = 600;
	start slave;

3.主库写入新数据
	create database yanshi;
	use yanshi;
	create table yanshi(id int);
	insert into yanshi values(1),(2),(3),(4);
	
	create database yanshi2;
	use yanshi2;
	create table yanshi2(id int);
	insert into yanshi2 values(1),(2),(3),(4);
3)模拟删除数据
删除一个库,可以是之前的,也可以是刚创建的

drop database world; #因为刚我们看了,只要我执行了,从库已经写到了relay-log,跟我数据库里的数据关系不大
4)使用延时从库恢复数据
1.停止从库sql线程
	stop slave sql_thread;

2.查看状态
	show slave status;

3.备份从库数据
	mysqldump -uroot -p123 -B world > /backup/congku.sql

4.截取一下relay-log
	1)确认起点
		[root@db02 data]# cat relay-log.info
		./mysqld-relay-bin.000002
		283
		
	2)确认终点
		[root@db02 data]# mysqlbinlog --base64-output=decode-rows -vvv mysqld-relay-bin.000002
		drop语句之前
		# # at 1269
	3)截取数据
		[root@db02 data]# mysqlbinlog --start-position=283 --stop-position=1112 mysqld-relay-bin.000002 > /backup/yanshi.sql

5.将从库全备的数据与relaylog截取数据拷贝到主库
	scp /backup/yanshi.sql 192.168.100.111:/backup/
	scp /backup/congku.sql 192.168.100.111:/backup/

6.将数据导入主库
	#导入前不要停掉binlog
	mysql < /backup/yanshi.sql
	mysql < /backup/congku.sql

7.开启从库的sql线程
	start slave sql_thread;

#主库那边执行到删除的时候没关系,因为还有创建的部分,他会再次把数据创建回来

五、半同步复制

  • mysql主从本身是异步复制
    IO线程将数据写入TCP/IP以后就不管了,当TCP缓存返回ACK的时候,IO线程会继续去主库拿数据

  • 从MYSQL5.5开始,支持半自动复制。之前版本的MySQL Replication都是异步(asynchronous)的,主库在执行完一些事务后,是不会管备库的进度的。如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),这时备库中的数据就是不完整的。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。

  • 半同步复制(Semi synchronous Replication)则一定程度上保证提交的事务已经传给了至少一个备库。
    出发点是保证主从数据一致性问题,安全的考虑。

  • 半同步复制是IO线程拿完数据,会等待SQL线程执行完以后再去拿数据,而且还会影响主库性能,他会阻塞主库数据的写入,如果SQL要执行十分钟,那么IO线程就一直等待,并且不让主库写入数据

  • 半同步,是在IO线程上做的手脚,数据写入到TCP/IP缓存中,不返回ACK,直到SQL线程执行完之后,才返回ACK
    ACK是一个确认字符

PS:半同步其实是mysql自带的一个和插件(很少有人用)
1.效率低
2.影响主库的性能
3.设置一个超时时间:过了这个超时时间,会恢复到异步复制

5.x版本区别:
5.5 出现概念,但是不建议使用,性能太差
5.6 出现group commit 组提交功能,来提升开启半同步复制的性能
5.7 更加完善了,在group commit基础上出现了MGR
5.7 的增强半同步复制的新特性:after commit; after sync;

1.半同步复制开启方法

1)主库
#登录数据库
[root@db01 ~]# mysql -uroot -p123

#查看是否有动态支持
mysql> show global variables like 'have_dynamic_loading';

#安装自带插件(.so结尾的文件在 /usr/local/mysql/lib/plugin/ 下面)
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';

#启动插件
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;

#设置超时
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;

#修改配置文件
[root@db01 ~]# vim /etc/my.cnf	# 在[mysqld]标签下添加如下内容(不用重启库)
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000

#查看半同步状态是否开启
mysql> show variables like'rpl%';
mysql> show global status like 'rpl_semi%';
2)从库
#登录数据库
[root@mysql-db02 ~]# mysql -uroot -poldboy123

#先检查从库状态
show slave status\G

#安装slave半同步插件
mysql>  INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';

#启动插件
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;

#重启io线程使其生效
mysql> stop slave io_thread;
mysql> start slave io_thread;

#编辑配置文件(不需要重启数据库)
[root@mysql-db02 ~]# vim /etc/my.cnf

#在[mysqld]标签下添加如下内容
[mysqld]
rpl_semi_sync_slave_enabled =1
3)测试半同步

六、过滤复制

我们在授权主从用户的时候必须使用:

mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by 'oldboy123';
	# 这里必须 *.* 不能指定库授权,因为 replication slave 是全局的,不用则报错
  • 企业里或许有只想同步某一个库的需求,可能是因为环境多为了节省资源
    企业里很多环境:
    1.开发环境:开发开发完自己测试
    2.测试环境:
    1)性能测试
    2)功能测试
    4.预发布环境(beta,内测不删档)、灰度环境、沙盒环境
    5.生产环境

PS:除了生产和预发布其他的环境都是虚拟机测试用的

  • 测试环境有很多游戏,我就想一个从库同步一种游戏,还有合服,建新服,其实就是一个库或者一个表而已
    创建角色总是提示改昵称已被创建,就是因为姓名也是唯一键

1.确认三台机器主从状态

show slave status\G

2.过滤复制两种方式

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      262 |  白名单   	  |       黑名单      |                   |
+------------------+----------+--------------+------------------+-------------------+

1)黑名单
不记录黑名单列出的库的二进制日志

#参数
--replicate-ignore-db
--replicate-ignore-table
--replicate-wild-ignore-table
2)白名单
只执行白名单中列出的库或者表的中继日志

#参数:
--replicate-do-db=test
--replicate-do-table=test.t1
--replicate-wild-do-table=test.t2

3.配置过滤复制

1)主库创建两个库
create database wzry;
create database yxlm;
2)从库1配置
[root@db02 ~]# vim /etc/my.cnf
[mysqld]
replicate-do-db=wzry

[root@db02 ~]# systemctl restart mysql

#查看主从状态
show slave status;
3)从库2配置
[root@db03 ~]# vim /etc/my.cnf
[mysqld]
replicate-do-db=yxlm

[root@db03 ~]# systemctl restart mysql

#查看主从状态
show slave status;
4)主库创建表测试
use wzry;
create table dianxin1;

use yxlm;
create table wangtong1;
5)从库查看表
#登陆两台数据库查看表是否存在

4.尝试把白名单配置到主库

[root@db01 ~]# vim /etc/my.cnf
[mysqld]
replicate-do-db=yxlm

[root@db01 ~]# systemctl restart mysql

#测试同步

5.过滤复制总结

PS:我们可以查看一下中继日志,其实数据都拿过来了,只不过他是读取配置文件过滤去执行sql的

  • 在主库上设置白名单:只记录白名单设置的库或者表,相关的SQL语句到binlog中
    在主库上设置黑名单:不记录黑名单设置的库或者表,相关的SQL语句到binlog中

  • 在从库上设置白名单:IO线程会拿所有的binlog,但是SQL线程只执行白名单设置的库或者表相关的SQL语句
    在从库上设置黑名单:IO线程会拿所有的binlog,但是SQL线程不执行黑名单设置的库或者表相关的SQL语句

#从库白名单,只同步某个库
replicate-do-db=test
#从库白名单,只同步某个库中的某个表
replicate-do-table=test.t1
replicate-do-table=test.c2
replicate-do-table=test.b3
replicate-do-table=test.a4
#从库白名单,只同步某个库中的以t开头的所有表
replicate-wild-do-table=test.t*
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋风お亦冷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值