La sauvegarde détecte la corruption, mais CHECKDB ne le fait pas

12

J'ai une base de données où lorsque j'exécute la commande de sauvegarde

BACKUP DATABASE [MyDatabase] TO     
DISK =  'G:\Backup\MyDatabase_01_01_2018.bak'   
WITH    NOFORMAT, NOSKIP, COMPRESSION, INIT, BUFFERCOUNT = 100

Je reçois le message d'erreur

Msg 3043, niveau 16, état 1, ligne 8
SAUVEGARDE 'MyDatabase' a détecté une erreur sur la page (1: 745345) dans le fichier 'F: \ Data \ MyDatabase_1.ndf'.
Msg 3013, niveau 16, état 1, ligne 8
BASE DE DONNÉES DE SAUVEGARDE se termine anormalement.

J'ai exécuté un CHECKDB complet mais il revient propre. J'ai remarqué que l'option Page Verify avait été définie sur NONE (ce n'est pas mon cas), je l'ai donc changé en CHECKSUM et reconstruit tous les index de la base de données pour qu'il écrive sur toutes les pages et génère des sommes de contrôle. Après cela, la sauvegarde échoue toujours et le checkdb affiche toujours propre (donc pas de changement).

DBCC CHECKDB('MyDatabase') WITH NO_INFOMSGS, ALL_ERRORMSGS,
DATA_PURITY, EXTENDED_LOGICAL_CHECKS;

à partir du journal SQL:

DBCC CHECKDB (MyDatabase) AVEC all_errormsgs, no_infomsgs, data_purity exécuté par xxx a trouvé 0 erreur et réparé 0 erreur. Temps écoulé: 0 heures 21 minutes 46 secondes. L'instantané de la base de données interne a un point de division LSN = 000ab776: 0000112f: 0001 et le premier LSN = 000ab776: 0000112d: 0001.

J'ai couru DBCC PAGE mais il a des erreurs (ne semble même pas retourner la bonne page en premier lieu). Je peux l'exécuter avec l'option d'impression 2 et il revient mais honnêtement, je ne sais pas ce que je cherche là-bas.

DBCC PAGE ('MyDatabase',1,745345,3)
PAGE: (3: 513793)

TAMPON:


BUF @ 0x00000003811F8280

bpage = 0x00000000F2D70000 bhash = 0x0000000000000000 bpageno = (1: 745345)
bdbid = 5 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 44283 bstat = 0x809
blog = 0x5adb215a bnext = 0x0000000000000000          

EN-TÊTE DE PAGE:


Page @ 0x00000000F2D70000

m_pageId = (3: 513793) m_headerVersion = 1 m_type = 2
m_typeFlagBits = 0x4 m_level = 0 m_flagBits = 0x0
m_objId (AllocUnitId.idObj) = 1075937538 m_indexId (AllocUnitId.idInd) = 2
Métadonnées: AllocUnitId = 633462595911680 Métadonnées: PartitionId = 0
Métadonnées: IndexId = -1 Métadonnées: ObjectId = 0 m_prevPage = (3: 513795)
m_nextPage = (3: 513820) pminlen = 17 m_slotCnt = 426
m_freeCnt = 2 m_freeData = 7338 m_reservedCnt = 0
m_lsn = (608841: 643611: 411) m_xactReserved = 0 m_xdesId = (0: 0)
m_ghostRecCnt = 0 m_tornBits = 0 ID de fragment de base de données = 1

Statut d'allocation

GAM (1: 511232) = SGAM ATTRIBUÉ (1: 511233) = NON ATTRIBUÉ     
PFS (1: 744096) = 0x40 DOTÉ 0_PCT_FULL DIFF (1: 511238) = NON MODIFIÉ
ML (1: 511239) = NON MIN_LOGGED      

Msg 2514, niveau 16, état 8, ligne 20
Une erreur de page DBCC s'est produite: métadonnées de page non valides - style de vidage 3 impossible.

Des idées que je pourrais essayer ensuite? La version du serveur est

select @@version
Microsoft SQL Server 2014 (SP2-CU11) (KB4077063) - 12.0.5579.0 (X64) 
    21 févr.2018 12:19:47 
    Copyright (c) Microsoft Corporation
    Developer Edition (64 bits) sur Windows NT 6.3 (Build 9600:) (Hyperviseur)

Le niveau de compatibilité de la base de données est 100 (SQL 2008).

Element Zero
la source
Les commentaires sur cette question ont été déplacés vers le chat .
Paul White 9

Réponses:

9

Cette réponse est tirée d'un numéro du bulletin d'information SQLskills.com écrit par Paul Randal, sur "une base de données qui échouerait une sauvegarde avec des erreurs de somme de contrôle de page, mais a réussi un DBCC CHECKDB".

Le seul cas où cela peut se produire est lorsqu'une étendue est une étendue mixte (où les 8 pages de l'étendue peuvent être allouées à potentiellement 8 unités d'allocation différentes - voir ici ) et certaines pages sont marquées à tort comme allouées par la page PFS concernée.

Lorsque cela se produit, DBCC CHECKDBne tentera pas de lire ces pages, car il dérive quelles pages lire à partir des pages IAM d'une unité d'allocation (dont la première répertorie les pages allouées à partir d'une étendue mixte). Ce cas est une lacune dans DBCC CHECKDBla logique de détection de corruption de.

[Parce que] DBCC CHECKDBn'a pas pu détecter la corruption, il n'a pas été possible d'effectuer les réparations nécessaires pour les réparer. Donc, en utilisant DBCC WRITEPAGE, j'ai travaillé sur les changements nécessaires dans le statut d'allocation pour les pages allouées par erreur, directement dans la page PFS, et cela a fonctionné!

C'était un cas extrêmement rare - il est beaucoup plus courant qu'un DBCC CHECKDB échec mais une sauvegarde réussisse.

À mon avis, la résolution de Paul va bien au-delà de l'exportation et de l'importation des données comme vous l'avez fait, donc je pense que vous avez fait la bonne chose.

Randolph West
la source