如何在docker中建立mysql的主從同步

關(guān)于主從同步的背景:

最近在工作上遇到一個任務(wù):將主服務(wù)器上的mysql數(shù)據(jù)庫和從服務(wù)器的mysql數(shù)據(jù)庫實現(xiàn)主從同步。即當主庫發(fā)生數(shù)據(jù)的變更時,從庫也能做出同樣的變更。
1.環(huán)境:Linux, docker;
2.mysql運行在docker容器中;

找到mysql的配置文件

MySQL默認讀取的配置文件是“my.cnf”,這個文件的位置可以通過以下命令查找:

$ mysql --help|grep 'my.cnf'

該查找命令會返回以下路徑,排序靠前的路徑會被優(yōu)先讀取,若文件不存在則往下讀:

order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf

我的my.cnf文件在路徑/etc/mysql下,文件內(nèi)容是這樣的:

# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
#******
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

“!includedir /etc/mysql/conf.d/” 表示my.cnf配置文件中引入了/etc/mysql/conf.d/目錄下所有的文件內(nèi)容,因此在該目錄下的文件中添加配置內(nèi)容也能達到配置的作用。

由于修改配置文件極有可能將容器掛掉,無法進入容器從而無法把配置文件復原,因此,在最初創(chuàng)建這個容器的時候,出于安全考慮,我將宿主機的/home/mysql/conf/目錄掛載到了容器的/etc/mysql/conf.d/目錄中。這樣,即使無法進入容器也可以在宿主機的掛載目錄中找到對應(yīng)的配置文件進行復原。

解決過程

a.主庫和從庫(master & slave)

我的主庫和從庫所在服務(wù)器分別在不同的服務(wù)器的docker中,mysql在容器的3306端口,對應(yīng)著宿主機的3306端口
1.主庫:10.30.129.204
2.從庫:10.30.129.191

b.主庫的配置

在主庫的配置文件中添加以下內(nèi)容:

[mysqld]
server_id=100 #服務(wù)器標志號,與從庫的server_id標識不得和主庫一致
log-bin=mysql-bin  #設(shè)置日志文件,從庫的I/O線程通過讀這個文件的日志實現(xiàn)同步
binlog_cache_size=1M #日志的緩存大小
binlog_format=mixed #設(shè)置bin-log日志文件格式為:mixed,防止主鍵重復
slave_skip_errors=1062 #忽略所有的1062錯誤
expire_logs_days=7 #設(shè)置bin-log日志文件保存的天數(shù)

配置完成后回到宿主機上,重啟mysql:

>docker restart mysql

重啟后進入容器,在mysql shell環(huán)境下查看主庫的狀態(tài):

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

在這里記錄下日志文件mysql-bin.000001和日志記錄到的Position,在從庫連接時需要用到。

除此之外,還需要在主服務(wù)器上添加一個用于從機訪問的帳號, 賦予REPLICATION SLAVE權(quán)限:

GRANT REPLICATION SLAVE ON *.* TO '<SLAVE_NAME>'@'<SLAVE_ADDRESS>' IDENTIFIED BY '<PASSWORD>';

稍后,<SLAVE_NAME>和<PASSWORD>將會在從庫的配置中使用。

c.從庫的配置

和主庫的配置過程一樣,先將宿主機的相關(guān)目錄掛載到配置文件所在的目錄上,以防不測?,F(xiàn)在我們來修改從庫的配置文件,在配置文件中添加以下內(nèi)容:

[mysqld]
server_id=101 #必須和主服務(wù)器不一致
slave_skip_errors=1062
relay_log=mysql-relay-bin #設(shè)置中繼日志
log_slave_updates=1
log_error=mysql_log_error #設(shè)置錯誤日志,當主從同步的過程中出現(xiàn)錯誤可以翻日志
master-host=10.30.129.204
master-user=<SLAVE_NAME>
master-password=<PASSWORD>
master-port=3306

配置完成后,在從服務(wù)器上重啟一下mysql:

docker restart mysql

然后進入mysql shell中輸入以下命令:

mysql> change master to
master_host='10.30.129.204', #主服務(wù)器地址
master_user='<SLAVE_NAME>',
master_password='<PASSWORD>',
master_port=3306,
master_log_file='mysql-bin.000001', #先前記錄的主庫日志文件名
master_log_pos=154; #日志給從庫I/O線程讀取的起始位置

開啟同步:

mysql> start slave;

最后,查看從庫同步的狀態(tài):

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.30.129.204
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 50325805
               Relay_Log_File: mysql-relay-bin.000007
                Relay_Log_Pos: 50325971
        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: 50325805

我們只需要關(guān)注以下幾個指標:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master_Log_File: mysql-bin.000001
Relay_Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 50325805
Exec_master_log_pos: 50325805

日志文件和記錄位置必須是兩兩一致的,IO線程和SQL線程都要是Yes狀態(tài)。若同步失敗,可以在錯誤日志下排查一下。到這里的時候,mysql的主從同步就大功告成了。

注意事項

1.主庫中原先就有數(shù)據(jù)

如果主庫中原來就存在數(shù)據(jù),并且需要將先前的數(shù)據(jù)同步到從庫中,可以全量備份數(shù)據(jù)庫到從庫。通過以下命令導出和導入:

#全量導出
mysqldump -h <host>  -u <username> -p <password> --all-databases >all-databases.sql

#全量導入(在從庫的mysql shell環(huán)境下)
mysql> source  
2.主庫一直有新數(shù)據(jù)的更新

在從主庫備份全庫數(shù)據(jù),到查看主庫mysql-bin-log日志文件的記錄位置position的這段時間里,如果數(shù)據(jù)庫被別的用戶寫入數(shù)據(jù),會導致主從不一致的情況。安全起見,可以在備份前鎖庫,待記錄完日志文件狀態(tài)后再解鎖:

#加鎖
mysql> FLUSH TABLES WITH READ LOCK;
#解鎖
mysql> UNLOCK TABLES;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容