使用或迁移到 H2 应用数据库

您已安装了Metabase,但

  • 您正在尝试将应用程序数据库从H2迁移到另一个数据库,但出现了问题,
  • 您尝试降级而不是升级,
  • 当您尝试运行时,Metabase记录了一个liquibase错误消息,
  • 或者当它在运行时记录另一个提及H2h2的错误消息,或者
  • 您在使用Windows 10时收到关于文件权限的警告。

您当前是否正在使用H2作为应用程序数据库?

根本原因: Metabase将其用户、问题等信息的存储在它自己的数据库中,称为“应用程序数据库”,或简称为“应用数据库”。默认情况下,Metabase使用H2作为应用程序数据库,但我们不建议在生产环境中使用它——因为它是一个磁盘数据库,对文件系统错误敏感,例如驱动器损坏或文件未正确刷新。

采取的步骤

  1. 要检查您正在使用什么作为应用数据库,请转到管理面板,打开故障排除选项卡,滚动到“诊断信息”,并在显示的JSON中查找application-database键。
  2. 有关如何迁移到更健壮的应用数据库的说明,请参阅从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>

采取的步骤

  1. 创建已导出的H2数据库的副本(见备份Metabase应用程序数据)。在出现问题之前,请完成此操作

  2. 请确保您导出的H2数据库文件命名为metabase.db.mv.db

  3. 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 -jar metabase.jar load-from-h2 /path/to/metabase.db # do not include .mv.db
    

如果您正在使用Metabase的专业版或企业版,则可以使用序列化来快照您的应用程序数据库。序列化在您想在新Metabase实例中预加载问题板和仪表板时很有用。

您是否正在尝试降级?

根本原因: Metabase不支持降级(即,回滚到应用程序的早期版本)。

采取的步骤

  1. 关闭Metabase。
  2. 恢复您在尝试升级或降级之前创建的应用数据库的备份副本。
  3. 恢复您要回滚到的较旧版本的JAR文件或容器。
  4. 重启Metabase。

应用数据库是否被锁定?

根本原因: 有时Metabase无法启动,因为上一个运行期间应用数据库锁没有正确清除。错误消息看起来像

liquibase.exception.DatabaseException: liquibase.exception.LockException: Could not acquire change log lock.

采取的步骤

  1. 在Metabase安装的服务器上打开一个shell,并手动运行以下命令来清除锁

    java -jar metabase.jar migrate release-locks
    
  2. 一旦此命令完成,正常重启您的Metabase实例(无需使用migrate release-locks标志)。

应用数据库是否损坏?

根本原因:H2 的可靠性不如生产级数据库管理系统,有时数据库本身也可能损坏。这可能导致应用数据库中的数据丢失,但不会损坏 Metabase 连接的数据库中的数据。

采取的步骤:错误信息可能因应用数据库损坏的方式而异,但在大多数情况下,日志消息会提到 h2。一个典型的命令和信息如下

myUser@myIp:~$ java -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 -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.

采取的步骤

  1. 右键单击 Metabase JAR 文件(不是应用程序数据库文件)。
  2. 选择“属性”。
  3. 选择“解除阻止”。

应用程序数据库加载是否太慢?

根本原因:您正在使用 H2 作为应用程序数据库,并且应用程序数据库太大,无法在 5 秒(默认超时值)内加载。当您尝试启动 Metabase 时,控制台将出现“超时”消息。

采取的步骤

  1. 为应用程序数据库使用生产级数据库,如 PostgreSQL(首选)。
  2. 转到 管理面板 并增加应用程序数据库的超时设置。
  3. 将 Metabase 移动到更快的服务器(特别是具有更快磁盘的服务器)。

阅读其他 Metabase 版本的文档

想要改进这些文档? 提出更改。