上个文章,我们成功搭建了某个库的主从同步了,但是在正常的使用中,可能多少会有问题,遇到这些问题后需要如何快速恢复呢,下面就讲一些我自己遇到和客户这里遇到的一些问题,供大佬们参考
一、主从复制简介
1、为什么要用主从复制
主从复制是依靠binlog日志来实现的,binlog日志会记录对于数据的变化的情况,以最小单元事件(events)来记录的,作用我理解是大体分为两类吧,一个是用于降低主库压力(对外提供读能力)、一个是用来备份主库的数据、实现高可用等功能
简单来说,MariaDB(MySQL)的复制机制是这样的:
在Master端所有数据库的变更(包括DML和DDL)都会以 Binlog Event 的方式写入Binlog中。Slave会连上Master然后读取 Binlog Event,再重放这些操作到自身的数据中。一个实例可以既是Master同时又是Slave,做成双向复制。也可以一级一级串联,做成级联复制,Binlog Event 中包含的 server_id 可以识别产生 Event 的实例,避免重复执行。
Slave会保存最后一次收到和应用的Binlog的位置,因此Slave重连Master时可以从中断的位置继续开始复制。也可以在暂停Slave后,将其整体拷贝到新的位置,然后作为一个新的Slave继续复制。
全局事务ID(Global transaction ID,GTID)为每个 Event Group (就是一系列 Event 组成的一个原子单元,要么一起提交要么都无法提交)引入了一个标识,因此 GTID 是标识“事务”的最佳方式(尽管 Event 里面还包含一些非事务的DML语句和DDL,它们可以作为一个单独的 Event Group )。每当一个 Event Group 从Master复制到Slave时,它的 GTID 也通过 GTID Event 被传到Slave。因为每个 GTID 在整个复制拓扑结构中都是一个唯一标志,所以这使得在不同的实例之间识别相同的 Binlog Events 非常简单,然而在有 GTID 之前,想做到这点是很困难的。MariaDB 从 10.0.2 开始提供 GTID 支持,但是 MariaDB 的 GTID 与 MySQL 的 GTID 在实现原理上并不相同,因为 MariaDB 支持像多源复制啊、多主复制等官方暂时还没考虑的复制模型。
2、主从状态常用查询命令已经主从状态中各个参数的含义
#查看同步状态
show slave statusG;
Slave_IO_State 表示io线程当前的状态,这个博主小哥写的很详细,参考地址:http://zhengmingjing.blog.51cto.com/1587142/1910565
我这里由于直接把从库重启了,所以直接查看slave状态如下
#Slave_IO_State: Waiting for master to send event
这个状态代表已经成功连接到master,正等待二进制日志时间的到达。如果master 空闲,这个状态会持续很长时间。如果等待的时间超过了slave_net_timeout(单位是秒)的值,会出现连接超时。在这种状态下,I/O线程会人为连接失败,并开始尝试重连
#master 信息
Master_Host: 172.xx.48.6
Master_User: jc-all
Master_Port: 3306
#连接中断后,重新尝试连接的时间间隔,默认值是60秒
Connect_Retry: 60
#master 二进制日志信息
Master_Log_File: binlog.000001(当前I/O线程正在读取的主服务器二进制日志文件的名称)
Read_Master_Log_Pos: 31098793(当前I/O线程正在读取的二进制日志的位点)
#slave relay_log 信息
Relay_Log_File: relay.000002(当前slave SQL线程正在读取并执行的relay log的文件名)
Relay_Log_Pos: 634(当前slave SQL线程正在读取并执行的relay log文件中的位置;Relay_Log_File下的Relay_Log_Pos其实一一对应着Relay_Master_Log_File的Exec_Master_Log_Pos)
Relay_Master_Log_File: binlog.000001(当前slave SQL线程读取并执行的relay log的文件中多数近期事件,对应的主服务器二进制日志文件的名称。(说白点就是我SQL线程从relay日志中读取的正在执行的sql语句,对应主库的sql语句记录在主库的哪个binlog日志中))
#主从同步是否成功,最明显的两个点,两个都是yes的情况下表示 正常同步
Slave_IO_Running: Yes
Slave_SQL_Running: No
#同步的库
Replicate_Do_DB: 白名单
Replicate_Ignore_DB:黑名单
#同步的表(库.表)
Replicate_Do_Table:
Replicate_Ignore_Table:
#模糊匹配
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
#重点:同步出现的报错信息
Last_Errno: 1146
Last_Error:
二、平常遇到的一些问题及相关的处理方法
1、因为我们是和主实例做的主从,如果说主实例出现异常,比如故障切换、升级配置切换等操作,是否会影响我们自建主从呢,如果影响了,如何恢复呢。
1.1、模拟主库切换
我直接升级配置来达到切换的目的,配置完成切换后,同步状态报错如下
stop slave;
如果直接 start slave 还是依然会报错,此时如果主库有数据再更新,这里会导致从库无法及时更新,这里我们需要去主库拿从库的gtid 位点,然后再跑起来
比如我主库删除了一个库
从库没有更新
此时去拿主库上面的 gtid值
show variables like '%gtid%';
然后去更新从库的位点
再去看从库的数据情况
刚刚主库删除的 jc 库没了
验证数据同步,正常
1.2 云mariadb 重启对自建主从同步不影响
2、change master 报错 需要super 权限
这里是由于我们在登陆从库的时候,用的非root账户,所以在起主从的时候会报错如上,只要我们更换为root账户重新知悉此命令即可
3、报错某个表不存在:mysql.gtid_slave_pos: Table 'mysql.gtid_slave_pos' doesn't exist
这个报错的背景是我从库的mysql库的user表被我搞的有些问题了,然后我去其他自建的库复制了一个mysql库到我这个里面来,但是其他库没有gtid_slave_pos表,然后我又去云上的mariadb 实例中 专门导的这个表到本地
之后再去获取云实例主库吧gtid_slave_pos 位点,在重新把主从跑起来了
这里是平常自己遇到的一些问题和想到的处理方法,如果有问题或者大佬们有更好的办法, 欢迎指正批评(*^_^*)
后面有遇到其他问题,在更新