Metabase H2 应用数据库故障排查与迁移生产数据库实战指南
Metabase 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/metabaseMetabase 默认使用内置的 H2 文件型数据库作为应用数据库app database来保存用户、问题Question、仪表盘等全部元数据。H2 便于本地快速上手但并不适合生产环境一旦遭遇文件损坏、迁移失败、Liquibase 锁残留、加载超时等问题往往会让实例无法正常启动。本文基于仓库中的官方排障文档 docs/troubleshooting-guide/loading-from-h2.md结合load-from-h2、migrate release-locks等命令的源码实现系统梳理 H2 应用数据库各类典型故障的识别方法与处置步骤帮助你准确判断当前是否在用 H2、正确完成 H2 → PostgreSQL/MySQL 的迁移并掌握锁清理、损坏恢复与超时调优的实操手段。一、先弄清背景什么是 Metabase 的应用数据库Metabase 自身运行所需的所有元数据——用户账号、保存的问题、仪表盘、集合、权限设置等——都存放在一个独立的 SQL 数据库中官方称之为应用数据库application database简称 app database。它与你通过 Metabase 连接并分析的业务数据库是两回事业务库里的数据不受应用数据库故障影响但应用数据库一旦丢失你在 Metabase 里积累的全部配置和内容都会随之消失。默认情况下Metabase 启动时会自动创建并使用内置的 H2 数据库即当前目录下的metabase.db.mv.db文件。H2 是纯磁盘文件型数据库对文件系统错误如磁盘损坏、文件未能正确落盘非常敏感因此官方明确不推荐将其用于生产环境。仓库源码 src/metabase/cmd/load_from_h2.clj 中的注释也印证了这一点load-from-h2被定位为从 H2 升级到『真正的』数据库的工具Intended as a tool for upgrading from H2 to a real database。从源码结构看所有命令行操作都注册在 src/metabase/cmd/core.clj 中通过java ... -jar metabase.jar command或clojure -M:run command两种方式触发。本文涉及的两个核心命令定义如下migrate执行数据库迁移可选方向包括up、force、down、down-force、print、release-locksload-from-h2把现有 H2 数据库中的数据转移到由环境变量指定的新 MySQL 或 Postgres 数据库。二、如何确认自己是否正在使用 H2根因许多故障只存在于 H2 场景因此排障的第一步是确认当前应用数据库类型。处置步骤以管理员身份登录 Metabase进入Admin Panel管理面板打开Tools工具标签页向下滚动到 Diagnostic Info诊断信息查看其返回的 JSON 中application-database字段的值。更直接的方式是调用诊断 API。迁移文档 docs/installation-and-operation/migrating-from-h2.md 指出管理员可调用GET /api/bug-reporting/details返回结果形如{ application-database: h2 }只要该字段不是postgres或mysql就说明你仍在使用内置 H2 数据库。关于诊断信息的获取与日志查看方式可进一步参考 docs/troubleshooting-guide/diagnostic-info.md。若确认是 H2 且实例要用于生产请参考 docs/installation-and-operation/migrating-from-h2.md 迁移到更健壮的应用数据库如果打算迁移到 Metabase Cloud则可参阅 docs/cloud/migrate/guide.md。三、从 H2 迁移到 PostgreSQL/MySQL 失败load-from-h2与.mv.db后缀陷阱根因你试图用load-from-h2命令把应用数据库从 H2 迁往 PostgreSQL 或 MySQL/MariaDB 等生产级数据库但传入的数据库文件名有误导致命令报错典型报错信息为Command failed with exception: Unsupported database file version or invalid file header in file YOUR FILENAME这条报错的产生机制在源码中有明确对应命令分发入口 src/metabase/cmd/core.clj 的run-cmd会捕获命令执行抛出的异常并以Command failed with exception: message的格式输出而 src/metabase/cmd/load_from_h2.clj 在解析文件名时会拼接;IFEXISTSTRUE并交给 src/metabase/cmd/copy/h2.clj 的h2-data-source建立数据源文件头无法识别时即会抛出上述异常。处置步骤先复制一份导出的 H2 数据库文件留作备份备份方法见 docs/installation-and-operation/backing-up-metabase-application-data.md。在完成备份之前不要继续任何操作以防迁移过程出现意外导致数据丢失。检查导出的 H2 数据库文件是否名为metabase.db.mv.db。关键点H2 会自动为命令行中指定的数据库路径追加.mv.db扩展名。因此传给load-from-h2的路径不能包含.mv.db后缀。这一点在源码 src/metabase/cmd/copy/h2.clj 的add-file-prefix-if-needed中也有体现它会把以.mv.db结尾的路径去掉扩展名后再使用。例如要把导出的 H2 数据导入 PostgreSQL命令应形如export MB_DB_TYPEpostgres export MB_DB_DBNAMEmetabase export MB_DB_PORT5432 export MB_DB_USERusername export MB_DB_PASSpassword export MB_DB_HOSTlocalhost java --add-opens java.base/java.nioALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db # 不要带上 .mv.db也可使用连接串形式的等价写法来自 docs/installation-and-operation/migrating-from-h2.mdexport MB_DB_TYPEpostgres export MB_DB_CONNECTION_URIjdbc:postgresql://host:5432/metabase?userusernamepasswordpassword java --add-opens java.base/java.nioALL-UNNAMED -jar metabase.jar load-from-h2 /path/to/metabase.db迁移到 MySQL 时还可以用 JVM 参数替代环境变量java -DMB_DB_TYPEmysql -DMB_DB_CONNECTION_URIjdbc:mysql://host:3306/metabase?userusernamepasswordpassword -jar metabase.jar load-from-h2 metabase.db重要约束迁移过程是一次性操作且整个迁移过程中必须使用同一版本的 Metabase执行迁移命令的 Metabase 版本、最后一次写入 H2 文件的版本、以及生产环境将要运行的版本必须一致。只有迁移成功后才考虑升级。Metabase 期望目标数据库是全新的空库命令会自动在目标库中创建表结构并把 H2 数据搬进去。迁移完成后用同样的连接参数去掉load-from-h2部分正常启动 Metabase例如export MB_DB_TYPEpostgres export MB_DB_CONNECTION_URIjdbc:postgresql://host:5432/metabase?userusernamepasswordpassword java --add-opens java.base/java.nioALL-UNNAMED -jar metabase.jar迁移期间应先停掉正在运行的 Metabase 实例避免迁移过程中产生新数据导致不一致。迁移时的加密密钥注意点从源码 src/metabase/cmd/load_from_h2.clj 可以看到load-from-h2还会检查数据加密状态如果 H2 数据库是用某个密钥加密的而当前环境的MB_ENCRYPTION_SECRET_KEY与之一致或未设置命令会直接报错The H2 database is encrypted with a different key ...如果目标数据未加密但当前环境设置了MB_ENCRYPTION_SECRET_KEY迁移过程会自动对落库数据进行加密。也就是说迁移 H2 之前若配置过加密密钥请确保密钥正确。Docker 容器场景的迁移如果你是用 Docker 运行的 Metabase迁移路径为详见 docs/installation-and-operation/migrating-from-h2.md确认能连接目标应用数据库先把 H2 文件从容器中复制出来备份docker cp metabase:/metabase.db/metabase.db.mv.db ./停止现有 Metabase 容器在与 H2 文件同目录下放置同版本的 Metabase JAR用上述load-from-h2命令执行迁移迁移完成后进程会自动退出用新应用数据库启动新容器docker run -d -p 3000:3000 \ -e MB_DB_TYPEpostgres \ -e MB_DB_DBNAMEyour-postgres-db-name \ -e MB_DB_PORT5432 \ -e MB_DB_USERdb-username \ -e MB_DB_PASSdb-password \ -e MB_DB_HOSTyour-database-host \ --name metabase metabase/metabase确认 H2 文件已有安全备份后再移除旧容器。备选方案序列化快照如果你使用的是 Pro 或 Enterprise 版本可以使用序列化Serialization功能为应用数据库做快照。当你希望在新实例中预置问题和仪表盘时序列化尤其有用。四、试图降级DowngradeMetabase 不支持根因Metabase 不支持降级即回退到更早的应用版本。如果你在升级后想退回旧版直接替换版本通常会导致启动失败或数据不兼容。处置步骤关闭 Metabase。恢复你在升级前为应用数据库制作的备份副本。恢复你想要回退到的旧版 JAR 文件或旧版容器镜像。重新启动 Metabase。这也是升级前务必备份应用数据库这一原则的由来备份操作详见 docs/installation-and-operation/backing-up-metabase-application-data.md。五、应用数据库被锁liquibase ... Could not acquire change log lock根因Metabase 在启动时会对应用数据库执行 Liquibase 迁移如果上一次运行异常退出变更日志锁change log lock没有正常释放下次启动就会失败报错形如liquibase.exception.DatabaseException: liquibase.exception.LockException: Could not acquire change log lock.处置步骤在 Metabase 所在服务器上打开终端手动释放锁java --add-opens java.base/java.nioALL-UNNAMED -jar metabase.jar migrate release-locks命令执行完毕后正常方式重启 Metabase不要带migrate release-locks参数。这一行为在源码中有明确实现命令入口 src/metabase/cmd/core.clj 中migrate命令支持release-locks方向在 src/metabase/app_db/setup.clj 中:release-locks分支会调用liquibase/force-release-locks!强制释放锁。值得注意的是该文件中的注释提到现在迁移在事务内执行锁残留问题通常不应再出现此命令只是作为兜底手段保留。此外release-migration-locks!函数体现了超时释放逻辑进程会先等待一段时间让迁移锁自然释放超时后才强制清理这也解释了为什么锁问题大多与异常中断有关。六、应用数据库损坏H2 文件修复流程根因H2 的可靠性不如生产级数据库管理系统应用数据库文件本身可能损坏。这会导致应用数据库中的数据丢失但不会损坏 Metabase 所连接的业务数据库中的数据。处置步骤损坏导致的报错信息各异但多数日志消息会提到h2。一个典型的损坏场景与报错如下使用 H2 自带的RunScript工具导出 SQL 时myUsermyIp:~$ java --add-opens java.base/java.nioALL-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 */ X5256470012572027c82fc5d2bfb855264ab45f8fec4cf48b0620ccad281d2fe4, 165) [90112-194] at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) [etc]如何修复并非所有 H2 错误都可恢复——这正是官方反复强调使用 H2 时务必为应用数据库文件制定备份策略的原因。如果你运行的是较新版本且使用 H2应用数据库存放在metabase.db.mv.db。请在 Metabase 实例所在服务器上打开终端依次执行以下四条命令尝试恢复损坏的 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.nioALL-UNNAMED -cp target/uberjar/metabase.jar org.h2.tools.RunScript -script metabase.db.h2.sql -url jdbc:h2:pwd/metabase.db各命令的作用第一条调用 H2 自带的Recover工具从损坏文件中尽力抽取数据并生成恢复脚本通常输出为metabase.db.h2.sql第二条把损坏的原始文件改名保留防止覆盖第三条创建一个全新的空数据库文件第四条用RunScript把恢复出的 SQL 脚本灌入新数据库。恢复是否成功取决于损坏程度若Recover阶段已无法导出有效数据则只能依靠备份恢复。此外仓库中还提供了dump-to-h2命令src/metabase/cmd/core.clj用于把当前应用数据库导出为 H2 文件配合--keep-existing可避免覆盖已有文件可作为日常备份手段之一。七、Windows 10 上启动报 Unable to connect to Metabase DB根因在 Windows 10 的某些环境下Metabase JAR 需要具备创建本地文件即应用数据库文件的权限。直接运行 JAR 时会看到如下报错Exception in thread main java.lang.AssertionError: Assert failed: Unable to connect to Metabase DB.处置步骤右键点击 Metabase 的 JAR 文件注意是 JAR 文件本身不是应用数据库文件。选择 Properties属性。勾选 Unblock解除锁定。这是因为从网络或某些来源下载的文件会被 Windows 标记为来自其他计算机从而阻止其创建本地文件解除锁定后即可正常写盘。八、应用数据库加载超时默认 5 秒限制根因使用 H2 作为应用数据库时如果数据库文件过大无法在默认的 5 秒超时时间内完成加载启动控制台会出现 Timeout 字样。处置步骤按优先级首选改用 PostgreSQL 等生产级数据库作为应用数据库。这不仅解决加载超时也从根本上规避 H2 的可靠性问题。进入Admin Panel调大应用数据库的超时设置。将 Metabase 迁移到更快的服务器尤其是磁盘更快的服务器。九、预防优于修复备份与生产库选型综合全文可见围绕 H2 的所有故障几乎都可以归结为一个共同建议尽早把应用数据库迁移到生产级数据库并始终保留备份。官方推荐顺序为PostgreSQL最低版本 14首选MySQL最低版本 8.4.0需utf8mb4_unicode_ci排序规则、utf8mb4字符集及innodb_large_prefixON这些均为默认值MariaDB最低版本 10.6.0要求同上。关于连接配置的完整说明MB_DB_TYPE、MB_DB_HOST、MB_DB_PORT、MB_DB_DBNAME、MB_DB_USER、MB_DB_PASS、MB_DB_CONNECTION_URI等环境变量参见 docs/configuring-metabase/environment-variables.md 与 docs/installation-and-operation/configuring-application-database.md。备份方面若仍在使用 H2Docker 场景用docker cp metabase:/metabase.db/metabase.db.mv.db ./导出文件JAR 场景则停止服务后直接复制metabase.db.mv.db并妥善保管。迁移完成后保留旧 H2 文件作为保险也不失为一个好习惯。相关排障总入口可参见 docs/troubleshooting-guide/index.md。十、故障速查对照表症状根因快速处置Command failed with exception: Unsupported database file version ...load-from-h2文件名带了.mv.db后缀去掉扩展名仅传/path/to/metabase.dbliquibase ... Could not acquire change log lock上次迁移异常退出锁未释放执行migrate release-locks后正常重启启动报错信息中出现h2H2 文件损坏按第六节的 Recover RunScript 四步恢复Windows 10 下Assert failed: Unable to connect to Metabase DBJAR 无本地写文件权限JAR 属性中勾选 Unblock控制台出现Timeout应用数据库加载超过默认 5 秒改用 PostgreSQL、调大超时或换更快磁盘想回退旧版本Metabase 不支持降级恢复升级前的备份与旧版 JAR以上所有结论均以当前仓库中的官方文档与源码实现为依据涉及的关键文件包括docs/troubleshooting-guide/loading-from-h2.md、docs/installation-and-operation/migrating-from-h2.md、src/metabase/cmd/load_from_h2.clj、src/metabase/cmd/core.clj、src/metabase/cmd/copy/h2.clj 与 src/metabase/app_db/setup.clj。建议读者在实际操作前先对照第二小节确认自己的应用数据库类型再按对应章节逐步处理。【免费下载链接】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),仅供参考

