Docker-實現MySQL主從複製

安裝Docker

安裝教程傳送門

下載鏡像並啓動容器

  • 下載鏡像
root@ubuntu:~# docker pull mysql:5.7
  • 啓動master容器與slave容器
root@ubuntu:~# docker run --name master -p 3339:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
root@ubuntu:~# docker run --name slave -p 3340:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
  • 查看容器
root@ubuntu:~# docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
88fab660ae5f        mysql:5.7           "docker-entrypoint.s…"   32 seconds ago      Up 16 seconds       33060/tcp, 0.0.0.0:3340->3306/tcp   slave
c62e1b47c365        mysql:5.7           "docker-entrypoint.s…"   29 minutes ago      Up 13 minutes       33060/tcp, 0.0.0.0:3339->3306/tcp   master

配置master

  • 進入master容器,對/etc/mysql/my.cnf進行編輯
root@ubuntu:~# docker exec -it master bash
root@c62e1b47c365:/# vi /etc/mysql/my.cnf

不出意外的話,你將會出現如下錯誤:

bash: vi: command not found

我們來安裝一下vim

root@c62e1b47c365:/# apt-get install vim

不出意外的話,你將會出現如下錯誤:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package vim

此時,我們可以更新一下apt-get,再進行安裝

root@c62e1b47c365:/# apt-get update
root@c62e1b47c365:/# apt-get install vim

如果還出現問題,可以看下面的常見問題!!! 接下來,往/etc/mysql/my.cnf添加如下內容:

[mysqld]
server-id=100
# 開啓二進制日誌功能
log-bin=mysql-bin

保存文件,重啓mysql,再重啓容器:

root@c62e1b47c365:/# service mysql restart
[info] Stopping MySQL Community Server 5.7.30.
..root@ubuntu:~# docker container restart master
  • 進入mysql
# 123456爲上面啓動容器中MYSQL_ROOT_PASSWORD環境變量配置的root密碼
root@c62e1b47c365:/# mysql uroot -p123456
mysql> 
  • 創建slave用戶,並賦予replication slave權限和replication client權限,用於主從庫之間同步數據
mysql> use mysql;
mysql> create user 'slave'@'%' identified by '123456';
mysql> grant replication slave, replication client on *.* to 'slave'@'%';
mysql> flush privileges;

配置slave

和配置master一樣,需要在/etc/mysql/my.cnf中添加如下配置:

[mysqld]
server-id=101
# 開啓二進制日誌功能,
log-bin=mysql-slave-bin
# relay_log配置中繼日誌
relay_log=edu-mysql-relay-bin

配置完之後,重啓MySQL與容器

root@c62e1b47c365:/# service mysql restart
[info] Stopping MySQL Community Server 5.7.30.
..root@ubuntu:~# docker container restart slave

鏈接master與slave

master中進入MySQL,執行show master status查看狀態:

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     1418 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

在接下來的操作完成之前,請保證不要對master中的MySQL做任何操作,否則將引起狀態的變化。

slave中的MySQL中執行如下命令,鏈接master,如下:

mysql> change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=1418, master_connect_retry=30;

命令說明:

  • master_host: master的地址,指的是容器的獨立IP。可以通過docker inspect --format '{{.NetworkSettings.IPAddress}}' master來查看
  • master_port: master的端口號,指的是容器的端口號
  • master_user: 用於數據同步的用戶
  • master_password: 用於同步的用戶的密碼
  • master_log_file: 指定slave從哪個日誌文件開始複製數據,即上文提到的File字段的值
  • master_log_pos: 從哪個position開始讀,即上文中提到的Position字段的值
  • master_connect_retry: 如果連接失敗,重試的時間間隔,單位爲秒

此時我們在slave中的MySQL查看主從同步狀態:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 172.17.0.2
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1418
               Relay_Log_File: edu-mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000001
             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: 1418
              Relay_Log_Space: 154
              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: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             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: 
               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.00 sec)

正常情況下,此時的Slave_IO_RunningSlave_SQL_Running都是NO,因爲我們還沒有開啓主從複製過程。此時,我們執行一下start slave,再次查看一下狀態:

mysql> start slave;
Query OK, 0 rows affected (0.03 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1418
               Relay_Log_File: edu-mysql-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             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: 1418
              Relay_Log_Space: 531
              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: e101f6c0-ba7b-11ea-8e31-0242ac110002
             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: 
1 row in set (0.00 sec)

此時,看到Slave_IO_RunningSlave_SQL_Running都是YES,說明主從複製已經開始,可以開始測試數據是否同步成功了

測試主從複製

我們在master容器中的MySQL創建一個數據庫:

mysql> create database web;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| web               |
+--------------------+
5 rows in set (0.00 sec)

此時,我們在來slave容器中的MySQL查看一下是否有這個數據庫:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| web               |
+--------------------+
5 rows in set (0.00 sec)

如果有,就表明主從複製是成功的!!!

常見問題

  • Temporary failure resolving 'security.ubuntu.com’

解決辦法:在/etc/docker/daemon.json文件中加入如下內容(文件不存在請新建該文件):

{
    "dns": [
        "114.114.114.114",
        "8.8.8.8"
    ]
}

然後再重啓docker

  • Could not connect to deb.debian.org:80 (151.101.230.133), connection timed out

執行命令service docker restart重啓docker

  • No query specified

出現問題的原因,SQL語句中的結尾加了個;,去掉就好了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章