一.主从复制简介

复制是 MySQL 的一项功能,允许服务器将更改从一个实例复制到另一个实例。

1)主服务器将所有数据和结构更改记录到二进制日志中。

2)从属服务器从主服务器请求该二进制日志并在本地应用其内容。

3)IO:请求主库,获取上一次执行过的新的事件,并存放到relaylog

4)SQL:从relaylog中将sql语句翻译给从库执行

二.主从复制原理

主从复制的前提

1)两台或两台以上的数据库实例

2)主库要开启二进制日志

3)主库要有复制用户

4)主库的server_id和从库不同

5)从库需要在开启复制功能前,要获取到主库之前的数据(主库备份,并且记录binlog当时位置)

6)从库在第一次开启主从复制时,时必须获知主库:ip,port,user,password,logfile,pos

7)从库要开启相关线程:IO、SQL

8)从库需要记录复制相关用户信息,还应该记录到上次已经从主库请求到哪个二进制日志

9)从库请求过来的binlog,首先要存下来,并且执行binlog,执行过的信息保存下来

主从复制涉及到的文件和线程

主库:

1)主库binlog:记录主库发生过的修改事件

2)dump thread:给从库传送(TP)二进制日志线程

从库:

1)relay-log(中继日志):存储所有主库TP过来的binlog事件

2)master.info:存储复制用户信息,上次请求到的主库binlog位置点

3)IO thread:接收主库发来的binlog日志,也是从库请求主库的线程

4)SQL thread:执行主库TP过来的日志

主从复制原理图

大前提条件:做主从复制之前,一定要保证主库和从库之间数据一致性

1)通过change master to语句告诉从库主库的ip,port,user,password,file,pos

2)从库通过start slave命令开启复制必要的IO线程和SQL线程

3)从库通过IO线程拿着change master to用户密码相关信息,连接主库,验证合法性

4)从库连接成功后,会根据binlog的pos问主库,有没有比这个更新的

5)主库接收到从库请求后,比较一下binlog信息,如果有就将最新数据通过dump线程给从库IO线程

6)从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中,并返回ACK更新master.info

7)将TCP/IP缓存中的内容存到relay-log中

8)SQL线程读取relay-log.info,读取到上次已经执行过的relay-log位置点,继续执行后续的relay-log日志,执行完成后,更新relay-log.info

三、主从复制搭建实战

主库操作:

1)修改配置文件

#编辑mysql配置文件
[root@db01 ~]# vim /etc/my.cnf
#在mysqld标签下配置
[mysqld]
#主库server-id为1,从库不等于1
server_id =1
#开启binlog日志
log_bin=mysql-bin

2)创建主从复制用户

#登录数据库
[root@db01 ~]# mysql -uroot -poldboy123
#创建rep用户
mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by '123';

从库操作:

1)修改配置文件

#修改db02配置文件
[root@db02 ~]# vim /etc/my.cnf
#在mysqld标签下配置
[mysqld]
#主库server-id为1,从库不等于1, 但从库之间的server_id可以相等
server_id =5
#重启mysql
[root@db02 ~]# /etc/init.d/mysqld restart #记录主库binlog及位置点
[root@db01 ~]# mysql -uroot -poldboy123
mysql> show master status;
| mysql-bin.000002 | 317
#登陆数据库
[root@db02 ~]# mysql -uroot -poldboy123
#执行change master to 语句
mysql> change master to
-> master_host='10.0.0.51',
-> master_user='rep',
-> master_password='123',
-> master_log_file='mysql-bin.000002',
-> master_log_pos=317,
-> master_port=3306; mysql> start slave;
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

四.主从复制基本故障处理

IO线程报错解决思路

# IO线程报错:
解决思路:
1.网络
[root@db02 ~]# ping 10.0.0.51
1)硬件层,路由,交换机,网络设备
2)网线
3)安全组规则
4)插错网线口 2.端口
[root@db02 ~]# telnet 10.0.0.51 3306
#关闭防火墙
systemctl stop firewalld
#防火墙添加允许mysql端口
firewalld-cmd --add-service=mysql
firewalld-cmd --add-port=3306/tcp 3.用户名
mysql> grant replication slave on *.* to rep@'%' identified by '123'; 4.密码,先登录测试
[root@db03 data]# mysql -urep -p123 -h10.0.0.51 如果报错 #rep@'db03',需在参数,跳过反向解析
vim /etc/my.cnf
skip_name_resolve #搭建主从时,用户名、密码、主机域、端口一定要一致。
change master to
master_host='10.0.0.51',#1
master_user='rep',#2
master_password='123',#3
master_log_file='mysql-bin.000003',
master_log_pos=169853,
master_port=3306;

SQL线程报错

处理方法一:

#临时停止同步
mysql> stop slave;
#将同步指针向下移动一个(可重复操作)
mysql> set global sql_slave_skip_counter=1;
#开启同步
mysql> start slave;

