Preskočiť na obsah
Návod

CHECKDB našiel chybu – čo ďalej (823 / 824 / 825)

Postup pri korupcii databázy: čo nerobiť, ako uložiť výstup, identifikovať objekt a index, kedy stačí rebuild nonclustered indexu, page restore, obnova zo zálohy a prečo je REPAIR_ALLOW_DATA_LOSS až posledná možnosť. Príčina býva v úložisku.

4 min čítania 7 krokov SQL Server 2016+
`DBCC CHECKDB` hlási chyby konzistencie, alebo error log ukazuje **823** (OS hlási chybu I/O), **824** (stránka sa prečítala, ale je logicky zlá – checksum, torn page) či **825** (čítanie sa podarilo až na opakovaný pokus – varovanie pred zlyhaním disku).

> [!CAUTION]
> **Nepanikár a nereštartuj** server – reštart chybu neopraví a databáza môže zostať v stave SUSPECT. **Nespúšťaj hneď** `REPAIR_ALLOW_DATA_LOSS` – zmaže poškodené stránky aj s dátami a nepovie ti, čo presne stratíš.

## 1. Zachyť dôkazy

1. Ulož **celý** výstup CHECKDB (záložka Messages) do súboru. Ak si ho nespúšťal ty, spusti ho znova cez [DBCC CHECKDB – šablóna](script.php?id=34&s=dbcc-checkdb-sablona-s-dry-run) s `NO_INFOMSGS, ALL_ERRORMSGS`.
2. [Suspect pages](script.php?id=32&s=suspect-pages-evidovane-poskodene-stranky) – zoznam poškodených stránok (`file_id:page_id`) aj v iných databázach.
3. [Error log s filtrom](script.php?id=52&s=error-log-s-filtrom) – hľadaj `823`, `824`, `825` a časy, kedy sa objavili.
4. Over, či máš **dobrú zálohu** spred poškodenia – [História záloh](script.php?id=31&s=historia-zaloh-typ-velkost-kompresia-subor).

## 2. Čo je poškodené

Na konci výstupu CHECKDB je odporúčaná **minimálna úroveň opravy** (`repair_rebuild` alebo `repair_allow_data_loss`) a pri každej chybe `Object ID`, `index ID` a stránka.

```sql
SELECT OBJECT_SCHEMA_NAME(<object_id>) AS schema_name, OBJECT_NAME(<object_id>) AS object_name, name AS index_name, index_id, type_desc
FROM sys.indexes
WHERE object_id = <object_id> AND index_id = <index_id>;
```

| Čo je poškodené | Čo urobiť |
|---|---|
| **nonclustered index** (`index_id > 1`) | Dáta sú v poriadku. Stačí `ALTER INDEX … REBUILD` (offline) alebo `DROP` + `CREATE` indexu. Potom `DBCC CHECKTABLE`. |
| **clustered index / heap** (`index_id` 0 alebo 1) | Poškodené sú samotné dáta → obnova stránok alebo databázy zo zálohy. |
| systémové tabuľky, alokačné stránky (GAM, SGAM, PFS), boot page | Page restore nepomôže → obnova celej databázy zo zálohy. |
| `DATA_PURITY` chyby (2570) | Neplatné hodnoty v stĺpcoch – oprava ručným `UPDATE`, REPAIR ich neopraví. |

Po oprave indexu over konkrétnu tabuľku: `DBCC CHECKTABLE (N'schema.tabuľka') WITH NO_INFOMSGS, ALL_ERRORMSGS;`

## 3. Oprava zo zálohy

1. **Page restore** – obnoví len poškodené stránky (FULL alebo BULK_LOGGED recovery, read/write filegroup). Online len v **Enterprise** edícii, inak offline:

```sql
RESTORE DATABASE MojaDB PAGE = N'1:57, 1:202' FROM DISK = N'<full>.bak' WITH NORECOVERY;
RESTORE LOG MojaDB FROM DISK = N'<log1>.trn' WITH NORECOVERY;
-- ... ďalšie LOG zálohy ...
BACKUP LOG MojaDB TO DISK = N'<nový_log>.trn';
RESTORE LOG MojaDB FROM DISK = N'<nový_log>.trn' WITH RECOVERY;
```

2. **Obnova celej databázy** zo zálohy spred poškodenia + všetky logy – postup v [Obnove k bodu v čase](script.php?id=60&s=obnova-databazy-k-bodu-v-case-point-in-time-restore). Najprv **tail-log backup** (pri poškodenej DB `WITH CONTINUE_AFTER_ERROR`).
3. Po obnove znova CHECKDB.

## 4. REPAIR_ALLOW_DATA_LOSS – až keď nie je záloha

- Odstráni poškodené stránky / riadky, aby bola databáza **fyzicky** konzistentná. Ktoré dáta zmiznú, presne nezistíš; cudzie kľúče sa nekontrolujú.
- Vyžaduje `SINGLE_USER` ([Vyhodiť všetkých z databázy](script.php?id=8&s=vyhodit-vsetkych-z-databazy-single-user)). Pred tým **skopíruj všetky súbory databázy** a vytiahni čo najviac dát z poškodených tabuliek.
- Spúšťaj v transakcii, aby si výsledok mohol odmietnuť (`ROLLBACK`). Po oprave `DBCC CHECKCONSTRAINTS` a okamžite FULL záloha.
- `REPAIR_REBUILD` opravuje len to, čo sa dá bez straty dát (typicky indexy).

## 5. Príčina je takmer vždy pod SQL Serverom

- Windows **System / Application** log: chyby disku, radiča, ovládača, multipath.
- Úložisko / virtualizácia: logy SAN, snapshoty VM, firmware, filter drivery (antivírus – vylúč dátové a log súbory zo skenovania).
- Opakovaná **825** = disk ešte číta, ale zlyháva – rieš hneď, kým nepríde 823 / 824.
- Over `PAGE_VERIFY` = `CHECKSUM` vo všetkých databázach ([Inventár databáz](script.php?id=12&s=inventar-databaz-recovery-model-compat-level-rcsi)).

## 6. Prevencia

- `PAGE_VERIFY CHECKSUM` všade, zálohy `WITH CHECKSUM`.
- Pravidelný CHECKDB – napr. `DatabaseIntegrityCheck` od Olu Hallengrena ([ola.hallengren.com](https://ola.hallengren.com/), MIT); na veľkých DB týždenne `PHYSICAL_ONLY` a plný CHECKDB na obnovenej kópii.
- SQL Agent alerty na chyby **823, 824, 825** a závažnosť 19–25.
- Pravidelný **test obnovy** – záloha bez testu je len nádej.

## Zdroje

- [DBCC CHECKDB](https://learn.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-checkdb-transact-sql)
- [MSSQLSERVER_824](https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/mssqlserver-824-database-engine-error)
- [Restore pages](https://learn.microsoft.com/en-us/sql/relational-databases/backup-restore/restore-pages-sql-server)
- [Tail-log backups](https://learn.microsoft.com/en-us/sql/relational-databases/backup-restore/tail-log-backups-sql-server)