相关新闻

open-seo 仓库的 Agent 协作指南:工程原则、审阅规则与安全边界

open-seo 仓库的 Agent 协作指南:工程原则、审阅规则与安全边界

open-seo 仓库的 Agent 协作指南:工程原则、审阅规则与安全边界 【免费下载链接】open-seo Open source alternative to Semrush and Ahrefs 项目地址: https://gitcode.com/GitHub_Trending/op/open-seo 本篇文章基于开源仓库 AGENTS.md(Agent g…

2026/9/13 16:45:52 阅读更多 →
10分钟跑通LunaTranslator:日文游戏实时翻译器首次配置走查

10分钟跑通LunaTranslator:日文游戏实时翻译器首次配置走查

10分钟跑通LunaTranslator:日文游戏实时翻译器首次配置走查 【免费下载链接】LunaTranslator 视觉小说翻译器 / Visual Novel Translator 项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator 想让日文游戏画面实时显示译文,又不想…

2026/9/13 16:45:52 阅读更多 →
listmonk 首次启动后如何访问 http://localhost:9000 创建 Super Admin 并登录

listmonk 首次启动后如何访问 http://localhost:9000 创建 Super Admin 并登录

listmonk 首次启动后如何访问 http://localhost:9000 创建 Super Admin 并登录 【免费下载链接】listmonk High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app. 项目地址: https://gitcode.com/GitHub_Trendin…

