☰
Metabase 怎么把 H2 应用数据库迁移到 PostgreSQL?
2026/10/4 0:31:08 网站建设 项目流程

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、执行迁移、启动新容器、移除旧容器。

  1. 备份 H2 文件:把 H2 文件从容器里拷出来,例如容器名为metabase时执行:

    docker cp metabase:/metabase.db/metabase.db.mv.db ./

    这会复制到你执行命令的当前目录。没有备份就替换或删除容器,会丢失全部应用数据。

  2. 停止现有 Metabase 容器。

  3. 下载与当前 Metabase 相同版本的 JAR(放在保存 H2 文件的目录里,即容器外)。如果想升级 Metabase,等确认迁移成功后再升级。

  4. 在 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.db

    Metabase 会启动、完成数据迁移,然后退出。

  5. 启动指向新应用数据库的容器,文档示例:

    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

    尖括号内的值替换为你的数据库名、账号、密码和主机。

  6. 确认无误后移除旧的 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-locks
  • Windows 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询