AzerothCore 数据库 Squash 全流程解析:从 Base 文件重建到维护者工具链实战
2026/9/16 22:36:43 网站建设 项目流程

AzerothCore 数据库 Squash 全流程解析:从 Base 文件重建到维护者工具链实战

【免费下载链接】azerothcore-wotlkComplete Open Source and Modular solution for MMO项目地址: https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk

本文围绕 data/sql/base/database-squash.md 展开,系统讲解 AzerothCore(WotLK 3.3.5a 模拟器核心)自 PR #18197 引入的数据库 Squash(压缩)新流程。该流程面向项目维护者,用于在积累了大量增量更新 SQL 后重建data/sql/base/下的基础数据库文件。读完本文,你将掌握 DatabaseSquash 工具链(DatabaseSquash.shVersionUpdater.shDatabaseExporter.sh)的完整执行步骤、底层实现原理、MySQL 参数约定,以及 squash 期间的协作纪律。

一、为什么需要数据库 Squash

AzerothCore 的三张核心数据库(Auth、Characters、World)的基线数据存放在仓库的data/sql/base/目录下,而日常的增量改动则以“每日一个 SQL 文件”的形式落入data/sql/updates/目录。长期积累后,增量文件会越来越多,每次在新环境上搭建服务器都需要依次执行成百上千个更新文件,代价高昂。

Squash 的核心思想:把“基线 + 所有增量”合并成一份全新的基线。维护者在干净的数据库上应用全部更新,再通过 mysqldump 将最终结果导出回data/sql/base/,从而让新搭建的环境只需导入一次 base 文件即可得到最新数据库状态。

一个容易被误解的关键机制在于updates表:base 文件中的updates表始终包含来自 updates 目录的条目,这些条目在全新环境上永远不会再被执行——因为 base 文件本身已经包含了它们的最终效果(详见 data/sql/base/database-squash.md)。

二、适用范围与硬性前置条件

⚠️ 本文描述的步骤仅面向项目维护者,普通玩家/自建服务器用户不应执行 squash,日常升级请直接应用data/sql/updates/中的增量文件。

2.1 环境要求

需求项说明
MySQL数据库服务,用于存放并导出三个核心库
mysqldumpMySQL 官方逻辑备份工具,负责导出每个表的结构与数据

2.2 干净数据库要求

[!IMPORTANT] Squash 必须在干净数据库上执行:必须删除 Auth、Characters、World 三库中的所有表后再开始。

这是保证结果正确性的前提——如果数据库中存在历史残留数据,导出的 base 文件将混入陈旧内容,污染整个项目的基线。实际执行时,通过先DROP所有表、再运行 WorldServer 让其按最新代码 + 全部增量重新建库填充,即可得到最“干净且最新”的数据源。

三、工具链总览:三个脚本的职责分工

整个 squash 流程由apps/DatabaseSquash/目录下的三个脚本协作完成:

脚本相对路径职责
总入口apps/DatabaseSquash/DatabaseSquash.sh校验操作者意图,依次驱动 VersionUpdater 与 DatabaseExporter
版本更新器apps/DatabaseSquash/VersionUpdater/VersionUpdater.sh提升acore.json版本号并生成新的版本更新 SQL
数据库导出器apps/DatabaseSquash/DatabaseExporter/DatabaseExporter.sh按表 mysqldump 三个数据库并回填 base 目录

三者文档分别见 databasesquash.md、versionupdater.md、databaseexporter.md。

四、完整执行流程(维护者实操)

以下流程综合自 database-squash.md 与DatabaseSquash.sh源码的实际交互逻辑:

步骤 1:启动总入口脚本

# 在 apps/DatabaseSquash 目录下运行(或直接调用绝对路径) ./DatabaseSquash.sh

脚本首先打印警告,确认你已阅读 squash 文档,并要求输入Y/N确认(输入yY继续,其余任意输入直接中止):

❗CAUTION This tool is only supposed to be used by AzerothCore Maintainers. ... Are you sure you want to continue (Y/N)?