2026/9/13 16:44:52 阅读更多 →

最新新闻

WebLLM Subgroups 能力路由实战:在 Web 应用中按 WebGPU 子组特性动态切换 WASM 模型库

WebLLM Subgroups 能力路由实战:在 Web 应用中按 WebGPU 子组特性动态切换 WASM 模型库

WebLLM Subgroups 能力路由实战:在 Web 应用中按 WebGPU 子组特性动态切换 WASM 模型库 【免费下载链接】web-llm High-performance In-browser LLM Inference Engine 项目地址: https://gitcode.com/GitHub_Trending/we/web-llm 导读:本文基于 …

2026/9/13 17:38:15 阅读更多 →
STM32CubeProgrammer:嵌入式AI编程的硬件可信锚点

STM32CubeProgrammer:嵌入式AI编程的硬件可信锚点

1. 为什么STM32CubeProgrammer不是“装个软件”那么简单——嵌入式AI编程链路上的关键卡点在嵌入式软件AI编程的实操现场,我见过太多人卡在第一步:STM32CubeProgrammer装不上、连不了设备、烧不进固件。他们以为这只是个“下载工具”,随手点开…

2026/9/13 17:38:15 阅读更多 →
STM32寄存器语义提示工程:让Claude精准生成可烧录代码

STM32寄存器语义提示工程:让Claude精准生成可烧录代码

