前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用 Docker 快速实现 MySQL binlog 主从备份

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

原创
作者头像
FesonX
修改2020-03-02 07:52:44
1.4K0
修改2020-03-02 07:52:44
举报
文章被收录于专栏:程序员的碎碎念
Docker
Docker

Intro

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

  • 不差钱方式, 买几台主机测试, 这种方式也比较接近线上环境.
  • 通过创建几台虚拟机来模拟. 这种方式对本机性能要求相对较高. 相对不差钱可以选这种方式, 但安装几台虚拟机也不是一件效率高的事.
  • 在一台主机上创建多个数据库实例. 缺点是环境无法隔离, 需要额外加多一些配置
  • 通过 Docker-compose 直接创建多个数据库容器, 暴露端口访问即可.

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

代码语言:txt
复制
+----------------------------+----------+--------------------+---------+---------+
| 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 及下列版本下进行, 使用其他版本可能会有使用差异.

代码语言:txt
复制
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

代码语言:txt
复制
{
    "registry-mirrors":[
        "https://dockerhub.azk8s.cn",
        "https://docker.mirrors.ustc.edu.cn",
        "https://reg-mirror.qiniu.com"
    ],
    "debug": true,
    "experimental": false
  }

一. Docker 文件准备

1.1 文件目录

  • Dockerfile 是一个文本文件, 只需要 touch Dockerfile 创建即可.
  • docker-compose.yml 是用于运行多个 Docker 容器的配置文件, 使用 yaml 语言.

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

代码语言:txt
复制
├── docker-compose.yml
├── master
│   ├── Dockerfile
│   └── my.cnf
├── slave01
│   ├── Dockerfile
│   └── my.cnf
└── slave02
    ├── Dockerfile
    └── my.cnf

1.2 docker-compose 文件及解释

  • environment 在创建 MySQL 密码时, 测试用途用 root 没问题, 其他时候记得创建复杂密码, 至少可以使用 uuidgen 命令生成. 支持在创建时同时创建一个数据库, 创建多个或进行其他数据初始化, 建议依靠外部 SQL 文件.
  • links 这个不是推荐的配置方式, 不利于扩展, 但在此处我们只是用于测试. 可以自由添加你要的从服务器名称, 用于容器间的连接. 更推荐配置 networks
  • ports 冒号左边为暴露的端口, 右边为容器内部的端口号, 在不配置网络的情况下(此时默认为 127.0.0.1), 为了避免端口冲突, 必须使暴露的端口号不一致.
代码语言:txt
复制
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 镜像版本
  • COPY 将源文件复制到目标容器, 从服务器相应地创建 Dockerfile, 修改源文件位置. 也可以使用 ADD 这个更高级的复制命令, 但没必要.
代码语言:txt
复制
FROM mysql:5.7.17
COPY ./master/my.cnf /etc/mysql/my.cnf

二. MySQL 配置文件准备

2.1 Master 节点配置

代码语言:txt
复制
# 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 中继日志的配置以及只读的设置

代码语言:txt
复制
[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 表示后台运行镜像.

代码语言:txt
复制
docker-compose up -d

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

代码语言:txt
复制
$ 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, 如下方示例:

代码语言:txt
复制
docker exec -it mysql-master_1 /bin/bash

四. 配置主从

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

代码语言:txt
复制
mysql -uroot -p -P[port] -h127.0.0.1

4.1 获取主节点状态

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

代码语言:txt
复制
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 填上相应信息

代码语言:txt
复制
CHANGE MASTER TO MASTER_HOST='mysql-master', MASTER_USER='root', MASTER_PASSWORD='root', MASTER_LOG_FILE='replicas-mysql-bin.000003', MASTER_LOG_POS=154;

接着启动复制.

  • 键入start slave;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 节点, 就这一步多做几次.
  • 键入show slave status\G;查看是否启用成功, 关注Slave_IO_RunningSlave_SQL_Running 是否为 Yes

4.3 验证是否成功

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

代码语言:txt
复制
mysql> create database db1;

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

代码语言:txt
复制
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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Intro
  • 环境准备
    • 0.1 测试环境
      • 0.2 Docker 加速
      • 一. Docker 文件准备
        • 1.1 文件目录
          • 1.2 docker-compose 文件及解释
            • 1.3 Dockerfile 文件及解释
            • 二. MySQL 配置文件准备
              • 2.1 Master 节点配置
                • 2.2 Slave 节点配置
                • 三. 构建容器并运行
                • 四. 配置主从
                  • 4.1 获取主节点状态
                    • 4.2 开启从节点复制
                      • 4.3 验证是否成功
                      • 五. 后话——另一种主从复制 GTID
                      • 参考
                      相关产品与服务
                      容器服务
                      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档