简单的做一个标准模式复写的示例。

为了方便建立多个 MariaDB 的实例,使用 MariaDB docker 镜像做 replication。

会创建 3 个安装 MariaDB 的 docker 容器,分别命名为 mariadb1(设为 Master)、mariadb2 和 mariadb3(Slave1 和 Slave2)。端口映射依次 3307、3308、3309。

简单的 replication 前置准备

1、MariaDB docker 准备与配置

快速安装 docker:

sudo sh -c "$(curl -fsSL https://get.docker.com)"
sudo usermod -aG docker $USER

第一行用 docker 官方提供的 script 快速安装。
第二行将现有的使用者加入 docker 群组,否则会没有权限操作 docker 命令。
记得注销账号重登,以获取 docker 操作权限。

拉取 MariaDB 镜像:

docker pull mariadb/server:10.4

创建 3 个用于安装 mariadb 的容器,命名为 mariadb1、mariadb2、mariadb3:

sudo docker run -it -p 3307:3306 --name mariadb1 -e MYSQL_ROOT_PASSWORD=root -d mariadb/server:10.4

创建3个mariadb容器

2、基准文件的准备

拷贝一份同样的数据库结构文件到 3 个容器中,并导入各自数据库

准备一份 sql script。

我这份示例是一个名为 test_replication 的数据库,以下有一个名为 call_record 的表,结构如下:

