SQL Serverは読み取り専用ファイルグループのレコードを更新しましたか?


8

データウェアハウスに非常に大規模なデータベースがあり、メンテナンスとバックアップを管理するためにパーティションを実装しています。特定の期間のレコードは、最終的には月に1回、読み取り専用ファイルグループに移行されます。

時々、私たちのETLプロセスはすでにアーカイブに移行された古いレコードを更新しようとしますが、これらは失敗すると予想されます。ただし、テスト環境のレコードが読み取り専用ファイルグループのパーティションにあるように見える場合でも、テストのレコードが更新される最近の例が少なくとも2つあります(クエリsys.partition_functionssys.partition_range_values)。

本番環境で同一のレコードを使用すると、レコードを更新しようとしたときに予期したエラーが発生します。これまでに2回これをキャッチしましたが、更新は本番環境では失敗しますが、テストでは成功します(その逆はありません)。

関連する環境の事実:

  • SQL Server 2012 SP3 CU3(ビルド11.0.6537.0)
  • テストは開発者版、製品はエンタープライズ版
  • リクエストに応じて他のユーザーに提供できます:現在深刻な困惑しています...

更新2016-08-19

新しいレコードがどういうわけか一晩で更新されました。読み取り専用ファイルグループ上にあることを確認しました。同時に挿入された(つまり、読み取り専用ファイルグループの同じパーティションにもある)レコードを更新できることがわかりました。同じパーティションで単一のレコードを識別し、そのレコードを複数回更新できました。夜間に更新されたレコードを更新しようとすると、予期した障害が発生します。

更新2016-08-11

更新は、読み取り専用パーティションでのテストの夜間処理中にも発生し続けます。プロセスから同じレコードを更新しようとすると失敗します。以前にそれを更新したユーザーとしてログインしたときに、同じレコードを更新しようとして失敗しました。私はまた、毎晩のプロセスでまだ触れられていない同様のレコードを更新して問題を再現することはできません。

更新2016-08-04

同じパーティションスキームを使用して、別のテーブルで同じ動作の別の発生を発見したため、その単一のテーブルに限定されないことを今日発見しました。

更新2016-08-03

このMSDNスクリプトからスクリプトを実行すると、Kendra Littleのパーティションヘルパービューを使用したときに得られる結果ph.FilegroupDetailph.ObjectDetailこのデモから確認できます。問題のレコードはパーティション#2にあります(問題のレコードのパーティション列の値は2015-03-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チームと一緒にパーティション分割計画を修正する必要がありますが、私はそれを再試行することについては恥ずかしがり屋ですが認めます。

マイクロソフトはこの動作を再現することができなかったため、現時点ではチケットを使用しています。彼らはそれをすくめるだけで2014/2016に存在しないと想定する準備ができているように見えますか?私のシステムのバックアップから復元した後でも、データベースに存在し続けることができる私の能力にもかかわらず、彼らは彼らのラボでそれを複製するようには見えません。


実際に使用中のデータベースのすべてのパーティションをバックアウトし、MSチケットを処理するために壊れたバージョンのバージョンを保持しました。DWチームと一緒にパーティション分割計画を修正する必要がありますが、もう一度
試す

回答:


1

私は告白する必要があります。

若い頃、私はETLプロセスを構築しました。まず、読み取り専用ファイルグループを読み取り/書き込みに変更し、そのETL作業を行ってから、それらを読み取り専用に戻しました。

だから、私と同じように悪魔的な同僚がいる場合(私は若かったので、お金が必要でした)、次の方法でテストできます。

  1. 読み取り専用のファイルグループの名前を変更します。そのようにすると、ファイルグループを名前で変更するスクリプトがハードコードされている場合、スクリプトは失敗し、犯人を捕まえます。または、少し難しい:

  2. プロファイラーまたは拡張イベントを使用して、ALTER DATABASEを実行するすべてのユーザーを追跡します。


実際にDWチームにこの変更を加えるためのスクリプトを提供したので、彼らは夜間、めったに起こらないと予想される状況で仕事が失敗することなく私たちを起こさなくて済みました。また、ファイルグループの読み取り/書き込みプロパティヒットを設定するサーバーレベルの監査トリガー(DDL_SERVER_LEVEL_EVENTS上)もあります。SQLスクリプト、ユーザー、およびIPアドレスを送信して、DBAチームが確認します。
toosuto 2017

スクリプトを使用してETLプロセスの前にファイルグループ設定を変更するのに十分だまされているように思えるかもしれませんが、トリガーを探して無効にするのに十分な技術的知識はありません。
toosuto
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.