SQL 2017 TDEデータベースで破損を引き起こすバックアップ圧縮


13

SQL Server 2017(CU3)では、TDEデータベースの1つでバックアップ圧縮を有効にすると、バックアッププロセスによってデータベースの特定のページが常に破損します。圧縮せずにバックアップを実行しても、破損しません。この問題を確認して再現するために行った手順は次のとおりです。

  1. データベース「TDE_DB1」でDBCC CheckDBを実行します。すべてが良好で、エラーはありません。
  2. 圧縮せずにデータベースを正常にバックアップします。RESTORE VERIFYONLYはすべてが良いと言っています。
  3. データベースを「TDE_DB2」として正常に復元します。すべて良好で、DBCC CheckDBはエラーを表示しません。
  4. 「TDE_DB1」データベースを圧縮して正常にバックアップします。「バックアップセットへの損傷が検出されました」と言うVERIFYONLYエラーを復元します。
  5. データベースを「TDE_DB2」として復元しようとします。「データベースでページ(1:92454)でエラーが検出されました」というエラー
  6. 手順1〜3を繰り返します。すべてが良いです;
  7. DROP "TDE_DB1"および "TDE_DB2"; バックアップから「TDE_DB1」を復元します。すべてが良いです;
  8. 手順1〜5を繰り返します。同じ結果が得られます。

要約すると、データベースと通常のバックアップは正常に見え、データベースでCHECKDBを実行し、バックアップでVERIFYONLYを実行してもエラーは報告されません。圧縮を使用してデータベースをバックアップすると、破損が発生するようです。

