使用 H2 应用程序数据库或从中迁移
您已安装 Metabase,但是
- 您正尝试将应用程序数据库从 H2 迁移到另一个数据库,但出现了一些问题,
- 您正尝试降级而不是升级,
- 当您尝试运行 Metabase 时,Metabase 记录了
liquibase
错误消息, - Metabase 记录了另一个错误消息,其中提到了
H2
或h2
,当它正在运行时,或者 - 您使用的是 Windows 10,并收到有关文件权限的警告。
您当前是否正在使用 H2 作为您的应用程序数据库?
根本原因: Metabase 将有关用户、问题等信息存储在它自己的数据库中,称为“应用程序数据库”,或简称为“app database”。默认情况下,Metabase 使用 H2 作为应用程序数据库,但我们不建议在生产环境中使用它——因为它是一个磁盘数据库,它对文件系统错误很敏感,例如驱动器损坏或文件未正确刷新。
采取的步骤
- 要检查您正在使用什么作为应用程序数据库,请转到管理面板,打开故障排除选项卡,向下滚动到“诊断信息”,并在其显示的 JSON 中查找
application-database
键。 - 请参阅从 H2 迁移,了解如何迁移到更强大的应用程序数据库的说明。
您是否正在尝试将应用程序数据库从 H2 迁移到其他数据库?
根本原因:您正在尝试使用 load-from-h2
命令将应用程序数据库从 H2 迁移到 PostgreSQL 或 MySQL/MariaDB 等生产数据库,但这失败了,因为数据库文件名不正确,并显示如下错误消息
Command failed with exception: Unsupported database file version or invalid file header in file <YOUR FILENAME>
采取的步骤
-
创建导出的 H2 数据库的副本(请参阅备份 Metabase 应用程序数据)。在您完成此操作之前,请勿继续,以防出现问题。
-
检查您导出的 H2 数据库文件是否命名为
metabase.db.mv.db
。 -
H2 会自动将
.mv.db
扩展名添加到您在命令行上指定的数据库路径,因此请确保您传递给命令的 DB 文件路径不包含.mv.db
扩展名。例如,如果您已导出应用程序数据库,并且想要使用load-from-h2
将数据从该 H2 数据库加载到 PostgreSQL 数据库中,则您的命令将类似于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 # do not include .mv.db
如果您使用的是 Metabase 的 Pro 或企业版,您可以使用序列化来快照您的应用程序数据库。当您想要在新 Metabase 实例中预加载问题和仪表盘时,序列化非常有用。
您是否正在尝试降级?
根本原因:Metabase 不支持降级(即,恢复到应用程序的早期版本)。
采取的步骤
- 关闭 Metabase。
- 恢复您在尝试升级或降级之前制作的应用程序数据库备份副本。
- 恢复您想要恢复到的旧版本的 JAR 文件或容器。
- 重启 Metabase。
应用程序数据库是否已锁定?
根本原因:有时 Metabase 启动失败,因为应用程序数据库锁在上一次运行时没有正确清除。错误消息类似于
liquibase.exception.DatabaseException: liquibase.exception.LockException: Could not acquire change log lock.
采取的步骤
-
在安装 Metabase 的服务器上打开一个 shell,并通过运行以下命令手动清除锁
java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar migrate release-locks
-
此命令完成后,正常重启您的 Metabase 实例(不带
migrate release-locks
标志)。
应用程序数据库是否已损坏?
根本原因:H2 的可靠性不如生产质量的数据库管理系统,有时数据库本身会损坏。这可能会导致应用程序数据库中的数据丢失,但不会损坏 Metabase 连接的数据库中的数据。
采取的步骤:错误消息可能因应用程序数据库的损坏方式而异,但在大多数情况下,日志消息会提到 h2
。典型的命令和消息是
myUser@myIp:~$ java --add-opens java.base/java.nio=ALL-UNNAMED -cp metabase.jar org.h2.tools.RunScript -script whatever.sql -url jdbc:h2:~/metabase.db
Exception in thread "main" org.h2.jdbc.JdbcSQLException: Row not found when trying to delete from index """"".I37: ( /* key:7864 */ X'5256470012572027c82fc5d2bfb855264ab45f8fec4cf48b0620ccad281d2fe4', 165)" [90112-194]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
[etc]
如何修复此问题:并非所有 H2 错误都是可恢复的(这就是为什么如果您正在使用 H2,请为应用程序数据库文件制定备份策略)。
如果您正在运行最新版本并使用 H2,则应用程序数据库存储在 metabase.db.mv.db
中。- 在运行 Metabase 实例的服务器上打开一个 shell,并尝试通过运行以下四个命令来恢复损坏的 H2 文件
java -cp metabase.jar org.h2.tools.Recover
mv metabase.db.mv.db metabase-old.db.mv.db
touch metabase.db.mv.db
java --add-opens java.base/java.nio=ALL-UNNAMED -cp target/uberjar/metabase.jar org.h2.tools.RunScript -script metabase.db.h2.sql -url jdbc:h2:`pwd`/metabase.db
您是否在 Windows 10 上使用 H2 运行 Metabase?
根本原因:在 Windows 10 上的某些情况下,Metabase JAR 需要具有创建应用程序数据库本地文件的权限。运行 JAR 时,您会看到如下错误消息
Exception in thread "main" java.lang.AssertionError: Assert failed: Unable to connect to Metabase DB.
采取的步骤
- 右键单击 Metabase JAR 文件(不是应用程序数据库文件)。
- 选择“属性”。
- 选择“解除阻止”。
应用程序数据库是否加载时间过长?
根本原因:您正在使用 H2 作为您的应用程序数据库,并且应用程序数据库非常大,以至于无法在少于 5 秒的时间内加载(这是默认的超时值)。当您尝试启动 Metabase 时,您将在控制台中看到“超时”消息。
采取的步骤
- 使用 PostgreSQL 等生产质量的数据库作为应用程序数据库(首选)。
- 转到管理面板并增加应用程序数据库的超时设置。
- 将 Metabase 移动到更快的服务器(特别是具有更快磁盘的服务器)。
阅读其他Metabase 版本的文档。