mariadb自建从库问题处理

2020-07-19 16:47:19 浏览数 (2)

上个文章,我们成功搭建了某个库的主从同步了,但是在正常的使用中,可能多少会有问题,遇到这些问题后需要如何快速恢复呢,下面就讲一些我自己遇到和客户这里遇到的一些问题,供大佬们参考

一、主从复制简介

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 位点,在重新把主从跑起来了

这里是平常自己遇到的一些问题和想到的处理方法,如果有问题或者大佬们有更好的办法, 欢迎指正批评(*^_^*)

后面有遇到其他问题,在更新

0 人点赞