Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Регистърът на транзакциите на SQL Server, част 2:Архитектура на журнала

В първата част на тази поредица въведох основна терминология около регистрирането, така че ви препоръчвам да прочетете това, преди да продължите с тази публикация. Всичко останало, което ще покрия в поредицата изисква познаване на част от архитектурата на регистъра на транзакциите, така че това ще обсъдя този път. Дори ако няма да следвате поредицата, някои от концепциите, които ще обясня по-долу, си струва да знаете за ежедневните задачи, с които DBA обработват в производството.

Структурна йерархия

Регистърът на транзакциите е вътрешно организиран с помощта на йерархия на три нива, както е показано на фигура 1 по-долу.

Фигура 1:Тристепенната структурна йерархия на регистъра на транзакциите

Регистърът на транзакциите съдържа виртуални регистрационни файлове, които съдържат регистрационни блокове, които съхраняват действителните регистрационни записи.

Виртуални регистрационни файлове

Регистърът на транзакциите е разделен на секции, наречени виртуални регистрационни файлове , обикновено наричани просто VLFs . Това се прави, за да се улесни управлението на операциите в дневника на транзакциите за мениджъра на журнала в SQL Server. Не можете да посочите колко VLF се създават от SQL Server, когато базата данни е създадена за първи път или регистрационният файл автоматично нараства, но можете да повлияете на него. Алгоритъмът за това колко VLF се създават е както следва:

  • Размер на регистрационния файл по-малък от 64 MB:създайте 4 VLF, всеки с приблизително 16 MB размер
  • Размер на регистрационния файл от 64MB до 1GB:създайте 8 VLFs, всеки приблизително 1/8 от общия размер
  • Размер на регистрационния файл, по-голям от 1 GB:създайте 16 VLF, всеки приблизително 1/16 от общия размер.

Преди SQL Server 2014, когато регистрационният файл нараства автоматично, броят на новите VLF, добавени в края на регистрационния файл, се определя от алгоритъма по-горе, въз основа на размера на автоматичното нарастване. Въпреки това, като се използва този алгоритъм, ако размерът на автоматичното нарастване е малък и регистрационният файл претърпява много автоматични нараствания, това може да доведе до много голям брой малки VLFs (наречени VLF фрагментация ), което може да бъде голям проблем с производителността за някои операции (вижте тук).

Поради този проблем в SQL Server 2014 алгоритъмът се промени за автоматично нарастване на регистрационния файл. Ако размерът на автоматичното нарастване е по-малък от 1/8 от общия размер на регистрационния файл, се създава само един нов VLF, в противен случай се използва старият алгоритъм. Това драстично намалява броя на VLF за регистрационен файл, който е претърпял голямо количество автоматично нарастване. Обясних пример за разликата в тази публикация в блога.

Всеки VLF има пореден номер което го идентифицира уникално и се използва на различни места, което ще обясня по-долу и в бъдещи публикации. Бихте си помислили, че поредните номера ще започват от 1 за чисто нова база данни, но това не е така.

На екземпляр на SQL Server 2019 създадох нова база данни, без да посоча никакви размери на файлове, и след това проверих VLF, използвайки кода по-долу:

CREATE DATABASE NewDB;
GO
 
SELECT
    [file_id], 
    [vlf_begin_offset],
    [vlf_size_mb],
    [vlf_sequence_number]
FROM 
    sys.dm_db_log_info (DB_ID (N'NewDB'));

Обърнете внимание на sys.dm_db_log_info DMV беше добавен в SQL Server 2016 SP2. Преди това (и днес, тъй като все още съществува) можете да използвате недокументирания DBCC LOGINFO команда, но не можете да й дадете списък за избор – просто направете DBCC LOGINFO(N'NewDB'); и VLF последователните номера са в FSeqNo колона на набора от резултати.

Както и да е, резултатите от заявката за sys.dm_db_log_info бяха:

file_id   vlf_begin_offset   vlf_size_mb   vlf_sequence_number
-------   ----------------   -----------   -------------------
2         8192               1.93          37
2         2039808            1.93          0
2         4071424            1.93          0
2         6103040            2.17          0

Обърнете внимание, че първият VLF започва с отместване 8 192 байта в регистрационния файл. Това е така, защото всички файлове на базата данни, включително регистъра на транзакциите, имат заглавна страница на файла, която заема първите 8 КБ и съхранява различни метаданни за файла.

