我有一个mysql实例运行在一个docker容器。我在/var/lib/mysql
中挂载一个卷,以便在关闭容器后保存数据。我想我有两个选择来备份我的数据库到我的主机系统:
- 备份完整卷:
docker run --rm --volumes-from db -v {BACKUP_PATH_ON_HOST_SYSTEM}:/backup ubuntu tar cvf /backup/backup.tar /var/lib/mysql
- 只备份mysqldump
基本上运行上面的命令,而是备份卷我创建一个,mysqldump副本/backup
。
哪个选项更好?
我也有类似的需求。在我的情况下,我故意使用旧的mysql
Docker映像,如下所示:
db:
image: mysql:5.6
container_name: ${COMPOSE_SITE_NAME}_mysql
volumes:
- db_files:/var/lib/mysql
# Load the initial SQL dump into the DB when it is created.
# This only runs once if the DB is empty.
- ${SQL_DUMP_FILE}:/docker-entrypoint-initdb.d/dump.sql
environment:
MYSQL_ROOT_PASSWORD: ${WORDPRESS_DB_PASS}
...
volumes:
db_files:
name: ${COMPOSE_SITE_NAME}_db_files
如果卷丢失了,那么可以使用转储文件重新创建它。在我的情况下,我更喜欢创建一个转储文件,而不是在/var/lib/mysql
文件夹中保留SQL文件的嘈杂声。
docker-compose exec db sh -c '
mysqldump -uroot -p$MYSQL_ROOT_PASSWORD --all-databases --routines --triggers
' | gzip -c > /path/outside/docker/backup-`date '+%Y-%m-%d'`.sql.gz
由于stdout重定向(>
),这将在Docker之外的主机上创建一个压缩转储文件。我使用sh -c ''
,所以我可以在容器中重用MYSQL_ROOT_PASSWORD
env变量。请随意调整以适应您的MySQL需求,例如指定一个有限的用户。
使用默认标志,转储文件将具有DROP TABLE IF EXISTS
语句,因此您可以替换现有的DB而无需删除卷(docker-compose down
然后docker volume rm ...
)。
我强烈建议不要使用放弃基于sql的备份,转而支持docker卷备份(针对数据库数据)!
虽然可能会忍不住这样做(很容易设置和自动化)你应该记住不保证您将检索您的数据。Docker卷转储不仅包含数据,还包含数据的结构(这在所有平台中并不通用)。
我可以举一个例子,当你想在另一个磁盘上使用你的docker卷转储时,它可能无法工作。例如:
- 你有你的docker容器(与SQL服务器)在机器
M-1
和卷在持久存储(磁盘)D-1
- 您想要在机器
M-2
上设置另一个容器化服务器,磁盘D-2
(假设这一个比D-1
有更多的空间 - 当格式化
D-2
时,您使用的块大小与D-1
不同 - 您将
D-1
上的卷转储到.tar,并希望将其加载到D-2
上的卷(例如从生产到开发) - 你在
M-2
上运行你的服务器并期望它工作
很可能它就是不会。此外,错误消息可能具有误导性,并且调试起来很痛苦。最糟糕的是,有时它可能工作,有时不(取决于磁盘格式化在这种情况下)。
查看MySQL官方文档,他们建议在dockerized服务器上使用mysqldump
的方法(忽略它们是不明智的)。