处理方法二:

#编辑配置文件
[root@db01 ~]# vim /etc/my.cnf
#在[mysqld]标签下添加以下参数,把线程号添加到配置文件
slave-skip-errors=1032,1062,1007

但是方法一、方法二都是有风险存在的,只是跳过错误,不能从根本上解决问题

处理方法三:

1)重新备份数据库,恢复到从库

2)给从库设置为只读

#在命令行临时设置
set global read_only=1;
#在配置文件中永久生效
read_only=1

注意:登录用户如果是all权限,包含了super超级权限,还是可以进行操作的

  1. all 权限,即使配置文件设置了只读,还是都可以操作的。
  2. 不加all权限。哪怕给他指定select,insert, delete ,create 权限,都是不能操作,只能只读的。

例如:

#设置配置文件永久生效
[root@db03 ~]# vim /etc/my.cnf
read_only=1
#重启
[root@db03 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
#查看
mysql> show variables like 'read_only';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only | ON |
+---------------+-------+
1 row in set (0.00 sec)

1. all 权限

[root@db03 ~]# mysql
mysql> grant all on *.* to rea@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec) [root@db03 ~]# mysql -urea -p123 -h 10.0.0.53
mysql> create database aaa;
Query OK, 1 row affected (0.01 sec)

2.不是all权限

mysql> grant select,create,delete,insert on *.* to rea1@'%' identified by '123';
Query OK, 0 rows affected (0.00 sec) [root@db03 ~]# mysql -urea1 -p123 -h10.0.0.53
mysql> create database bbb;
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
mysql> drop database test;
ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement
...

五.延时从库

普通的主从复制可能存在不足

1)逻辑损坏怎么办?

2)不能保证主库的操作,从库一定能做

3)高可用?自动failover?

4)过滤复制

企业中一般会延时3-6小时

延时从库配置方法

#停止主从
mysql>stop slave;
#设置延时为180秒
mysql> change master to master_delay= 180;
#开启主从
mysql>start slave;
#查看状态
mysql> show slave status\G
SQL_Delay: 60 #或者做主从的时候直接指定延时
change master to
master_host='10.0.0.51',
...
master_delay=3600; 3.延时从库停止方法
#停止主从
mysql> stop slave;
#设置延时为0
mysql> change master to master_delay = 0;
#开启主从
mysql> start slave;

企业案例:

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

1)配置延时3600秒

mysql>change master to master_delay = 3600;

2)主库

drop database db;

3)怎么利用延时从库,恢复数据?

提示:

1、从库relaylog存放在datadir目录下

2、mysqlbinlog 可以截取relaylog内容

3、show relay log events in 'db01-relay-bin.000001';

处理的思路:

1)停止SQL线程

2)截取relaylog到误删除之前点

  • relay-log.info 获取到上次运行到的位置点,作为恢复起点
  • 分析relay-log的文件内容,获取到误删除之前position

模拟故障处:

1)关闭sql

2)模拟数据

3)开启从库延时3600s

4)破坏,模拟删库故障。(以下步骤在5分钟内操作完成。)

5)从库,关闭SQL线程

6)截取relay-log

恢复relay.sql

方法一:取消从库身份,恢复数据,从库当主库

方法二:从库导出来的数据传给主库,恢复数据

模拟环境

1.主库

#一直写数据
[root@db01 ~]# sh mysqldump.sh
#全备
[root@db01 ~]# mysqldump -uroot -p1 -A --triggers -R --master-data=2 --single-transaction |gzip >/backup/full.gz
Warning: Using a password on the command line interface can be insecure.
#查看
[root@db01 ~]# ll /backup/
total 376
-rw-r--r-- 1 root root 384381 Nov 17 09:22 full.gz
#查看mysql-bin和起点
[root@db01 ~]# zcat /backup/full.gz |head -25
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=517; #scp到对端
[root@db01 ~]# scp /backup/dbdb.sql 172.16.1.54:/tmp
[root@db01 ~]# mysql -uroot -p1
mysql> grant replication slave on *.* to rep@'%' identified by '123';
  1. 从库
#准备初始化环境
[root@db04 ~]# /etc/init.d/mysqld stop
[root@db04 ~]# rm -fr /application/mysql/data/*
[root@db04 ~]# ./mysql_install_db --user=mysql --basedir=/opt/mysql --datadir=/opt/mysql/data/
[root@db04 ~]# /etc/init.d/mysqld start #导库
[root@db04 ~]# zcat /tmp/dbdb.sql |mysql
#主从
[root@db04 ~]# mysql -uroot -p1
mysql> change master to
master_host='10.0.0.51',
master_user='db',
master_password='123',
master_log_file='mysql-bin.000001',
master_log_pos=517,
master_port=3306,
master_delay=3600;
  1. 主库模拟删库故障
