Docker 部署 MariaDB 指南
编辑
本文档基于常见的 Docker 部署实践(拉取镜像 -> 运行一次获取配置 -> 挂载配置与数据目录)并扩展为适用于生产环境的 MariaDB 部署与调优建议。
参考文章:Docker 环境安装 Mysql。
目录
目标与适用场景
前提条件
拉取镜像
初次运行(生成默认配置 & 初始化数据目录)
拷贝并自定义
my.cnf
使用 Docker Run 持久化部署(数据与配置卷)
推荐的
docker-compose.yml
示例性能与大表(千万/亿级)调优建议
备份 / 恢复方案
安全性与网络配置
监控与日志
常见问题与排查要点
1. 目标与适用场景
本文档适用于希望用 Docker 快速部署 MariaDB 的开发/测试及小到中型生产环境。重点考虑:
数据目录持久化
可定制配置(字符集、innodb 调优)
针对单表大数据量(千万/亿行)的查询性能优化建议
若需要线性扩展或分布式能力(例如 sharding / HTAP),请考虑 TiDB / Vitess 等分布式方案。
2. 前提条件
已安装 Docker Engine(建议 20.x+)和 docker-compose(v2+)
主机有稳定磁盘(SSD 推荐)和足够内存(建议至少 8GB)
对 MariaDB 基本配置(
my.cnf
)和 SQL 执行计划(EXPLAIN
)有基本认识
3. 拉取镜像
以 MariaDB 官方镜像为例:
# 列出可用镜像
docker search mariadb
# 拉取指定版本(示例:10.11)
docker pull mariadb:10.11
选择固定版本以保证可重复部署与回滚能力。
4. 初次运行(生成默认配置 & 初始化数据目录)
建议第一步先用临时容器初始化数据目录并导出默认配置作为模版:
docker run --name mariadb-temp -e MYSQL_ROOT_PASSWORD='StrongRootPass123!' -d mariadb:10.11
# 等待容器初始化数据库(查看日志)
docker logs -f mariadb-temp
# 将容器内的 /etc/mysql 或 /etc/mysql/mariadb.conf.d 拷贝到主机
mkdir -p /opt/docker/mariadb/{data,conf}
docker cp mariadb-temp:/etc/mysql /opt/docker/mariadb/conf
# 停止并删除临时容器
docker stop mariadb-temp && docker rm mariadb-temp
# 将容器内的数据目录拷贝到宿主机(如果已有数据)
# docker cp mariadb-temp:/var/lib/mysql /opt/docker/mariadb/data
目的:获取官方默认配置,便于以后在主机上编辑
my.cnf
并通过挂载生效。
5. 拷贝并自定义 my.cnf
把刚才拷贝出的配置目录下的 my.cnf
(或 mariadb.conf.d
下文件)做为基础,调整为适合大表与查询密集场景的配置。下面给出推荐项(示例,仅供参考,请结合实际硬件调整):
[mysqld]
user=mysql
bind-address=0.0.0.0
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
skip-name-resolve = 1
# InnoDB
innodb_buffer_pool_size = 6G # 根据内存分配,通常 = 60%-80% 可用内存
innodb_buffer_pool_instances = 4
innodb_file_per_table = 1
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 2 # 权衡性能与持久性
innodb_io_capacity = 2000
innodb_io_capacity_max = 4000
# 临时表/排序/并发
tmp_table_size = 256M
max_heap_table_size = 256M
sort_buffer_size = 4M
join_buffer_size = 8M
# 连接
max_connections = 500
table_open_cache = 4000
open_files_limit = 65535
# 日志与慢查询
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_error = /var/log/mysql/error.log
# 其他
query_cache_type = 0
query_cache_size = 0
说明:
innodb_buffer_pool_size
对查询性能决定性影响最大;单表很大时尽量将热点数据放到 buffer pool。innodb_file_per_table=1
便于表级别管理与压缩。innodb_flush_log_at_trx_commit=2
可以显著提升写性能,但在断电时可能会丢失最后一秒的数据(权衡可接受时使用)。
6. 使用 Docker Run 持久化部署(数据与配置卷)
下面给出一个生产可用的 docker run
示例,包含主机目录挂载与重启策略:
docker run -d \
--name mariadb \
-p 3306:3306 \
-v /opt/docker/mariadb/data:/var/lib/mysql \
-v /opt/docker/mariadb/conf:/etc/mysql \
-v /opt/docker/mariadb/logs:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD='StrongRootPass123!' \
-e TZ='Asia/Shanghai' \
--restart=always \
mariadb:10.11 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_general_ci
注意:第一次使用宿主机空目录作为 /var/lib/mysql
时,容器会自动初始化数据;若之前有残留数据请确保权限(UID/GID)一致。
7. 推荐的 docker-compose.yml
示例
生产或多容器场景建议使用 docker-compose(便于扩展、备份/恢复):
version: '3.8'
services:
mariadb:
image: mariadb:10.11
container_name: mariadb
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=StrongRootPass123!
- TZ=Asia/Shanghai
volumes:
- /opt/docker/mariadb/data:/var/lib/mysql
- /opt/docker/mariadb/conf:/etc/mysql
- /opt/docker/mariadb/logs:/var/log/mysql
restart: always
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
deploy:
resources:
limits:
cpus: '2'
memory: 8G
8. 性能与大表(千万/亿级)调优建议
针对单表很大、以查询为主的场景,除了上面的 my.cnf
调整,还应考虑如下策略:
8.1 索引策略
合理建索引:覆盖索引优先,避免全表扫描。使用联合索引时注意索引前缀原则(leftmost)。
避免冗余索引:过多索引会影响写入和占用空间。定期审查索引使用情况(
EXPLAIN
、performance_schema
)。分区(Partitioning):对历史数据或按时间范围查询频繁的表使用 RANGE 或 LIST 分区,减小单次扫描数据量。
8.2 表设计
垂直拆表/水平拆分:当单表列非常多时考虑垂直拆表;当单表行数影响性能时考虑水平拆分(sharding)。
归档冷数据:将不常访问的历史数据迁移到归档库或冷存储(例如单独实例或对象存储 + MyRocks)。
8.3 查询优化
用
EXPLAIN
分析慢查询,避免SELECT *
、过多子查询和不走索引的JOIN
。对大范围
ORDER BY
或GROUP BY
使用合适索引或预聚合表。利用批量分页(
WHERE id > last_id LIMIT N
)替代OFFSET
分页。
8.4 硬件与系统参数
SSD(NVMe 更佳)可显著提升 IO 性能。
提高系统
vm.swappiness=1
,避免频繁 swap。为 MariaDB 容器预留足够内存与 CPU,避免与 host 上其他容器争抢资源。
8.5 使用查询缓存 / 缓存层
MariaDB 的 query cache 在高并发写场景中并不推荐启用(容易锁竞争)。推荐使用 Redis / Varnish 等外部缓存层缓存热点数据或结果。
9. 备份 / 恢复方案
9.1 逻辑备份(mysqldump)
docker exec -i mariadb mysqldump -u root -p'password' --single-transaction --routines --events --databases mydb > mydb.sql
9.2 物理备份(xtrabackup / mariabackup)
使用 Percona XtraBackup 或 MariaDB 官方的
mariabackup
做热备份,适合大数据量快速恢复。示例(容器内运行 mariabackup):
# 在宿主机安装 mariabackup 或将备份工具打包到容器
docker exec mariadb mariabackup --backup --target-dir=/backupdir --user=root --password='password'
9.3 备份存储与策略
备份文件建议上传到对象存储(S3/MinIO)并设置生命周期策略。
建议保留:每日备份 7 天、周备份 4 周、月备份 12 个月。
10. 安全性与网络配置
不要把数据库端口暴露到公网,使用私有网络或 VPN。若必须暴露,请用防火墙(安全组)限制访问来源。
强制使用强密码并关闭匿名账户。
定期更新镜像并修补安全漏洞。
启用 TLS 加密(
--ssl-ca
、--ssl-cert
、--ssl-key
)以保护传输层数据。
11. 监控与日志
建议接入 Prometheus + Grafana 或使用 Percona Monitoring and Management(PMM)来监控:
QPS / TPS、慢查询数、Innodb Buffer Pool 命中率、磁盘 IO、连接数等。
打开慢查询日志并定期分析(
pt-query-digest
)。
12. 常见问题与排查要点
容器无法启动:检查
/var/lib/mysql
目录权限(UID/GID)、日志文件(/var/log/mysql/error.log
)。性能下降:排查慢查询、Buffer Pool 命中率、IO 阻塞、swap 使用。
数据目录损坏:从最近备份恢复或用
--innodb_force_recovery
参数尝试导出数据(谨慎使用)。
附录:快速操作命令汇总
# 查看容器日志
docker logs -f mariadb
# 进入容器
docker exec -it mariadb bash
# 备份示例
docker exec -i mariadb mysqldump -u root -p'password' --single-transaction mydb > mydb.sql
# 恢复示例
cat mydb.sql | docker exec -i mariadb mysql -u root -p'password'
- 0
- 0
-
赞助
赞赏
-
分享