Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE no SQL Server


Você já executou acidentalmente o comando TRUNCATE comando em uma tabela errada? Isso levará a toda a perda de dados. O pior é que você não terá a chance de recuperar seus dados. Neste artigo, veremos como evitar tais situações e teremos a chance de ROLLBACK TRUNCATE .

Você não pode ROLLBACK TRUNCATE


Simplesmente, você não pode reverter uma transação se ela já estiver confirmada, mas você pode fazer outra coisa para recuperar os dados (ou pelo menos algumas partes deles).

Quando você executa o TRUNCATE declaração, seus dados ainda estão no arquivo MDF. No entanto, não é visível porque o SQL Server está tratando isso como espaço livre (TRUNCATE está dizendo ao SQL Server para desalocar páginas de dados).

A única maneira de recuperar os dados é ler de alguma forma as páginas de dados desalocadas e convertê-las em dados legíveis.

Você deve agir rápido porque o espaço livre será substituído por novos dados, se ainda não estiver. Se você puder interromper sua instância do SQL Server e fazer uma cópia dos arquivos MDF e LDF, você ganhará mais tempo.

Existem algumas ferramentas que podem fazer esse tipo de restauração.

Você pode ROLLBACK TRUNCATE


TRUNCAR é uma operação registrada, mas o SQL Server não registra todas as linhas, pois TRUNCA a tabela. O SQL Server registra apenas o fato de que o TRUNCATE operação aconteceu. Ele também registra as informações sobre as páginas e extensões que foram desalocadas. No entanto, há informações suficientes para reverter, apenas realocando essas páginas. Um backup de log precisa apenas das informações que o TRUNCATE TABLE ocorreu. Para restaurar a TRUNCATE TABLE , a operação é apenas reaplicada. Os dados envolvidos não são necessários durante o RESTORE (como seria para uma verdadeira operação 'minimamente registrada' como um BULK INSERT ).

O SQL Server sabe quais páginas pertenciam à tabela desde que estejam bloqueadas com um bloqueio exclusivo e, assim como todos os bloqueios X, são mantidas até o final da transação. É por isso que páginas ou extensões não podem ser desalocadas e, certamente, não podem ser reutilizadas.

Aqui está um exemplo:



Temos uma contagem de 504 linhas e um número de páginas. Agora veremos a contagem de linhas e as páginas que pertencem à tabela.
BEGIN TRAN
TRUNCATE TABLE dbo.Products;
SELECT COUNT(*) FROM dbo.Products;
 
DBCC IND('AdventureWorks', 'Products', -1);
DBCC EXTENTINFO('AdventureWorks', 'Products', -1);
 
SELECT resource_type, resource_description,
        request_mode FROM sys.dm_tran_locks
WHERE  resource_type IN ('EXTENT', 'PAGE')
AND   resource_database_id = DB_ID('AdventureWorks');

Você não verá nenhuma linha de DBCC IND , e 0 linhas de count(*). As informações de bloqueios retornam o seguinte:

resource_type resource_description request_mode
————- ——————— ————
EXTENT 1:33352 X
PAGE 1:42486 X
EXTENT 1:42488 X
PAGE 1:42487 X
PAGE 1:42488 X
PAGE 1:42489 X
PAGE 1:23027 X
PAGE 1:23030 X
PAGE 1:23029 X
PÁGINA 1:26992 X
PÁGINA 1:26993 X

A extensão e os bloqueios de página incluem todas as páginas que vimos no DBCC IND saída. Somente depois de ROLLBACK na transação os bloqueios serão liberados e você deverá ver todas as linhas e páginas de volta na tabela novamente.
ROLLBACK TRAN;
GO
SELECT COUNT(*) FROM dbo.Products;
DBCC IND('AdventureWorks', 'Products', -1);
GO

Tenha cuidado e sempre envolva a instrução da tabela TRUNCATE na transação.