🧰 异常数据处理
异常快照是插件在保存、导入或迁移数据遇到问题时,留在本地供管理员检查的档案。它可能保留了完整的玩家数据,也可能只有损坏的原始内容或诊断信息。先查看原因,再判断能否恢复。
🔍 查看异常快照
在发生异常的服务器上执行:
/sparrow-sync exception list
该命令会分页列出本服务器所有玩家的异常快照。也可以指定玩家,或根据列表中的相对路径查看详情:
| 命令 | 用途 |
|---|---|
/sparrow-sync exception list [player] [page] | 查看全部异常快照,或按玩家筛选。 |
/sparrow-sync exception view <file> | 查看异常档案的身份信息、正文状态和可读取的数据。 |
/sparrow-sync gui <player> | 打开玩家的快照列表,再切换到异常快照页面。 |
以上命令默认需要 sparrow_sync.command.view,其中 gui 只能由玩家执行。GUI 中的异常列表同样读取本地文件,不能直接查看其他服务器的异常目录。操作权限见权限命令。
列表可以通过独立的头文件显示玩家、时间和来源等信息,即使快照正文已经损坏或根本没有生成。查看详情时,请同时留意正文是否存在、能否解码,以及哪些数据可以读取。
📂 哪些情况会生成异常档案?
异常档案保存在 plugins/SparrowSync/snapshot/exception/ 下,按原因分为四类:
| 子目录 | 触发情况 | 先检查什么 |
|---|---|---|
corrupted/ | 启动时读取待重试快照失败,或无法解析快照整体格式;批量导入时,某条记录的快照格式无法解码。 | 文件是否完整、是否被改动,以及控制台中的读取或格式错误。 |
malformed/ | 保存时快照编码失败或数据违反存储约束;批量导入时,具体数据块的校验、解压或 NBT 解析失败。 | 报错涉及的数据类型、编码原因或数据库约束。 |
oversized/ | 快照超过插件存储层或数据库允许的大小,例如数据库的数据包大小限制。 | 快照体量、各类型的数据大小和数据库报错。 |
migration/ | 从其他插件迁移时,读取某位玩家的数据、解码或转换字段失败,或者转换后的快照编码失败。 | 错误报告中的来源插件、失败阶段和原始异常。 |
普通保存与启动重试
正常保存中,被存储层明确拒绝的数据会按原因进入 malformed 或 oversized。例如,某份数据无法编码,或一份快照已经超过存储大小上限,原样重试通常无法解决问题。
数据库暂时不可用时,快照会先保存到 plugins/SparrowSync/snapshot/pending/,插件在下次启动时尝试重新写入数据库。写入成功后,本地待重试文件会被删除;如果文件无法读取或解码,则移到 corrupted;如果被存储层拒绝,则移到 malformed 或 oversized。数据库仍不可用时,剩余文件会留在 pending。
批量导入与插件迁移
执行 data import_all 时,插件会检查每份快照的整体格式和内部数据块。单份数据有问题时,会保留原始记录并生成错误报告,跳过该条后继续处理。数据库暂时不可用或异常档案无法写入时,整次导入会中断,需要根据控制台报错处理。
执行 data migrate 时,来源数据的读取、转换或编码失败会进入 migration。错误报告中的 stage 会标明失败阶段:read、decode/convert 或 encode。迁移生成的 ZIP 随后还会经过批量导入,因此也可能产生前面三类异常。迁移步骤见数据迁移。
如果异常发生在完整快照生成之前,或本地编码、磁盘写入也失败了,就可能没有可用的正文。整个 ZIP 无法读取、来源插件整体读取中断等问题,也不一定能归档到某个玩家名下。此时仍需保留控制台报错和本地同步日志。
📦 一份异常档案包含什么?
同一条记录的文件使用相同的名称前缀。下面以 example.snapshot 为例:
| 文件 | 内容与用途 |
|---|---|
example.snapshot | 快照正文。可能是完整快照,也可能是批量导入时保留下来的损坏原始字节,需要实际读取后才能判断。 |
example.snapshot.head | 独立的二进制头文件,保存可取得的玩家身份、快照 ID、时间、保存原因、来源服务器、Minecraft 数据版本及数据类型体量摘要,供列表展示。它不包含完整背包数据。 |
example.snapshot.error.txt | 批量导入或迁移失败时生成的错误报告,包含分类、原因,以及可取得的玩家信息;迁移报告还包含来源插件和失败阶段。有原始异常时会附带堆栈。 |
example.snapshot.source | 迁移失败时保留的来源插件原始数据,仅在能够取得原始字节时生成。它仍是来源插件的格式,不能直接当作 Sparrow Sync 快照导入。 |
这些文件并不保证全部存在。 普通保存和启动重试转存的异常通常是正文加 .head,原因需要结合日志查看,不会额外生成 .error.txt。迁移在转换完成前失败时,可能只有 .head、.error.txt 和可选的 .source,没有 .snapshot 正文。
头文件缺失或损坏时,只要正文仍能提供信息,插件在读取异常详情时会尝试重建头文件。这只修复列表所需的信息,不会修复损坏的玩家数据。
🧰 如何处理与反馈?
先取回仍然完好的数据
只要快照没有完全损坏,仍然可以通过 GUI 访问其中能够正常读取的数据。 某个数据类型解码失败,不代表背包、末影箱等其他内容也全部不可用。
在保存异常档案的服务器中,以玩家身份执行:
/sparrow-sync gui <player>
切换到该玩家的异常快照列表,打开对应记录,再查看背包、末影箱等页面。如果这些数据仍然完好,可以直接从界面中取出物品,核对玩家实际缺失的内容后及时补偿,不必等整份快照的问题修复后再处理。
打开 GUI 需要 sparrow_sync.command.view,从中取出物品还需要 sparrow_sync.ui.edit。无法读取的数据不能通过这种方式取回;请保留原始异常档案,供后续排查。
排查原因并反馈
先保留对应档案,查看详情、错误报告和同一时间的日志。数据库连接、账号权限、磁盘空间或文件访问权限有明确报错时,可以先处理这些问题;oversized 则需要结合数据大小和数据库限制判断。异常目录中的档案不会像 pending 一样在启动时自动重试。
下面这些情况可以考虑提交 Issue 或反馈给作者:
- 正常游玩产生的数据反复编码、解码、校验或转换失败,无法确定原因。
- 从受支持的插件版本迁移时,某些玩家总是失败,或出现接口、字段不兼容的报错。
- 快照体量异常增长、普通玩家数据触及大小限制,无法判断是哪类数据导致的。
- 已经发生数据丢失、回滚或内容不一致,需要结合档案和同步日志追查。
- 连本地异常档案都写入失败,或出现无法解释的程序异常。
反馈时,请将同一条记录的正文、头文件、错误报告和原始附件一起打包,存在的文件都保留,并附上:
- Sparrow Sync 版本、服务端类型与版本、数据库类型;迁移问题还需提供来源插件版本。
- 发生时间、玩家名或 UUID、当时执行的命令或操作步骤。
- 控制台完整报错,以及对应玩家、对应时间段的本地同步日志。
- 迁移或批量导入问题所使用的 ZIP,以及控制台显示的处理结果。
公开提交 Issue 时,连接密码等敏感配置请先移除;玩家档案不方便公开时,可以联系作者提供。
确认处理完毕并保留所需备份后,可以使用 /sparrow-sync exception delete <file> 清理异常记录。该命令会同时删除正文及其关联的头文件、原始附件和错误报告。