企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持知识库和私有化部署方案 广告
### 文档目标 由于集群模式容易出现脑裂,恢复起来速度慢,难度大,不稳定,所以采用主从模式托管,容易恢复,更加稳定,同时建立成功主从模式以后,及时关机再重启也不会丢失主从状态。 通过本文档可以把mariadb或mysql从三节点集群模式切换为互为主从(成环) - 相对于集群的好处就是不会发生脑裂,故障恢复相对比较容易 - 坏处是如果挂掉一个节点时,剩下的两个节点就会变成主从模式,如果应用读写到从节点,那么数据就不同步了,需要等待恢复以后才能自动同步(所以我们要控制,挂掉一个节点后,让读写正确的切换到主节点上,可能要`keepalived`、`haproxy`的配合) [TOC] ### 0、检查是否是集群状态 ps: 监测当前是否是集群模式, 而且整个集群的所有服务器正常,如果不是 `ON` ,则停止操作,并联系管理员。 **在集群中所有服务器上执行** ``` sql MariaDB [(none)]> show global variables like '%wsrep_on%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | wsrep_on | ON | +---------------+-------+ 1 row in set (0.00 sec) ``` ### 1、停止所有写入 **在集群所有服务器上执行此步** **在集群所有服务器上执行此步** **在集群所有服务器上执行此步** 如果 `mariadb` 是通过 `hosts` 文件中的域名进行访问的,那么只需要编辑 `/etc/hosts` , 把 `mysql.cloud.local` 的域名解析删掉就可以停止所有读写,执行以下命令。 ``` BASH cp /etc/hosts /etc/hosts.bak sed -i "/mysql.cloud.local/d" /etc/hosts ``` 等待1分钟,依次进入集群中所有的 `mariadb` ,查看进程状态,确保没有额外的读写操作( `command` 列除了 `show processlist` 外没有多余的 `sleep` 和 `query` )。 ``` sql MariaDB [(none)]> show processlist; ``` ### 2、添加一个专门用来同步的用户 在节点1中的 `mariadb` 执行以下命令,如果全部输出ok,则继续。 ``` BASH /usr/local/mariadb/bin/mysql -A -e "GRANT replication slave ON *.* TO 'rep'@'%' IDENTIFIED BY '123456'; flush privileges;" mysql -A -urep -p123456 -e "select 'ok';" ``` 依次在第二台、第三台上重复此操作 ### 3、设置所有集群中的节点为只读。 进入节点1中的 `mariadb` 执行以下命令 ``` sql flush table with read lock; ``` 依次在第二台、第三台上顺序重复此操作 ### 4、停止集群 如果你使用的是`supervisor`守护`mariadb`,则 ``` BASH supervisorctl stop mariadb ``` 如果你使用的是`systemctl`托管,则 ``` BASH systemctl stop mariadb ``` 此时节点应该自动停止了,检查是否没有 `mariadb` 和 `mysql` 进程,如果有按需求判断是否停掉。 ``` BASH ps -ef | grep -E "mariadb|mysql" ``` 如果没有停止,则执行以下命令停止 ``` BASH /usr/local/mariadb/bin/mysqladmin shutdown ``` 依次在第二台、第三台上顺序重复[4、停止集群](#4停止集群)操作 ### 5、配置集群中每个节点为单点 执行下面命令改为单点(注意现在不启动),执行完检查是不是变成了 `wsrep_on=OFF` ``` BASH sed -i "s/^wsrep_on=.*/wsrep_on=OFF/g" /etc/my.cnf.d/server.cnf ``` 创建`relaylog`日志存储的目录,用来防止同步波动缓存同步信息。 ``` BASH mkdir /data/mariadb/relaylog chown -R mysql.mysql /data/mariadb/relaylog/ ``` 添加配置到 `[mysqld]` 配置节中(**注意现在不启动**),该配置表示我们只同步 `cloud` 库和其下的表,如果要同步更多的库和表可以用逗号分隔,追加。 如果想了解各个参数是什么含义可以到本小册 [relaylog](https://www.kancloud.cn/coding3min/playdb/1760394)里看 ``` BASH vim /etc/my.cnf.d/server.cnf # 添加内容如下 replicate-do-db=cloud #cloud是你想同步的库名,如果有多个请用逗号隔开 log-slave-updates replicate-wild-do-table=cloud.% #cloud是你想同步的库名,cloud.% 代表这个库下面的所有表,如果有多个请用逗号隔开 binlog-ignore-db=mysql # 忽略mysql库 max_relay_log_size = 0 relay_log=/data/mariadb/relaylog/relay-bin #请设置成正确的目录,上面刚刚创建的那个,最后的relay-bin是文件前缀 relay_log_purge = 1 relay_log_recovery = 1 sync_relay_log =0 sync_relay_log_info = 0 slave-skip-errors=1032,1062,1053,1146,2003 ``` 参考添加成功的图片 ![](https://coding3min.oss-accelerate.aliyuncs.com/2020/06/10/hKADxe1630.png) 依次在第二台、第三台上顺序重复[5、配置集群中每个节点为单点](#5配置集群中每个节点为单点)操作 ### 6、建立 `2同步3` 主从结构 假如是三节点主从,我们使用 `1同步2` , `2同步3` , `3同步1` 的方案,现在三台机器上的 `mariadb` 都是停止状态的。 `2同步3` ,所以 `3` 是主节点, `2` 是从节点。 逆序启动,并建立主从 **启动节点3** ``` BASH mkdir -p /var/run/mariadb; chown -R mysql:mysql /var/run/mariadb; /usr/local/mariadb/bin/mysqld_safe --datadir=/data/mariadb/data --pid-file=/var/run/mariadb/mariadb.pid > /dev/null 2>&1 & ``` **获取同步主节点的关键信息** 进入主【节点3】数据库中,执行命令 ``` sql unlock tables; show master status; ``` 得到同步主节点的关键信息 ![](https://coding3min.oss-accelerate.aliyuncs.com/2020/06/04/yilSlx1718.png) **启动节点2** ``` BASH mkdir -p /var/run/mariadb; chown -R mysql:mysql /var/run/mariadb; /usr/local/mariadb/bin/mysqld_safe --datadir=/data/mariadb/data --pid-file=/var/run/mariadb/mariadb.pid > /dev/null 2>&1 & ``` **建立主从结构** 进入从【节点2】中的数据库,指定主库信息,完成主从关系建立(注意:节点3的ip地址别忘记替换,使用 `eth0` 本地网卡的 `ip` ,不要使用浮动 `ip` ,也不要使用 `vip` ) ``` sql unlock tables; CHANGE MASTER TO MASTER_HOST='节点3的ip地址', MASTER_PORT=3306, MASTER_USER='rep', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000171', MASTER_LOG_POS=33105258; start slave; #开始同步 ``` 查看slave的状态,注意查看slave的进程状态,下面红色方框中圈起来的是两个 `Yes` 就表示状态正常了,注意等待主库复制的延迟秒数变为0 `Seconds_Behind_Master: 0` ``` sql show slave status \G ``` ![](https://coding3min.oss-accelerate.aliyuncs.com/2020/06/04/K12msW1736.png) ### 7、测试 `2同步3` 主从同步状态 **进入主节点3的数据库中,执行sql命令,创建一个测试表。** ``` sql use cloud; CREATE TABLE IF NOT EXISTS `testrep` ( `xx_id` INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY ( `xx_id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; show tables like "testrep"; ``` 结果如下则创建成功 ``` sql MariaDB [cloud]> show tables like "testrep"; +---------------------------+ | Tables_in_cloud (testrep) | +---------------------------+ | testrep | +---------------------------+ 1 row in set (0.00 sec) ``` 进入从节点2的数据库上,再执行查询命令查看同步状态,如果同上面结果一样则表示主从建立成功 ``` sql use cloud; show tables like "testrep"; ``` ### 8、建立 `1同步2` 主从结构 同上面类似,只不过是在 `1` 和 `2` 节点上执行而已。 要注意四个点!!! * 重复 `6` 和 `7` 两步,把【主节点3】和【从节点2】换成【主节点2】和【从节点1】 * 注意此时节点2已经启动了 **不要再重复启动节点** * `unlock tables;` 重复执行无所谓 * 步骤【 `7` 主从同步状态】不要再重复创建测试表了,主从建立成功后直接查看【从节点 `1` 】中是否有 `testrep` 表就可以了 ### 9、建立 `3同步1` 主从结构 同上面类似,只不过是在 `3` 和 `1` 节点上执行而已。 要注意四个点!!! * 重复 `1.6` 即可,把【主节点3】和【从节点2】换成【主节点1】和【从节点3】 * 注意此时所有节点都已经启动了 **不要再重复启动节点** **测试同步状态** 在节点1上执行命令 ``` sql MariaDB [(none)]> use cloud; Database changed MariaDB [cloud]> drop table testrep; Query OK, 0 rows affected (0.01 sec) MariaDB [cloud]> show tables like "testrep"; Empty set (0.00 sec) ``` 在节点3和节点2和执行以下命令,如果结果都是 `Empty set` ,表示三节点主从模式建立成功。 ``` sql MariaDB [cloud]> show tables like "testrep"; Empty set (0.00 sec) ``` ### 10、恢复域名解析 在全部服务器上执行 ``` BASH cp /etc/hosts.bak /etc/hosts ```