Всяка база данни на SQL Server съдържа един или повече регистрационни файлове на транзакции в допълнение към файловете с данни. Регистрационните файлове записват всички транзакции и модификации на базата данни, направени от всяка от тях.
Тази статия се фокусира върху регистъра на транзакциите и как SQL Server регистрира модификациите на данните, за да използва данните за възстановяване при срив на базата данни.
Въведение в регистрационния файл на транзакциите на SQL Server
Както помним, всяка транзакция е „всичко или нищо“. Ако част от транзакцията се провали, цялата транзакция се проваля и състоянието на базата данни остава непроменено.
SQL Server съхранява запис за всяка транзакция, извършена в базата данни, в регистрационния файл. Ако някакво бедствие доведе до спиране на SQL Server, той използва регистър на транзакциите, за да възстанови базата данни до последователно състояние с целостта на данните.
След рестартирането SQL Server стартира процеса на възстановяване при срив. Той чете регистрационния файл на транзакциите, за да гарантира, че всички валидни данни се съхраняват във файловете с данни, а неангажираните транзакции се връщат обратно.
По време на нормална работа SQL Server също използва регистъра на транзакциите. Информацията, съдържаща се във файла, е необходима, за да се идентифицира какво трябва да направи SQL Server, когато транзакция се върне обратно поради грешка или посочен от потребителя израз ROLLBACK.
Как SQL Server използва регистъра на транзакциите
Регистърът на транзакциите е физически файл с разширение LDF . SQL Server го създава автоматично за всяка нова база данни заедно с основния файл с данни (.MDF ), който съхранява обектите на базата данни и самите данни.
Винаги, когато T-SQL кодът промени обект на база данни или данните, които съдържа, подробностите за промяната се записват като регистрационен запис в регистрационния файл на транзакциите.
Регистрационният запис съдържа информацията за конкретна промяна, направена в базата данни (например вмъкване на един ред). Следователно ще имаме поредица от регистрационни записи, за да опишем напълно ефектите от една транзакция.
Архитектура на регистрационния файл на транзакциите
Последователни номера на регистрационните файлове
Записът в дневника има уникален, автоматично увеличаващ се пореден номер на регистрационния файл (LSN ), което ни позволява да намерим този запис в регистъра на транзакциите. LSN описва промяната на данните и съдържа следната информация:
- операцията и засегнатия ред
- старата и новата версия на данните
- транзакцията, която е извършила промяната
LSN се състои от три числа:
LSN =
Всяка страница с файл с данни има LSN в заглавката на страницата, която идентифицира най-новия регистрационен запис, чиято промяна е отразена на страницата. Това е от решаващо значение за възстановяването при срив.
Когато се изпълнява възстановяването при срив, то сравнява LSN на регистрационните записи за ангажирани или незаети транзакции с LSN в страниците с файлове с данни, за да определи дали има повторно или отмяна, което трябва да се направи за тези конкретни регистрационни записи.
Когато създавате база данни, добра практика е да укажете размера на регистъра на транзакциите . Ако не направите това, SQL Server автоматично ще създаде регистъра на транзакциите с размер по подразбиране.
Размерът по подразбиране на регистъра на транзакциите от нова база данни е по-големият от 0.5MB или 25% от общия размер на всички файлове с данни, създадени в същия израз CREATE DATABASE.
Трябва да сте много внимателни, защото новите части от регистрационния файл на транзакциите винаги са инициализирани с нула . Ако имате израза CREATE DATABASE, без да посочвате размера на регистрационния файл, и създадете например база данни от 1TB, SQL Server ще създаде регистрационния файл на транзакциите от 250 GB.
Тъй като дневникът трябва да бъде инициализиран с нула, той не използва мигновената инициализация на файла. Тази функция беше добавена в SQL Server 2005, за да позволи на файловете с данни да се създават или увеличават почти мигновено.
Можем да видим какво се случва, когато СЪЗДАВАМЕ БАЗА ДАННИ – нулевата инициализация се извършва на нашия дневник с помощта на флаг за проследяване 3004 който отпечатва съобщения за нулева инициализация и флаг за проследяване 3605 което позволява отпечатване на тези съобщения в регистрационния файл чрез флага за проследяване 3004.
Следната демонстрация показва как можете да видите как се случва нулиране на регистрационния файл.
1. Изпълнете следния скрипт, за да се уверите, че нямаме база данни, наречена DBTest2014
USE master;
GO
IF DATABASEPROPERTY(N'DBTest2014', N'Version')>0
BEGIN
ALTER DATABASE DBTest2014 SET SINGLE_USER
WITH ROLLBACK IMMEDIATE;
DROP DATABASE DBTest2014;
END
GO
2. Активирайте флаговете за проследяване, за да наблюдавате инициализацията с нула
DBCC TRACEON (3605, 3004, -1);
GO
3. Flush the error log
EXEC sp_cycle_errorlog;
GO
3. Създайте база данни
CREATE DATABASE DBTest2014 ON PRIMARY (
NAME = N'DBTest2014',
FILENAME = N'D:\DBTest2014_data.mdf')
LOG ON (
NAME= N'DBTest2014_log',
FILENAME= N'D:\DBTest2014_log.ldf',
SIZE = 10MB,
FILEGROWTH = 10 MB);
GO
4. Прочетете регистрационния файл за грешки
EXEC sys.xp_readerrorlog;
GO
Виртуални регистрационни файлове
Регистърът на транзакциите е разделен вътрешно на серия от парчета, наречени виртуални регистрационни файлове (VLFs ) за опростяване на управлението.
Всеки път, когато се създава регистър на транзакциите, той дава определен брой VLF. Новосъздадените VLF са неактивни и неизползвани. Активен VLF не може да се използва повторно, докато не стане неактивен чрез изчистване на журнала.
Има обаче едно изключение – първият VLF в нова база данни винаги е активен, тъй като всеки регистър на транзакциите трябва да има поне един активен VLF.
Всеки регистрационен файл също има заглавна страница на файла което отнема 8KB в началото на регистрационния файл на транзакциите. Заглавната страница на файла съхранява метаданни за файла, като размер и настройки за автоматично нарастване.
Броят и размерът на VLF в нова част от регистъра на транзакциите се определят от SQL Server. Невъзможно е да го конфигурирате.
Ако новодобавеният размер е:
- <1MB не е от значение за обсъждане
- <64MB ще има 4 нови VLF (всеки 1/4 от размера на растежа)
- 64MB до 1GB ще има 8 нови VLFs (всеки 1/8 от размера на растежа)
- > 1 GB ще има 16 нови VLF (всеки 1/16 от размера на растежа)
Това се отнася за първоначално създадения регистър на транзакциите и за всяко ръчно или автоматично нарастване, което се случва. Когато знаете формулата за потенциалния брой VLF и техния потенциален размер, това помага да управлявате регистъра. Твърде малко или твърде много VLF могат да причинят проблеми с производителността при операциите в регистъра на транзакциите.
Пореден номер на VLF
Всеки VLF има пореден номер за уникално идентифициране на VLF в регистъра на транзакциите. Поредният номер се увеличава с едно всеки път, когато системата за управление на журнала активира следващия VLF. Веригата от последователни номера дава активния в момента набор от VLFs.
Началото на активната част на регистъра на транзакциите започва с VLF, който има най-ниския пореден номер и все още е активен. Неактивните VLF имат последователни номера, но не са част от активната част на дневника.
Активната част на регистрационния файл има регистрационни записи, които се изискват по някаква причина от SQL Server.
Когато за първи път създадете нова база данни, поредните номера на VLF няма да започват от 1. Те започват с какъвто и да е най-високият пореден номер на VLF в регистъра на транзакциите на базата данни на модела, плюс 1 . Невъзможно е да се изчерпят поредните номера на VLF. SQL Server има код, който ще принуди екземпляра да се изключи, ако пореден номер на VLF някога се увие около нула (ако следващият пореден номер на VLF е по-малък от предишния).
VLF и регистрационни блокове
В рамките на VLF има лог блокове с различен размер. Минималният размер на блока на регистрационния файл е 512 байтовете и регистрационните блокове нарастват домаксимален размер от 60 KB . Размерът се задава, когато възникне един от следните случаи:
- Транзакцията генерира регистрационен запис за ангажимент за приключване на прекратяването на транзакция
- Размерът на блока на регистрационния файл достига 60 KB без транзакция да бъде ангажирана или прекратена
В дневник има записи в дневника (оцветени на диаграмата). Регистрационните записи също са с различен размер. Диаграмата показва, че регистрационните записи от множество едновременни транзакции могат да съществуват в рамките на един и същ регистрационен блок. Записите в дневника се съхраняват в реда, написан подобно на файл със страница с данни.
Всеки VLF съдържа VLF заглавка със следната информация:
- Дали VLF е активен или не.
- Поредният номер на регистрационния файл при създаването на VLF.
- Текущите битове за паритет за всички 512-байтови блокове във VLF.
Битовете за четност започват от 64 за първия път на използване на VLF. Ако VLF стане неактивен, но допълнително се активира отново, битовете за четност ще станат 128. Те се използват по време на възстановяване при срив.
Проверка на подробности за регистрационния файл на транзакциите – DBCC LOGINFO
Единственият начин да разгледате структурата на регистъра на транзакциите е да използвате недокументирания DBCC LOGINFO команда. Синтаксисът на командата е:
DBCC LOGINFO [({'dbname | dbid'})]
Ако не посочите dbname и dbid , ще ви изхвърли съдържанието на журнала за текущата база данни.
Резултатът е един ред за всеки VLF, който е в регистъра на транзакциите за тази база данни. Върнатите полета са:
- RecoveryUnitId — добавен в SQL Server 2012, но в момента не се използва
- FileId — ID на регистрационния файл на транзакциите в база данни.
- Размер на файла — VLF размер в байтове.
- StartOffset — начално отместване на VLF в регистрационния файл на транзакциите, в байтове
- FSeqNo — Поредният номер на VLF
- Състояние — Дали VLF е активен или не (0 =неактивен, 2 =активен, 1 – не се използва)
- Паритет — текущи битове за паритет (64 или 128 или 0, ако VLF никога не е бил активен)
- Създайте LSN — LSN, когато е създаден VLF (0 =VLF е създаден при първоначалното създаване на регистрационния файл на транзакциите). Всички други VLF, добавени след първоначалното създаване на регистрационния файл на транзакциите, ще имат ненулев CreateLSN.
Можем да изпълним следната команда за DBTest2014 база данни, която създадохме по-рано:
DBCC LOGINFO (N'DBTest2014');
GO
Вижте резултата:
DBCC SQLPERF (LOGSPACE)
Единственият начин в Transact-SQL да се провери количеството на използвания дневник е DBCC SQLPERF. Синтаксисът на командата е:
DBCC SQLPERF
(
[ LOGSPACE ]
|
[ "sys.dm_os_latch_stats" , CLEAR ]
|
[ "sys.dm_os_wait_stats" , CLEAR ]
)
[WITH NO_INFOMSGS ]
Командата връща набор от резултати с един ред на база данни:
- Име на базата данни
- Размер на регистрационния файл (MB)
- Използвано пространство в регистрационния файл (%)
- Състояние:винаги на нула
В моята среда, следната команда:
DBCC SQLPERF (LOGSPACE);
GO
Връща следния резултат:
В следващата статия ще разгледаме регистрационните записи.