sql >> Databáze >  >> RDS >> Sqlserver

ROLLBACK TRUNCATE v SQL Server

Spustili jste někdy omylem příkaz ZKRÁTIT příkaz na špatném stole? To povede ke ztrátě všech dat. Nejhorší je, že nebudete mít šanci svá data získat zpět. V tomto článku se podíváme, jak se takovým situacím vyhnout a mít šanci ROLLBACK ZKRÁTIT .

Nelze ROLLBACK TRUNCATE

Jednoduše nemůžete vrátit zpět transakci, pokud je již potvrzena, ale můžete udělat něco jiného, ​​abyste získali data zpět (nebo alespoň některé jejich části).

Když spustíte příkaz ZKRÁTIT vaše data jsou stále v souboru MDF. Není však vidět, protože SQL Server to považuje za volné místo (ZKRÁTIT říká serveru SQL Server, aby uvolnil datové stránky).

Jediný způsob, jak získat data zpět, je nějakým způsobem číst uvolněné datové stránky a převádět je na čitelná data.

Musíte jednat rychle, protože volné místo bude přepsáno novými daty, pokud se tak již nestalo. Pokud můžete zastavit instanci serveru SQL a vytvořit kopii souborů MDF a LDF, získáte více času.

Existují některé nástroje, které mohou provádět tento druh obnovení.

Můžete ROLLBACK ZKRÁTIT

ZKRÁTIT je protokolovaná operace, ale SQL Server nezaprotokoluje každý jednotlivý řádek, protože zkracuje tabulku. SQL Server pouze zaprotokoluje skutečnost, že ZKRÁTIT operace proběhla. Zaznamenává také informace o stránkách a rozsazích, které byly uvolněny. Existuje však dostatek informací, které lze vrátit zpět pouhým přerozdělením těchto stránek. Záloha protokolu potřebuje pouze informace, že ZKRÁTIT TABULKU došlo. Obnovení ZKRÁTIT TABULKU , operace se právě znovu použije. Příslušná data nejsou během OBNOVENÍ potřeba (jako by tomu bylo u skutečně „minimálně protokolované“ operace, jako je HROMADNÉ VLOŽENÍ ).

SQL Server ví, které stránky patřily do tabulky, pokud jsou uzamčeny exkluzivním zámkem, a stejně jako všechny zámky X jsou drženy až do konce transakce. To je důvod, proč stránky nebo rozsahy nelze uvolnit a rozhodně je nelze znovu použít.

Zde je příklad:

Dostali jsme 504 řádků a počet stránek. Nyní se podíváme na počet řádků a stránky, které do tabulky patří.

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

Neuvidíte žádné řádky z DBCC IND a 0 řádků z count(*). Informace o zámcích vrátí následující:

resource_type resource_description request_mode
————- ——————– ————
ROZSAH 1:33352 X
STRANA 1:42486 X
ROZSAH 1:42488 X
STRANA 1:42487 X
STRANA 1:42488 X
STRANA 1:42489 X
STRANA 1:23027 X
STRANA 1:23030 X
STR. 1:23029 X
STRANA 1:26992 X
STRANA 1:26993 X

Zámky rozsahu a stránky zahrnují všechny stránky, které jsme viděli v DBCC IND výstup. Až poté, co ROLLBACK transakce se uvolní zámky a měli byste znovu vidět všechny řádky a stránky na stole.

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

Buďte opatrní a vždy zabalte příkaz TRUNCATE do transakce.


  1. Připojení PolyBase k Salesforce.com

  2. Jak date_trunc() funguje v PostgreSQL

  3. Úlohy hybridní databáze OLTP/Analytics:Replikace dat MySQL do ClickHouse

  4. Dílčí dotazy SQL v kontrolním omezení