MySQL 主从搭建


前言

MySQL 主从搭建

操作系统:CentOS Linux release 7.9.2009 (Core)
操作系统镜像:CentOS-7-x86_64-Minimal-2009.iso
MySQL 版本:8.0.32

测试方式:Docker
Docker 版本:24.0.2 (Docker Engine - Community)
Docker 相关说明可以参考之前的文章


一、MySQL 主从是什么?

关于 MySQL 主从是什么,请参考这篇文章,感觉大神介绍的非常详尽!手动点赞!!!

二、通过 Docker 部署

# master 主节点
docker run -p 10001:3306 --name mysql_master --restart=always -e MYSQL_ROOT_PASSWORD='master' -d mysql:8.0.32 --server-id=100 --log_bin=master-bin --binlog_format=row --expire_logs_days=7 --max_binlog_size=100M --binlog_cache_size=4m --max_binlog_cache_size=512m --max_connections=1000
# slave 从节点
docker run -p 10002:3306 --name mysql_slave --restart=always -e MYSQL_ROOT_PASSWORD='slave' -d mysql:8.0.32 --server-id=101 --log_bin=slave-bin --binlog_format=row --expire_logs_days=7 --max_binlog_size=100M --binlog_cache_size=4m --max_binlog_cache_size=512m --max_connections=1000 --read_only=1

说明:

  • 仅为示例,生产环境不推荐使用 Docker 环境部署 MySQL。频繁重启容易导致数据异常
  • 搭建主从,需要开启 binlog,主从关系是通过 binlog 进行数据同步的
  • binlog 会比较大,所以需要设置保存时长,文件大小等相关参数(应根据实际情况进行配置)
  • 从节点开启了 read_only 属性,避免误写导致同步异常。一般情况下,从节点也只作为读节点使用
-- 查询 read_only 属性(对 root 不生效,root 可以进行写操作)
show global variables like '%read_only%';
-- 查询 super_read_only 属性
SELECT @@super_read_only;

三、配置主从关系

1、主节点

# 进入容器
docker exec -it mysql_master bash
# 连接
mysql -uroot -pmaster
-- 创建账户,提供给从节点进行数据同步
CREATE USER 'master_user_sync'@'%' IDENTIFIED WITH mysql_native_password BY 'sync';
FLUSH PRIVILEGES;
GRANT REPLICATION SLAVE ON *.* TO 'master_user_sync'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'master_user_sync'@'%';
GRANT BACKUP_ADMIN ON *.* TO 'master_user_sync'@'%';
FLUSH PRIVILEGES;

2、从节点

# 进入容器
docker exec -it mysql_slave bash
# 连接
mysql -uroot -pslave
-- 设置为只读(此处为错误示范!这样设置,服务重启将失效。应通过更改配置进行设置!)
-- mysql> set global read_only=1;
-- Query OK, 0 rows affected (0.00 sec)

-- 设置 Master
change master to master_host='master_ip',
    master_port=10001,
    master_user='master_user_sync',
    master_password='sync',
    master_log_file='master-bin.000001', -- 开始的文件
    master_log_pos=0; -- 开始的位置
-- 示例
mysql> change master to master_host='192.168.2.129',
    ->     master_port=10001,
    ->     master_user='master_user_sync',
    ->     master_password='sync',
    ->     master_log_file='master-bin.000003', -- CLONE 到的文件
    ->     master_log_pos=1478; -- CLONE 到的位置
Query OK, 0 rows affected, 9 warnings (0.05 sec)

-- 启动 Slave
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.17 sec)

-- 查看状态
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: master_ip
                  Master_User: master_user_sync
                  Master_Port: 10001
                Connect_Retry: 60
              Master_Log_File: master-bin.000003
          Read_Master_Log_Pos: 1478
               Relay_Log_File: 0e3d59342a9e-relay-bin.000002
                Relay_Log_Pos: 327
        Relay_Master_Log_File: master-bin.000003
             Slave_IO_Running: Yes -- 正常连接
            Slave_SQL_Running: Yes -- 正常运行
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1478
              Relay_Log_Space: 544
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 100
                  Master_UUID: 3f9a8fa7-2694-11ee-bf3c-0242ac110003
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
       Master_public_key_path:
        Get_master_public_key: 0
            Network_Namespace:
