Metabase 应用数据库配置完全指南:从 PostgreSQL/MySQL 选型到 H2 迁移实战
2026/9/18 21:33:17 网站建设 项目流程

Metabase 应用数据库配置完全指南:从 PostgreSQL/MySQL 选型到 H2 迁移实战

【免费下载链接】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 的**应用数据库(Application Database)**是存放用户账号、问题(Question)、仪表盘(Dashboard)等全部 Metabase 内部数据的核心存储,它与存放业务数据的数据仓库是两个完全不同的概念。本文基于当前仓库 docs/installation-and-operation/configuring-application-database.md 展开,完整覆盖 PostgreSQL、MySQL/MariaDB、H2 三种应用数据库的配置方法、环境变量详解、SSL 连接注意事项,并结合仓库源码剖析 Metabase 底层如何解析连接信息、如何构建数据源,帮助你为生产环境选型并完成从默认 H2 到生产级数据库的迁移。

什么是应用数据库

Metabase 在运行过程中需要保存两类截然不同的数据:

  • 应用数据库(App DB):Metabase 自身产生的内部数据,包括用户账号、问题、仪表盘、集合(Collection)、定时任务、权限设置等。
  • 数据仓库(Data Warehouse):你通过 Metabase 连接和分析的业务数据库,连接方式见 Connecting to a supported database。

两者必须区分清楚:配置应用数据库是部署 Metabase 自身的第一步,而连接数据仓库则是后续分析业务的配置项。

Metabase 会在应用启动时读取应用数据库的连接配置,运行期间无法动态更换应用数据库——任何连接信息的修改都需要重启应用(或重新部署容器)才能生效。这是理解后续所有配置方式的前提。

支持的数据库选型

官方文档明确给出的选型建议是:

数据库生产建议最低版本要求说明
PostgreSQL✅ 推荐官方支持"最老的仍受支持版本"至最新稳定版生产首选
MySQL / MariaDB⚠️ 可用MySQL 8.4.0 / MariaDB 10.6.0,必须使用utf8mb4字符集也能支撑生产
H2❌ 仅限本地演示默认内置,生产环境必须避免

另外注意:不支持阿里云 ApsaraDB MySQL,如使用阿里云可改用 ApsaraDB PostgreSQL。

使用 PostgreSQL 作为应用数据库

PostgreSQL 是生产环境的首选。Metabase 支持从"官方仍在支持的最老版本"一直到最新稳定版。

方式一:拆分环境变量

通过一组MB_DB_*环境变量指定连接信息:

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

Metabase不会帮你创建数据库,需要提前手动创建。使用createdb工具(注意显式指定 UTF-8 编码):

createdb --encoding=UTF8 -e metabase

方式二:完整 JDBC 连接串

如果连接包含额外参数(如 SSL、连接超时等),可以直接使用MB_DB_CONNECTION_URI提供完整 JDBC 连接串:

export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase?user=<username>&password=<password>" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

方式三:连接串 + 独立账号密码

当密码包含&?=等 JDBC 连接串中的特殊字符时,URL 编码容易出错。此时建议只把用户名和密码放入环境变量,与连接串分离。该组合方式自 Metabase 0.43.0 起支持(对应 issue #20122,源码注释见 src/metabase/app_db/env.clj):

export MB_DB_CONNECTION_URI="jdbc:postgresql://localhost:5432/metabase" export MB_DB_USER=<username> export MB_DB_PASS=<password> java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

源码视角:环境变量如何被解析

在 src/metabase/app_db/env.clj 中可以清楚看到连接信息的三种来源及优先级:

  1. MB_DB_TYPEMB_DB_HOSTMB_DB_PORTMB_DB_DBNAMEMB_DB_USERMB_DB_PASS拆分指定(对应broken-out-details函数);
  2. MB_DB_CONNECTION_URI单条 JDBC 连接串指定(raw-connection-string->DataSource);
  3. 连接串 + 独立的MB_DB_USER/MB_DB_PASS(0.43.0 起)。

MB_DB_CONNECTION_URI与拆分变量同时存在时,连接串优先env->db-typeenv->DataSource都优先使用mb-db-connection-uri)。同时,env-defaults方法还内置了默认值::postgres默认localhost:5432:mysql默认localhost:3306,这意味着即便你不显式设置MB_DB_HOSTMB_DB_PORT,Metabase 也会自动补齐(见 src/metabase/app_db/env.clj)。

