目錄
1.題目部分
- 參考文檔: https://hub.docker.com/_/mysql
- 使用docker-compose, 創建兩個MySQL容器, 滿足如下條件:
- 使用自定義的my.cnf
- 形成主從復制關系
- 容器銷毀后, 主實例的數據仍保留, 從實例的數據清零銷毀
- 重建兩個容器, 主實例沿用之前的數據, 從實例重建數據, 並建立復制
2.解答部分
2.1 docker安裝
docker-compose依賴docker環境,需要先安裝好docker,本實驗環境為在CentOS7虛擬機中安裝docker,參考鏈接:https://docs.docker.com/install/linux/docker-ce/centos/
## 卸載舊版本的docker及相關組件
[root@10-186-61-162 ~]# yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
## 安裝yum工具包及docker相關依賴包
[root@10-186-61-162 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
## 添加docker社區版的軟件源(這里將軟件源替換為了阿里雲提供的軟件源,加快鏡像下載速度)
[root@10-186-61-162 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
## 安裝並啟動docker-ce
[root@10-186-61-162 ~]# yum install docker-ce docker-ce-cli containerd.io
[root@10-186-61-162 ~]# systemctl start docker
[root@10-186-61-162 ~]# systemctl status docker
## 驗證docker運行正常
[root@10-186-61-162 ~]# docker --version
Docker version 19.03.6, build 369ce74a3c
[root@10-186-61-162 ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest
## 有以下輸出表示docker安裝且運行正常
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
2.2 docker-compose 安裝
docker-compose是一個用來編排多個容器的工具,我們可以編輯一個YMAL格式的配置文件,將多個容器的配置寫入,使用compose工具來統一啟停維護。安裝參考鏈接:
## 直接使用官方鏈接提供的下載命令下載1.23.3版本docker-compose並保存到/usr/local/bin/docker-compose
curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
## 對docker-compose增加可執行權限
chmod +x /usr/local/bin/docker-compose
## 驗證docker版本
[root@10-186-61-162 ~]# docker-compose --version
docker-compose version 1.25.3, build d4d1b42b
2.3 docker-compose 配置
在編排前需規划好相關運行目錄及my.cnf配置文件
## 創建docker-compose編排MySQL的系統目錄便於維護管理
[root@10-186-61-162 mysql]# mkdir -p /data/docker-compose/mysql
## 在該目錄下創建主從需要的文件及目錄
[root@10-186-61-162 mysql]# pwd
/data/docker-compose/mysql
[root@10-186-61-162 mysql]# tree -L 2
.
├── docker-compose.yml ## MySQL主從編排的配置文件
├── master
│ ├── data ## master節點保留數據,數據用volumes的方式保留在宿主機本地,需要額外創建data目錄
│ ├── init_sql ## 在MySQL初始化完成后需要執行的SQL文件目錄,目錄下包含創建的初始化用戶、數據庫、表及測試數據等。
│ └── my.cnf ## 自定義的MySQL配置文件
└── slave
├── init_sql
└── my.cnf
2.3.1 init.sql內容
- master節點
- 創建一個repl用戶做復制同步使用
- 創建一個測試庫zhenxing並在其中創建一張t1表插入少量數據
- slave節點
- reset master清除執行的基礎操作產生的GTID信息
- change master to指向master節點建立主從復制同步連接
## master節點的初始化sql文件
[root@10-186-61-162 init_sql]# pwd
/data/docker-compose/mysql/master/init_sql
[root@10-186-61-162 init_sql]# cat init.sql
create user 'repl'@'%' identified by 'repl';
grant replication client,replication slave on *.* to 'repl'@'%';
create database zhenxing;
use zhenxing;
create table t1(id int primary key auto_increment,username varchar(20));
insert into t1(username) values('yuzhenxing'),('zhenxingyu');
## slave節點的初始化sql文件
[root@10-186-61-162 init_sql]# pwd
/data/docker-compose/mysql/slave/init_sql
[root@10-186-61-162 init_sql]# cat init.sql
reset master;
CHANGE MASTER TO MASTER_HOST='172.20.0.10',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;
start slave;
2.3.2 my.cnf配置文件
其中除server_id與從庫不一樣以外,其他參數均一致
[mysqld]
# Base Config
server_id = 1623306
user = mysql
port = 3306
default_storage_engine = InnoDB
character_set_server = utf8mb4
# skip_slave_start = 1 ## 該參數需要注釋,不然docker調用初始化腳本時不會觸發start slave開啟主從復制同步
skip-name-resolve = 1
skip-external-locking = 1
lower_case_table_names = 1
query_cache_type = 0
query_cache_size = 0
max_connections = 1000
default-time-zone = '+8:00'
log_timestamps = SYSTEM
# InnoDB config
innodb_strict_mode = 1
innodb_file_per_table = 1
innodb_stats_on_metadata = 0
innodb_flush_method = O_DIRECT
innodb_log_files_in_group = 3
innodb_data_file_path = ibdata1:128M:autoextend
innodb_buffer_pool_size = 128M
innodb_log_file_size = 32M
innodb_log_buffer_size = 8M
innodb_max_dirty_pages_pct = 60
innodb_io_capacity = 200
innodb_buffer_pool_instances = 8
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
innodb_undo_logs = 128
innodb_undo_tablespaces = 3
innodb_flush_neighbors = 1
# Cache config
key_buffer_size = 8M
tmp_table_size = 8M
max_heap_table_size = 8M
thread_cache_size = 1000
table_open_cache = 2048
open_files_limit = 65535
max_allowed_packet = 64M
# Log config
log_error = mysql-error.log
slow_query_log_file = mysql-slow.log
relay-log = mysql-relay
log-bin = mysql-bin
slow_query_log = 1
long_query_time = 0.2
#log_slow_admin_statements = 1
#log_slow_slave_statements = 1
# Replication config
slave-parallel-type = LOGICAL_CLOCK
slave-parallel-workers = 4
expire_logs_days = 14
binlog_format = row
log_slave_updates = ON
binlog_checksum = NONE
max_binlog_size = 250M
binlog_cache_size = 2M
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
relay-log-info-repository = TABLE
master_info_repository = TABLE
relay_log_recovery = 1
binlog_rows_query_log_events = 1
log_bin_trust_function_creators = 1
# GTID
gtid-mode = ON
enforce-gtid-consistency = 1
# Performance Schema
performance-schema-instrument = 'wait/lock/metadata/sql/mdl=ON'
2.3.3 docker-compose.yml
- 采用MySQL5.7.29版本數據庫
- 主從配置文件均采用自定義的配置文件
- 主庫的數據目錄采用宿主機上創建的data目錄
- 將init_sql下的文件映射到/docker-entrypoint-initdb.d下(注:/docker-entrypoint-initdb.d下以sql或sh結尾的文件會在數據庫初始化完成后自動執行)
[root@10-186-61-162 mysql]# cat docker-compose.yml
version: '3.7'
networks:
mysql_net:
name: mysql_net
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.1/24
services:
master:
networks:
mysql_net:
ipv4_address: 172.20.0.10
image: mysql:5.7.29
restart: always
environment:
MYSQL_ROOT_PASSWORD: oracle
hostname: 172-20-0-10
container_name: 172-20-0-10
volumes:
- "./master/my.cnf:/etc/my.cnf"
- "./master/data:/var/lib/mysql"
- "./master/init_sql:/docker-entrypoint-initdb.d/"
slave:
networks:
mysql_net:
ipv4_address: 172.20.0.11
image: mysql:5.7.29
restart: always
environment:
MYSQL_ROOT_PASSWORD: oracle
hostname: 172-20-0-11
container_name: 172-20-0-11
volumes:
- "./slave/my.cnf:/etc/my.cnf"
- "./slave/init_sql:/docker-entrypoint-initdb.d/"
2.4 docker-compose運行
當相關配置文件編輯完成后,即可啟動docker-compose
## 使用docker-compose后台方式創建容器
[root@10-186-61-162 mysql]# cd /data/docker-compose/mysql
[root@10-186-61-162 mysql]# docker-compose up -d
Creating network "mysql_net" with driver "bridge"
Creating 172-20-0-11 ... done
Creating 172-20-0-10 ... done
## 查看mysql_net自定義網絡
[root@10-186-61-162 mysql]# docker network ls
NETWORK ID NAME DRIVER SCOPE
d5072726a5c8 bridge bridge local
3443080f11fc host host local
deda6b29ddd0 mysql_net bridge local
25391fba169c none null local
c4aeb18be8c4 root_default bridge local
## 查看當前網絡組下各節點對應具體IP
[root@10-186-61-162 mysql]# docker network inspect mysql_net |egrep "IPv4Address|Name"
"Name": "mysql_net",
"Name": "172-20-0-10",
"IPv4Address": "172.20.0.10/16",
"Name": "172-20-0-11",
"IPv4Address": "172.20.0.11/16",
## 使用docker ps命令可以看到當前運行的容器狀態
[root@10-186-61-162 mysql]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e1f7ff7f1e2e mysql:5.7.29 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 3306/tcp, 33060/tcp 172-20-0-11
af1fe13e199d mysql:5.7.29 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 3306/tcp, 33060/tcp 172-20-0-10
## 也可使用docker-compose的ps命令查看狀態
[root@10-186-61-162 mysql]# docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------
172-20-0-10 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
172-20-0-11 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
## 訪問數據庫主節點,數據均初始化成功
[root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhenxing |
+--------------------+
5 rows in set (0.01 sec)
mysql> select * from zhenxing.t1;
+----+------------+
| id | username |
+----+------------+
| 1 | yuzhenxing |
| 2 | zhenxingyu |
+----+------------+
2 rows in set (0.01 sec)
## 訪問MySQL從庫,從庫為空實例
[root@10-186-61-162 mysql]# mysql -h172.20.0.11 -uroot -P3306 -poracle
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
## 主從同步正常
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.20.0.10
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 190
Relay_Log_File: mysql-relay.000006
Relay_Log_Pos: 395
Relay_Master_Log_File: mysql-bin.000004
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: 190
Relay_Log_Space: 835
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: 1623306
Master_UUID: 72aa5e86-51ff-11ea-8a5a-0242ac14000a
Master_Info_File: mysql.slave_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: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:2-10
Executed_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:1-10
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
2.5 重置容器並保存master節點數據
- 因為主節點數據保存在容器外宿主機上,可直接將容器刪除,再重新構建時指定容器使用已存在的數據即可完成構建。不會對已存在的數據庫做改變,
- If you start your mysql container instance with a data directory that already contains a database (specifically, a mysql subdirectory), the $MYSQL_ROOT_PASSWORD variable should be omitted from the run command line; it will in any case be ignored, and the pre-existing database will not be changed in any way
## 在刪除容器前在主節點新增一條數據驗證是否會在重建后保留
[root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle
mysql> insert into zhenxing.t1 select null,'xingzhenyu';
mysql> select * from t1;
+----+------------+
| id | username |
+----+------------+
| 1 | yuzhenxing |
| 2 | zhenxingyu |
| 3 | xingzhenyu |
+----+------------+
3 rows in set (0.00 sec)
## 停止並刪除容器
## 使用docker-compose stop && docker-compose rm不會刪除創建的網絡,如需要一並刪除網絡可使用docker-compose down
[root@10-186-61-162 mysql]# docker-compose stop && docker-compose rm
Stopping 172-20-0-11 ... done
Stopping 172-20-0-10 ... done
Going to remove 172-20-0-11, 172-20-0-10
Are you sure? [yN] y
Removing 172-20-0-11 ... done
Removing 172-20-0-10 ... done
## 重新構建容器
[root@10-186-61-162 mysql]# docker-compose up -d
Creating 172-20-0-11 ... done
Creating 172-20-0-10 ... done
## 登錄主庫查看數據
[root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| zhenxing |
+--------------------+
5 rows in set (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------------------------------+
| mysql-bin.000004 | 190 | | | 036a86a3-516e-11ea-9394-0242ac130003:1-10 |
+------------------+----------+--------------+------------------+-------------------------------------------+
1 row in set (0.00 sec)
## 驗證主庫數據仍保留完整
mysql> select * from zhenxing.t1;
+----+------------+
| id | username |
+----+------------+
| 1 | yuzhenxing |
| 2 | zhenxingyu |
| 3 | xingzhenyu |
+----+------------+
3 rows in set (0.01 sec)
## 登錄slave查看與主庫的同步
[root@10-186-61-162 mysql]# mysql -h172.20.0.11 -uroot -P3306 -poracle
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.20.0.10
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 190
Relay_Log_File: mysql-relay.000007
Relay_Log_Pos: 395
Relay_Master_Log_File: mysql-bin.000005
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: 190
Relay_Log_Space: 1158
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: 1623306
Master_UUID: 72aa5e86-51ff-11ea-8a5a-0242ac14000a
Master_Info_File: mysql.slave_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: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:2-11
Executed_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:1-11
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
## 數據同步正常
mysql> select * from zhenxing.t1;
+----+------------+
| id | username |
+----+------------+
| 1 | yuzhenxing |
| 2 | zhenxingyu |
| 3 | xingzhenyu |
+----+------------+
3 rows in set (0.00 sec)
## 也可使用dump方式導出導入到slave后再建立主從同步
docker exec -i master sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > all.sql
docker exec -i slave sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' <all.sql
## 或將master的宿主機上的數據拷貝一份供從庫使用
2.6 參考鏈接
- docker 安裝
- docker-compose 安裝
- docker-compose 配置參數說明
- docker 自定義網絡創建