notes

MYSQL 8.0 主从复制

步骤0. 配置之前

如果是对全新的数据库建立主从关系,则不需要考虑现有数据的问题。可以直接跳到步骤1。

那么对于已有数据的数据库,要建立 slave 数据库有两种方式:

如果是停掉 master 直接拷贝 data 目录,操作方便一点,这里就不做介绍。

如果是不停机的方案,我们需要先导出 master 上的全部数据到 sql,再到 slave 导入:

# 导出
mysqldump -p -A -F --single-transaction --master-data=2 > /test.sql

# 把 sql 拷贝到 slave 再导入
mysql -u<username> -p < /test.sql

我们还需要从刚才的 sql 文件里面获取 binlog 信息,需要记录下 MASTER_LOG_FILEMASTER_LOG_POS 的值,后面会用到:

grep '^-- CHANGE MASTER' /test.sql

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000005', MASTER_LOG_POS=155;

步骤1. master 服务器配置

- 创建复制账号,并赋予 replication slave 权限

这里创建的账号和密码都是 repl,只有拥有 replication slave 权限才能进行复制。

# 使用命令行登录 mysql
mysql -u<username> -p

# 创建 repl 账号
mysql> create user 'repl'@'%' identified by 'repl';
mysql> grant replication slave on *.* to 'repl'@'%';

- 修改配置文件

mysql 8.0 的配置文件在 /etc/mysql/conf.d/ 目录,我们只需要在目录中加一个 master.cnf 配置文件,内容为:

[mysqld]

# 数据库编号, 要具有唯一性, 不能跟其他数据库重复, 方便同步区分
server-id=1

# 开启 binlog,会生成相应的文件 mysql-bin.000001
log-bin=mysql-bin

# 要同步的库。可选,不设置表示所有库的变化都会以 binlog 的形式发送给 slave
binlog_do_db=<your_database>

重启 master 服务使配置生效。

- 获取 binlog 信息

如果之前从 sql 文件中获取过 binlog 信息,可以跳过此步。

执行 show master status

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |     1481 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

我们需要记录下 FilePosition 的值。

步骤2. slave 服务器配置

- 修改 slave 配置文件

在 slave 服务器的 /etc/mysql/conf.d/ 目录,加一个 slave.cnf 配置文件,内容为:

[mysqld]
server-id=2
log-bin=mysql-bin
binlog_do_db=<your_database>

重启 slave 服务使配置生效。

- 和 master 建立主从关系

登录 slave 服务器的 mysql 命令行:

mysql -u<username> -p

和 master 建立主从关系,填入之前保存的 MASTER_LOG_FILEMASTER_LOG_POS 的值:

mysql> CHANGE MASTER TO master_host='<MASTER_IP>', master_port=<MASTER_PORT>, master_user='repl', master_password='repl', master_log_file='<MASTER_FILE>', master_log_pos=<MASTER_POSITION>;

开启 slave:

mysql> start slave;

查看 slave 状态:

mysql> show slave status\G;

结果一般是这样的:

*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: mysqlmaster
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 1795
               Relay_Log_File: 30e516eee02b-relay-bin.000002
                Relay_Log_Pos: 1459
        Relay_Master_Log_File: mysql-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: 1795
              Relay_Log_Space: 1674
              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: 1
                  Master_UUID: 168c6343-4394-11ec-8a74-0242ac130002
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave 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 (0.00 sec)

我们主要看 Slave_IO_RunningSlave_SQL_Running 这两个字段为 YES 就表示已经在接收主服务器发来的 binlog 了。到这里,主从的配置就配好了。

FAQ