docker 設定 Mysql主從叢集

2023-04-14 12:01:04

docker 設定Mysql叢集

Docker version 20.10.17, build 100c701

MySQL Image version: 8.0.32

Docker container mysql-master is source. mysql-replica is replication.

master == source. replica == slave.名稱叫法不一樣而已。

Choose one of the way,與replica同步資料兩種情況:

  1. source有存在的資料並且你想同步到replica,這種需要mysqldump備份source資料,然後CHANGE REPLICATION SOURCE TO
  2. you are setting up a new source and replica combination,其實就是你source沒有資料,沒有想同步到replica的,這種的不需要mysqldump備份source資料復原到replica,直接CHANGE REPLICATION SOURCE TO

網路大多為第二種情況,那麼我就寫第一種情況,第一種情況基本就多了mysqldump這個步驟。

Pull MySQL image And run mysql-master

docker pull mysql/mysql-server:latest

你可以去Docker Hub尋找適合的版本: docker hub

主節點的my.cnf設定為:

[mysqld]
server_id=1
socket=/var/lib/mysql/mysql.sock
user=mysql

Mysql8很多設定已經為預設,比如binlog預設開啟,log_replica_updates預設開啟,注意server_id需要source和replica不要相同。

datadir資料夾下要注意為空才行,否則會啟動不成功。如果啟動過程遇到任何問題,可以使用docker logs mysql-master命令檢視出了什麼問題。

注意docker使用mount命令,需要檔案或者資料夾都存在,而-v不需要。
可搜尋--mount和-v兩個命令的區別。

docker run -p 3307:3306 --name mysql-master \
--mount type=bind,src=/root/working/mydata/mysql-master/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/root/working/mydata/mysql-master/datadir,dst=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql/mysql-server:latest

-p: 3307為雲伺服器埠,我用他連線datagrip。3306為容器內部埠。

mount:src為雲服務路徑,dst為容器內部路徑。

MYSQL_ROOT_PASSWORD:為root使用者指定密碼,否則需要在docker logs去檢視此容器自己生成的密碼。

建立一個遠端存取的賬號和一個做主從同步的賬號

建立一個遠端存取的賬號,方便我們使用datagrip等工具連線我們的資料庫。

注意雲伺服器的安全組規則,是否把我們需要的埠放開了,比如3306,3307,3308

docker exec -it mysql-master mysql -uroot -p命令進入到資料庫,root賬號的密碼為上面我們設定的root

進來資料庫後,我們建立賬號:

#新增遠端登入使用者
CREATE USER 'keboom'@'%' IDENTIFIED BY 'keboom';
GRANT ALL PRIVILEGES ON *.* TO 'keboom'@'%';

keboom這個賬號用來datagrip軟體連線我們的資料庫。

接著我們建立一個用來做主從同步的使用者:

CREATE USER 'repl'@'%' IDENTIFIED BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

repl這個賬號用來replica節點來向source節點同步資料。

mysqldump命令在主庫備份資料,接著從庫恢復此備份

  1. 在主庫執行FLUSH TABLES WITH READ LOCK;將主庫唯讀,這時記錄主庫binlog位置,並做mysqldump備份。備份做好之後,則解鎖。

  2. 我們新開一個終端,進入資料庫執行SHOW MASTER STATUS\G 獲得主庫binlog位置。

    mysql> SHOW MASTER STATUS\G
    *************************** 1. row ***************************
                 File: binlog.000002
             Position: 2185
         Binlog_Do_DB: 
     Binlog_Ignore_DB: 
    Executed_Gtid_Set: 
    1 row in set (0.00 sec)
    
    
  3. 我們再新開一個終端,執行 docker exec -it mysql-master bash,進入容器進行備份。

    注意docker exec -it mysql-master bashdocker exec -it mysql-master mysql -uroot -p 區別

  4. mysqldump -uroot -p --databases test --source-data > dbdump.db,這裡我自己建立了一個test資料庫,我只備份這一個資料庫。可以在test資料庫建立一個表,插入幾條資料,用來驗證同步資料是否成功。

  5. UNLOCK TABLES; 備份好資料之後,就可以解鎖了。

啟動replica節點

replica—my.cnf設定為:

[mysqld]
server_id=21
socket=/var/lib/mysql/mysql.sock
user=mysql
docker run -p 3308:3306 --name mysql-replica \
--mount type=bind,src=/root/working/mydata/mysql-replica/my.cnf,dst=/etc/my.cnf \
--mount type=bind,src=/root/working/mydata/mysql-replica/datadir,dst=/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql/mysql-server:latest
  1. replica啟動好後,將dbdump.db 檔案複製到掛載的目錄下,進入到replica容器,執行mysql -uroot -p < dbdump.db ,這時我們就把備份恢復到從節點了,我們可以在主庫試著新增幾條資料,可以看到此時從庫還不能同步資料。

  2. 進入到replica資料庫,執行命令:

    CHANGE REPLICATION SOURCE TO
        -> MASTER_HOST='172.17.0.2',SOURCE_USER='repl',SOURCE_PASSWORD='repl',SOURCE_LOG_FILE='binlog.000002',SOURCE_LOG_POS=2185,GET_MASTER_PUBLIC_KEY=1;
    
    MASTER_PORT如果你的mysql用的不是3306,記得設定一下。
    

    獲得MASTER_HOST,可執行:

    docker inspect mysql-master | grep IP                                   
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                        "IPAMConfig": null,
                        "IPAddress": "172.17.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
    
    

    SOURCE_USER就是我們在主庫建立的用於主從同步的使用者。

    SOURCE_LOG_FILE,SOURCE_LOG_POS是上面在主庫中查詢到的。

    GET_MASTER_PUBLIC_KEY,mysql8 預設使用 caching_sha2_password authentication plugin。replica需要向source獲得公匙。

  3. START REPLICA;

  4. SHOW REPLICA STATUS\G 檢視同步狀態。如果Replica_IO_RunningReplica_SQL_Running 都為Yes那麼基本就成功了。如果有其他問題,可以通過docker logs mysql-replica檢視紀錄檔。

可以試試在test資料庫的表中插入幾條資料,看看從庫是否同步過來。

參考檔案:https://dev.mysql.com/doc/refman/8.0/en/binlog-replication-configuration-overview.html