我們使用 docker 來一主一從部署mariadb,步驟如下:
1. 配置文件
事先創(chuàng)建一個 mariadb-master-slave 的文件夾,然后在文件夾中新建主節(jié)點的配置文件 master.cnf:
[client]
# 默認字符集
default-character-set=utf8mb4
[mysqld]
# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
# 允許最大鏈接數(shù)
max_connections=4096
# 服務器引擎
default-storage-engine=InnoDB
# 表名小寫
# lower_case_table_names=1
# 為每個session 分配的內存,在事務過程中用來存儲二進制日志的緩存
binlog_cache_size=1M
# binlog 格式 row statement mixed
binlog_format=mixed
# 忽略的數(shù)據(jù)庫binlog
binlog-ignore-db=mysql,information_schema
# 到期自動刪除
expire_logs_day=7
# 跳過主從復制中遇到的所有錯誤或指定類型的錯誤,避免slave端復制中斷。
# 如:1062錯誤是指一些主鍵重復,1032錯誤是因為主從數(shù)據(jù)庫數(shù)據(jù)不一致
slave_skip_errors=1062
# 設置server_id,一般設置為IP,注意要唯一
server-id=1
# bin-log
log_bin=mariadb-bin
再新建從節(jié)點的配置文件 slave.cnf :
[client]
# 默認字符集
default-character-set=utf8mb4
[mysqld]
# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
# 服務器引擎
default-storage-engine=InnoDB
# 表名小寫
# lower_case_table_names=1
# 為每個session 分配的內存,在事務過程中用來存儲二進制日志的緩存
binlog_cache_size=1M
# binlog 格式 row statement mixed
binlog_format=mixed
# 忽略的數(shù)據(jù)庫binlog
binlog-ignore-db=mysql,information_schema
# 到期自動刪除
expire_logs_day=7
# 跳過主從復制中遇到的所有錯誤或指定類型的錯誤,避免slave端復制中斷。
# 如:1062錯誤是指一些主鍵重復,1032錯誤是因為主從數(shù)據(jù)庫數(shù)據(jù)不一致
slave_skip_errors=1062
# 設置server_id,一般設置為IP,注意要唯一
server-id=10
# bin-log
log_bin=slave-mariadb-bin
# 表示slave將復制事件寫進自己的二進制日志
log_slave_updates=1
# 記錄同步信息
relay-log=slave-relay-bin
# 防止改變數(shù)據(jù)(除了特殊的線程)
read_only=1
# 同步刷新binlog,當事務提交之后,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,
# 而讓Filesystem自行決定什么時候來做同步,或者cache滿了之后才同步到磁盤。
# sync_binlog=n,當每進行n次事務提交之后,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數(shù)據(jù)強制寫入磁盤
# 1 最安全,但是最慢。 0 最快,但是風險最大
sync_binlog=0
2. docker-compose 配置
在文件夾中新建 docker-compose.yml 文件,寫入:
version: "3"
services:
mariadb-master:
image: mariadb:10.7.1
container_name: mariadb-master
restart: always
ports:
- "3307:3306"
environment:
- MARIADB_ROOT_PASSWORD=mysql-666
volumes:
- ./master/data:/var/lib/mysql:cached
- ./master.cnf:/etc/mysql/my.cnf:cached
security_opt:
- seccomp:unconfined
logging:
driver: "json-file"
options:
max-size: "500m"
networks:
- dev_network
mariadb-slave:
image: mariadb:10.7.1
container_name: mariadb-slave
restart: always
ports:
- "3308:3306"
environment:
- MARIADB_ROOT_PASSWORD=mysql-666
volumes:
- ./slave/data:/var/lib/mysql:cached
- ./slave.cnf:/etc/mysql/my.cnf:cached
security_opt:
- seccomp:unconfined
logging:
driver: "json-file"
options:
max-size: "500m"
networks:
- dev_network
networks:
dev_network:
external:
name: dev_network
由于我是在同一臺機器上部署,避免端口沖突,所以我將主節(jié)點映射到了 3307 端口,從節(jié)點映射到了 3308 端口。
為了持久存儲數(shù)據(jù),我們把容器內的數(shù)據(jù)掛載到宿主機,將主節(jié)點和從節(jié)點的數(shù)據(jù)分別保存到當前文件夾 master, slave 目錄中。
最終的目錄結構如下:

將這兩個服務都放到同一個網(wǎng)絡 dev_network 中,需要使用 docker network create dev_network 命令先創(chuàng)建網(wǎng)絡。
3. 啟動服務
命令行執(zhí)行:docker-compose up -d,啟動這兩個服務。如果沒啥問題,docker ps 之后應該顯示如下:

4. master 節(jié)點配置
執(zhí)行 docker exec -it mariadb-master bash 進入主節(jié)點容器
再執(zhí)行 mysql -uroot -pmysql-666 進入 mysql 命令行

查看是否已經開啟log_bin, 執(zhí)行: show variables like '%log_bin%';

創(chuàng)建數(shù)據(jù)同步賬號
create user 'slave'@'%' identified by 'mysql-666';
授權
grant replication slave on *.* to 'slave'@'%';
刷新權限
flush privileges;

下面一步很關鍵了,執(zhí)行show master status; 命令,查看 master 節(jié)點當前狀態(tài)

牢記這兩個值,接下來進入 slave 節(jié)點要用到。
5. slave 節(jié)點配置
執(zhí)行 docker exec -it mariadb-slave bash 進入從節(jié)點容器
同樣再執(zhí)行 mysql -uroot -pmysql-666 進入 mysql 命令行

配置連接哪個主節(jié)點:
change master to master_host='mariadb-master',master_port=3306,master_user='slave',master_password='mysql-666',master_log_file='mariadb-bin.000003',
master_log_pos=785;
由于我是同一臺機器,所以 master_host 我設置的是主節(jié)點的host名稱,真實業(yè)務中應該是主節(jié)點ip地址,確認無誤之后,執(zhí)行 start slave 開始同步

使用 show slave status \G; 命令查看是否成功

如果看到 Slave_IO_Running 和 Slave_SQL_Running 都是Yes狀態(tài)就表示主從搭建完畢。
6. 數(shù)據(jù)庫測試
我們使用第三方mysql連接工具或者進入 master 節(jié)點的命令行執(zhí)行,創(chuàng)建數(shù)據(jù)庫和表的命令。
# 創(chuàng)建數(shù)據(jù)庫
create database ms_test DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
# 創(chuàng)建表
CREATE TABLE `account` (
`id` int(11) NOT NULL,
`email` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
`mobile` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

執(zhí)行完畢之后,我們連到 slave 節(jié)點,發(fā)現(xiàn)同樣的庫和表也自動創(chuàng)建了。

7. 總結
使用 docker 主從部署 mariadb 還是挺簡單的,條件允許可以部署多個從節(jié)點,實現(xiàn)一主多從,配合業(yè)務上做數(shù)據(jù)庫讀寫分離,能大幅提高數(shù)據(jù)庫的性能。