工具

利用 Docker 快速实现 MySQL binlog 主从备份

2020-03-01  本文已影响0人  FesonX
Docker

Intro

主从备份是容灾的一种手段, 模拟主从备份可以有下面几种方式:

binlog 是MySQL数据库的二进制日志,用于记录用户对数据库操作的SQL语句(不包括 SELECT),可以在配置文件开启,也可以在 MySQL 客户端开启. 可以在客户端键入show plugins; 查看 binlog 是否已安装开启( Active )

+----------------------------+----------+--------------------+---------+---------+
| Name                       | Status   | Type               | Library | License |
+----------------------------+----------+--------------------+---------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL    | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL    | GPL     |

环境准备

0.1 测试环境

必须安装有 dockerdocker-compose 用于构建容器环境, 本测试在 Ubuntu 16.04 及下列版本下进行, 使用其他版本可能会有使用差异.

docker-compose 1.25.4
docker 19.03.6

有关安装的细节, 请搜索相关关键词, 或者直接根据 Docker 官方文档 进行安装

0.2 Docker 加速

由于众所周知的原因, 拉取镜像时可能会很慢, 推荐设置国内的镜像源进行加速
Ubuntu/Centos/Debian 下修改或创建此文件 /etc/docker/daemon.json
示例文件内容如下, 可以自由添加镜像源. 镜像源有可能会宕机, 镜像源测试请参阅docker-registry-cn-mirror-test

{
    "registry-mirrors":[
        "https://dockerhub.azk8s.cn",
        "https://docker.mirrors.ustc.edu.cn",
        "https://reg-mirror.qiniu.com"
    ]
  }

一. Docker 文件准备

1.1 文件目录

如只准备测试一主一从, 那么移除 slave02 目录, 添加多个从服务器则相应增加文件夹.

├── docker-compose.yml
├── master
│   ├── Dockerfile
│   └── my.cnf
├── slave01
│   ├── Dockerfile
│   └── my.cnf
└── slave02
    ├── Dockerfile
    └── my.cnf

1.2 docker-compose 文件及解释

version: '2' 
services:
  mysql-master: 
    build:
      context: ./                      # 声明构建的文件夹
      dockerfile: master/Dockerfile    # 声明 Docker 文件目录
    environment: # 环境变量, 支持数组或列表方式
      - "MYSQL_ROOT_PASSWORD=root"
      - "MYSQL_DATABASE=db0" # 初始创建的数据库
    links:
      - mysql-slave01
      - mysql-slave02
    ports:
      - "33065:3306" 
    restart: always
    hostname: mysql-master

  mysql-slave01:
    build:
      context: ./
      dockerfile: slave/Dockerfile
    environment:
      - "MYSQL_ROOT_PASSWORD=6954D5F0"
      - "MYSQL_DATABASE=db0"
    ports:
      - "33066:3306"
    restart: always
    hostname: mysql-slave01

  mysql-slave02:
    build:
      context: ./
      dockerfile: slave02/Dockerfile
    environment:
      - "MYSQL_ROOT_PASSWORD=6954D5F0"
      - "MYSQL_DATABASE=db0"
    ports:
      - "33067:3306"
    restart: always
    hostname: mysql-slave02

1.3 Dockerfile 文件及解释

FROM mysql:5.7.17
COPY ./master/my.cnf /etc/mysql/my.cnf

二. MySQL 配置文件准备

2.1 Master 节点配置

# master/my.cnf
[mysqld]
## 设置server_id,注意要唯一
server_id=100  
## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql  
## 开启二进制日志功能,可以随便取,最好有含义
log-bin=replicas-mysql-bin  
## 为每个session分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M  
## 主从复制的格式(mixed,statement,row,默认格式是statement)
binlog_format=mixed  
## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。
expire_logs_days=7  
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

2.2 Slave 节点配置

Slave 节点的配置与 Master 相似, 但每个节点的 server_id 必须不同, 此外增加了 relay_log 中继日志的配置以及只读的设置

[mysqld]
## 设置server_id,注意要唯一
server_id=101 
# ... 省略配置
## relay_log配置中继日志
relay_log=replicas-mysql-relay-bin  
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1  
## 防止改变数据(除了特殊的线程)
read_only=1 

三. 构建容器并运行

进入有 docker-compose.yml 的目录, 执行以下命令
该命令十分强大,它将尝试自动完成包括构建镜像,(重新)创建服务,启动服务,并关联服务相关容器的一系列操作, -d 表示后台运行镜像.

docker-compose up -d

之后执行docker ps 查看正在运行的镜像, 如果是一主一从, 可以看到至少两个正在运行的镜像

$ docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                     NAMES
ef799b7d8cf8        mstest_mysql-master   "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        0.0.0.0:33065->3306/tcp   mstest_mysql-master_1
9d7ea93b7a85        mstest_mysql-slave    "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        0.0.0.0:33066->3306/tcp   mstest_mysql-slave_1

键入 docker exec -it [name/id] /bin/bash 进入容器, 可以是容器名称也可以是容器 id, 如下方示例:

docker exec -it mysql-master_1 /bin/bash

四. 配置主从

可以直接进入容器再进入 mysql 配置, 也可以不进入, 直接在终端键入下方命令, port 就是 docker-compose.xml 设置的端口号, 例如前面 master33065

mysql -uroot -p -P[port] -h127.0.0.1

4.1 获取主节点状态

键入 show master status; 记住当前 File 的名称和 Position, 这是从节点进行 binlog 复制找点用的.

mysql> show master status
    -> ;
+---------------------------+----------+--------------+------------------+-------------------+
| File                      | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------------------+----------+--------------+------------------+-------------------+
| replicas-mysql-bin.000003 |      154 |              | mysql            |                   |
+---------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec

4.2 开启从节点复制

这里设置复制主节点的相关信息, 在前面文件用的是 root 密码,因此这里也是 root 用户, 将MASTER_LOG_FILEMASTER_LOG_POS 填上相应信息

CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='root', MASTER_PASSWORD='root', MASTER_LOG_FILE='replicas-mysql-bin.000003', MASTER_LOG_POS=154;

接着启动复制.

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
            ...
            Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
            ...

同样地, 如果有多个 Slave 节点, 就这一步多做几次.

4.3 验证是否成功

回到 Master 节点, 创建一个数据库 或者 往已经创建好的 db0 写入数据,

mysql> create database db1;

回到 Slave 节点, 查看两边是否同步.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db0                |
| db1                |

五. 后话——另一种主从复制 GTID

GTID 自 MySQL 5.6.MySQL 5.6.5 便引入了,中文叫全局事务 ID(Global Transaction ID)

在本文的基于二进制日志复制中,从库需要告知主库要从哪个偏移量(就是 Log File 的 Position)进行增量同步,如果指定错误会造成数据的遗漏,从而造成数据的不一致。

但有了 GTID,发生主备切换时,MySQL 的其它从库可以自动在新主库上找到正确的复制位置,这大大简化了复杂复制拓扑下集群的维护,也减少了人为设置复制位置发生误操作的风险。另外,基于 GTID 的复制还可以忽略已经执行过的事务

参考

  1. Docker Compose搭建MySQL主从复制集群
  2. GTID Concept - MySQL
  3. Docker 从入门到实践 - Compose 命令说明

公众号:程序员的碎碎念
Github:github.com/FesonX

上一篇 下一篇

猜你喜欢

热点阅读