《MySQL数据库》MySQL主从复制搭建与原理
前言
主从复制:两台或者更多的数据库实例,通过二进制日志,实现数据同步。为什么需要主从复制,主从复制的作用是什么,答:为了预防灾难。
搭建
第一步:准备多实例环境。如何创建多实例见:
第二步:确保每一个实例的server_id 不同。
检查各自实例图中(my.cnf)的配置是否不同。
第三步:主库检查binlog 是否开启
第四步:主库创建复制用户
grant replication slave on *.* to repl@'%' identified by 'repl';
第五步:主库和从库在主从之前要保证数据结构一致。
主库备份,恢复到从库:https://www.cnblogs.com/jssj/p/13514597.html
第六步:主从连接(重点)
从库中执行以下语句,告知从库连接信息,同步开始点等(我这里有两个从库就两个从库都登入执行)
CHANGE MASTER TO
MASTER_HOST='127.0.0.1', -- 主库ip
MASTER_USER='repl', -- 主从专用用户
MASTER_PASSWORD='repl', -- 用户密码
MASTER_PORT=3307, -- 主库ip
MASTER_LOG_FILE='mysql-bin.000001', --复制开始点的binlog文件
MASTER_LOG_POS=653, --binlog 文件中的开始点
MASTER_CONNECT_RETRY=10; -- 重连次数
MASTER_DELAY = 300; -- 从库SQL线程延时时间设置,(一般一主二从的时候,一从不加延时,一从加延时,这样逻辑误操作可以及时修复)
第七步:从库中启动专用主从线程
start slave ; -- 启动主从
stop slave; -- 关闭主从
扩展:
start slave sql_thread -- 单独启动从库sql线程
start slave io_thread -- 单独启动从库I/O线程
stop slave sql_thread -- 单独停从库sql线程
stop slave io_thread -- 单独停从库I/O线程
第八步:验证主从复制是否正常
查看从库线程
mysql -uroot -S /usr/local/mysql/data/3308/mysql.sock -e "show slave status\G | grep Running"
还有就是在主库上创建数据库,创建表等操作,看看从库是否和主库一致。
如果搭建失败:
执行:(没有问题别执行),然后重新执行以上步骤。 reset slave all 表示重置主从配置信息。
mysql -uroot -S /usr/local/mysql/data/3308/mysql.sock -e "stop slave; reset slave all;"
好了,到这里我们已经搭建完毕。
原理
文件部分
从库文件(以下文件都默认放在数据文件目录下):
主机名-relay-bin.000001 -- 默认叫这个名字,从主库接收到的binlog信息记录在这里
主机名-relay-bin.000002 -- 默认叫这个名字,从主库接收到的binlog信息记录在这里
主机名-relay-bin.index -- 默认叫这个名字,从主库接收到的binlog信息记录在这里
master.info --从库的配置信息: CHANGE MASTER TO ... 的信息。
relay-log.info --存储接收的binlog
mysql> select @@master_info_repository; -- 设置从库配置信息存放的方式:文件/表
mysql> select @@relay_log_info_repository; -- relay-log存放方式:文件/表,默认文件
mysql> select @@relay_log_purge; -- relay_log是否开启删除已经被使用过的relay_log
主库文件就是binlog 已经再之前文档讲过,这里不在说明https://www.cnblogs.com/jssj/p/13472394.html
线程:
主库下执行以下命令,查询线程:
show processlist;
图中可以看到两个 Binlog Dump的主从线程。
从库线程:搭建的第八步已经给出。两个线程一个I/O,一个SQL。
主从复制的原理图:
额外补充: 主库有变化会通过从库,从库就会及时去主库获取新的变化,MySQL的主从复制是通过这种方式来保证实时性的。
参数
mysql> show slave hosts; -- 查看主库中被连接的从库信息
mysql> show slave status \G; --查看从库信息
重点字段说明
change master to 的配置信息
Master_Host: 127.0.0.1
Master_User: repl
Master_Port: 3307
Connect_Retry: 10
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 154
Relay_Log_File的执行情况:
Relay_Log_File: iZm5e5v2zi93osbr5z21fvZ-relay-bin.000005
Relay_Log_Pos: 367
Relay_Master_Log_File: mysql-bin.000004
Exec_Master_Log_Pos: 154
从库线程状态:
Slave_IO_Running: Yes -- no 或者 connecting 都表示不正常。 网络,端口,防火墙,用户密码 ,权限replication slave,连接数上限,版本不一致等。
Slave_SQL_Running: Yes
mysql> select @@max_connections; -- 最大连接数
从库线程报错信息:
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
过滤复制相关信息:
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
主从延时
Seconds_Behind_Master: 0 -- 单位为秒(主二进制文件的事件和从库获取二进制文件的事件差,所以这个时间并不能说明主从没有延时)
延时从库的配置信息:
SQL_Delay: 0 -- 通过主从配置的时候设置的 MASTER_DELAY;
SQL_Remaining_Delay: NULL
GTID相关复制信息:从库显示的就是主库的GTID 和从库执行到的GTID。
Retrieved_Gtid_Set:
Executed_Gtid_Set:
故障
主从不一致的时候,会出现从库SQL线程down掉。
先看参数: 报错内容
Last_SQL_Errno: 0
Last_SQL_Error:
处理方式一:
stop slave; -- 停主从
set global sql_slave_skip_counter = 1; -- 设置参数跳过本次主从同步操作。
start slave;
处理方式二:
从库反操作一下:比如从库中已经存在主键记录,先把主键记录删除,重启start slave; 让其再同步一次。
处理方式三(统一处理一下重复报错,不推荐):
在MySQL参数配置文件:/etc/my.cnf 中设置
slave-skip-errors = 1032,1062,1007 -- 常见错误代码:1007:对象已存在;1032:无法执行DML;1062:主键冲突,或约束冲突
终极方式:重新搭建主从。
一般情况:MySQL主从搭建从库是不需要有其他的操作的,也是为了减少不必要的主从问题,所以会设置一个参数:
mysql> select @@read_only; -- 1:只读,0:不是 (针对普通用户)
mysql> select @@super_read_only; -- 1:只读,0:不是 (针对普通管理员用户)
主从延时
主从延时监控:
主库binlog执行到的位置点:
从库relaylog执行到的位置点,
是否存在差异,差异越大延时越严重。
主从延时原因:
1. 网络太慢。
2. 硬件性能。
3. 主库业务繁忙。
4. 从库太多。
5. 5.6版本没有开启GTID(串行传输日志)。 -- 开启GTID,或者升级5.7 ,5.7默认支持并发传输日志。
6. 锁也会导致延时。
7.从库SQL线程串行执行,效率低,导致延时, 需要开启多个SQL线程来保证效率(必须开启GTID).并且5.7 版本还有逻辑时钟保证并发执行。 MTS
恢复
1. 如果是物理损坏, 主从非常简单的就可以恢复数据。 直接将从库数据导出,导入主库, 或者直接将从库当成主库使用。
stop slave; -- 停掉主从服务
reset slave all; -- 去掉主从配置
然后就可以临时当主库使用。
2. 如果数逻辑损坏,比如drop了数据库。
上面的情况下,我们就需要使用延时从库的功能了, 因为该从库是延时执行操作的, 故主库出现问题的时候从库是正常的。 所以可以通过从库恢复数据:
CHANGE MASTER TO MASTER_DELAY = 300; -- 设置延时
1. 登录从库数据库停从库sql线程:
stop slave sql_thread
2. 查看relay.info 的位置点是否主库一致,表示日志文件已经同步:
3. 恢复从库:
截取relay_bin log位置点的起点
show slave status \G;
截取relay_bin log位置点的终点
找到使用的relay-bin 文件,然后使用下面的命令找到终点
show relaylog events in 'iZm5e5v2zi93osbr5z21fvZ-relay-bin.000002' -- 查看relaybinlog 文件
获取pos字段就可以了,
起点,终点都有了,然后截取命令:
mysqlbinlog --start-position=634 --stop-position=861 /usr/local/mysql/data/3309/data/iZm5e5v2zi93osbr5z21fvZ-relay-bin.000002 > /usr/local/mysql/relay.sql
恢复从库数据:
mysql> set sql_log_bin = 0; -- 关闭binlog日志
mysql> source /usr/local/mysql/relay.sql; -- 导入sql脚本(通过binlog截取出来的)
mysql> set sql_log_bin = 1; -- 开启binlog日志
检查数据:
4. 恢复主库:
参考:https://www.cnblogs.com/jssj/p/13514597.html 的恢复章节。 导出从库数据库文件,导入主库。
5. 恢复主从:
从新设置主从:参考本文第一部分。
过滤主从
图中 数据库C 不需要主从复制。
1. 主库设置不同步,不产生binlog 即可(不推荐)
其中:binlog_Do_DB 是包含哪些库需要生成binlog日志; binlog_ignore_DB 忽略掉一些数据库产品binlog日志
2. 从库设置SQL线程不执行不需要复制的数据库(推荐)。
[root@db01 ~]# vim my.cnf -- 打开参数文件设置
replicate_do_db=test -- 需要写入从库的数据库
replicate_do_db=test1 -- 需要写入从库的数据库
重启数据库实例生效。
扩展:
replicate_do_db=test -- 需要写入从库的数据库
replicate_ignore_db=test1 -- 需要忽略写入从库的数据库 replicate_do_table=test.test -- 需要写入从库的数据库的表
replicate_ignore_db=test1.test -- 需要忽略写入从库的数据库的表 replicate_wild_do_db=test.t* -- 需要写入从库的数据库的模糊的表
replicate_wild_ignore_db=test1.t* -- 需要忽略写入从库的数据库模糊的表
半同步主从
在上面的主从复制的框架中有一个问题,就是主库不关心从库是否接收到数据,写入磁盘,容易出现从库和主库不一致的情况。
已经属于历史功能,基本已经不使用了。
原理:
1. 主库执行新的事务,commit时,更新 show master status\G ,触发一个信号给
2. binlog dump 接收到主库的 show master status\G信息,通知从库日志更新了
3. 从库IO线程请求新的二进制日志事件
4. 主库会通过dump线程传送新的日志事件,给从库IO线程
5. 从库IO线程接收到binlog日志,当日志写入到磁盘上的relaylog文件时,给主库ACK_receiver线程
6. ACK_receiver线程触发一个事件,告诉主库commit可以成功了
7. 如果ACK达到了我们预设值的超时时间,半同步复制会切换为原始的异步复制.
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; -- 主库加载插件
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; --从库加载插件
show plugins; -- 查看加载情况
SET GLOBAL rpl_semi_sync_master_enabled = 1; -- 主库设置半同步
SET GLOBAL rpl_semi_sync_slave_enabled = 1; -- 从库设置半同步
STOP SLAVE IO_THREAD; -- 停止I/O线程
START SLAVE IO_THREAD; -- 启动I/O线程
show status like 'Rpl_semi_sync_master_status'; -- 主库查看半同步状态
show status like 'Rpl_semi_sync_slave_status'; -- 从库查看半同步状态
GTID 主从复制(推荐)
搭建GTID主从要注意一点:MySQL的data文件需要清理之后,从新搭建。
my.cnf的配置文件如下:
cat > /usr/local/mysql/data/3307/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql/mysql-5.7.22-linux-glibc2.12-x86_64
datadir=/usr/local/mysql/data/3307data
socket=/usr/local/mysql/data/3307/mysql.sock
log_error=/usr/local/mysql/data/3307/mysql.log
port=3307
server_id=7
log_bin=/usr/local/mysql/log/3307/mysql-bin
secure-file-priv=/tmp
binlog_format=row
autocommit=0
gtid-mode=on #开启GTID
enforce-gtid-consistency=true #开启GTID
log-slave-updates=1 #主从一至
[mysql]
prompt=db01 [\\d]>
EOF
重新初始化数据:
mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql/mysql-5.7.22-linux-glibc2.12-x86_64 --datadir=/usr/local/mysql/data/3307/data
启动实例:
mysqld --defaults-file=/usr/local/mysql/data/3309/my.cnf &
重新构建主从:主库
grant replication slave on *.* to repl@'%' identified by 'repl';
从库执行命令(和普通主从有区别):
-- 主从配置信息
change master to
master_host='127.0.0.1',
MASTER_PORT=3307,
master_user='repl',
master_password='repl' ,
MASTER_AUTO_POSITION=1; -- 主动获取主库的的位置点,根据从库的relay-bin.info去判断
-- 开启主从
start slave;
原理:
GTID 备份数据,然后复制到从库,从库启动后会自动判断到那些GTID被执行过,可以自动获取下一个GTID. 需要结合--set-gtid-purged。 默认自动开启。
总结
数据安全非常重要,所以数据库保证数据的安全是必须要实现的,这也是为什么会出现主从复制的原因,备份恢复操作比较麻烦,而且物理损坏修复也比较麻烦。主从演变到现在已经比较靠谱和完善了。
《MySQL数据库》MySQL主从复制搭建与原理的更多相关文章
- mysql 5.7 主从复制搭建及原理
1. 主从复制搭建 1.1 环境准备 OS: Ubuntu 18.04 master: 192.168.0.3 slave: 192.168.0.6 1.2 安装依赖包 # Ubuntu apt-ge ...
- 一、初识MySQL数据库 二、搭建MySQL数据库(重点) 三、使用MySQL数据库 四、认识MySQL数据库的数据类型 五、操作MySQL数据库的数据(重点)
一.初识MySQL数据库 ###<1>数据库概述 1. 数据库 长期存储在计算机内的,由组织的可共享的数据集合 存储数据的仓库 文件 ...
- windows系统下使用mycat实现mysql数据库的主从复制,从而实现负载均衡
在之前有记录过在一台系统中安装多台数据库,同时实现主从复制,但是那个主从复制只是一个基于dosc命令的,再实际的开发中我们不会去直接连接数据库,一般情况下我们也是通过间接的采用一些中间件去连接,本来是 ...
- 第二百八十四节,MySQL数据库-MySQL触发器
MySQL数据库-MySQL触发器 对某个表进行[增/删/改]操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行[增/删/改]前后的行为. 1.创建触发器基本语法 ...
- 第二百八十六节,MySQL数据库-MySQL事务操作(回滚)
MySQL数据库-MySQL事务操作(回滚) 事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性. 举例:有这样一张表 从表里可以看出张 ...
- 第二百八十五节,MySQL数据库-MySQL函数
MySQL数据库-MySQL函数 1.MySQL内置函数 SELECT执行函数,后面跟要执行的函数 CHAR_LENGTH(str)函数:返回字符串的字符长度 -- CHAR_LENGTH(str)函 ...
- 第二百八十三节,MySQL数据库-MySQL存储过程
MySQL数据库-MySQL存储过程 MySQL存储过程,也就是有点像MySQL函数,但是他与MySQL函数是有区别的,后面会讲到函数,所以注意区分 注意:函数与存储过程的区别 存储过程是:CREAT ...
- 第二百八十二节,MySQL数据库-MySQL视图
MySQL数据库-MySQL视图 1.视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 2.也 ...
- MySQL数据库”mysql SQL Error:1146,SQLState:42S02 “解决方法
项目在开发的时候在Mac平台下开发的,开发完了之后在LINUX环境上部署好之后,运行时MySQL数据库报错,提示为某个表不存在之类的错误信息,后来修改了MySQL的配置文件将大小写敏感去掉,问题解决. ...
- 【Data Cluster】真机环境下MySQL数据库集群搭建
真机环境下MySQL-Cluster搭建文档 摘要:本年伊始阶段,由于实验室对不同数据库性能测试需求,才出现MySQL集群搭建.购置主机,交换机,双绞线等一系列准备工作就绪,也就开始集群搭建.起初笔 ...
随机推荐
- ZROI 提高十连测 Day1
第一天的提高模拟测 考前特意睡了20min 还是歇菜了,果然自己菜是真实的. 题目质量海星 但是我都不会这是真的...题目由于是花钱买的这里就不放了 LINK:problem 熟悉我的人应该都知道账号 ...
- navicat for mysql 连接报错1251的解决方法
这是因为比较新的mysql版本采用新的保密方式,若要用navicat连接需要改使用到的用户的密码方式:use mysql:ALTER USER 'root'@'localhost' IDENTIFIE ...
- Linux的VMWare下Centos7的三种网络配置过程(网络二)
Linux之VMWare下Centos7的三种网络配置过程 环境:虚拟软件:VMWare 14.0客户机:windows 10虚拟机:centos 7 VMware三种网络连接方式 Bridge(桥接 ...
- 028_go语言中的超时处理
代码演示 package main import "fmt" import "time" func main() { c1 := make(chan strin ...
- 解决使用rollup构建ECharts过程中遇到的问题
1.ECharts官方文档 参考:自定义构建 ECharts - ECharts Documentation 2.解决问题 改动一: // line.js // 引入 echarts 主模块. // ...
- IOS - ACL (访问控制列表)
ACL 介绍 ACL 是一款 IOS 软件工具,而不是某种协议.从名字上来看,ACL 的主要功能是控制对网络资源的访问.事实上这是 ACL 最早的用途.现在 ACL 除了能够限制访问外,更多时候,我们 ...
- Python中 *args 和 **kwargs 的含义?
答:在python中,*args和**kwargs通常使用在函数定义里.*args 和 **kwargs 都允许你给函数传不定数量的参数,即使在定义函数的时候不知道调用者会传递几个参数.ps: *ar ...
- Java—接口
接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”. 接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义与实 ...
- 《闲扯Redis十》Redis 跳跃表的结构实现
一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...
- 02树莓派4B—C语言编程——PWM
01树莓派直接输出PWM波 —— 硬件PWM程序 (推荐使用) #include <stdio.h> #include <wiringPi.h> #include <s ...