我们使用 docker
来一主一从部署mariadb,步骤如下:
1. 配置文件
事先创建一个 mariadb-master-slave
的文件夹,然后在文件夹中新建主节点的配置文件 master.cnf
:
[client]
# 默认字符集
default-character-set=utf8mb4
[mysqld]
# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
# 允许最大链接数
max_connections=4096
# 服务器引擎
default-storage-engine=InnoDB
# 表名小写
# lower_case_table_names=1
# 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存
binlog_cache_size=1M
# binlog 格式 row statement mixed
binlog_format=mixed
# 忽略的数据库binlog
binlog-ignore-db=mysql,information_schema
# 到期自动删除
expire_logs_day=7
# 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
# 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
# 设置server_id,一般设置为IP,注意要唯一
server-id=1
# bin-log
log_bin=mariadb-bin
再新建从节点的配置文件 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
# 忽略的数据库binlog
binlog-ignore-db=mysql,information_schema
# 到期自动删除
expire_logs_day=7
# 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
# 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
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
# 防止改变数据(除了特殊的线程)
read_only=1
# 同步刷新binlog,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息到磁盘,
# 而让Filesystem自行决定什么时候来做同步,或者cache满了之后才同步到磁盘。
# sync_binlog=n,当每进行n次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘
# 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
由于我是在同一台机器上部署,避免端口冲突,所以我将主节点映射到了 3307
端口,从节点映射到了 3308
端口。
为了持久存储数据,我们把容器内的数据挂载到宿主机,将主节点和从节点的数据分别保存到当前文件夹 master
, slave
目录中。
最终的目录结构如下:
将这两个服务都放到同一个网络 dev_network
中,需要使用 docker network create dev_network
命令先创建网络。
3. 启动服务
命令行执行:docker-compose up -d
,启动这两个服务。如果没啥问题,docker ps
之后应该显示如下:
4. master 节点配置
执行 docker exec -it mariadb-master bash
进入主节点容器
再执行 mysql -uroot -pmysql-666
进入 mysql 命令行
查看是否已经开启log_bin
, 执行: show variables like '%log_bin%';
创建数据同步账号
create user 'slave'@'%' identified by 'mysql-666';
授权
grant replication slave on *.* to 'slave'@'%';
刷新权限
flush privileges;
下面一步很关键了,执行show master status;
命令,查看 master
节点当前状态
牢记这两个值,接下来进入 slave
节点要用到。
5. slave 节点配置
执行 docker exec -it mariadb-slave bash
进入从节点容器
同样再执行 mysql -uroot -pmysql-666
进入 mysql 命令行
配置连接哪个主节点:
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 我设置的是主节点的host名称,真实业务中应该是主节点ip地址,确认无误之后,执行 start slave
开始同步
使用 show slave status \G;
命令查看是否成功
如果看到 Slave_IO_Running
和 Slave_SQL_Running
都是Yes状态就表示主从搭建完毕。
6. 数据库测试
我们使用第三方mysql连接工具或者进入 master
节点的命令行执行,创建数据库和表的命令。
# 创建数据库
create database ms_test DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
# 创建表
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;
执行完毕之后,我们连到 slave
节点,发现同样的库和表也自动创建了。
7. 总结
使用 docker 主从部署 mariadb 还是挺简单的,条件允许可以部署多个从节点,实现一主多从,配合业务上做数据库读写分离,能大幅提高数据库的性能。