Inicial > Não categorizado > Fabiano VS DBCC PAGE

Fabiano VS DBCC PAGE

Pessoal, estes dias eu resolvi fazer algumas brincadeiras com o SQL… e cheguei na procedure em anexo.

 

Para deixar as coisas mais interessantes, vou começar o artigo perguntando o seguinte: É possível ler os dados armazenados em uma tabela temporária por uma sessão que não seja a que criou a tabela?

 

Por padrão sabemos apenas a sessão que criou a tabela temporária pode ler os dados armazenados nela, e estes dados ficam armazenados no banco temporário do SQL Server o Tempdb. Sabendo disso podemos pensar o seguinte… ora eu poderia criar uma tabela ir no Tempdb, e tentar dar um select nesta tabela… vamos ver se isso funciona?

 

Primeiro vamos criar uma tabela temporária e inserir uma linha nela…

 

Bom agora vamos no Tempdb tentar ver se a tabela que criei na sessão acima existe lá.

 

Opa, achamos a tabela, ele criou com o mesmo nome que dei, mas colocou uns caracteres na frente… vamos tentar dar um select nela.

Aaaa, não é possível ler os dados… será que tem um jeito?

 

Programador Marreta: Ummm, mas Fabiano ele cria a tabela o TempDB, e se eu usar o DBCC PAGE para ler os dados? Será que rola?

Fabiano: Opa! SIM claro!

Programador Marreta: Aaa Fabiano mas daí vai dar muito trabalho… não é?

Fabiano: Não, claro que não.

Programador Marreta: Como não, mas e se a tabela tiver 1000 páginas, vou ter que escrever 1000 comandos de DBCC Page?

Fabiano: Imagina, claro que não. É só rodar um exec  na proc que ele mostra os dados a partir do DBCC Page.

Programador Marreta: Opa, qual proc? Daí você me pegou.

Fabiano: st_SelectPAGEs !

 

Pois é galera, criei uma proc que usa DBCC IND e DBCC PAGE para ler os dados de uma tabela diretamente a partir das páginas de dados. J Pura geekeza!

 

Vamos ver se funciona? … Você pode baixar o código de criação da procedure aqui.

Pronto, desta forma conseguirmos ler o valor da tabela temporária…

 

Fora isso, pra que mais essa procedure pode ser útil? Vou mostrar outro exemplo com uma página corrompida.

 

Primeiro vamos criar um banco de dados qualquer.

USE Master

— Caso exista um banco chamado DBCorrupt, apaga ele.

IF (SELECT DB_ID(‘DBCorrupt’)) IS NOT NULL

BEGIN

  USE Master

  ALTER DATABASE DBCorrupt SET SINGLE_USER WITH ROLLBACK IMMEDIATE

  DROP DATABASE DBCorrupt

END

GO

— Criar um banco de dados chamado DBMirroring

IF (SELECT DB_ID(‘DBCorrupt’)) IS NULL

BEGIN

  CREATE DATABASE DBCorrupt

END

GO

— Altera o banco para utilizar CHECKSUM no Page_Verify

ALTER DATABASE [DBCorrupt] SET PAGE_VERIFY CHECKSUM

GO

 

Agora vamos criar uma tabela e inserir uma linha nela.

USE DBCorrupt

GO

— Vamos criar uma tabela para utilizar nos testes.

CREATE TABLE Teste(ID   Int IDENTITY(1,1) PRIMARY KEY,

                   Nome VarChar(250))

GO

— Vamos inserir uma linha na tabela

INSERT INTO Teste(Nome) VALUES(‘Fabiano Neves Amorim’)

GO

SELECT * FROM Teste

GO

CHECKPOINT

GO

 

Agora vamos setar o banco para OFFLINE para poder editar o arquivo e simular uma corrupção. Para isso eu utilizei o Hex Editor Neo, você pode usar qualquer programa de edição de hexa.

 

USE master

GO

ALTER DATABASE DBCorrupt SET OFFLINE

GO

 

Procura pelo valor “Amorim” incluído na tabela.

 

Vou editar e trocar para XXXXXX, para causar um erro de lógico de CheckSum, leia mais e entenda o CheckSum aqui.

Após isso, vou voltar o banco para ONLINE.

 

ALTER DATABASE DBCorrupt SET ONLINE

GO

 

Agora vamos tentar rodar um select na tabela “Teste”.

 

USE DBCorrupt

GO

SELECT * FROM Teste

 

Ao tentar rodar este comando, o seguinte erro é exibido:

 

Msg 824, Level 24, State 2, Line 1

SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0xe7f12a45; actual: 0xf3e431c5). It occurred during a read of page (1:78) in database ID 18 at offset 0x0000000009c000 in file ‘C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSQL\DATA\DBCorrupt.mdf’.  Additional messages in the SQL Server error log or system event log may provide more detail. This is a severe error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.

 

Para recuperar a tabela, teríamos que rodar o DBCC CHECKDB com a opção REPAIR_ALLOW_DATA_LOSS.

Mas e se eu tentar ler usando minha proc? Ou seja, diretamente nas páginas de dados?

 

Feito, desta forma você poderia fazer um backup da tabela, apaga-la e voltar os dados a partir da tabela lida pelo DBCC Page.

 

Galera, fica ai a dica e o script da proc… have fun…

 

Categorias:Não categorizado
  1. Demétrio
    31 de maio de 2010 às 16:45

    Putz,Muito interessante Fabiano, muito mesmo. Parabéns pelo post.AbraçoDemétrio Silva

  2. Fabiano Neves
    31 de maio de 2010 às 17:31

    Valeu Demétrio :-)… Abraços

  3. Laerte
    31 de maio de 2010 às 17:45

    Show de bola Fabiano..pura geekeza hahahaha…

  4. Felipe
    31 de maio de 2010 às 19:35

    Muito bom Fabiano!!!, muito bem lembrado a ideia de utilizar o DBCC PAGE e verificar os dados da tabela corrompida.Parabéns pelo post.

  5. Fabrício
    1 de junho de 2010 às 11:27

    Irado!!! Post com nível de ser postado no Simple Talk…. Vai para minha lista de referencias aqui….Parabéns….

  6. 19 de agosto de 2015 às 4:36

    Hi Fabiano,

    Great post! I was just trying to tune a stored proc and really needed to see into one of its temp tables.

    Thanks,
    Tom

  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: