使用 Docker 官方镜像进行迁移

在这篇博客中,我们将探讨 如何设置一个 docker compose 文件以便从 MySQL 5.7 迁移到最新的 MariaDB。
在下一篇博客中,我们将解释如何设置一个 docker compose 文件以便从 MySQL 8.0 迁移到 MariaDB。
从 MySQL 5.7 迁移到 MariaDB 的步骤如下:
- 通过运行 docker-compose 文件启动容器
- 使用 MySQL 数据目录并使用 MARIADB_AUTO_UPGRADE=1 启动 MariaDB
让我们来探讨每个步骤。
1. 启动 MySQL
MySQL 容器使用以下 docker-compose 文件启动。
# compose-mysql.yml
version: "3"
services:
mysql:
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: ${DB_DATABASE}
container_name: ${MYSQL_name}
image: mysql:5.7
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"]
interval: 5s
timeout: 3s
retries: 2
start_period: 0s
volumes:
# Preload files for MySQL data
- ./mysql:/docker-entrypoint-initdb.d:z
# We have to save MySQL volume that will be used in upgrade
- dbdata:/var/lib/mysql
volumes:
dbdata: {}
networks:
backend:
- 验证它是否正在运行
$ docker compose -f compose-mysql.yml up
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a24898f78c7 mysql:5.7 "docker-entrypoint.s…" 27 seconds ago Up 15 seconds (healthy) 3306/tcp, 33060/tcp mysql-container
- 验证表和数据
$ docker exec -it mysql-container mysql -uroot -psecret -e "select * from testdb.countries"
+----------------------+
| name |
+----------------------+
| Bosnia & Herzegovina |
+----------------------+
- 目标是在迁移到 MariaDB 服务器后获取这些数据。
- 停止容器
$ docker compose -f compose-mysql.yml down
[+] Running 3/3
✔ Container mysql-container Removed 1.6s
✔ Network migrate-mysql-mariadb_default Removed
- 通过检查命名卷来检查数据目录
$ docker volume ls -f name=dbdata
DRIVER VOLUME NAME
local migration-57_dbdata
2. 使用 MySQL 数据目录并使用 MARIADB_AUTO_UPGRADE=1 启动 MariaDB
- 启动一个新的 docker-compose 文件 compose-migrate-mysql.yml,该文件将环境变量 MARIADB_AUTO_UPGRADE 设置为非空值。
- 通过此更改,将在用作 MariaDB 数据目录的 MySQL 数据目录卷上调用
mariadb-upgrade
。
# compose-migrate-mysql.yml
version: "3"
services:
mariadb-from-mysql57:
environment:
MARIADB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MARIADB_USER: ${DB_USER}
MARIADB_PASSWORD: ${DB_PASSWORD}
MARIADB_AUTO_UPGRADE: 1
container_name: ${MYSQL_MIGRATE_name}
image: mariadb:lts
volumes:
# MySQL data that we want to migrate
- dbdata:/var/lib/mysql
volumes:
dbdata: {}
- 结果如下所示
$ docker compose -f compose-migrate-mysql.yml up
mysql-container-migrated | 2024-01-04 13:28:35+00:00 [Note] [Entrypoint]: Temporary server started.
mysql-container-migrated | 2024-01-04 13:28:35+00:00 [Note] [Entrypoint]: Backing up system database to system_mysql_backup_unknown_version.sql.zst
mysql-container-migrated | 2024-01-04 13:28:35+00:00 [Note] [Entrypoint]: Backing up complete
mysql-container-migrated | 2024-01-04 13:28:35+00:00 [Note] [Entrypoint]: Starting mariadb-upgrade
mysql-container-migrated | The --upgrade-system-tables option was used, user tables won't be touched.
mysql-container-migrated | MariaDB upgrade detected
mysql-container-migrated | Phase 1/8: Checking and upgrading mysql database
...
mysql-container-migrated | 2024-01-04 13:28:41+00:00 [Note] [Entrypoint]: Finished mariadb-upgrade
mysql-container-migrated | 2024-01-04 13:28:41+00:00 [Note] [Entrypoint]: Stopping temporary server
mysql-container-migrated | 2024-01-04 13:28:41 0 [Note] mariadbd (initiated by: unknown): Normal shutdown
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
983036482fb3 mariadb:lts "docker-entrypoint.s…" 15 seconds ago Up 14 seconds 3306/tcp mysql-container-migrated
- 由于未设置
MARIADB_DISABLE_UPGRADE_BACKUP
变量,因此还会创建备份。通过将此变量设置为非空值可以删除备份。 - 要检查备份,请运行
$ docker exec mysql-container-migrated sh -c 'ls /var/lib/mysql/*zst'
/var/lib/mysql/system_mysql_backup_unknown_version.sql.zst
- 最后,我们应该通过检查启动的容器上的数据来验证升级是否成功完成
$ docker exec -it mysql-container-migrated mariadb -uroot -psecret -e "select * from testdb.countries"
+----------------------+
| name |
+----------------------+
| Bosnia & Herzegovina |
+----------------------+
- 请注意,您不能再在 MySQL 中使用 MariaDB 数据目录,这是一个不可逆的过程。
# Not started container
$ docker run --name new-mysql-container-with-mariadb -v ./mysql-volume:/var/lib/mysql -eMYSQL_ROOT_PASSWORD=secret -d mysql:5.7
# Check logs
2024-01-04T13:38:30.761747Z 0 [ERROR] InnoDB: Only one log file found.
2024-01-04T13:38:30.761757Z 0 [ERROR] InnoDB: Plugin initialization aborted with error not found
2024-01-04T13:38:31.362301Z 0 [ERROR] Plugin 'InnoDB' init function returned error.
2024-01-04T13:38:31.362327Z 0 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2024-01-04T13:38:31.362332Z 0 [ERROR] Failed to initialize builtin plugins.
2024-01-04T13:38:31.362334Z 0 [ERROR] Aborting
- 停止容器并移除卷以清理空间
$ docker compose -f compose-migrate-mysql.yml down -v
[+] Running 3/3
✔ Container mysql-container-migrated Removed 0.5s
✔ Volume migration-57_dbdata Removed 0.0s
✔ Network migration-57_default Removed
结论和进一步阅读
本博客展示了如何使用单步流程轻松地将容器中的 MySQL 5.7 迁移到最新的 MariaDB 版本。
如果您在本博客中遇到任何问题,无论是设计问题,还是未按预期工作的边缘情况,请告知我们。欢迎您在 Zulip 上讨论。一如既往,您可以使用我们的 JIRA 问题跟踪器,指定 MDEV 项目,提交您可能遇到的任何错误/功能请求。