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

Protokol transakcí serveru SQL – část 2

Toto je druhý článek ze série věnované protokolu transakcí SQL Server a jeho specifikům. Zde prozkoumáme podrobnosti záznamu protokolu.

Protokolovat záznamy

Záznamy protokolu jsou jádrem mechanismů protokolování a obnovy. Záznam protokolu popisuje jednu změnu v databázi. Každá změna v databázi má tedy záznam protokolu nebo záznamy protokolu, které pomáhají popsat danou konkrétní změnu. Ačkoli nemusíte rozumět podrobnostem záznamu protokolu, abyste pochopili, co se děje s protokolováním a obnovou, jsou tyto podrobnosti nesmírně zajímavé.

Záznam protokolu má jedinečné pořadové číslo protokolu, které jsme definovali v prvním článku. Pořadové číslo protokolu umožňuje nalézt záznam protokolu v protokolu transakcí. Kromě toho má každá stránka datového souboru v záhlaví stránky LSN, které identifikuje nejnovější záznam protokolu, jehož změna se na stránce projeví. To je zásadní pro obnovu po havárii.

Záznamy protokolu pro souběžné transakce se v protokolu transakcí prolínají podle toho, kdy k nim došlo v čase. Záznamy protokolu jsou uloženy v blocích protokolu ve fondu vyrovnávacích pamětí, dokud nejsou vyprázdněny na disk.

V uživatelských nebo systémových databázích nejsou žádné nezaprotokolované operace. Existuje však výjimka:v databázi tempdb nejsou operace úložiště verzí a pracovních souborů protokolovány. Záznamy protokolu se v protokolu transakcí nikdy nepřesouvají.

Co je uvnitř záznamu protokolu?

Informace v záznamu protokolu umožňují jejich opětovné provedení (převrácení vpřed) nebo vrácení zpět (vrácení zpět). Tato schopnost záznamu protokolu je zásadní pro umožnění vrácení transakcí a pro práci na obnově. Záznamy protokolu obsahují mnoho polí v závislosti na typu záznamu protokolu. Některá pole jsou společná pro všechny záznamy, včetně:

  • Typ záznamu protokolu
    • zahájit záznam protokolu transakcí
    • potvrdit záznam protokolu transakcí
    • přidělení stránky změnou bitmapy přidělení
    • vložení řádku
    • smazání řádku
    • úprava řádku
  • Kontext záznamu protokolu , pokud existuje.
  • ID transakce, jehož je záznam protokolu součástí jestli nějaký. Většina záznamů protokolu je součástí transakcí.
  • Délka záznamu protokolu . Záznamy protokolu mají obvykle pevnou velikost a v závislosti na množství dat, která jsou v záznamu protokolu, bude existovat také proměnná část.
  • LSN předchozího záznamu protokolu ve stejné transakci . Jestli nějaký. LSN je v podstatě ukazatel na předchozí záznam protokolu transakcí, který byl vygenerován touto konkrétní transakcí. Tento řetězec předchozích LSN umožňuje danou konkrétní transakci vrátit zpět, protože vrácení se provádí v opačném pořadí, počínaje posledním záznamem protokolu.
  • Množství vyhrazeného prostoru protokolu v případě, že záznam protokolu musí být zrušen.

Rezervace místa přihlášení

Každý záznam protokolu, který je vygenerován v dopředné části transakce, musí vyhradit volné místo v protokolu transakcí, aby bylo možné záznam protokolu vrátit zpět, aniž by se protokol transakcí musel zvětšovat.

Mechanismus rezervace prostoru pro protokoly je velmi konzervativní, vždy si vyhradí dostatek místa a obvykle i více, pro případ, že by nastala neočekávaná situace. Například aktualizace nebo odstranění v komprimované tabulce vyhradí více místa než podobná aktualizace nebo odstranění v nekomprimované tabulce. K tomu dochází, protože vrácení aktualizace na komprimované tabulce se možná bude muset vypořádat s tím, že aktualizovaný řádek již není na komprimované stránce, a proto by bylo nutné do záznamu protokolu zapisovat sloupce s plnou šířkou namísto komprimovaných dat.