以下にエラーのあるコードサンプルを示します。(注:TDEデータベースで圧縮を使用するには、MAXTRANSFERSIZEが必要です

-- Good, completes with no corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1a.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';


-- Bad, I haz corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM, COMPRESSION, MAXTRANSFERSIZE = 131072;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1b.bak' WITH CHECKSUM;
-- ERROR
--Msg 3189, Level 16, State 1, Line 1
--Damage to the backup set was detected.
--Msg 3013, Level 16, State 1, Line 1
--VERIFY DATABASE is terminating abnormally.

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1b.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';
-- ERROR
--Msg 3183, Level 16, State 1, Line 7
--RESTORE detected an error on page (1:92454) in database "TDE_DB2" as read from the backup set.
--Msg 3013, Level 16, State 1, Line 7
--RESTORE DATABASE is terminating abnormally.

次に、エラーがあると報告されたページ(常に同じページです)をチェックしようとしましたが、DBCC PAGEはObjectIdが0である報告しました。PaulRandal によるこの記事によると、メタデータが見つかりません理由の1つは、ページ自体が破損しており、メタデータの検索に誤った値が使用されたためです。彼のアドバイスはCHECKDBを実行することです。これは、破損したバックアップが復元されないため実行できません。

私はこのSO投稿から提案を試みました(BACKUPコマンドへのINITおよびFORMATの追加)メタデータをリセットしましたが、何も変わらないようでしたが、圧縮されたバックアップが破損します。

これは、TDEデータベースの1つでのみ発生します。この同じサーバー上に4つのTDEデータベースがありますが、この問題はありません。これは、この特定のデータベースに根本的な問題がある可能性があることを示しています。簡単な解決策は圧縮を使用しないことであることに気づきますが、これは実際に大きな問題が発生することに対する早期の警告であると感じています。

誰もこれを見たことがありますか、または圧縮がそのページを破損する理由をご存知ですか?この時点で、次に何をすべきか迷っています。以前のバックアップからページを復元することを検討しましたが、通常のデータベースのページは問題ないと思われるので、それは問題ではないと思います。

更新1: 以下は、オプション0を使用したDBCC PAGEの結果です。

DBCCの実行が完了しました。DBCCがエラーメッセージを出力した場合は、システム管理者に連絡してください。

ページ:(1:92454)

バッファ:

BUF @ 0x000002187AE55640

bpage = 0x000002184865E000 bhash = 0x0000000000000000
bpageno =(1:92454)bdbid = 8 breferences = 0 bcputicks = 563 bsampleCount = 1
bUse1 = 51429 bstat = 0x809 blog = 0x15a
bnext = 0x0000000000000000 bDirtyContext = 0x0000000000000000 bstat2 = 0x0

ページヘッダー:

ページ@ 0x000002184865E000

m_pageId =(1:92454)m_headerVersion = 111
m_type = 189 m_typeFlagBits = 0x2d m_level = 197
m_flagBits = 0x525e m_objId(AllocUnitId.idObj)= 788815194
m_indexId(AllocUnitId.idInd)= 515メタデータ:AllocUnitId = 14501メタデータ:AllocUnitId = 14501 IndexId = -1メタデータ:ObjectId = 0 m_prevPage =(32842:1881351155)m_nextPage =(13086:-560562340)
pminlen = 36067 m_slotCnt = 8149 m_freeCnt = 51871 m_freeData = 7295 m_reservedCnt = 4810 m_lsn =(742012401:720884976:30191) 14755
m_xdesId =(12811:1559482793)m_ghostRecCnt = 12339
m_tornBits = -1381699202 DB Frag ID = 1

割り当て状況

GAM(1:2)= ALLOCATED SGAM(1:3)= NOT ALLOCATED
PFS(1:88968)= 0x0 0_PCT_FULL DIFF(1:6)= NOT CHANGED
ML(1:7)= NOT MIN_LOGGED

他のオプションでDBCC PAGEを実行しようとすると、次のエラーが表示されます。

オプション1のDBCC PAGE:メッセージ0、レベル11、状態0、行0現在のコマンドで重大なエラーが発生しました。結果があれば、破棄する必要があります。

オプション3のDBCC PAGE:メッセージ2514、レベル16、状態5、行3 DBCC PAGEエラーが発生しました:ページタイプが無効です-ダンプスタイル3は使用できません。

更新2: sys.dm_db_database_page_allocations DMOの結果の一部を次に示します。

OBJECT_ID = 75 INDEX_ID = 1 rowset_id = 281474981625856 allocation_unit_id = 281474981625856
allocation_unit_type = 1 allocation_unit_type_desc = IN_ROW_DATA extent_file_id = 1 extent_page_id = 92448
allocated_pa​​ge_iam_file_id = 1 allocated_pa​​ge_iam_page_id = 104
allocated_pa​​ge_file_id = 1 allocated_pa​​ge_page_id = 92454
is_allocated = 0 is_iam_page = 0 is_mixed_pa​​ge_allocation = 0

回答:


8

この問題は、SHRINK操作が実行されたデータベースに関するもののようです。私の場合、SQL Server 2014(既にTDEで暗号化されています)で運用データベースの1つをコピーし、データファイルとログファイルの両方でDBCC SHRINKFILEを実行してから、新しいSQLでバックアップと復元を行いました2017サーバー。(縮小の理由は、サイズを小さくしてバックアップの転送を高速化することでした。)

テストとして、DBCC SHRINKFILEを実行していないデータベースのコピーを復元しましたが、バックアップの圧縮時に破損の問題はありませんでした。

要約すると、私のテストの結果は次のとおりです。

  • この「縮小された」TDEデータベースでの通常のバックアップ/復元操作は、SQL 2017で正しく機能します。
  • 「縮小された」TDEデータベースのバックアップを圧縮すると、sys.sysmultiobjrefsテーブルが破損するようです
  • 通常のTDEデータベース(DBCC SHRINKFILEを実行しない)のバックアップの圧縮は正しく機能し、破損を報告しません。

これがSQL Server 2017で確認されたバグであるかどうかはわかりませんが、調査結果をMicrosoftに送信し、確認しました。

したがって、この話の教訓は次のとおりです。データベースを縮小しないでください!今まで!:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.