1. 程式人生 > >使用Docker容器為MySQL搭建主從複製

使用Docker容器為MySQL搭建主從複製

1. 編寫主MySQL的Docker檔案

新建資料夾,命名為mysql-master-v1。在資料夾mysql-master-v1中新建檔案Dockerfile和master.cnf。筆者推薦使用的編輯器是Visual Studio Code。利用編輯器將這兩個檔案的編碼設定成UTF-8。因為本文介紹安裝到linux系統下,所以筆者建議讀者把換行符設定成LF,以兼顧Linux作業系統。按照如下內容編寫這兩個檔案。

Dockerfile

FROM mysql:5.7

# set timezone as china/shanghai
RUN cp /usr/share/zoneinfo/PRC /etc/localtime

# copy mysql config file
COPY master.cnf /etc/mysql/conf.d/ ENTRYPOINT ["docker-entrypoint.sh"] EXPOSE 3306 CMD ["mysqld"]

master.cnf

[mysqldump]
user=root
password='123456'
[mysqld]
max_allowed_packet=8M
lower_case_table_names=1
character_set_server=utf8
max_connections=900
max_connect_errors=600
server-id=1
log-bin=mysql-bin

slow_query_log
=1 long_query_time=1 log_error

2. 主MySQL的配置檔案引數說明

解釋一下master.cnf。
lower_case_table_names:忽略表名、列名等資料結構的大小寫(注意:不是每行記錄內容的大小寫!)。

server-id=1: 表示此MySQL伺服器是主伺服器 。

log-bin:開啟二進位制記錄。這是為了主從複製而做的設定。本文使用RBR(Row-Based Replication)模式。

slow_query_log=1:開啟慢查詢日誌。如果某一條SQL執行的時間超過long_query_time設定的秒數,那麼就記錄下來。記錄檔案路徑可以使用show variables;

命令,在變數名是slow_query_log_file下查詢到具體的日誌檔案路徑。

long_query_time=1:單位是秒。指如果某一條SQL語句執行時間超過1秒,就記錄下來。必須開啟慢查詢日誌了以後,此變數才能使用。

log_error:開啟錯誤日誌。show variables like 'log_error'; 就可以查詢到日誌檔案的路徑。mysql的docker官方映象如果設定別的取值會導致容器無法正常啟動。

3. 生成並使用主MySQL的映象

上傳資料夾mysql-master-v1到Linux伺服器上。為了便於說明,用伺服器A來指代這臺伺服器。筆者的Linux版本是Ubuntu14.04。通過cd命令進入目錄mysql-master-v1。然後輸入以下命令來編譯映象:

docker build -t zhangchao/mysql-master5.7:v1 .

注意不要落下行末尾最後一個點。

根據編譯好的映象,生成新的容器:

docker run --name mysql-master \
-p 3306:3306 \
-v /zc/mysql-master/datadir:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD='123456' -d zhangchao/mysql-master5.7:v1

使用MySQL的客戶端連線MySQL主伺服器,筆者使用的是MySQL Workbench。執行如下命令:

show master status;

記錄下file和position。這裡假設file是mysql-bin.000001,post是154。

4. 編寫從MySQL的Docker檔案

新建資料夾 mysql-slave-v1。仿照步驟1在資料夾 mysql-slave-v1下新建 Dockerfile 和 slave.cnf 兩個檔案。下面是這兩個檔案的內容。

Dockerfile

FROM mysql:5.7

# set timezone as china/shanghai
RUN cp /usr/share/zoneinfo/PRC /etc/localtime

# copy mysql config file
COPY slave.cnf /etc/mysql/conf.d/

ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306
CMD ["mysqld"]

slave.cnf

[mysqldump]
user=root
password='123456'
[mysqld]
max_allowed_packet=8M
lower_case_table_names=1
character_set_server=utf8
max_connections=900
max_connect_errors=600
slow_query_log=1
long_query_time=1
replicate-wild-do-table=db1.%
replicate-wild-do-table=db2.%
log_error

# Regard this db as a slave
server-id=2

slave.cnf 檔案中的 server-id=2 會把MySQL伺服器設定成從伺服器。

replicate-wild-do-table:規定有哪些表可以從主伺服器複製到從伺服器。db1.%是指只要是資料庫db1的表,就都可以複製到從伺服器上。可以多條設定,來允許多個數據庫。
沒有使用replicate-do-db是因為replicate-do-db禁止跨資料庫的訪問。比如使用者已經使用use db2;選擇了資料庫db2,使用者還要執行update db1.t_student set c_name='stu_c' where c_id='1234c',那麼就不能使用replicate-do-db。在程式設計的時候雖然程式設計師不會用到use,但是程式設計師有可能把連線mysql的url寫成指定某個資料庫或沒有指定具體的資料庫。即便沒有指定資料庫,使用replicate-do-db也是不允許的。

5. 生成並使用從MySQL的映象

上傳 mysql-slave-v1 到第二臺伺服器。用伺服器B來指代這臺伺服器。
編譯映象:

docker build -t zhangchao/mysql-slave5.7:v1 .

利用新的映象建立容器:

docker run --name mysql-slave \
-p 3306:3306 \
-v /zc/mysql-slave/datadir:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD='123456' -d zhangchao/mysql-slave5.7:v1

這時MySQL的主從伺服器都在執行中,需要讀者自行保證兩邊的資料相同。只有當兩臺伺服器的資料都一樣的時候,才能建立主從複製連線。

6. 把從MySQL連線到主MySQL上

使用客戶端連線到MySQL從伺服器,假定伺服器A的IP是192.168.10.1。
執行如下命令:

change master to 
master_host='192.168.10.1',
master_user='root',
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=154;

待命令正常執行後,接著執行如下命令:

start slave;

這樣就可以主從複製了。只要在主伺服器的db1和db2資料庫插入或修改資料,就可以自動複製到從伺服器上了。