基于二进制日志文件位置的复制

配置主节点

  1. 修改主数据库服务器的配置文件 my.cnf,开启 BINLOG设置 server-id 的值。这两个参数的修改需要重新启动数据库服务才可以生效。

    [mysqld]
    server-id=1
    log-bin=mysql-bin    # 一个相对路径,相对于 Data 存放的目录
    binlog_format=Row
  2. 创建一个专门用于复制的用户,并授予 REPLICATION SLAVE 的权限。

    CREATE USER 'repl'@'%' IDENTIFIED BY '123456';
    GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
  3. 通过命令行客户端连接到源并启动一个会话,执行 FLUSH TABLES WITH READ LOCK 语句来刷新所有表并阻止写入语句(这个操作是为了确保没有数据库操作,以便获得一个一致性的快照)。

    FLUSH TABLES WITH READ LOCK;
  4. 启动另一个会话,使用 SHOW MASTER STATUS 语句来确定当前的二进制日志文件名称和位置。

    SHOW MASTER STATUS\G;
    *************************** 1. row ***************************
                 File: mysql-bin.000001
             Position: 154
         Binlog_Do_DB:
     Binlog_Ignore_DB:
    Executed_Gtid_Set:
    1 row in set (0.00 sec)

    File 列显示日志文件的名称,而 Position 列显示文件中的位置。在这个例子中,二进制日志文件是mysql-bin.000003,位置是 154,它们表示副本应该从主数据库开始处理的复制坐标

  5. 使用 mysqldump 工具创建主数据库的快照(推荐使用 mysqldump 特别是在使用 InnoDB 引擎时)。以下示例将所有数据库转储到名为 dbdump.db 的文件中,包含 --master-data 选项会自动附加在副本上启动复制过程所需的 CHANGE MASTER TO 语句

    mysqldump -uroot -p --all-databases --master-data > dbdump.db
  6. 主数据库的备份完毕后,可以恢复写操作,剩下的操作只需要在从库上执行:

    UNLOCK TABLES;

每个副本都使用 MySQL 的用户名和密码连接到主数据库,因此在主数据库上必须有一个用户帐户,副本可以使用该帐户进行连接。

当设置副本时,会通过 CHANGE MASTER TO 命令的 MASTER_USER 选项指定用户名。任何帐户都可以用于此操作,只要已授予 REPLICATION SLAVE 权限。你可以选择为每个副本创建一个不同的帐户,或者使用相同的帐户连接到源。

用于复制的用户名和密码会以明文的形式存储在从数据库元数据存储库中。因此,需要创建一个仅用于复制过程的帐户,以最小化对其他帐户的威胁。

配置从节点

  1. 修改从数据库的配置文件 my.cnf,增加 server-id 参数。注意 server-id 的值必须是唯一的,不能和主数据库的配置相同,如果有多个从数据库服务器,每个从数据库服务器必须有自己唯一的 server-id值。

    [mysqld]
    server-id=10
  2. 在从库上,使用 --skip-slave-start 选项启动从数据库,这样不会立即启动从数据库服务上的复制进程,方便我们对从数据库的服务进行进一步的配置。

  3. 将主库的快照文件(dbdump.db)复制到从节点服务器上,然后导入快照:

    mysql < dbdump.db
  4. 对从数据库服务器做相应设置,指定复制使用的用户,主数据库服务器的 IP、端口以及开始执行复制的日志文件和位置等:

    CHANGE MASTER TO MASTER_HOST = '222.20.72.166',
        MASTER_USER = 'repl',
        MASTER_PASSWORD = '123456',
        MASTER_LOG_FILE = 'mysql-bin.000001',
        MASTER_LOG_POS = 154;
  5. 启动 slave 线程:

    START SLAVE;
  6. 查看复制状态:

    show slave status\G;
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 222.20.72.166
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 1249
                   Relay_Log_File: 1030dacf93dd-relay-bin.000002
                    Relay_Log_Pos: 614
            Relay_Master_Log_File: mysql-bin.000001
                 Slave_IO_Running: Yes
                Slave_SQL_Running: No
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 1049
                       Last_Error: Error 'Unknown database 'test'' on query. Default database: 'test'. Query: 'CREATE table test(id int)'
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 448
                  Relay_Log_Space: 1629
                  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: NULL
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 1049
                   Last_SQL_Error: Error 'Unknown database 'test'' on query. Default database: 'test'. Query: 'CREATE table test(id int)'
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1
                      Master_UUID: 2e7c13f7-92e1-11ec-b712-b42e99f272fa
                 Master_Info_File: /var/lib/mysql/master.info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: 
               Master_Retry_Count: 86400
                      Master_Bind: 
          Last_IO_Error_Timestamp: 
         Last_SQL_Error_Timestamp: 231115 09:48:50
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 
                Executed_Gtid_Set: 
                    Auto_Position: 0
             Replicate_Rewrite_DB: 
                     Channel_Name: 
               Master_TLS_Version: 
    1 row in set (0.01 sec)

MySQL的复制功能并不要求副本必须启用二进制日志记录

但是,在副本上启用二进制日志记录意味着可以使用副本的二进制日志进行数据备份和崩溃恢复。如果要在副本上启用二进制日志记录,可以在配置文件的 [mysqld] 部分中使用 log-bin 选项。

对于之前未使用二进制日志的服务器,需要重新启动服务器以启动二进制日志记录。

最后更新于