Su SQL Server 2017 (CU3), ogni volta che abilito la compressione del backup su uno dei miei database TDE, il processo di backup corrompe sempre una pagina specifica nel database. Se eseguo il backup senza compressione, non viene danneggiato. Ecco i passaggi che ho seguito per verificare e riprodurre questo problema:
- Eseguire DBCC CheckDB sul database "TDE_DB1"; tutto va bene, nessun errore;
- Esegui correttamente il backup del database senza compressione; RESTORE VERIFYONLY dice che tutto va bene;
- Ripristina correttamente il database come "TDE_DB2"; tutto va bene, DBCC CheckDB non mostra errori;
- Eseguire correttamente il backup del database "TDE_DB1" CON compressione; RIPRISTINA errori VERIFICATIVI, dicendo "Rilevato danno al set di backup";
- Tentare di ripristinare il database come "TDE_DB2"; errori, dicendo "RESTORE ha rilevato un errore nella pagina (1: 92454) nel database"
- Ripeti i passaggi 1-3; va tutto bene;
- DROP "TDE_DB1" e "TDE_DB2"; Ripristina "TDE_DB1" dal backup; va tutto bene;
- Ripetere i passaggi 1-5; ottenere gli stessi risultati;
Riassumendo: il database e i backup regolari sembrano a posto, l'esecuzione di CHECKDB sul database e VERIFYONLY sui backup non riportano errori. Il backup del database con compressione sembra causare il danneggiamento.
Di seguito sono riportati gli esempi di codice con errori. (Nota: MAXTRANSFERSIZE è necessario per utilizzare la compressione con un database TDE )
-- 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.
Ho quindi provato a controllare la pagina che riporta l'errore (è sempre la stessa pagina), ma DBCC PAGE riporta che ObjectId è 0. Secondo questo articolo di Paul Randal ciò significa che non sono stati trovati metadati, e uno dei motivi potrebbe essere che la pagina stessa è corrotta e sono stati usati valori errati per cercare di cercare i metadati. Il suo consiglio è di eseguire CHECKDB, cosa che non posso fare perché il backup danneggiato non verrà ripristinato.
Ho provato i suggerimenti di questo SO Post (aggiungendo INIT e FORMAT al comando BACKUP) per ripristinare i metadati, ma ciò non sembra aver cambiato nulla, ho ancora la corruzione sul backup compresso.
Questo succede solo con uno dei miei database TDE. Ho altri 4 database TDE su questo stesso server e non presentano questo problema. Questo mi dice che potrebbe esserci un problema di fondo con questo specifico database. Mi rendo conto che la soluzione semplice è semplicemente quella di non usare la compressione, ma penso che questo potrebbe in realtà essere un avvertimento tempestivo di un problema più grande che sta arrivando.
Qualcuno l'ha mai visto prima o hai idea del perché la compressione corrompa quella pagina? A questo punto, sono quasi in perdita su cosa fare dopo. Ho preso in considerazione il ripristino della pagina da un backup precedente, ma non penso che avrebbe importanza poiché la pagina nel database normale sembra a posto.
AGGIORNAMENTO 1: Di seguito sono riportati i risultati della PAGINA DBCC, con l'opzione 0:
Esecuzione DBCC completata. Se DBCC ha stampato messaggi di errore, contattare l'amministratore di sistema.
PAGINA: (1: 92454)
BUFFER:
BUF @ 0x000002187AE55640
bpage = 0x000002184865E000 bhash = 0x0000000000000000
bpageno = (1: 92454) bdbid = 8 breferences = 0 bcputicks = 563 bsampleCount = 1
bUse1 = 51429
bstat = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000INTESTAZIONE DI PAGINA:
Pagina @ 0x000002184865E000
m_pageId = (1: 92454) m_headerVersion = 111
m_type = 189 m_typeFlagBits = 0x2d m_level = 197
m_flagBits = 0x525e m_objId (AllocUnitId.idOdj4 = Metata = 145 = Metata = 788815194
m_indexId = Metc IndexId = -1 Metadata: ObjectId = 0 m_prevPage = (32842: 1881351155) m_nextPage = (13086: -560562340)
pminlen = 36067 m_slotCnt = 8149 m_freeCnt = 51871 m_freeData = 7295 m_serv = 7015 14755
m_xdesId = (12811: 1559482793) m_ghostRecCnt = 12339
m_tornBits = -1381699202 DB Frag ID = 1Stato di allocazione
GAM (1: 2) = SGAM ASSEGNATO (1: 3) =
PFS NON ASSEGNATO (1: 88968) = 0x0 0_PCT_FULL DIFF (1: 6) = NON MODIFICATO
ML (1: 7) = NON MIN_LOGGED
Se provo a eseguire DBCC PAGE con altre opzioni, ottengo gli errori seguenti:
PAGINA DBCC con opzione 1: Messaggio 0, Livello 11, Stato 0, Riga 0 Si è verificato un errore grave nel comando corrente. I risultati, se presenti, devono essere eliminati.
PAGINA DBCC con opzione 3: Messaggio 2514, livello 16, stato 5, riga 3 Si è verificato un errore PAGINA DBCC: tipo di pagina non valido - stile di dump 3 non possibile.
AGGIORNAMENTO 2: Ecco alcuni dei risultati del DMO sys.dm_db_database_page_allocations:
object_id = 75 index_id = 1 rowset_id = 281.474.981.625.856 allocation_unit_id = 281.474.981.625.856
allocation_unit_type = 1 allocation_unit_type_desc = IN_ROW_DATA extent_file_id = 1 extent_page_id = 92.448
allocated_page_iam_file_id = 1 allocated_page_iam_page_id = 104
allocated_page_file_id = 1 allocated_page_page_id = 92454
is_allocated = 0 is_iam_page = 0 is_mixed_page_allocation = 0