sqlserver 重建聚集索引后,记录丢失

2022-03-28 09:29:07 +08:00
 shyrock

最近遇到一个怪异的现象,给大家分享一下。 有一张存储了 36w 条记录的表,存储了从 2013 年到现在的历史数据,并基于主键 retID 建了聚簇索引。

最近新增的应用访问这张表的时候,发现有些条件查不出来数据, [现象 1 ] :比如同一条记录,用 BarCode 字段能查出来,用 CKCode 就不出来。我比较两者的查询计划,发现走的索引不一样。 于是尝试重建了该表的对应字段的索引,发现没有变化。 又尝试重建了该表的聚簇索引,这下好了,建完之后,之前的 [现象 1 ] 消失了,但是整个表的记录数变成了 33w 条,有 3w 条消失了。。。

有人知道这个问题的根本原因吗?

1044 次点击
所在节点    数据库
6 条回复
tzigone
2022-03-28 11:23:10 +08:00
10 年的数据 30w ,每个月几千条,主键数据丢失涉及数据文件损坏了,找备份 roll back 吧
thinkershare
2022-03-28 11:44:40 +08:00
你最好将数据先全部先备份,数据库以页为存储, 索引和页数据都在页上, 我怀疑物理某些页在磁盘扇区上物理损坏了.
xsm1890
2022-03-28 14:03:07 +08:00
不知道这个 36w 和 33w 是不是 count()计算出来的总数;如果不是的话,那很正常,对于很多数据库及存储引擎,表总数只是维护一个大概数,并不精确。不然的话,得备份恢复下了
shyrock
2022-03-28 14:36:40 +08:00
@xsm1890 #3 厉害了,我又看了一下,count ()出来的总数没变,只是数据表属性页里面的条数少了 3w 。
而且按 id 排序的话,发现中间 58000 到 90000 的 id 缺失了。
如果总数没变,不知道这些 id 跑到哪里去了。。。
shyrock
2022-03-28 15:29:58 +08:00
对这个现象我有一个 90%可能性的猜测:
这个表本来有 36w 行数据,但是因为某些物理损坏,在聚集索引中丢失了中间 3w 行记录的引用。这时候从表的属性看,数据仍然有 36w 行,而且其他非聚集索引仍然完整指向了这 36w 行记录。
当使用聚集索引时,中间的 3w 行数据查不到,但是用非聚集索引查找时能查到所有 36w 行记录。

我尝试重建聚集索引,数据库引擎为了保持数据完整性,把 3w 行记录删除掉,并且通知其他非聚集索引重建。
之后所有方式的查询结果一致,但是 3w 行记录就消失了。
xsm1890
2022-03-28 18:33:58 +08:00
@shyrock 关于 id 不见了,从你的表述来看,可能没你想的那么复杂;如果是自增 id ,可能只是单纯的 id 跳过,有很多种情况都会发生,这对业务,对数据都没有任何的影响。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/843285

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX