MySQL 5.7 集群(dual master)方案

背景

只有用真实的环境实践 才能知道这个这个机制是怎么样的。

MySQL 集群可以部署为 master slave,master master,master slave slave,等等,这需要依据你的场景来选择。不同的组合可能会带来不同的问题。

集群之间复制 主要依靠 mysql-bin 来实现,这需要你来指定具体的位置,另外值得注意的是,如果你是扩展现有 Stand alone 节点的话,你需要锁库来完成整个集群流程。具体方案在最下面会讲到。

环境

MySQL 5.7.28 on Docker

配置

这里就不从头开始讲了 你需要在docker上启动两个MySQL 并且正常运行。

  1. 编辑配置文件 (需要在多个节点上配置)
# server-id 可以为任意自然数,但必须保证两台mysql主机不重复
server-id=1

# log_bin 启动 mysql 二进制日志,如果没有配置这个将无法远程链接
log-bin=mysql-bin

# auto_increment_increment 步进值auto_imcrement。一般有n台主MySQL就填n
auto_increment_increment=2

# auto_increment_offset   设定数据库中自动增长的起点,两台mysql的起点必须不同,这样才能避免两台服务器同步时出现主键冲突
auto_increment_offset=1

# replicate-ignore-db 指定不同步的数据库,如果有多个数据库不需要同步可以多个分别声明
replicate-ignore-db=mysql
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema

# character_set_server 指定默认字符集
character_set_server=utf8mb4

# log-bin-trust-function-creators 在默认情况下 mysql 会阻止主从同步的数据库 function 的创建,这会导致我们在导入 sql 文件时如果有创建 function 或者使用 function 的语句将会报错。
log-bin-trust-function-creators=1

添加同步账户

mysql> grant replication slave on *.* to 'repl'@'your_salve_ip' identified by 'dontdropanything';

设定同步信息

  1. 先分别在节点上查看 master 信息
show master status;
  1. 会得到类似于下面的信息
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |  1608028 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
  1. 分别在节点上设定

注意 master_log_file 对应 上面的 File,master_log_pos 对应上面的 Position

change master to master_host='your_salve_ip',\
master_port=3306,\
master_user='repl',\
master_password='dontdropanything',\
master_log_file='mysql-bin.000001',\
master_log_pos=1608028;
  1. 启动同步
start salve;
  1. 查看 slave 节点状态
show slave status\G;

比较重要的状态是下面两个 都为 Yes 即可认定是成功的。
如果有一项为 No,可以通过 Slave_IO_State, Last_Error, Last_SQL_Error 字段信息来看问题。

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

如果你的操作有误

# 1. 停止同步
stop salve;

# 2. 清除 第三步设定的信息
reset slave all;

或者

直接修改不对的值

change master to 仅会生效设定的部分。

change master to master_log_pos=1608028;

如果原有的数据库有数据

如果原有的数据库有数据 并且想要同步他们,这需要做一些额外的操作。

因为 集群复制只会对新数据同步 而老数据是不管的。但手动同步需要控制原节点不能有写入 否则会破坏一致性。

流程概要

  1. Stand alone 节点设置为 readonly
  2. 导出 Stand alone 节点 数据库
  3. 新节点 导入 Stand alone 原有的数据库
  4. 配置同步信息
  5. 开始同步
  6. Stand alone 节点 unlock

一些关键命令

# 锁定整个数据库
FLUSH TABLE WITH READ LOCK;

# 解锁
UNLOCK TABLES;

TIPS

  1. 重要数据先备份!
  2. 重要数据先备份!
  3. 重要数据先备份!
  4. docker 上的 MySQL 5.7 镜像不能在容器内部通过 service mysql restart 来重启,必须使用 docker 命令来 restart container。
  5. 请注意你的 MySQL 版本,不同版本之间部分命令不兼容。