运维现场

已有一个通过Docker部署的MySQL单实例,实例中有多个库,且已有数据,备份容灾目的现扩充从库。

docker run -d --name mysql --restart unless-stopped -p 3406:3306 --log-opt max-size=50m \
-v /data/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=xxx \
mysql:5.7

主库调整

The default configuration for MySQL can be found in /etc/mysql/my.cnf, which may !includedir additional directories such as /etc/mysql/conf.d or /etc/mysql/mysql.conf.d.

MySQL的镜像已经把主配置my.cnf映射到/etc/mysql/conf.d目录,所以只需自定义一个my.conf,通过目录挂载到容器里面即可。

[mysqld]
skip-host-cache
skip-name-resolve
server_id=1  //设置服务id
log_bin=mysql-bin //开启二进制日志
binlog-ignore-db=mysql
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062

[mysql]

[mysqldump]
quick
quote-names
max_allowed_packet=16M

停止当前容器,修改启动命令,挂载my.cnf,重新启动。

docker run -d --name mysql --restart unless-stopped -p 3406:3306 --log-opt max-size=50m \
-v /data/mysql:/var/lib/mysql \
-v /data/mysql.conf.d:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=xxx \
mysql:5.7

查看master状态。

MySQL [(none)]> show master status;
+------------------+-----------+--------------+------------------+-------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 452181159 |              | mysql            |                   |
+------------------+-----------+--------------+------------------+-------------------+

从库搭建

配置slave的my.cnf,在另外一台机器上,启动一个空实例。

[mysqld]
skip-host-cache
skip-name-resolve
server_id=2
log_bin=slave-bin
binlog-ignore-db=mysql
binlog_cache_size=1M
binlog_format=mixed
expire_logs_days=7
slave_skip_errors=1062
relay_log=slave-relay-bin
log_slave_updates=1
read_only=1

[mysql]

[mysqldump]
quick
quote-names
max_allowed_packet=16M
docker run -d --name mysql --restart unless-stopped -p 3406:3306 --log-opt max-size=50m \
-v /data/mysql:/var/lib/mysql \
-v /data/mysql.conf.d:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=xxx \
mysql:5.7

全量备份主库

首先锁表。

#全备主库时需要另开一个终端,给数据库加上读锁,避免在备份期间有其他人在写入导致数据不一致
#此锁表的终端必须在备份完成以后才能退出
mysql> flush tables with read lock;

记录binlog状态,锁表之后binlog的Position就不会再变了,记录下File和Position。

MySQL [(none)]> show master status;
+------------------+-----------+--------------+------------------+-------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 461472295 |              | mysql            |                   |
+------------------+-----------+--------------+------------------+-------------------+

操作备份,备份完成,即可释放表锁。

mysqldump -h 172.x.x.10 -P 3406 -uroot -pxxx --all-databases > all-database-$(date '+%F-%H-%M-%S').sql

#解除主库的锁表状态,直接退出交互式界面即可
mysql> quit

把全量数据导入到从库中

mysql -h 172.x.x.11 -P 3406 -uroot -pxxx < all-database-2024-10-09-11-27-41.sql

配置从库同步

登录从库,执行change master,注意master_log_file和master_log_pos,填写在备份主库前记录值。

change master to master_host='172.x.x.10',master_port=3406,master_user='root',master_password='xxx',master_log_file='mysql-bin.000002',master_log_pos=461472295;

查看从库状态。

MySQL [(none)]> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.x.x.10
                  Master_User: root
                  Master_Port: 3406
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 479860795
               Relay_Log_File: slave-relay-bin.000003
                Relay_Log_Pos: 111190829
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: No
            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: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 479860795
              Relay_Log_Space: 432038788
              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: cd0f01f3-27c4-11ef-9394-0242ac130002
             Master_Info_File: /var/lib/mysql/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:

可以看到Slave_IO_Running和Slave_SQL_Running,开始为No,需要执行slave start。

mysql> slave start
mysql> show slave status \G;
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...

验证同步

通过主库创建库表,写入数据,验证从库同步。