[root@db01 ~]# mysql -uroot -p1
mysql> select count(*) from db1.t1;
+----------+
| count(*) |
+----------+
| 888 |
+----------+
1 row in set (0.00 sec) mysql> drop database db1;
Query OK, 1 row affected (0.02 sec)
  1. 从库先关闭sql线程
[root@db04 ~]# mysql
SQL_Delay: 3600 mysql> select count(*) from db1.t1;
+----------+
| count(*) |
+----------+
| 655 |
+----------+
1 row in set (0.00 sec) mysql> stop slave sql_thread;
Query OK, 0 rows affected (0.01 sec)
Slave_IO_Running: Yes
Slave_SQL_Running: No

5.从库将误删除的主库导出拷贝到主库

[root@db04 data]# mysqldump -B db1>/tmp/db_quan.sql
[root@db04 data]# scp /tmp/db_quan.sql 172.16.1.51:/backup/

6.截取未同步的数据到删库之前的操作.

#获取起点
[root@db04 data]# cat relay-log.info
7
./db04-relay-bin.000002
283
mysql-bin.000003
44040
3600
0
1 #获取终点
方法一:
[root@db04 data]# mysql
#查看relaylog事件
mysql> show relaylog events in 'db04-relay-bin.000002';
| db04-relay-bin.000002 | 45118 | Query | 1 | 161795 | drop database db1
#或者在命令行执行
[root@db04 ~]# mysql -e "show relaylog events in 'db04-relay-bin.000002'"; #方法二:
[root@db04 data]# mysqlbinlog -d db1 --base64-output=decode-rows -vvv db04-relay-bin.000002 |grep -i -B 5 'drop database'
#191117 13:38:56 server id 1 end_log_pos 88875 CRC32 0xcfd701dd Xid = 15750
COMMIT/*!*/;
# at 45118
#191117 13:38:58 server id 1 end_log_pos 88964 CRC32 0x905241e7 Query thread_id=2671 exec_time=0 error_code=0
SET TIMESTAMP=1573969138/*!*/;
drop database db1 #截取这段数据导出并发送给主库
[root@db04 data]# mysqlbinlog --start-position=283 --stop-position=45118 /opt/mysql/data/db04-relay-bin.000002 >/tmp/db_zeng.sql
[root@db04 data]# scp /tmp/db_zeng.sql 172.16.1.51:/backup/

7.主库将两段内容导入并查看数据完整性

[root@db01 data]# mysql -uroot  -p1 </backup/db_quan.sql
[root@db01 data]# mysql -uroot -p1 </backup/db_zeng.sql
mysql> select count(*) from db1.t1;
+----------+
| count(*) |
+----------+
| 900 |
+----------+
1 row in set (0.00 sec)

8.从库开启sql线程 将延时关闭查看是否同步

[root@db04 data]# mysql
mysql> start slave sql_thread;
mysql> stop slave;
mysql> change master to master_delay=0;
mysql> start slave;
#查看
mysql> select count(*) from db1.t1;
+----------+
| count(*) |
+----------+
| 900 |
+----------+
1 row in set (0.00 sec)

9.再次开启延时

mysql> stop slave;
mysql> change master to master_delay=3600;
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

最新文章

  1. Atitit 设计模式与算法,与流程的关系
  2. ulua 路径小记 以及 lua require 机制整理
  3. iScroll4.2.5中的无法滑动或点击的解决方案(转)
  4. 微信5.4你所不知道的事 X5浏览引擎提速50%-80%
  5. P2296 寻找道路
  6. Codeforces Round #307 (Div. 2) C. GukiZ hates Boxes 贪心/二分
  7. IntelliJ IDEA 创建web项目后添加Java EE (Tomcat)的依赖包
  8. 跟我一起学CMake
  9. Windows常用shell命令大全
  10. String s=new String("abc")产生了几个对象?[权威面试版]
  11. JavaScript 运行机制详解:Event Loop
  12. android 无法import
  13. mysql乱码问题解决办法
  14. Python网络爬虫第一弹《Python网络爬虫相关基础概念》
  15. VS2013的安装与C#进行简单单元测试(英文版教程)
  16. Oracle之rman命令的使用全备输出信息的详解(51CTO风哥rman课程)
  17. [WorldWind学习]20.修改ShapeFileLayer类及托管D3D文字绘制方法
  18. UVALive 6955 Finding Lines(随机化优化)题解
  19. 160425、linux安装SVN服务器
  20. qemu网络虚拟化之数据流向分析三

热门文章

  1. centos 6.5 安装 nginx
  2. pandas.Series函数用法
  3. cmd优化
  4. 108天南京银行完成不可能完成的新金融DevOps转型
  5. 29 基于PCL的点云平面分割拟合算法技术路线(针对有噪声的点云数据)
  6. 史上最全最实用HBuilder快捷键大全
  7. IDEA搭建spingboot项目
  8. form表单action带参数传递
  9. centos7中yum安装lamp环境
  10. VS2015发布web服务