Metabase 怎么把 H2 应用数据库迁移到 PostgreSQL?
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
如果你的 Metabase 还在用内置的 H2 应用数据库,而你已经准备把它投入生产环境,就需要完成一次应用数据库迁移:把 H2 文件里保存的所有 Metabase 应用数据(问题、仪表盘、集合、用户等)导入一个 PostgreSQL 实例。H2 是 Metabase 默认附带的文件型嵌入式数据库,官方文档明确不推荐在生产中使用它——它位于磁盘文件上,对文件系统错误敏感,一旦损坏且没有备份,这些数据都会丢失。迁移是一次性操作,可以从任何持有 H2 应用数据库文件的机器上执行。本文基于 Migrating to a production application database 和 H2 迁移排查指南,先给出 JAR 部署的主路径,再给出 Docker 部署的替代路径。
迁移前:确认当前用的是 H2,并满足版本要求
作为管理员,调用GET /api/bug-reporting/details接口查看当前应用数据库。文档给出的返回示例如下:
{ "application-database": "h2" }这是文档示例。如果application-database字段的值不是postgres或mysql,说明你正在使用嵌入式 H2。也可以在 Admin Panel 的 Tools 标签页往下滚动到 "Diagnostic Info",查看其中显示的 JSON。
版本要求是这次迁移里最容易踩的坑:
- 整个迁移过程必须使用同一版本的 Metabase。运行迁移命令的 Metabase 版本,必须与最后一次创建或更新 H2 文件的版本一致,并且这也是你之后要在生产环境使用的版本。只有在迁移完成之后,才考虑升级 Metabase。
- 迁移期间不要同时做升级操作。
- 目标 PostgreSQL 的最低版本为
14。Postgres 是官方推荐的应用数据库。
另外,运行迁移命令的环境必须能连上目标应用数据库。如果目标库在云端,先确认从执行命令的机器可以访问它。
准备目标 PostgreSQL 数据库
Metabase 不会替你创建 Postgres 数据库,需要预先建好。文档给出的示例命令:
createdb --encoding=UTF8 -e metabase同时要注意:Metabase 期望针对一个全新的(空)数据库执行迁移,它会自动创建 schema 并导入数据。不要指向一个已经有其他内容的库。
JAR 部署:执行 H2 到 PostgreSQL 的迁移
以下顺序来自文档:确认连接、停止实例、备份 H2、运行迁移命令、重新启动。
1. 停止 Metabase 并备份 H2 文件
停止 Metabase 进程,避免迁移期间有人继续创建内容。如果 Metabase 以服务方式运行,停止服务即可。
然后备份应用数据库文件。备份方法见 Backing up Metabase:把 H2 文件(metabase.db.mv.db)复制一份存到安全的位置。较早版本的文件名可能是metabase.db.h2.db,可以在 Metabase 目录下执行ls metabase.*确认实际文件。这个备份在迁移出错时是恢复数据的唯一途径,没有备份就不要继续。
2. 运行 load-from-h2 迁移命令
用指向 PostgreSQL 的环境变量运行load-from-h2命令。文档示例:
export MB_DB_TYPE=postgres export MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db命令中的<host>、<username>、<password>、/path/to/metabase.db需要替换为你实际的目标库主机、账号、密码和 H2 文件路径。
关键细节:传给命令的 H2 路径不能带.mv.db扩展名。文件本身可能叫/path/to/metabase.db.mv.db,但 H2 会自动在命令行指定的路径后追加扩展名,所以参数要截断成/path/to/metabase.db。
如果不想用完整的 JDBC 连接串,也可以改用单独的环境变量,文档给出的另一组示例:
export MB_DB_TYPE=postgres export MB_DB_DBNAME=metabase export MB_DB_PORT=5432 export MB_DB_USER=<username> export MB_DB_PASS=<password> export MB_DB_HOST=localhost java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db如果密码包含特殊字符,还可以把MB_DB_CONNECTION_URI与MB_DB_USER、MB_DB_PASS分开设置,避免特殊字符出现在连接串里。各变量的含义见 环境变量参考。此外,MB_DB_FILE在迁移时也可以用来指定从哪个 H2 文件读取现有数据。
3. 用 PostgreSQL 启动 Metabase
迁移命令执行完后,用新的数据库连接信息(不带load-from-h2参数)正常启动 Metabase:
export MB_DB_TYPE=postgres export MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar文档同时建议:旧的 H2 文件先保留下来,作为安全备份。
Docker 部署:替代路径
如果你是用 Docker 容器跑的 Metabase,流程是:确认连接、备份 H2 文件、停止旧容器、下载 JAR、执行迁移、启动新容器、移除旧容器。
备份 H2 文件:把 H2 文件从容器里拷出来,例如容器名为
metabase时执行:docker cp metabase:/metabase.db/metabase.db.mv.db ./这会复制到你执行命令的当前目录。没有备份就替换或删除容器,会丢失全部应用数据。
停止现有 Metabase 容器。
下载与当前 Metabase 相同版本的 JAR(放在保存 H2 文件的目录里,即容器外)。如果想升级 Metabase,等确认迁移成功后再升级。
在 H2 文件和 JAR 所在的目录运行迁移命令,与 JAR 部署部分相同:
export MB_DB_TYPE=postgres export MB_DB_CONNECTION_URI="jdbc:postgresql://<host>:5432/metabase?user=<username>&password=<password>" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.dbMetabase 会启动、完成数据迁移,然后退出。
启动指向新应用数据库的容器,文档示例:
docker run -d -p 3000:3000 \ -e "MB_DB_TYPE=postgres" \ -e "MB_DB_DBNAME=<your-postgres-db-name>" \ -e "MB_DB_PORT=5432" \ -e "MB_DB_USER=<db-username>" \ -e "MB_DB_PASS=<db-password>" \ -e "MB_DB_HOST=<your-database-host>" \ --name metabase metabase/metabase尖括号内的值替换为你的数据库名、账号、密码和主机。
确认无误后移除旧的 H2 容器。前提是 H2 文件已经备份到安全位置。
验证迁移结果
- 迁移命令本身:Metabase 启动、把 H2 文件里的数据导入新应用数据库,然后退出,不再继续运行。
- 用新的 Postgres 连接启动 Metabase 后,再次调用
GET /api/bug-reporting/details(或查看 Admin Panel 的 Diagnostic Info),此时application-database字段应为postgres。按文档的判定逻辑,只要该字段不是postgres或mysql,就说明实例仍在用 H2。 - 旧 H2 文件继续保留,不删除。
常见问题排查
以下问题均来自 H2 排查指南:
报
Command failed with exception: Unsupported database file version or invalid file header in file <YOUR FILENAME>:传给load-from-h2的路径带了.mv.db扩展名。先确认导出的文件确实是metabase.db.mv.db,再把不含扩展名的路径传给命令。启动时报
liquibase.exception.DatabaseException: liquibase.exception.LockException: Could not acquire change log lock.:上一次运行残留的锁没有正常释放。先执行释放锁命令,然后按正常方式(不带migrate release-locks参数)重启 Metabase:java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate release-locksWindows 10 上 JAR 报
java.lang.AssertionError: Assert failed: Unable to connect to Metabase DB.:某些情况下 JAR 需要创建本地文件的权限。右键 Metabase JAR 文件(不是应用数据库文件),选择 Properties,点 Unblock。H2 文件太大导致启动超时报 "Timeout":默认加载超时是 5 秒。文档的首选建议就是改用 PostgreSQL 作为应用数据库,也可以到 Admin Panel 调大应用数据库的超时设置。
限制与回退
- 迁移是一次性过程;执行前必须备份 H2 文件,迁移命令要求目标库是全新空库。
- Metabase不支持降级。如果之后需要从新版本退回,文档给出的做法是:停止 Metabase,恢复升级/尝试前备份的应用数据库副本,恢复旧版本的 JAR 或容器,再重启。迁移失败时同理,恢复 H2 备份即可退回原状态。
- 迁移与版本升级要分开做:先用当前版本完成 H2 到 PostgreSQL 的迁移,确认没问题后再升级 Metabase。
更多应用数据库配置细节(含 MySQL/MariaDB、SSL 连接参数)见 Configuring the application database。
【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考