La compression de sauvegarde provoque une corruption dans la base de données TDE SQL 2017

13

Sur SQL Server 2017 (CU3), chaque fois que j'active la compression de sauvegarde sur l'une de mes bases de données TDE, le processus de sauvegarde corrompt toujours une page spécifique de la base de données. Si j'exécute la sauvegarde sans compression, elle n'est pas corrompue. Voici les étapes que j'ai suivies pour vérifier et reproduire ce problème:

  1. Exécutez DBCC CheckDB sur la base de données "TDE_DB1"; tout va bien, pas d'erreurs;
  2. Sauvegarder avec succès la base de données sans compression; RESTORE VERIFYONLY dit que tout va bien;
  3. Restaurer avec succès la base de données en tant que "TDE_DB2"; tout va bien, DBCC CheckDB ne montre aucune erreur;
  4. Sauvegarder avec succès la base de données "TDE_DB1" AVEC compression; RESTORE VERIFYONLY erreurs, disant "Des dommages au jeu de sauvegarde ont été détectés";
  5. Tentative de restauration de la base de données en tant que "TDE_DB2"; erreurs, en disant "RESTORE a détecté une erreur sur la page (1: 92454) dans la base de données"
  6. Répétez les étapes 1 à 3; tout est bon;
  7. DROP "TDE_DB1" et "TDE_DB2"; Restaurer "TDE_DB1" à partir de la sauvegarde; tout est bon;
  8. Répétez les étapes 1 à 5; obtenir les mêmes résultats;

Pour résumer: la base de données et les sauvegardes régulières semblent correctes, l'exécution de CHECKDB sur la base de données et VERIFYONLY sur les sauvegardes ne signale aucune erreur. La sauvegarde de la base de données avec compression semble provoquer la corruption.

Voici les exemples de code avec des erreurs. (Remarque: MAXTRANSFERSIZE est requis pour utiliser la compression avec une base de données 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.

J'ai ensuite essayé de vérifier la page signalée comme contenant l'erreur (il s'agit toujours de la même page.), Mais DBCC PAGE signale que l'ObjectId est égal à 0. Selon cet article de Paul Randal, cela signifie qu'aucune métadonnée n'a été trouvée, et l'une des raisons pourrait être que la page elle-même est corrompue et que des valeurs incorrectes ont été utilisées pour essayer de rechercher les métadonnées. Son conseil est d'exécuter CHECKDB, ce que je ne peux pas faire car la sauvegarde corrompue ne sera pas restaurée.

J'ai essayé les suggestions de ce SO Post (Ajout de INIT et FORMAT à la commande BACKUP) pour réinitialiser les métadonnées, mais cela ne semble rien changer, j'obtiens toujours de la corruption sur la sauvegarde compressée.

Cela ne se produit qu'avec l'une de mes bases de données TDE. J'ai 4 autres bases de données TDE sur ce même serveur et elles n'ont pas ce problème. Cela me dit qu'il peut y avoir un problème sous-jacent avec cette base de données spécifique. Je me rends compte que la solution simple est de ne pas utiliser la compression, mais j'ai l'impression que cela peut en fait être un avertissement précoce d'un problème plus important à venir.

Quelqu'un a-t-il déjà vu cela auparavant, ou a-t-il une idée pourquoi la compression corromprait cette page? À ce stade, je ne sais pas quoi faire ensuite. J'ai envisagé de restaurer la page à partir d'une sauvegarde antérieure, mais je ne pense pas que cela importerait car la page de la base de données régulière semble correcte.

MISE À JOUR 1: Voici les résultats de DBCC PAGE, avec l'option 0:

L'exécution de DBCC est terminée. Si DBCC a imprimé des messages d'erreur, contactez votre administrateur système.

PAGE: (1: 92454)

TAMPON:

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 bDirtyContext = 0x0000000000000000 bDirtyContext = 0x2

EN-TÊTE DE PAGE:

Page @ 0x000002184865E000

m_pageId = (1: 92454) m_headerVersion = 111
m_type = 189 m_typeFlagBits = 0x2d m_level = 197
m_flagBits = 0x525e m_objId (AllocUnitId.idObjj) = 788815194
m_indexId (AllocUnitId815I_Id8: 14 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_reservedCnt = 4810 m_40n: 720) 14755
m_xdesId = (12811: 1559482793) m_ghostRecCnt = 12339
m_tornBits = -1381699202 ID de frag DB = 1

Statut d'allocation

GAM (1: 2) = SGAM ATTRIBUÉ (1: 3) =
PFS NON ATTRIBUÉ (1: 88968) = 0x0 0_PCT_FULL DIFF (1: 6) = NON CHANGÉ
ML (1: 7) = NON MIN_LOGGED

Si j'essaie d'exécuter DBCC PAGE avec d'autres options, j'obtiens les erreurs ci-dessous:

PAGE DBCC avec option 1: Msg 0, niveau 11, état 0, ligne 0 Une erreur grave s'est produite sur la commande actuelle. Le cas échéant, les résultats doivent être ignorés.

PAGE DBCC avec option 3: Msg 2514, niveau 16, état 5, ligne 3 Une erreur PAGE DBCC s'est produite: type de page non valide - style de vidage 3 impossible.

MISE À JOUR 2: Voici quelques-uns des résultats du DMO sys.dm_db_database_page_allocations:

object_id = 75 index_id = 1 rowset_id = 281474981625856 281474981625856 allocation_unit_id =
allocation_unit_type = 1 allocation_unit_type_desc = IN_ROW_DATA extent_file_id = 1 extent_page_id = 92448
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 = 0 is_mixed_page_allocation

Eric Cobb
la source

Réponses:

8

Il semble que ce problème concerne les bases de données sur lesquelles des opérations SHRINK ont été exécutées. Dans mon cas, je prenais une copie de l'une de nos bases de données de production sur SQL Server 2014 (qui est déjà crypté avec TDE), exécutant DBCC SHRINKFILE sur les données et les fichiers journaux, puis effectuant une sauvegarde et la restaurant sur mon nouveau SQL Serveur 2017. (La raison de la réduction était de réduire la taille pour accélérer le transfert de la sauvegarde.)

À titre de test, j'ai restauré une copie de la base de données sur laquelle je n'ai pas exécuté DBCC SHRINKFILE et elle n'a pas rencontré les problèmes de corruption lors de la compression des sauvegardes.

Donc, pour résumer, les résultats de mes tests sont les suivants:

  • Les opérations de sauvegarde / restauration normales sur cette base de données TDE «réduite» fonctionnent correctement dans SQL 2017
  • La compression des sauvegardes de la base de données TDE «réduite» semble provoquer une corruption dans la table sys.sysmultiobjrefs
  • La compression des sauvegardes de la base de données TDE normale (sans l'exécution de DBCC SHRINKFILE) fonctionne correctement et ne signale pas de corruption

Je ne sais pas s'il s'agit d'un bogue confirmé dans SQL Server 2017, mais j'ai envoyé mes conclusions à Microsoft pour qu'il les examine.

Donc, la morale de cette histoire est: NE PAS RÉTRÉCIER VOS BASES DE DONNÉES! DÉJÀ! :)

Eric Cobb
la source