И така, защо SQL Server избира 37, а не 1 за първия пореден номер на VLF? Той намира най-високия VLF пореден номер в модела база данни и след това, за всяка нова база данни, първият VLF на регистъра на транзакциите използва това число плюс 1 за своя пореден номер. Не знам защо този алгоритъм беше избран в мъглата на времето, но това е така поне от SQL Server 7.0.

За да го докажа, изпълних този код:

SELECT
    MAX ([vlf_sequence_number]) AS [Max_VLF_SeqNo]
FROM 
    sys.dm_db_log_info (DB_ID (N'model'));

И резултатите бяха:

Max_VLF_SeqNo
--------------------
36

И така, ето го.

Има още какво да обсъдим за VLF и как се използват, но засега е достатъчно да знаем, че всеки VLF има пореден номер, който се увеличава с един за всеки VLF.

Регистрационни блокове

Всеки VLF съдържа малка заглавка на метаданни, а останалата част от пространството е запълнена с регистрационни блокове. Всеки лог блок започва от 512 байта и ще нараства на стъпки от 512 байта до максимален размер от 60 KB, в който момент трябва да бъде записан на диск. Регистрационният блок може да бъде записан на диска, преди да достигне максималния си размер, ако се случи едно от следните:

  • Транзакция се извършва и за тази транзакция не се използва отложена издръжливост, така че блокът на регистрационния файл трябва да бъде записан на диск, за да направи транзакцията трайна.
  • Използва се отложена издръжливост и се задейства задачата с таймер за 1 мс на фона „изтриване на текущия регистрационен блок на диск“
  • Страница с файл с данни се записва на диск от контролна точка или от мързеливия записващ и има един или повече регистрационни записи в текущия регистрационен блок, които засягат страницата, която предстои да бъде записана (не забравяйте, че записът трябва да бъде гарантирано)

Можете да разглеждате регистрационния блок като нещо като страница с променлив размер, която съхранява регистрационните записи в реда, в който са създадени от транзакции, променящи базата данни. Няма регистрационен блок за всяка транзакция; регистрационните записи за множество едновременни транзакции могат да бъдат смесени в лог блок. Може да си помислите, че това ще създаде трудности за операциите, които трябва да намерят всички регистрационни записи за една транзакция, но не е така, тъй като ще обясня, когато обясня как работи връщането на транзакции в по-късна публикация.

Освен това, когато регистрационен блок се записва на диск, е напълно възможно той да съдържа регистрационни записи от незаети транзакции. Това също не е проблем поради начина, по който работи възстановяването при срив – което е добра няколко публикации в бъдещето на поредицата.

Последователни номера на регистрационните файлове

Регистрационните блокове имат идентификатор в рамките на VLF, като се започва от 1 и се увеличава с 1 за всеки нов регистрационен блок във VLF. Записите на регистрационни файлове също имат идентификатор в рамките на блок от регистрационни файлове, като се започва от 1 и се увеличава с 1 за всеки нов запис в дневника в регистрационния блок. И така, и трите елемента в структурната йерархия на регистъра на транзакциите имат идентификационен номер и те са събрани в тристранен идентификатор, наречен последователен номер на регистрационния файл , по-често наричан просто LSN .

LSN се дефинира като :: (4 байта:4 байта:2 байта) и уникално идентифицира единичен регистрационен запис. Това е постоянно нарастващ идентификатор, защото номерата на VLF последователността се увеличават завинаги.

Основната работа готова!

Въпреки че VLF е важно да се знае, според мен LSN е най-важната концепция за разбиране около прилагането на регистриране от SQL Server, тъй като LSN са крайъгълният камък, върху който се изграждат връщането на транзакциите и възстановяването при срив, а LSN ще се появяват отново и отново, тъй като Напредвам през сериала. В следващата публикация ще разгледам съкращаването на регистрационните файлове и кръговото естество на регистъра на транзакциите, което е свързано изцяло с VLF и как те се използват повторно.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server:динамично завъртане на 5 колони

  2. SQL Server - обединете редовете в списък, разделен със запетая

  3. Не може да се отвори тестът на базата данни, поискан от входа. Влизането не бе успешно. Неуспешно влизане за потребител 'xyz\ASPNET'

  4. java.sql.SQLException:Не е намерен подходящ драйвер за jdbc:microsoft:sqlserver

  5. Разделени със запетая резултати в SQL