1 row in set, 1 warning (0.00 sec)

四、从库提供只读账号

-- 查询 read_only 属性(对 root 不生效,root 可以进行写操作)
show global variables like '%read_only%';

-- 创建账号
CREATE USER 'read_only_user_name'@'%' IDENTIFIED WITH mysql_native_password BY 'read_only_user_password';
-- 授予数据库 database_name1 权限
GRANT ALL PRIVILEGES ON database_name1.* TO 'read_only_user_name'@'%';
-- 授予数据库 database_name2 权限
GRANT ALL PRIVILEGES ON database_name2.* TO 'read_only_user_name'@'%';
-- 配置立即生效
FLUSH PRIVILEGES;
-- 查看账户权限
show grants for 'read_only_user_name';

五、实际情况分析&解决方案

实际情况:生产环境中,可能最开始并未建立主从关系,并且主节点已使用一段时间,已存在历史数据。
问题:binlog 会定期清理,历史数据不全。也可能主节点并未开启 binlog。无法直接建立主从管理。
推荐方案:先不要着急建立主从关系。从节点搭建好,需要先完成数据同步,推荐使用 CLONE 方法。然后再建立主从关系,并启用数据同步(CLONE 会返回位置信息)。

# CLONE 需要先启用插件,Docker 部署可以通过增加参数实现
# --plugin-load-add=mysql_clone.so
-- 通过此 SQL 可以确认是否启用 CLONE 插件
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone       | ACTIVE        |
+-------------+---------------+
1 row in set (0.00 sec)
-- CLONE 方法
mysql> set global clone_valid_donor_list="master_ip:10001";
mysql> CLONE INSTANCE FROM 'master_user_sync'@'master_ip':10001 IDENTIFIED BY 'sync';
-- CLONE 完成后,容器会自动重启

特别注意:CLONE 把账号、密码也同步了。因此从节点的 root 密码会变更为主节点的 root 密码。

-- 验证是否 CLONE 成功
mysql> select * from performance_schema.clone_status\G
*************************** 1. row ***************************
             ID: 1
            PID: 0
          STATE: Completed -- Completed 数据同步已完成
     BEGIN_TIME: 2023-07-20 00:31:12.592
       END_TIME: 2023-07-20 00:31:20.192
         SOURCE: master_ip:10001
    DESTINATION: LOCAL INSTANCE
       ERROR_NO: 0
  ERROR_MESSAGE:
    BINLOG_FILE: master-bin.000003 -- 从节点配置参数 master_log_file
BINLOG_POSITION: 1478 -- 从节点配置参数 master_log_pos
  GTID_EXECUTED:
1 row in set (0.01 sec)

六、常见问题处理

1、CLONE需要版本不同

问题:不同版本 CLONE 有异常,相同版本正常(都是 8.0.32 没有问题)。但是,可以正常建立主从关系。
解决方案:统一版本(不用 CLONE ,也建议主从统一版本)

示例:

master 8.0.32

slave 8.0.29

mysql> set global clone_valid_donor_list="master_ip:10001";
mysql> CLONE INSTANCE FROM 'master_user_sync'@'master_ip':10001 IDENTIFIED BY 'sync';
ERROR 3867 (HY000): Clone Donor collation: utf8mb4_nb_0900_ai_ci is unavailable in Recipient.

2、CLONE需要参数相同

问题:因为参数不同,导致 CLONE 之后服务启动报错,导致服务无法启动
解决方案:统一参数

示例:lower_case_table_names 一个节点配置为 0,另一个节点配置为 1

MySQL 启动异常信息如下

[ERROR] *** Different lower_case_table_names settings for server ('0') and data dictionary ('1')
[ERROR] *** Data Dictiongary initialization failed.s

总结

以上即为全部内容。至于测试部分,就不磨叽了,直接在主节点操作,从节点可以直观看出变化。
总体上来说,配置并不算复杂,但是需要思路比较清晰!不过故障处理起来,会稍微麻烦一点,需要注意数据一致性的问题!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值