sql >> Base de Datos >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE en SQL Server

¿Alguna vez ha ejecutado accidentalmente TRUNCATE comando en una mesa equivocada? Esto conducirá a la pérdida de todos los datos. Lo peor es que no tendrá la oportunidad de recuperar sus datos. En este artículo, veremos cómo evitar tales situaciones y tener la oportunidad de ROLLBACK TRUNCATE .

No se puede ROLLBACK TRUNCATE

Simplemente, no puede deshacer una transacción si ya está confirmada, pero puede hacer algo más para recuperar los datos (o al menos algunas partes de ellos).

Cuando ejecutas TRUNCATE declaración, sus datos todavía están en el archivo MDF. Sin embargo, no es visible porque SQL Server lo trata como espacio libre (TRUNCATE le está diciendo a SQL Server que desasigne páginas de datos).

La única forma de recuperar los datos es leer de alguna manera las páginas de datos desasignados y convertirlos en datos legibles.

Debe actuar rápido porque el espacio libre se sobrescribirá con nuevos datos si no lo ha hecho ya. Si puede detener su instancia de SQL Server y hacer una copia de los archivos MDF y LDF, eso le daría más tiempo.

Existen algunas herramientas que pueden realizar este tipo de restauración.

Puede ROLLBACK TRUNCATE

TRUNCADO es una operación registrada, pero SQL Server no registra cada fila, ya que TRUNCA la tabla. SQL Server solo registra el hecho de que TRUNCATE ocurrió la operación. También registra la información sobre las páginas y las extensiones que se desasignaron. Sin embargo, hay suficiente información para retroceder, simplemente reasignando esas páginas. Una copia de seguridad del registro solo necesita la información que TRUNCATE TABLE ocurrió. Para restaurar la TABLA TRUNCADA , la operación se acaba de volver a aplicar. Los datos involucrados no son necesarios durante RESTORE (como lo serían para una verdadera operación de "registro mínimo" como INSERCIÓN BULK ).

SQL Server sabe qué páginas pertenecían a la tabla en la medida en que están bloqueadas con un bloqueo exclusivo y, al igual que todos los bloqueos X, se mantienen hasta el final de la transacción. Es por eso que las páginas o extensiones no se pueden desasignar y, ciertamente, no se pueden reutilizar.

Aquí hay un ejemplo:

Obtuvimos un recuento de 504 filas y un número de páginas. Ahora veremos el recuento de filas y las páginas que pertenecen a la tabla.

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');

No verá filas de DBCC IND , y 0 filas desde el conteo (*). La información de bloqueos devuelve lo siguiente:

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

Los bloqueos de extensión y página incluyen todas las páginas que vimos en DBCC IND producción. Solo después de ROLLBACK la transacción liberará los bloqueos y debería volver a ver todas las filas y páginas en la tabla.

ROLLBACK TRAN;
GO
SELECT COUNT(*) FROM dbo.Products;
DBCC IND('AdventureWorks', 'Products', -1);
GO

Tenga cuidado y siempre ajuste la declaración de la tabla TRUNCATE en la transacción.