CREATE TABLE `call_record` (
  `start_time` char(19) DEFAULT NULL,
  `dial_out_number` varchar(12) DEFAULT NULL,
  `dial_out_name` varchar(20) DEFAULT NULL,
  `dial_out_department` varchar(20) DEFAULT NULL,
  `call_duration` char(19) DEFAULT NULL,
  `uuid` varchar(36) NOT NULL,
  `create_time` char(19) NOT NULL,
  `create_user` varchar(20) NOT NULL,
  `update_time` char(19) DEFAULT NULL,
  `update_user` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

同时插入了 10w 条测试数据。

将示例 sql 脚本,复制到 3 个容器中

sudo docker cp /home/sanotsu/Dump20200303.sql mariadb1:/home/Dump20200303.sql

示例sql脚本复制到3个容器

为了方面修改配置文件,给 3 个容器中安装 vim。

sudo docker exec -it mariadb1  bash
apt update
apt install vim

docker容器中安装vim

导入数据库

就在刚刚的容器的交互界面,继续执行:

mysql -uroot -p < /home/Dump20200303.sql
mysql_upgrade -uroot -p

root 账号的密码就是之前创建容器时指定的 MYSQL_ROOT_PASSWORD 参数的值。
mysql_upgrade 用于更新表格到最新的版本。

容器中mariadb导入数据库

3、Master-Slaves 设置(主从服务器设定)

配置 3 个容器中的 MariaDB server-id 分别为 1、2、3,log-basename 分别为 master01、slave01、slave02,并建立 relication 用账号。

修改配置文件:

使用 vim 打开容器中 mariadb 的配置文件,在容器的终端运行

vim /etc/mysql/my.cnf

修改或添加以下参数:

server-id = 1
log_bin = /var/log/mysql/mariadb-bin
log_basename = master01
binlog_format=mixed

示例的设定是,mariadb1(master)容器如下:

mariadb1的相关配置

mariadb2(slave1)容器如下:

mariadb2的相关配置

mariadb3(slave2)容器如下:

mariadb3的相关配置

建立 replication 用账号:

在容器中,进入到 MariaDB 的命令窗口,创建一个用于备份的账号和赋予复制权限,记得要刷新权限。

CREATE USER 'reptest'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'reptest'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;

创建用于备份复制使用的账号

设定完权限后,重启 docker 容器来重启 MariaDB 。

重启docker容器使配置等生效

重启之后,查看下 master01 binarylog 状态,后续将 master01 作为 MASTER 主机,slave01 和 slave02 作为 SLAVE 主机。

mariadb1 会作为 master,查看状态如下

master状态

mariadb2 和 mariadb3 要作为 slave,需要在 mariadb 命令窗口 执行以下配置:

CHANGE MASTER TO
    MASTER_HOST='192.168.28.93',
    MASTER_USER='reptest',
    MASTER_PASSWORD='123456',
    MASTER_PORT=3307,
    MASTER_LOG_FILE='master01-bin.000001',
    MASTER_LOG_POS= 331,
    MASTER_CONNECT_RETRY=6;

注意配置的属性都要与 master 的状态一致。

配置slave

配置完之后在启动 slave,然后查看下 slave 状态:

START SLAVE;
SHOW SLAVE STATUS\G;

两台 slave 实例应该会现实如下

两台slave状态

到这里,简单的 master-slave 的设定就完成了,可以测试一下。

简单的 replication 测试示例

1、master 的修改是否会同步到 slave 去

先查看目前 3 个 MariaDB 的测试数据,可见 master 和两个 slave 在 test_replication.call_record 测试数据都是 10w 条。

查看测试数据

对 MASTER 进行删除操作:

delete from test_replication.call_record limit ;

查看测试数据

注意:如果想马上看到级联更新的效果,建议对一条数据进行修改删除插入的操作。如果如示例一样进行了 5w 条的删除,可能需要等待一段时间才能完成同步到 Slaves。

一般情况下,同步都是实时的,如果上述的操作是删除 1 条数据或者修改 1 条数据可以更加清晰地看到。(没有截图,有实际删除 1 条看效果,目前 3 个表中数据还有 49999 条)

但是也有可能需求,master 更新之后,要延迟一点时间,再同步到 slave。

只需简单设定如下:

在需要被延迟更新的 SLAVE 中,设定延迟时间

STOP SLAVE;
CHANGE MASTER TO master_delay= 60;
START SLAVE;

再次测试结果(3 个表分表有 49999 条数据)
选取 SLAVE02,设定 60s 延迟更新:

salve2设定60s更新延迟

查看两个 slave 的状态可见 SQL_Delay 的数值变化:

show slave status\G;

查看更新延迟设定

在 master 表删除 1 条数据,从下图可以看出,slave01 是很快就同步了,二 slave02 是延迟时间到达之前,是没有更新的。

查看更新延迟设定效果

2、SLAVE 取代 MASTER

在 master 主机因为一些情况不能继续使用的时候,可以快速地升级某一台 SLAVE 机器替换 master,避免相关业务中断。

基本步骤如下:

1> 停止 master 写入

设置 mater 读锁定

FLUSH TABLES WITH READ LOCK ;

检查 master、slave 数据是否同步完成

master:

SHOW MASTER STATUS;

slave:

SHOW SLAVE STATUS\G;

停止master写入
(注意红框中参数)

2> 设置 slave02 主机为 MASTER

STOP ALL SLAVES;
RESET SLAVE ALL;
SHOW  MASTER STATUS;
SELECT @@global.gtid_binlog_pos;
SET @@global.read_only=0;

设置slave02主机为MASTER

3 更改 slave01 主机连接配置

之前 slave01 连接的主服务器是 master01,现在要为 slave02。在原 salve01 中执行:

STOP SLAVE;
RESET SLAVE;
CHANGE MASTER TO
    MASTER_HOST='192.168.28.93',
    MASTER_USER='reptest',
    MASTER_PASSWORD='123456',
    MASTER_PORT=3309,
    MASTER_LOG_FILE='slave02-bin.000002',
    MASTER_LOG_POS= 331,
    MASTER_CONNECT_RETRY=6;
START SLAVE;
SHOW SLAVE STATUS\G;

更改slave01主机连接配置

4 更改原 master 主机配置,修改为 slave 主机

原来的主服务器,现在是从服务器了,修改主服务器连接为原 slave02。

UNLOCK TABLES;
SET @@global.read_only=1;
STOP ALL SLAVES;
RESET MASTER;
RESET SLAVE ALL;
CHANGE MASTER TO
    MASTER_HOST='192.168.28.93',
    MASTER_USER='reptest',
    MASTER_PASSWORD='123456',
    MASTER_PORT=3309,
    MASTER_LOG_FILE='slave02-bin.000002',
    MASTER_LOG_POS= 330,
    MASTER_CONNECT_RETRY=6;
START SLAVE;
SHOW SLAVE STATUS\G;

更改原master主机配置,修改为slave2主机

完成之后,可以测试一下,在新 master 删除两条数据,然后可以看到新的两个 salve 中数据少了两条:

设置完成测试delete语句

当然,除了 delete 其它语句可以自行测试。

3、设定并行复制 Parallel Replication

可以在从属服务器上并行(同时)执行从主服务器复制的某些写入操作。

将 slave01 设置并行复制:

STOP SLAVE SQL_THREAD;
SET GLOBAL slave_parallel_threads = 4;
SET GLOBAL slave_parallel_max_queued=67108864;
START SLAVE SQL_THREAD;
SELECT @@slave_parallel_threads;
show processlist;

有看到进程列表中有 4 个 slave_worker

进程列表中有4个slave_worker

STOP SLAVE;
Change master to master_use_gtid =slave_pos;
START SLAVE;

使用 gitd 位置:

使用gitd位置

查看 slave 状态:

master 主机查看:

select @@gloabl.gtid_binlog_pos;

slave server 查看 slave 状态:

SHOW SLAVE STATUS\G;

使用gitd位置

设定 salve01 可并行复制完成。