在 src/metabase/app_db/data_source.clj 的raw-connection-string->DataSource中还有几处值得注意的兼容处理:

  • 连接串以postgres:开头会被自动改写为postgresql:,缺少jdbc:前缀会自动补齐(兼容 Heroku 等平台传入的裸协议串);
  • 兼容jdbc:postgresql://user:password@host:port/db这种 URL 内嵌账号密码的旧写法(issue #14678、#20121);
  • 当连接串内嵌账号密码与MB_DB_USER/MB_DB_PASS同时存在时,环境变量中的值优先,且会打印错误日志提示;
  • 每个新连接都会被显式设置为READ_COMMITTED事务隔离级别,避免 MySQL/MariaDB 默认的REPEATABLE_READ引发频繁锁表导致性能问题。

使用 MySQL 或 MariaDB 作为应用数据库

虽然官方推荐 PostgreSQL,但 MySQL 与 MariaDB 也支持生产使用。最低推荐版本为MySQL 8.4.0 或 MariaDB 10.6.0,且必须使用utf8mb4字符集

环境变量配置

export MB_DB_TYPE=mysql export MB_DB_DBNAME=metabase export MB_DB_PORT=3306 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

同样,Metabase 不会自动建库,需要手动执行 SQL(显式指定字符集与排序规则):

CREATE DATABASE metabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

JDBC 连接串方式

export MB_DB_CONNECTION_URI="jdbc:mysql://localhost:3306/metabase?user=<username>&password=<password>" java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

与 Postgres 一样,也可以把用户/密码拆出来独立设置(注意官方示例中端口写的是 5432,MySQL 实际应使用 3306):

export MB_DB_CONNECTION_URI="jdbc:mysql://localhost:3306/metabase" export MB_DB_USER=<username> export MB_DB_PASS=<password> java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

源码视角:驱动与默认参数

在 src/metabase/app_db/spec.clj 中可以看到,Metabase 底层实际使用MariaDB 的 JDBC 驱动org.mariadb.jdbc.Driver)来连接 MySQL 应用数据库,并默认使用OpenSourceSubProtocolOverride避免与 Redshift 驱动冲突。make-subname函数会把 host/port/db 拼接成//host:port/db形式的 subname。

H2 应用数据库(默认,仅限本地演示)

Metabase 默认内置 H2 数据库 明确指出:如果持续使用 H2 且不定期备份,应用数据库可能损坏,导致所有问题、仪表盘、集合数据丢失。

默认行为:自动创建 H2 文件

如果不提供任何应用数据库连接环境变量,Metabase 会在JAR 文件所在目录自动创建 H2 数据库文件。可以通过ls命令查看:

ls metabase.*

你会看到以下文件:

metabase.db.h2.db # 或者 metabase.db.mv.db(取决于首次启动 Metabase 的版本) metabase.db.trace.db

metabase.db.h2.db对应旧的 PageStore 存储引擎,metabase.db.mv.db对应新版默认的 MVStore 引擎。

指定 H2 文件位置

使用MB_DB_TYPE=h2配合MB_DB_FILE指定数据库文件路径:

export MB_DB_TYPE=h2 export MB_DB_FILE=/the/path/to/my/h2.db java --add-opens java.base/java.nio=ALL-UNNAMED -jar metabase.jar

关键注意点:H2 会自动为路径追加.mv.db.h2.db后缀,因此MB_DB_FILE不能包含扩展名。也就是说应写/path/to/metabase.db,而不是/path/to/metabase.db.mv.db(即使后者才是实际生成的文件名)。