1. 这不是“用AI写Hello World”,而是让Claude真正理解STM32寄存器级语义你有没有试过把“初始化PA5为推挽输出,50MHz,高电平”直接扔给通用大模型?它大概率会返回一段语法正确但根本跑不通的代码:GPIOA->MODER | G…

2026/9/13 17:38:15 阅读更多 →
Python无人机集群编队仿真:从一致性控制到工程实现

Python无人机集群编队仿真:从一致性控制到工程实现

简介:这份基于 Python 的无人机集群编队飞行项目资料,面向毕业设计、课程设计与项目开发场景。项目围绕多机器人群体控制展开,系统梳理了集中式、分布式与混合式三种控制结构的原理与适用场景,配合源码讲解和设计思路,…

2026/9/13 17:38:15 阅读更多 →
鸿蒙人脸识别门禁对接业务系统:API与MQTT工程规范实战

鸿蒙人脸识别门禁对接业务系统:API与MQTT工程规范实战

鸿蒙人脸识别门禁这东西,单机跑起来不难,真正让人头疼的是怎么跟业务系统打通。前阵子我正好在做一个园区项目,设备端基于鸿蒙系统做人脸识别门禁,后端要对接一套现成的综合管理平台。刚开始我天真地以为不就是调几个接口嘛&#…