Typy záznamů protokolu

Existuje mnoho typů záznamů protokolu, včetně:

  • LOP_FORMAT_PAGE Operace s formátem stránky protokolu – je to místo, kde byla stránka naformátována, což znamená, že bylo vytvořeno její záhlaví. Záznam protokolu bude zaznamenávat alespoň záhlaví stránky a potenciálně i další obsah stránky, pokud byla stránka vytvořena a vyplněna jako součást operace, jako je sestavení nebo opětovné sestavení indexu)
  • LOP_MODIFY_ROW Tato operace mění malou část existujících dat.
  • LOP_SET_BITS Tento záznam protokolu se vztahuje na alokační bitmapy.
  • LOP_INSERT_ROWS a LOP_DELETE_ROWS
  • LOP_SET_FREE_SPACE Platí pro PFS – alokace bitmapy, která sleduje stavy alokace stránek.

Jakékoli záznamy protokolu, které se chystají změnit datovou stránku nebo stránku indexu v tabulkovém indexu, zahrnují :

    • ID alokační jednotky
    • ID stránky a ID bloku záznamu na stránce, což je v podstatě nulové ID záznamu dat nebo indexového záznamu na stránce.
    • Dodatečný obraz nebo obraz před aktualizací a obraz po změněných datech. V jednom záznamu protokolu jich může být více. Dodatečné obrazy umožňují opakování. Obrázky před zobrazením umožňují vrácení zpět.

Zamknout protokolování

Některé záznamy protokolu obsahují bitmapu, jejíž zámky byly drženy, když došlo k popsané změně. Bitmapa obsahuje:

      • Počet počtu zámků.
      • Jaký typ a režim zámku – například zámek stránky v režimu X.
      • Jaký je zámek

Během zotavení po havárii a převzetí služeb při selhání zrcadlením databáze/skupinou dostupnosti budou tyto zámky získány pro všechny záznamy protokolu, které budou vráceny zpět. To umožňuje funkci rychlé obnovy v Enterprise Edition od SQL Server 2005 a novější.

Zaznamenat záznamy v transakcích

Všechny transakce generují alespoň tři záznamy protokolu, vždy v následujícím pořadí:

        • LOP_BEGIN_XACT – obsahuje informace jako SPID, název transakce a čas zahájení. Všechny transakce spuštěné SQL Serverem mají názvy popisující operaci (např. AllocFirstPage, DROPOBJ)
        • Další záznamy pro transakci.
        • LOP_COMMIT_XACT – pokud se transakce zavazuje.
        • LOP_ABORT_XACT – pokud se transakce vrátí zpět.

Oba zahrnují čas ukončení transakce.
Záznamy protokolu v transakci jsou zpětně propojeny pomocí LSN. To znamená, že další záznam protokolu, který je vygenerován pro transakci, má LSN předchozího záznamu protokolu, který byl vygenerován pro tuto konkrétní transakci. To umožňuje správné vrácení transakce. Některé záznamy protokolu jsou vůbec netransakční, včetně:

        • Změny volného místa PFS (nelze sladit s jinými transakcemi)
        • Různé změny bitmapy (pouze jednosměrná změna)

Zkoumání záznamů protokolu

Záznamy protokolu lze zkoumat dvěma způsoby. Můžete použít funkci DBCC LOGINFO, ale doporučuje se použít funkci s hodnotou tabulky fn_dblog. Má extrémně jednoduchou syntaxi:

SELECT * FROM fn_dblog (startLSN, endLSN);
GO

Je to extrémně výkonná funkce, protože:

        • vrátí tabulkovou sadu výsledků, kterou lze snadno spravovat.
        • umožňuje použití složitých predikátů.
        • prohledává všechny protokoly transakcí v aktivní části protokolu, od začátku nejstarší nepotvrzené transakce po nejnovější záznam protokolu. To lze přepsat pomocí příznaku trasování 2537

