非常奇怪bug,使我滨州旋转

lemonaid:非常奇怪bug,使我滨州旋转仅镜像
https://mirror.chromaso.net/thread/55516
镜像站中该帖子的首楼内容消失了,导致在原作者的个人页面会看到一个首楼不是作者的帖子。
我猜作者是在forum.mazochina.com发的帖子,然后由于
chromaso
billshen而且我现在是能进去的
OK 我搞清楚了。
源站 forum.mazochina.com 的域名还是崩着的;只有 mazochina.com/forum 的地址可以访问了。
但是镜像的自动同步进程、手动同步进程,以及每个帖子的「回源站查看」链接全部用的都是 forum.mazochina.com(因此点击「回源站查看」看到的当然也是访问不了的)。
要全部改成 mazochina.com/forum 得花一点时间。
当然也可以等源站把 forum.mazochina.com 的域名修好(虽然我很怀疑是否会修好)。
的相关更新导致mazochina.com/forum的帖子产生了冲突
我不知道,但是很乐
chromaso:Re: 非常奇怪bug,使我滨州旋转仅镜像
绷,这事情发生过一次。跟域名有可能没关系,可能是源站的数据库回滚了(似乎是回滚到了大概半个月前的状态),导致这半个月来的帖子从源站消失了。

然后源站新的帖子从半个月前(也就是更小的) ID 开始重新排数,重新占用了那些 ID。这点从源站最新的(今天发布的)主题的 ID 还是 55514(http://mazochina.com/forum/viewtopic.php?f=18&t=55514,小于楼上提到的 55516)就不难发现。

而镜像从源站同步帖子的时候数据库的主键当然是 ID,这样一来,源站新的(同一 ID)的帖子就把原先在镜像数据库中的给覆盖掉了。

上一次源站出这问题时我及时发现了,把镜像里存在的从源站消失了的(因此可能被覆盖的)帖子的 ID 都手动更改了,从而避免了这种情况的发生。

这一次我根本没发现源站的数据库回滚了。现在还没想好怎么修。我先暂时把从源站同步的程序给暂停了,以免造成进一步的混乱/损失。
chromaso:Re: 非常奇怪bug,使我滨州旋转仅镜像
楼上我提到的半个月的估算是完全错误的。

Posts 方面,当前看来受到影响的会是 post ID 468151 及之后在源站发布的帖子。考察 468150 的发布时间可以得出,源站的数据库丢失只影响了 2023-09-30T16:54Z 之后的帖子。在源站数据发生丢失/回滚前,镜像所收录到的源站的 post id 就只到 468198 为止;目前源站回滚后重新发布的帖子的 post id 也是暂且到了 468198,这实在是太巧合了,有些奇怪。但如果我没弄错,这也意味着未来来自源站的帖子都将会是是 468199 以及之后的了,它们就不存在再错误覆盖任何镜像先前收录的内容的可能性,所以即使重新开启同步程序,也不会错误覆盖任何 post 了。当然之前的脏数据还是得设法清理/恢复。

Threads 方面,55512 的发布时间小于 2023-09-30T16:54Z 这个时间点,因此只有 55513 及之后的 thread 会受到影响。源站回滚前的 ID 到了 55516,而目前只到 55514,所以如果现在就开启同步程序,55515 和 55516 将会被覆盖;所以现在还不能重启同步程序。

对于因为源站数据库回滚而被丢失的 post,准备采取的方案是:(如果还没被覆盖,或者能从日志中恢复)就在镜像中将它们的 ID 加上 285212672 来保存。这个方案在两年前源站数据库回滚时就采用过,例如这个主题就是源站丢失掉的 thread 50174。但这次我不确定有多少数据能够找到。

接下来我可能分批会手动处理数据库中的脏数据,途中可能发生更奇怪的情况,请见谅。
chromaso:Re: 非常奇怪bug,使我滨州旋转仅镜像
我暂且如楼上所提到的,将受到影响的 thread ID 进行了平移,例如 55516 移动到了 285268188,55513 移动到了 285268185。这样我今天晚些时候应该就可以重新开启同步程序了。丢失的数据要恢复起来难度会非常高,请不要抱太高的期望。
chromaso:Re: 非常奇怪bug,使我滨州旋转仅镜像
我从日志里成功恢复了所有被覆盖掉的帖子的内容。具体来说是运行了这个现写的脚本之后做了手动修正。

一小部分 metadata 无法恢复:首先是一部分回帖无法找到所在的主题了,我就全部丢到了这个主题里面。此外就是一部分帖子的作者已不可考,现在只能显示为「UNKNOWN」。

总的来说问题解决了。Totally stupid,浪费了我好几个小时本来可以用来看黄片打手冲的时间。

简单的 postmortem 总结:
  • 在源站不可控的情况下,镜像为避免这种情况,应该更 robust 一些,例如发现某个 post ID 对应的作者发生了变动一类的情况,不应该覆盖之前同步的内容,而是另存一份并且发出警告。但这事情工作量太大了,不太现实。一方面另存一份需要 some deliberate design,另一方面目前从源站同步程序毫无 monitoring 或是 alerting 机制。稍简单一点的 fix 就是遇到这种情况直接 panic exit,自动关停同步程序。
  • 还是多 log 多存一些东西好,恢复起来也方便一些,不至于像这次一样找不到帖子的作者只能写成 UNKNOWN。但是这也要涉及到改 schema,短期内不现实。
  • 所以说使用 auto-increment integer 作为主键/ID 注定会有各种问题,people will assume it's monotonic and unique but it's not。不管是 Twitter/Discord 用的 snowflake ID,还是其它任何以时间戳作为 prefix 的 ID,甚至是 UUID v4,都会好得多。即使是单机而不是分布式的东西也是如此。可惜镜像也是一开始就选择了用 auto-increment integer 作为主題/文章/用户的主键。