web-dev-qa-db-ja.com

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

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」としてデータベースを復元しようとしました。エラー、「RESTOREがデータベースのページ(1:92454)でエラーを検出しました」
  6. 手順1〜3を繰り返します。すべてが良いです;
  7. DROP "TDE_DB1"および "TDE_DB2";バックアップから「TDE_DB1」を復元します。すべてが良いです;
  8. 手順1〜5を繰り返します。同じ結果が得られます。

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

エラーのあるコードサンプルを以下に示します。 (注: TTRANデータベースで圧縮を使用するには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であると報告しています。 Paul Randalによるこの記事によると メタデータが見つかりませんでした。理由の1つは、ページ自体が破損していて、メタデータを検索するために不正な値が使用されたことが考えられます。彼のアドバイスは、CHECKDBを実行することです。破損したバックアップは復元されないため、私は実行できません。

this SO Post (INITとFORMATをBACKUPコマンドに追加)からの提案を試してメタデータをリセットしましたが、何も変更していないようでしたが、圧縮されたバックアップで破損が発生します。

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

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

UPDATE 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ブログ= 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 = 145011308798541824メタデータ:PartitionId = 0メタデータ: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)m_xactReserved = 14755
m_xdesId =(12811:1559482793)m_ghostRecCnt = 12339
m_tornBits = -1381699202 DB Frag ID = 1

割り当てステータス

GAM(1:2)=割り当て済みSGAM(1:3)=割り当てなし
PFS(1:88968)= 0x0 0_PCT_FULL DIFF(1:6)=変更されていません
ML(1:7)= MIN_LOGGEDではありません

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

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

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

UPDATE 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_DATAextent_file_id = 1extent_page_id = 92448
allocated_pa​​ge_iam_file_id = 1located_pa​​ge_iam_page_id = 104
allocated_pa​​ge_file_id = 1located_pa​​ge_page_id = 92454
is_allocated = 0 is_iam_page = 0 is_mixed_pa​​ge_allocation = 0

13
Eric Cobb

この問題は、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に送信して調査してもらいました。

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

8
Eric Cobb