Pole startLSN a endLSN se obvykle předávají jako NULL
Zde je ukázka:

USE DBTest2014
GO
 
SET NOCOUNT ON;
GO
 
--Set the SIMPLE recovery mode with no auto-stats
-- to avoid unwanted log records
ALTER DATABASE DBTest2014 SET RECOVERY SIMPLE;
ALTER DATABASE DBTest2014 SET AUTO_CREATE_STATISTICS OFF;
 
CREATE TABLE [TEST_TABLE] ([C1] INT, [C2] INT, [C3] INT);
 
INSERT INTO [TEST_TABLE] VALUES (1,1,1);
GO
 
--Clear out the log
CHECKPOINT;
GO
 
-- Implicit transaction
INSERT INTO [TEST_TABLE] VALUES (2,2,2);
GO
 
SELECT * FROM fn_dblog(null, null);
GO

Zde je zkrácená sada výsledků. fn_dblog ve skutečnosti vrací řadu různých záznamů, jako je délka záznamu protokolu, bity příznaku, rezerva protokolu, AllocUnitId, PageID, SlotID, LSN předchozí stránky a další.

Úprava obsahu řádku

Změny protokolu jsou protokolovány dvěma způsoby:jako LOP_MODIFY_ROW nebo LOP_MODIFY_COLUMNS záznam. Bez ohledu na použitou metodu zaznamená bajty, které se skutečně mění. Například změna hodnoty INT z 1 na 24 zaznamená pouze jeden bajt změny, protože ostatní tři nulové bajty se nezměnily. SQL Server bude používat LOP_MODIFY_ROW záznam protokolu, pokud je aktualizována jedna část řádku. Část je definována následovně:každý sloupec s proměnnou délkou v řádku je „část“ a celá oblast s pevnou šířkou řádku je „část“, i když je aktualizováno více sloupců, ale pouze v případě, že jsou bajty aktualizované jsou v řádku od sebe vzdáleny 16 bajtů nebo méně.

LOP_MODIFY_ROW obsahuje:

  • Před obrázkem
  • Po obrázku
  • V případě potřeby indexujte klíčové sloupce
  • Zamknout bitmapu

LOP_MODIFY_COLUMNS obsahuje:

  • Pole před a po offsetech
  • Pole délky
  • V případě potřeby indexujte klíčové sloupce
  • Zamknout bitmapu
  • Páry obrázků před a po

Záznamy protokolu kompenzací

Jedná se o speciální druh záznamů protokolu, které se používají k usnadnění vrácení transakce. Když se transakce vrátí zpět, musí být v databázi vrácena změna popsaná každým záznamem protokolu v transakci. Vrácení změn začíná nejnovějším záznamem protokolu pro transakci a následuje předchozí odkazy LSN až do záznamu protokolu LOP_BEGIN_XACT. Pro každý záznam protokolu:

  • Proveďte „antioperaci“, která zruší účinky záznamu protokolu
  • Vygenerujte záznam protokolu a označte jej jako záznam protokolu COMPENSATION, protože kompenzuje záznam protokolu v přední části transakce.
  • Předchozí LSN záznamu protokolu KOMPENZACE ukazuje na záznam protokolu před tím, za který je kompenzován. V podstatě způsobuje, že záznam protokolu již není součástí řetězce záznamů protokolu pro transakci.
  • Vyhrazený prostor protokolu pro záznam protokolu je uvolněn

Záznamy protokolu COMPENSATION nelze vrátit zpět, pouze znovu provést.

Vrácení transakce zpět

Zde je grafické znázornění toho, co se děje, když se transakce vrátí zpět:

Podívejme se na následující kód:

USE DBTest2014
GO
 
SET NOCOUNT ON;
GO
 
ALTER DATABASE DBTest2014 SET RECOVERY SIMPLE;
ALTER DATABASE DBTest2014 SET AUTO_CREATE_STATISTICS OFF;
 
CREATE TABLE [TEST_TABLE] ([C1] INT, [C2] INT, [C3] INT);
 