源码视角:H2 连接细节

src/metabase/app_db/env.clj 揭示了 H2 连接的底层细节:

  • 路径会被转换为file:绝对路径形式(get-db-file函数);
  • 连接属性包含DB_CLOSE_DELAY=-1(JVM 关闭前不关闭数据库)、MVCC=true(为 Quartz JDBC 后端启用行级锁支持,避免死锁)、DEFRAG_ALWAYS=true(关闭时碎片整理,可减少数 GB 空间)、LOCK_TIMEOUT=60000(锁等待时间从默认 1 秒延长到 1 分钟);
  • 当检测到db-type:h2时,启动阶段会打印醒目的红色 WARNING,明确提示 H2 不推荐用于生产部署(见 src/metabase/app_db/env.clj)。

从 H2 迁移到生产数据库

如果你已经用默认 H2 创建了内容,Metabase 提供有限的迁移支持:H2 → PostgreSQL。完整迁移步骤(含 JAR 与 Docker 两种方式的命令)见 Migrating to a production application database,核心命令如下:

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 # 不要包含 .mv.db

迁移的要点:

  • 迁移全程必须使用同一个 Metabase 版本:迁移命令所用的版本、最后写入 H2 文件的版本、以及生产环境的版本必须一致,迁移成功之后再考虑升级;
  • 目标数据库必须是全新的空库,Metabase 会自动创建 schema 并搬移数据;
  • load-from-h2参数路径同样不能带.mv.db后缀
  • 迁移前务必备份 H2 文件,参见 Backing up Metabase Application Data。

从源码看,load-from-h2命令实现在 src/metabase/cmd/load_from_h2.clj:它读取 H2 数据源后调用copy/copy!将数据按实体依赖顺序复制到目标库,随后检查加密状态——如果设置了MB_ENCRYPTION_SECRET_KEY而迁移的数据未加密,会立即对目标库执行加密;若 H2 用与当前密钥不同的密钥加密,则直接抛出异常。

从 0.38 之前版本升级的 SSL 注意事项

Metabase 0.38 起移除了 PostgreSQL 连接中NonValidatingFactory的默认使用。如果从旧版本升级,可能在启动时(PostgreSQL 应用数据库)或查询 PostgreSQL 数据仓库时遇到 SSL 校验失败。解决方式有两种:

  1. 为 PostgreSQL 连接配置 SSL 证书校验(推荐);
  2. 手动启用NonValidatingFactory不安全,仅用于排障或安全要求不高的场景)。

针对 PostgreSQL 应用数据库

使用MB_DB_CONNECTION_URI开启证书校验:

export MB_DB_CONNECTION_URI="postgres://localhost:5432/metabase?user=<username>&password=<password>&sslmode=verify-ca&sslrootcert=<path to CA root or intermediate root certificate>"

无法启用证书校验时,可临时启用NonValidatingFactory

export MB_DB_CONNECTION_URI="postgres://localhost:5432/metabase?user=<username>&password=<password>&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory"

针对 PostgreSQL 数据仓库数据库

在数据仓库的 JDBC 连接串末尾追加以下参数:

&sslmode=verify-ca&sslrootcert=<path to CA root or intermediate root certificate>

若仍失败,追加(不安全方案):

&ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory

更详细的 SSL 参数可参考 PostgreSQL JDBC 官方 SSL 客户端文档。

源码中的额外提示