从源码看,脚本通过SCRIPT_DIR/PROJECT_ROOT自行定位仓库根目录(DatabaseSquash.sh),并对 Git Bash 下的 Windows 盘符路径做了C:/...形式的兼容转换,因此维护者在 Windows Git Bash 与 Linux 下均可直接运行。

步骤 2:版本自动更新(VersionUpdater)

总入口脚本接着调用:

"$PROJECT_ROOT/apps/DatabaseSquash/VersionUpdater/versionupdater.sh"

VersionUpdater 会自动完成两件事:

  1. 提升acore.json中的项目版本号:解析仓库根目录 acore.json 中的"version"字段(当前仓库实际值为"17.0.0-dev"),将主版本号加一并重置小版本,即17.0.0-dev18.0.0-dev(VersionUpdater.sh)。注意:这等价于一次 major 版本发布,符合 squash 对应一次重大基线重构的语义。
  2. 生成新的版本更新 SQL 文件:在data/sql/updates/db_world/下创建以日期_序号.sql命名的文件(如2026_01_01_00.sql),序号基于当日已存在文件自动递增(00起步,最大 +1),文件内容形如:
-- Auto-generated by VersionUpdater.sh on <date> UPDATE `version` SET `db_version`='ACDB 335.18-dev', `cache_id`=18 LIMIT 1;

其中db_versioncache_id由新主版本号推导(VersionUpdater.sh)。该 SQL 必须随 squash 一并进入基线,保证版本表与 base 数据一致。

步骤 3:重建干净数据库(人工关键步骤)

VersionUpdater 完成后,总入口脚本会暂停并给出两条强制提示:

  1. 在继续之前,你必须DROP 掉所有数据库
  2. 运行 WorldServer 以重新填充数据库。

⚠️ 此时脚本会再次要求Y/N确认,未完成上述两步前绝不能确认继续。WorldServer 会基于最新代码、最新 base 文件以及全部 updates 增量自动重建三张库,这正是“干净且最新”数据源的来源。从源码结构看,这一步骤刻意被设计为脚本外部的人工操作,以避免自动化误操作覆盖正式数据。

步骤 4:导出数据库并回填 Base 文件(DatabaseExporter)

确认后,总入口脚本调用:

"$PROJECT_ROOT/apps/DatabaseSquash/DatabaseExporter/databaseexporter.sh"

DatabaseExporter 会以交互方式询问 MySQL 连接参数与库名,然后执行逐表导出(详见第五节)。全部完成后打印✅ DatabaseExporter Completed...✅ DatabaseSquash Completed...,按回车退出。

步骤 5:提交 PR 与协作纪律

squash 完成后,维护者需要将变更(新的 base 文件、更新的版本 SQL、新的acore.json)整理为一个 Pull Request 提交。

[!IMPORTANT]squash 进行期间,禁止合并任何数据库相关的 PR!

原因很直接:squash 期间的任何增量合并都会导致 base 导出与 updates 目录状态不一致,破坏基线重建的正确性。这是整个流程中最关键的协作约束。

五、DatabaseExporter 源码级解析:导出参数与目录映射

DatabaseExporter 是整个流程中技术含量最高的一环,其交互与导出逻辑值得深入拆解。

5.1 交互式参数输入

脚本依次读取以下参数(DatabaseExporter.sh),除用户/密码外均带默认值:

参数默认值说明
MySQL 用户名必填-u参数
MySQL 密码必填-p参数
MySQL 主机localhost-h参数
MySQL 端口3306-P参数
Auth 库名acore_auth导出到db_auth目录
Characters 库名acore_characters导出到db_characters目录
World 库名acore_world导出到db_world目录

5.2 库名到目录名的映射

脚本通过 Bash 关联数组建立映射(DatabaseExporter.sh):

declare -A DB_MAP=( ["$DB_AUTH"]="db_auth" ["$DB_CHARACTERS"]="db_characters" ["$DB_WORLD"]="db_world" )