2026/9/13 17:38:15 阅读更多 →
olmOCR Elo 评分体系:基于人工成对评审的 OCR 工具排名与显著性检验

olmOCR Elo 评分体系:基于人工成对评审的 OCR 工具排名与显著性检验

olmOCR Elo 评分体系:基于人工成对评审的 OCR 工具排名与显著性检验 【免费下载链接】olmocr Toolkit for linearizing PDFs for LLM datasets/training 项目地址: https://gitcode.com/GitHub_Trending/ol/olmocr 导读 本文系统讲解 olmOCR 仓库中用于衡量…

2026/9/13 17:37:14 阅读更多 →

日新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/13 0:00:24 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/13 0:00:24 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/13 0:00:24 阅读更多 →

周新闻

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验 【免费下载链接】ai The AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and ag…

2026/9/13 0:00:24 阅读更多 →
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化

Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.com/GitH…

2026/9/13 0:00:24 阅读更多 →
Flutter应用改名全指南:从Android到iOS的配置与工具实践

Flutter应用改名全指南:从Android到iOS的配置与工具实践

刚接一个外包项目时,甲方要求把工程里临时用的应用名改成正式产品名。我本来觉得“改名”这种小事,打开配置文件改一行不就完了?结果真动手才发现,Flutter项目里“应用名称”根本不是一处配置,而是一整套散落在 Androi…

2026/9/13 0:00:24 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/13 16:51:11 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/12 18:29:34 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/12 19:02:44 阅读更多 →