从 SQL Server ColumnStore 中删除会出现“无法插入重复键”错误
Posted
技术标签:
【中文标题】从 SQL Server ColumnStore 中删除会出现“无法插入重复键”错误【英文标题】:Deleting from SQL Server ColumnStore gives "Cannot insert duplicate key" error 【发布时间】:2020-06-11 11:17:55 【问题描述】:我们的产品通过 .NET System.Data.SqlClient.SqlBulkCopy 类将数据从 CSV 文件加载到各种表中。 成功加载后,所有早于某个时间戳的数据都将从数据库中删除。这是通过执行以下命令来完成的,直到没有行被删除:
DELETE TOP (100000) FROM DBO.TBL_DDBB WHERE MeasureDateTime < CAST('2020/04/05 00:00:00' as datetime)
这适用于 RowStore 格式的表,但是在具有 ColumnStore 索引的表上执行此命令时,我们会收到以下错误:
无法在对象“dbo.deleted_bitmap”中插入重复的键行 唯一索引'tuple_key'。重复键值为 (98, 0)。 语句已终止。
问题是可以在这台 SQL Server 机器上以 ColumnStore 格式的多个表重现,但在我们拥有的其他 SQL Server 上不能重现。
我无法弄清楚为什么会发生这种情况,我也无法在网络上提及此错误。有没有人见过这种情况,或者有人可以告诉我如何预防吗?
所用 SQL Server 的版本信息:
Microsoft SQL Server 2016 (SP2-CU12) (KB4536648) - 13.0.5698.0 (X64) 2020 年 2 月 15 日 01:47:30 版权所有 (c) Microsoft Corporation 标准 Windows Server 2012 R2 Standard 6.3(内部版本)上的版本(64 位) 9600:)(管理程序)
【问题讨论】:
您在记录已删除行信息的表上有触发器吗? 不;没有触发器,没有约束,甚至没有二级索引。我认为错误提到的“dbo.deleted_bitmap”对象是用于处理 ColumnStores 中的行删除的 SQL Server 构造。它肯定不是我们的。 查看包含被删除数据的行组是否关闭。由于删除适用于其他服务器,因此差异可能是由于打开与关闭。 嗨,丹。很好的建议,但我检查了,不幸的是事实并非如此。 【参考方案1】:columnstore :SQL Server 将该行标记为逻辑删除,但在重建索引之前不会回收该行的物理存储。
所以逻辑上直到你重建索引数据在索引中。
删除后,您必须重建索引以回收键和空间。
或 ALTER INDEX ...重新组织
更多详情请关注Msdn link
如何删除列存储好页面deleted_bitmap的工作
【讨论】:
我知道这一点,并且考虑到 ColumnStores 的工作原理,这确实很有意义。但是链接没有提到或解释的是为什么会发生这个错误。我的理论是 SQL Server 使用 deleted_bitmap 存储已删除行的唯一标识符,以便后续 ALTER INDEX .. REORGANIZE 知道要删除的内容。但如果这是真的,那么重复键错误一定意味着一行被删除了两次。这就是让我困惑的地方。 每次你都会被删除时,你有前 1000 个 .. 只需重新索引,你就不会遇到这个问题或删除顶部 这里有更多关于deleted_bitmap的细节aboutsqlserver.com/2014/05/06/… @Ide 希望得到这个答案。 "每次你都会有前 1000 个被删除" 如果你说的是真的,那么这意味着 SQL Server 的删除机制被破坏了 ColumnStore。当您删除一行时,如果该行不再存在,SQL Server 应该采取行动。这适用于任何操作,无论是插入、更新选择还是删除。 DELETE TOP 1000 删除了 1000 行,因此任何后续的 DELETE 语句都将(或者更确切地说,应该)忽略先前删除的行。我无法想象这确实是微软创建 ColumnStores 的方式。以上是关于从 SQL Server ColumnStore 中删除会出现“无法插入重复键”错误的主要内容,如果未能解决你的问题,请参考以下文章