INSERT INTO [TEST_TABLE] VALUES (1,1,1);
INSERT INTO [TEST_TABLE] VALUES (2,2,2);
GO
--Clear out the log
CHECKPOINT;
GO
-- Explicit transaction to insert a new record
BEGIN TRAN;
INSERT INTO [TEST_TABLE] VALUES (3,3,3);
GO
 
SELECT * FROM fn_dblog(null, null);
GO
--Roll it back
ROLLBACK TRAN;
GO
 
SELECT * FROM fn_dblog(null, null);

Zde můžeme vidět speciální záznam protokolu s popisem “KOMPENZACE”

Pokud se podíváme na předchozí LSN, vidíme, že LOP_INSERT_ROWS že jsme to udělali, odkazuje zpět na …0f40:0001 a toto je transakce BEGIN, protože dopředná část transakce odkazuje zpět na předchozí záznam protokolu. LOP_DELETE_ROW Záznam protokolu kompenzace neodkazuje zpět na záznam, který kompenzuje – odkazuje na něj (na záznam protokolu BEGIN transakcí).

DELEDE tedy kompenzovalo INSERT a odstranilo jej ze seznamu záznamů protokolu. LOP_ABORT_XACT je signál, že transakce je ukončena vrácením zpět. Také můžete vidět, že LOP_ABORT_XACT odkazy zpět na LOP_BEGIN_XACT.
Když provedeme záznam protokolu kompenzace, rezervace prostoru protokolu se sníží [-74]. Takže vlastně vrací nějaký prostor, který byl vyhrazen pro dopřednou část transakce (LOP_INSERT_ROWS [178]). Jak můžete vidět, systém rezervace místa v protokolu je velmi konzervativní – INSERT rezervuje více místa, než DELETE vrátí.

Vrácení změn a rozdílové zálohy

Pokud je v databázi provedena úplná záloha, pak transakce aktualizuje 100 000 záznamů, ale transakce je vrácena zpět, proč rozdílová záloha tolik dat? Určitě vrácení transakce znamená, že se nic nezměnilo? Kousek skládačky, který zde chybí, je, že vrácení transakce zpět nevymaže všechny změny provedené transakcí. Jak jsme viděli, rollback musí generovat záznamy protokolu kompenzace, protože rollback musí generovat další změny, které kompenzují dopřednou část transakce. Záhlaví všech dotčených stránek byla změněna nejméně dvakrát. Jeden pro aktualizaci LSN stránky pro dopřednou část transakce a jednou pro aktualizaci LSN stránky pro rollback část transakce. V obou případech aktualizace způsobí, že rozsah bude v rozdílové bitmapě označen jako změněný. Nezáleží na tom, jaká to byla změna, jen na tom, že se něco změnilo v rozsahu. Neexistuje způsob, jak tyto rozsahy vyloučit z rozdílové zálohy.

Shrnutí

V tomto článku jsme se podívali na záznamy protokolu. Záznamy protokolu jsou jádrem mechanismů protokolování a obnovy. Každá změna v databázi má přidružený záznam protokolu. Každý záznam protokolu popisuje malou změnu. Velká změna má v rámci jedné transakce více záznamů protokolu. Existuje mnoho různých typů záznamů protokolu a my jsme se podívali na několik z nich.

Transakční protokol je v podstatě velké téma a pár článků nestačí k odhalení všech podrobností. Pokud tedy chcete získat podrobnější informace, doporučuji vám přečíst si následující knihu:Správa protokolu transakcí serveru SQL od Tonyho Davise a Gail Shaw a tento článek:Správa protokolu transakcí.

Přečtěte si také:

Ponořte se do protokolu transakcí serveru SQL – část 1
Ponořte se do protokolu transakcí serveru SQL Server – část 2


  1. Jak vytvořím generátor řádků v MySQL?

  2. MySQL spoušť nefunguje, jednoduchá syntaxe, nic složitého

  3. MariaDB CHARACTER_LENGTH() Vysvětleno

  4. MigrationSchemaMissing(Nelze vytvořit tabulku django_migrations (%s) % exc)