Phorge 现代化改造实战(十六):把数据库自省搬进 Gorge,跨仓契约不能靠手工同步

💡 原文中文,约8100字,阅读约需20分钟。
📝

内容提要

本文介绍Phorge数据库诊断功能迁移至独立Go服务gorge-db-api,提供八个只读接口采集节点健康、复制状态、结构差异和升级状态。通过契约版本1.1、/api/db/meta握手和跨仓测试确保PHP与Go字段一致,避免静默错误。支持文件拓扑配置和只读账号,未配置时保留原生SQL路径。

🔎

延伸解读

契约版本与握手:防止静默字段错位

文章指出,接口返回200但字段名不一致会导致PHP生成错误对象,且不易察觉。r3通过契约版本1.1和/api/db/meta握手,检查namespace、capabilities等,确保PHP与Go字段一致。运行时握手能阻止已知不兼容版本组合,但开发阶段仍需三层测试(Go标准JSON、PHP映射、跨仓对比)来及时发现字段变化。

拓扑配置与只读账号:安全与灵活性

db-api支持文件拓扑配置,优先级高于环境变量,且文件缺失或非法时启动失败,避免静默回退到单节点。生产环境应使用只读账号,并验证所需权限。未配置服务时,Phorge保留原生SQL路径,现有安装无需立即切换,但配置后需成对升级Phorge与Gorge。

复制状态与结构查询的边界处理

服务优先使用SHOW REPLICA STATUS,兼容旧语法;每次探测创建新结果对象,避免旧状态残留。结构查询遇到连接中断或扫描失败时直接失败,不返回部分结果,防止PHP误判。对于无权访问的库,标记accessDenied: true,区分“不存在”与“无权限”。

Q&A

Phorge 数据库诊断迁移到 gorge-db-api 后,主要解决了什么问题?

主要解决了在多主库、多副本或应用分区环境下,数据库诊断查询(如节点健康、复制状态、结构差异和升级状态)占用 PHP Web 进程的问题。通过将这些查询迁移到独立的 Go 服务 gorge-db-api,减轻了 PHP 的负担,并提供了更清晰的权限边界。

gorge-db-api 提供了哪些接口?

gorge-db-api 提供了八个只读接口:/api/db/servers、/api/db/servers/:ref/health、/api/db/schema-diff、/api/db/schema-issues、/api/db/setup-issues、/api/db/charset-info、/api/db/migrations/status 和 /api/db/meta。前七个实时查询数据库,/api/db/meta 只读取启动时确定的配置。

如何确保 PHP 和 Go 之间的字段一致性?

通过三项措施:1) 在运行时通过 /api/db/meta 检查契约版本和命名空间;2) 两个仓库共享标准 JSON 文件,用于测试字段映射;3) 跨仓测试连接两个仓库,比较 PHP 最终得到的对象,确保字段一致。

gorge-db-api 的鉴权机制是怎样的?

所有 /api/db/** 路由共用 X-Service-Token 鉴权。token 留空时关闭鉴权,生产环境应明确配置。/healthz、/readyz 和根路径探针不需要 token。r3 关闭了查询参数传 token 的方式,只接受请求头。

gorge-db-api 支持哪些拓扑配置方式?

支持两种拓扑来源:通过标量环境变量(GORGE_DB_MYSQL_HOST/PORT/USER/PASS 等)配置单节点,或通过 GORGE_DB_CONFIG_FILE 指定 JSON 文件配置多节点拓扑。文件配置优先级更高,且 r3 起文件缺失或非法会导致启动失败。

如果未配置 gorge-db-api,Phorge 会怎样?

如果未启用 gorge-db-api,Phorge 会继续执行原来的 SQL 查询,现有安装无需立刻切换。也就是说,原生 SQL 路径仍然可用。

gorge-db-api 如何处理复制状态检查?

服务优先执行 SHOW REPLICA STATUS,如果服务器返回 1064 语法错误,则尝试旧的 SHOW SLAVE STATUS。同时会检查接收线程和执行线程是否都在运行,即使复制延迟为 0。每次探测都会创建新的结果对象,避免旧状态残留。

gorge-db-api 的错误处理有什么特点?

数据库错误会映射成可区分的状态码,如 ERR_DB_UNREACHABLE、ERR_DB_ACCESS_DENIED、ERR_READONLY。错误信封只写通用说明,不返回原始 SQL、数据库名或主机名。无法分类的内部错误交给平台日志记录。

🏷️

标签

➡️

继续阅读