随后遍历所有库名,对每个库先用mysql ... SHOW TABLES获取表清单(-N去除表头),再对每张表单独执行 mysqldump——这保证了输出文件与data/sql/base/下“一表一文件”的组织结构完全一致(当前db_world下约有 309 个 SQL 文件,db_auth22 个、db_characters108 个)。

5.3 两个关键 dump 参数

mysqldump -u $DB_USER -p$DB_PASS -h $DB_HOST -P $DB_PORT \ --skip-tz-utc --extended-insert $DB_NAME $TABLE \ > $BASE_OUTPUT_DIR/$FOLDER_NAME/$TABLE.sql
  • --skip-tz-utc:源码注释明确说明“needed to keep TIMESTAMP values as-is”,即禁用 mysqldump 默认的时区换算,保证 TIMESTAMP 字段值原样落盘,避免 base 文件在不同时区机器上产生漂移。
  • --extended-insert:将多行数据合并为扩展 INSERT 语句,显著压缩 base 文件体积并提升导入速度。

5.4 输出格式化与"每行一个 VALUES"规约

导出后脚本立即用sed对文件做格式化(DatabaseExporter.sh):

sed -E ' s/VALUES[[:space:]]*/VALUES\n/; :a s/\),\(/\),\n\(/g; ta ' file.sql > formatted.sql && mv formatted.sql file.sql

效果是把VALUES (...),(...),...展开为VALUES独占一行、每个元组独立成行。这一格式规约与 AzerothCore SQL 风格检查(apps/codestyle/codestyle-sql.py)对齐,保证 base 文件通过 CI 校验,也便于 Git diff 评审。

若某个库查不到表或连接失败,脚本打印警告并跳过该库(DatabaseExporter.sh),避免因单个库异常导致整个导出流程崩溃。

六、Archive 目录的角色转变(重要认知)

[!NOTE] 在数据库 squash 流程中,我们不会移动任何文件archive目录不再作为 squash 流程的一部分使用,它只是当 updates 目录中更新文件数量过多时,用来手动归档这些文件的普通存放位置。

换句话说:

  • 旧流程:squash 时会涉及把更新文件移入 archive 等文件搬移动作;
  • 新流程(PR #18197 起):不再搬移文件,base 文件中的updates表条目天然与 updates 目录中的文件保持对应,但这些条目在全新环境上永远不会再被重复执行(因为 base 已包含其效果)。

因此维护者在日常工作中,应仅在data/sql/updates/文件数量过多、不便管理时,才将它们手工挪入data/sql/archive/(当前 archive 下db_world已有 2192 个历史 SQL 文件,正是长期归档的产物)。

七、Squash 前后的检查清单

阶段检查项依据
前置三库所有表已 DROPdatabase-squash.md
前置环境含 MySQL 与 mysqldump同上
执行中WorldServer 已完成全量建库填充DatabaseSquash.sh交互提示
执行后acore.json主版本号已 +1VersionUpdater.sh
执行后updates/db_world下已生成日期_序号.sql版本文件同上
执行后data/sql/base/{db_auth,db_characters,db_world}已被新导出覆盖DatabaseExporter.sh
协作squash 期间无其他 DB PR 被合并database-squash.md

八、延伸阅读

  • 流程主文档:data/sql/base/database-squash.md
  • 工具入口与子工具文档:databasesquash.md、versionupdater.md、databaseexporter.md
  • 关键实现:DatabaseSquash.sh、VersionUpdater.sh、DatabaseExporter.sh
  • 导出产物目录:data/sql/base/db_auth、data/sql/base/db_characters、data/sql/base/db_world
  • 增量更新目录与归档目录:data/sql/updates/db_world、data/sql/archive/db_world
  • 版本载体文件:acore.json

【免费下载链接】azerothcore-wotlkComplete Open Source and Modular solution for MMO项目地址: https://gitcode.com/GitHub_Trending/az/azerothcore-wotlk

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询