Meu Banco Corrompeu no SQL Server… e Agora?

Uma das situações mais críticas que um DBA pode enfrentar é a corrupção de páginas de dados em um banco SQL Server. Ela pode ocorrer por falhas de disco, problemas de memória ou até interferências do sistema operacional. E quando acontece, o impacto pode ser grave: consultas que caem, perda de registros e falhas na integridade do banco.

Neste post, você vai aprender:

  • Como simular uma corrupção para estudo

  • Como identificar e tratar páginas corrompidas

  • Como restaurar ou reparar um banco afetado

  • Como configurar alertas automáticos no SQL Server


💥 Simulando Corrupção de Tabela

Para estudo, podemos utilizar DBCC WRITEPAGE (com EXTREMA cautela) para escrever bytes diretamente em uma página específica do arquivo .mdf.

Exemplo de criação e corrupção:

DROP DATABASE If exists VendasDB
go
CREATE DATABASE VendasDB
go

-- IF EXISTS só a partir do SQL Server 2016
DROP TABLE IF EXISTS VendasDB.dbo.Cliente

CREATE TABLE VendasDB.dbo.Cliente 
(ClienteID int not null primary key,Nome char(900),Telefone varchar(20))
go

INSERT VendasDB.dbo.Cliente VALUES 
(1,'Jose','1111-1111'),
(2,'Maria','2222-2222'),
(3,'Ana','3333-3333'),
(4,'Paula','1111-1111'),
(5,'Marcio','2222-2222'),
(6,'Erick','3333-3333'),
(7,'Luana','1111-1111'),
(8,'Mario','2222-2222'),
(9,'Carla','3333-3333'),
(10,'Marina','3333-3333')
go

CREATE UNIQUE INDEX ixu_Cliente_Nome ON VendasDB.dbo.Cliente (Nome)
go

Usando DBCC IND e DBCC PAGE localizamos a página de dados (ex: 1:258) e forçamos uma corrupção:

/*********************************************
DBCC IND - Lista as páginas de um objeto no banco de dados
DBCC IND ( { 'dbname' | dbid }, { 'objname' | objid }, { nonclustered indid | 1 | 0 | -1 | -2 } [, partition_number] )

1o parâmetro: nome do banco, se passar zero pega o banco corrente

2o parâmetro: nome da tabela

3o parâmetro: index_id (-1 mostra tudo)
SELECT [name] as NomeIndice, index_id, [type], type_desc 
FROM sys.indexes WHERE [object_id] = object_id('Cliente')

4o parâmetro: opcional, indica o número da partição (partition_id)

PageFID: número do arquivo de dados onde a página está.
PagePID: número da página dentro do arquivo de dados.
IAMFIND: número do arquivo de dados que contém a página do IAM que armazena o endereço da página
IAMFPID: número da página do IAM que armazena o endereço da página

PageType:
1  - Data Page
2  - Index Page
10 - IAM Page

IndexLevel: zero nível folha
***********************************************************************************/

DBCC IND (VendasDB,'Cliente',-1)
-- Página com IndexID 1 e PageType 1 = 258

DBCC TRACEON(3604) -- Habilita o uso do DBCC PAGE
DBCC PAGE(VendasDB, 1, 256, 3)
DBCC PAGE(VendasDB, 1, 258, 3) --WITH NO_INFOMSGS, TABLERESULTS 

/*****************************************************************************************************************
 dbcc WRITEPAGE ({'dbname' | dbid}, fileid, pageid, {offset | 'fieldname'}, length, data [, directORbufferpool])
******************************************************************************************************************/
ALTER DATABASE VendasDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC WRITEPAGE ('VendasDB',1,258,4000,1, 0x45, 1)
ALTER DATABASE VendasDB SET  MULTI_USER WITH NO_WAIT

🔍 O Erro Clássico de Corrupção

Ao consultar uma linha afetada, temos:

SELECT * FROM VendasDB.dbo.Cliente WHERE Nome = 'Jose' -- OK
SELECT * FROM VendasDB.dbo.Cliente WHERE Nome = 'Carla'-- Erro, cai a conexão

💥 Resultado:

Msg 824, Level 24, State 2 SQL Server detected a logical consistency-based I/O error...

🧪 Verificando Integridade com DBCC CHECKDB

DBCC CHECKDB (VendasDB) WITH NO_INFOMSGS, TABLERESULTS

Essa é a principal ferramenta para diagnosticar páginas suspeitas ou inconsistentes.

Você pode consultar o histórico pelo msdb..suspect_pages:

SELECT * FROM msdb..suspect_pages

🛠️ Reparando Corrupção com Perda de Dados

Se não houver backup, a única opção pode ser:

ALTER DATABASE VendasDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CHECKDB (VendasDB, REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE VendasDB SET MULTI_USER

📢 Criando Alertas para Corrupção (Erro 824)

Você pode configurar um alerta automático no SQL Server para identificar ocorrências de erro 824:

EXEC msdb.dbo.sp_add_alert 
  @name = N'Suspect Pages Error', 
  @message_id = 824,
  @enabled = 1,
  @include_event_description_in = 5

Corrupções não são frequentes, mas quando ocorrem, exigem ação rápida. Ter rotinas de backup confiáveis, uso de CHECKDB agendado e monitoramento automatizado de páginas suspeitas são práticas indispensáveis para qualquer DBA.


Fui, mas volto com mais SQL Server em breve!

✍️ Sobre o autor
O Prof. Landry é especialista em Microsoft SQL Server desde 1999, Microsoft Trainer, Professor Universitário e criador do canal SQL Server Expert no YouTube, com conteúdo técnico semanal para DBAs e profissionais de dados.

🚀 Quer aprender mais sobre SQL Server?
👉 Me acompanhe no LinkedIn e inscreva-se no canal para não perder nenhuma dica prática!

0
Subscribe to my newsletter

Read articles from SQL Server Expert directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SQL Server Expert
SQL Server Expert

O Prof. Landry Duailibe é especialista em Microsoft SQL Server desde 1999, Microsoft Certified Trainer, professor universitário e criador do canal SQL Server Expert no YouTube, onde compartilha conteúdo técnico semanal para DBAs e profissionais de dados. Já ajudou milhares de alunos a evoluírem suas habilidades com SQL Server e conquistarem melhores oportunidades na área de dados.