Metabase 在 src/metabase/app_db/env.clj 中还会做一项善意检查:如果检测到 Postgres 连接串包含ssl=true但缺少sslmode=require,会打印警告,提示你可能需要在连接串中补充?sslmode=require,否则应用可能无法启动(对应 issue #8908)。

应用数据库环境变量速查

以下参数均在 Environment variables 中有完整定义(该文档由源码clojure -M:ee:doc environment-variables-documentation自动生成):

环境变量类型默认值说明
MB_DB_TYPEstring"h2"取值"h2""postgres""mysql"。为h2时使用MB_DB_FILE,否则使用MB_DB_HOST
MB_DB_CONNECTION_URIstringnullJDBC 风格连接串,可替代大部分MB_DB_*变量,优先级最高
MB_DB_HOSTstringnull应用数据库主机名或 IP
MB_DB_PORTintegernull应用数据库端口(Postgres 默认 5432、MySQL 默认 3306 由源码补齐)
MB_DB_DBNAMEstringnull应用数据库名,配合MB_DB_HOST使用
MB_DB_USERstringnull连接用户名
MB_DB_PASSstringnull连接密码
MB_DB_FILEstring"metabase.db"H2 文件路径,不得包含.mv.db/.h2.db后缀;也可用于load-from-h2指定数据来源
MB_DB_AUTOMIGRATEbooleantruefalse时 Metabase 打印需要手工执行的迁移 SQL 并退出
MB_DB_AWS_IAMbooleanfalse(v0.58.0+)通过 AWS IAM 认证连接 AWS RDS/Aurora 上的 PostgreSQL/MySQL,需省略MB_DB_PASS
MB_DB_AZURE_MANAGED_IDENTITY_CLIENT_IDstringnull(v0.51.0+)用 Azure 托管身份认证连接 PostgreSQL/MySQL,需省略MB_DB_PASS,属于 Pro/Enterprise 功能
MB_DB_SSL_CERTstringnull(v0.58.0+)MySQL/MariaDB 在 AWS IAM 认证下的 SSL 配置:"trust"或 PEM 证书文件路径

补充几个容易踩坑的细节:

  • MB_DB_CONNECTION_URI中的currentSchema参数无效,PostgreSQL 应用数据库的 schema 必须是public(见 environment-variables.md);
  • 环境变量的优先级高于Admin 面板中的设置,且环境变量不会写入应用数据库;
  • 通过MB_DB_AUTOMIGRATE=false可查看并手动执行数据库迁移:启动时会输出Database Upgrade Required提示与完整的 Liquibase SQL 脚本,执行完后再正常启动。注意它与 H2→生产库的迁移(load-from-h2)是两回事。

手工执行应用数据库迁移

正常情况下 Metabase 启动时会自动检测并执行应用数据库 schema 变更。如果你想先查看这些变更再手动执行,只需在启动前设置:

export MB_DB_AUTOMIGRATE=false

启动后若检测到需要变更,Metabase 会输出类似下面的信息并停止启动:

2015-12-01 12:45:45,805 [INFO ] metabase.db :: Database Upgrade Required NOTICE: Your database requires updates to work with this version of Metabase. Please execute the following sql commands on your database before proceeding. -- ********************************************************************* -- Update Database Script -- ********************************************************************* -- Change Log: migrations/liquibase.yaml ...

将输出的 SQL 脚本手动应用到数据库后重启 Metabase 即可。迁移过程遇到问题可参考 Loading from H2 troubleshooting guide。

总结

配置 Metabase 应用数据库的核心要点可以归纳为四条:

  1. 生产首选 PostgreSQL,通过MB_DB_TYPE/MB_DB_HOST/MB_DB_PORT/MB_DB_DBNAME/MB_DB_USER/MB_DB_PASS拆分变量或MB_DB_CONNECTION_URI连接串配置,密码含特殊字符时建议将用户密码拆出独立设置;
  2. MySQL/MariaDB 也可用于生产,但必须满足最低版本与utf8mb4字符集要求;
  3. H2 仅限本地演示,如果已经用了 H2 且内容需要保留,务必先备份再通过load-from-h2迁移到 PostgreSQL,且全程保持同一版本;
  4. 从 0.38 之前升级时留意 PostgreSQL SSL 校验策略变化,必要时按上文方案显式配置sslmode或(不安全的)NonValidatingFactory

更完整的参数列表可查阅 Environment variables,迁移细节见 Migrating to a production application database,生产环境部署建议参考 Running Metabase in production。

【免费下载链接】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),仅供参考

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

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

立即咨询