mysql不停机添加从节点

简介

今天在创建数据库备份任务的时候,猛然发现从库和主库已经主从不一致了,报错

Slave failed to initialize relay log info structure from the repository, Error_code: 1872

应该是有一次机房断电造成的,只要主库没问题,一切都是ok的,但是生产的主库是不能停机的,也就是说不能锁库去添加一个从库。

下面我来说下如何不停主库去添加一个slave

步骤

  • 备份主库
  • 还原数据
  • 创建新的主从关系

环境

  • docker-mysql:8.0
  • centos:7
  • XtraBackup:8.0-9

使用mysqldump添加从节点

备份有两种备份的方式,一种是使用mysqldump去备份,但是这种方法我不推荐,因为过程可能会比较坎坷,我简单说下我遇到的坑

首先使用mysqldump备份数据库

1
2
3
4
5
6
7
/usr/local/mysql/bin/mysqldump \
-u root --password='passwd' \
-h 8.8.8.8 \
--all-databases \
--single-transaction \
--add-drop-database \
--master-data=2 -R -E > all-bak.sql

解释下参数

--all-databases 表示备份所有的数据库
--add-drop-database 表示在任何创建库语句前,附加DROP DATABASE 语句,这样就算从库原来有数据也没有任何关系
--single-transaction 是用来表示会话的一致性,为的是在dump的时候不会有新的提交数据
--master-data=2 为了记录binlog的位置
-R 表示导出存储过程以及自定义函数
-E 表示导出事件

备份之后去从库恢复报错

ERROR 3552 (HY000) at line 3295: Access to system schema 'mysql' is rejected.

因为我不想解决这个问题,所以直接跳过采用XtraBackup备份的方式

使用XtraBackup备份

第二种方式是使用XtraBackup去备份,这种方式比较好,因为是直接备份是数据库文件,相比于mysqldump少了执行sql的过程,更加的方便

因为我的数据库运行在容器里面,所以我要在容器里面安装XtraBackup,首先下载XtraBackup

wget https://www.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.9/binary/debian/stretch/x86_64/Percona-XtraBackup-8.0-9-rc5cbbe4-stretch-x86_64-bundle.tar

因为国内的网络环境问题,所以你懂的,我是下载到我在国外的服务器,然后在国外服务器上开一个http服务下载到本地的,而且要注意,如果你不想等很多下载的时间,你可以参考我这篇博客

如何超级快的从你的vps下载一个很大的文件(served加axel使用) /)

唉,中国运维很大一部分的生命就是因为网络的缘故被浪费掉的

之后拷贝到容器内部安装即可

docker cp 文件名 mysql:/tmp

之后执行备份的命令

1
2
3
4
5
xtrabackup --defaults-file=/etc/mysql/my.cnf \
--backup --target-dir=./bak \
--datadir=/var/lib/mysql/ \
--user=root --host=8.8.8.8 \
--password='password'

解释下参数

--defaults-file mysql的配置文件
--backup 表示执行备份操作
--target-dir 备份文件的位置
--datadir 你mysql数据目录

备份完成之后,会显示

1
2
3
4
5
6
7
8
9
10
11
12

200312 17:10:48 All tables unlocked
200312 17:10:48 [00] Copying ib_buffer_pool to /etc/mysql/backup/bak/ib_buffer_pool
200312 17:10:48 [00] ...done
200312 17:10:48 Backup created in directory '/etc/mysql/backup/bak/'
MySQL binlog position: filename 'mysql-bin.000009', position '155'
200312 17:10:48 [00] Writing /etc/mysql/backup/bak/backup-my.cnf
200312 17:10:48 [00] ...done
200312 17:10:48 [00] Writing /etc/mysql/backup/bak/xtrabackup_info
200312 17:10:48 [00] ...done
xtrabackup: Transaction log of lsn (1023609313) to (1023610198) was copied.
200312 17:10:49 completed OK!

记住上面的

MySQL binlog position: filename 'mysql-bin.000009', position '155'

这个很重要

之后把数据移到slave机器执行还原数据

还原数据

还原之前prepare一下

xtrabackup --prepare --target-dir=./bak

prepare的作用就是验证数据的一致性

之后就是恢复数据

1
2
3
xtrabackup \
--defaults-file=/data/mysql/etc/my.cnf \
--copy-back --target-dir=./bak --datadir=/data/mysql/data

参数的含义都差不多,我就不解释了,因为我使用的是docker搭建的,所以只要把
datadir挂载到mysql容器的数据目录就可以了,最后启动mysql的容器

重新创建主从关系

恢复之后都没有问题之后,到slave机器执行

1
2
3
4
5
6
CHANGE master to
MASTER_HOST="8.8.8.8",
MASTER_USER="root",
MASTER_PASSWORD="password",
MASTER_LOG_FILE="mysql-bin.000009",
MASTER_LOG_POS=155

之后启动slave就好了,当看到Slave_SQL_Running为Yes的时候,应该就不会有很大的问题了

欢迎关注Bboysoul的博客www.bboy.app

Have Fun

欢迎关注我的其它发布渠道