SQL Server更新了只读文件组上的记录?


8

我的数据仓库中有一个非常大的数据库,我们在其中实施了分区以管理维护和备份。一定期限的记录最终每月一次迁移到一个只读文件组。

有时,我们的ETL流程会尝试更新已迁移到存档的较旧记录,我们希望这些记录会失败。但是,我至少有两个最近的示例,其中即使测试记录似乎位于测试环境中的只读文件组的分区中(查询sys.partition_functionssys.partition_range_values),该记录也会被更新。

当尝试更新记录时,生产中的相同记录会导致预期的失败。到目前为止,我们已经两次捕获到该更新,但在生产中失败了,但是在测试中成功了(反之亦然)。

相关环境事实:

  • SQL Server 2012 SP3 CU3(内部版本11.0.6537.0)
  • 测试是开发人员版,生产是企业
  • 可以根据要求提供其他人:现在已严重困扰...

更新2016-08-19

新记录在一夜之间以某种方式更新了。确认它在只读文件组中。发现我可以更新同时插入的记录(即也位于只读文件组的同一分区上)。我在同一分区上确定了一条记录,并且能够多次更新该记录。尝试更新过夜更新的记录会导致预期的失败。

更新2016-08-11

在每晚的测试过程中,只读分区上的更新继续发生。尝试从该过程中更新相同的记录失败。尝试以以前更新记录的用户身份登录时更新相同的记录失败。我也无法通过更新夜间程序尚未触及的类似记录来重复该问题。

更新2016-08-04

今天发现它不限于该单个表,因为我发现了使用相同分区方案在不同表上再次出现相同行为的情况。

更新2016-08-03

运行该脚本这个MSDN脚本证实了我使用肯德拉小的分区助手的意见时得到ph.FilegroupDetailph.ObjectDetail该演示。有问题的记录位于分区2中(有问题的记录的分区列值为2015年3月18日)

Filegroup     Low Boundary     UpperBoundary
Archive  (RO) NULL             1900-01-01
Archive  (RO) 1900-01-01       2015-04-01
ActiveFG (RW) 2015-04-01       2015-07-01
ActiveFG (RW) 2015-07-01       2015-10-01
ActiveFG (RW) 2015-10-01       2015-01-01
ActiveFG (RW) 2016-01-01       2016-04-01
ActiveFG (RW) 2016-04-01       2016-07-01
ActiveFG (RW) 2016-07-01       2016-10-01
ActiveFG (RW) 2016-10-01       2017-01-01
ActiveFG (RW) 2017-01-01       2115-01-01
ActiveFG (RW) 2115-01-01       NULL

将表放在分区上的代码(没有其他索引)

ALTER TABLE [dbo].[TABLE_NAME] ADD  CONSTRAINT [pk_TABLE_NAME] PRIMARY KEY CLUSTERED 
(
    [ETL_VERS_START_DTM] ASC,
    [ACCT_NO] ASC,
    [ACCT_TYPE] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ps_SmallTablesDate(ETL_VERS_START_DTM)

应该失败的更新语句(通过Informatica):

UPDATE TABLE_NAME SET ETL_JOB_SEQ_NUM = ?, ETL_IUD_CD = ?, ETL_UPD_DTM = ?, ETL_DEL_DTM = ? WHERE ETL_VERS_START_DTM = ? AND ACCT_NO = ? AND ACCT_TYPE = ?
ETL_VERS_START_DTM (ETL_VERS_START_DTM:Date:): "03/17/2015 23:30:02.140000000"
ETL_JOB_SEQ_NUM (ETL_JOB_SEQ_NUM:Int:): "1173651"
ETL_IUD_CD (ETL_IUD_CD:Char.1:): "D"
ETL_UPD_DTM (ETL_UPD_DTM:Date:): "08/02/2016 02:32:45.000000000"
ETL_DEL_DTM (ETL_DEL_DTM:Date:): "08/02/2016 00:10:03.567000000"
ACCT_NO (ACCT_NO:Char.12:): "1234567890"
ACCT_TYPE (ACCT_TYPE:Char.3:): "OLN"

更新2017-02-21

因此,在所有这些时间之后,我们发现以某种方式将最旧的活动分区合并到存档中时,记录的一部分并未从磁盘上从活动文件组移动到存档文件组。以下查询显示,分区2中的记录已映射到ActiveFG,而检查实际的分区方案则表明,应使用分区功能将这些相同的记录分类到“存档”文件组中。

SELECT  OBJECT_NAME(P.[object_id]) ,
    P.index_id ,
    P.partition_number ,
    F.name ,
    F.filegroup_guid
FROM    sys.allocation_units AU
    JOIN sys.partitions P ON P.partition_id = AU.container_id
    JOIN sys.filegroups F ON F.data_space_id = AU.data_space_id
WHERE   P.partition_number IN ( 1, 2, 3 )
    AND P.[object_id] = OBJECT_ID('TABLE_NAME')
ORDER BY P.partition_number;

我撤消了实际使用的数据库中的所有分区,并保留了一个损坏的版本以用于Microsoft票证。我需要与我们的DW团队一起修改分区计划,但我会承认对再次尝试不满意。

Microsoft无法复制此行为,因此此时已完成票证。他们似乎准备将其耸肩,并假设它在2014/2016年不存在?尽管我有能力让它继续存在于数据库中,但即使我从系统中将其还原后,他们似乎也无法在实验室中复制它。


我撤消了实际使用的数据库中的所有分区,并保留了要用于MS票证的那个版本的版本。我需要与我们的DW团队一起修改分区计划,但我会承认对再次尝试感到
有些怯

Answers:


1

我要坦白。

有一次,我很小的时候就建立了一个ETL流程,首先将只读文件组更改为可读写,然后进行ETL工作,然后将它们设置回只读状态。

因此,以防万一您有一个像我一样令人反感的同事(我还很年轻,我需要钱),您可以通过以下方式进行测试:

  1. 更改只读文件组的名称-这样,如果某人具有按名称更改文件组的硬编码脚本,则他们的脚本将失败,您将被追究罪魁祸首。或者,更难一点:

  2. 使用探查器或扩展事件来跟踪执行ALTER DATABASE的任何人。


实际上,我们已经为DW团队提供了一个脚本来进行此更改,因此,他们不必在罕见但可预期的工作失败的夜晚醒来。我们还有一个服务器级审核触发器(在DDL_SERVER_LEVEL_EVENTS上),用于设置文件组的读/写属性命中率。它向我们发送了SQL脚本,用户和IP地址,供DBA团队检查。
toosuto

尽管我看起来他们似乎很狡猾,可以在他们的ETL过程之前使用我们的脚本来更改文件组设置,但是他们在技术上还不足以查找和禁用我们的触发器。
toosuto '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.