Ведення журналу і відновлення в SQL Server, Інші СУБД, Бази даних, статті

Одними з найбільш незрозумілих складових частин SQL Server є механізми ведення журналу та відновлення. Складається враження, що сам факт існування журналу транзакцій і те, що неправильне управління цим журналом може призводити до неполадок, ставить в тупик багатьох “невільних адміністраторів баз даних” (DBA). Чому журнал транзакцій може необмежено збільшуватися в розмірі? Чому в деяких ситуаціях потрібно занадто багато часу для того, щоб база даних стала доступною після збою системи? Чому неможливо повністю відключити ведення журналу? Чому не вдається належним чином відновити базу даних? Що з себе являє журнал транзакцій, і навіщо він існує?

Всі ці питання я постійно бачу на форумах SQL Server, Тому в даній статті я збираюся надати огляд системи ведення журналу та відновлення і пояснити, для чого існує ця невід’ємна частина модуля сховищ SQL Server. Буде розглянута архітектура журналу транзакції і те, яким чином три моделі відновлення, доступні для бази даних, можуть змінити поведінку журналу транзакцій і сам процес ведення журналу. Заодно я надаю деякі посилання на ресурси, що описують оптимальні методики упрвленія журналом транзакцій.


Що з себе являє ведення журналу?


Ведення журналу і процедура відновлення притаманні не тільки SQL Server– В усі комерційні системи управління реляційними базами даних (RDBMS) повинні входити ці кошти для забезпечення підтримки різних властивостей ACID транзакцій. Скорочення ACID позначає Atomicity (Атомарность), Consistency (узгодженість), Isolation (ізоляція) і Durability (стійкість), що є фундаментальними властивостями систем обробки транзакцій (таких як RDBMS).


Операції, що виконуються в RDBMS, реєструються (або записуються) на фізичному і логічному рівні в термінах подій, що відбуваються в структурах сховища бази даних. Для кожної зміни в структурах сховища є окремий запис журналу, що описує змінну структуру і власне зміна. Це виконується способом, що дозволяє повторити зміна або, при необхідності, скасувати зміну і повернути все в початковий стан. Записи журналу зберігаються в спеціальному файлі, який називається журналом транзакцій – далі це буде описано докладніше, а поки його можна представляти у вигляді файлу з послідовним доступом.


Набір з одного або декількох змін можна згрупувати (і, фактично, так завжди і робиться) в транзакцію, що забезпечує базову одиницю процесу внесення змін (атомарность) в базу даних, коли мова йде про користувачів, розробників додатків і DBA. Транзакція завершується успішно (фіксація) або завершується аварійно або скасовується (відкат). У першому випадку гарантується, що операції, формують транзакцію, відображені в базі даних. У другому випадку гарантується, що операції не будуть відображені в базі даних.


Транзакції в SQL Server бувають явними і неявними. При явній транзакції користувач або додаток видає оператор BEGIN TRANSACTION T-SQL, що сповіщає про запуск даними сеансом групи пов’язаних змін. Явна транзакція успішно завершується, коли видається оператор COMMIT TRANSACTION, що сповіщає про успішне виконання групи змін. Якщо замість нього видається оператор ROLLBACK TRANSACTION, всі зміни, виконані в даному сеансі з моменту видачі оператора BEGIN TRANSACTION, звертаються (відкочуються), і транзакція відміняється. Відкат транзакції може бути примусово викликаний зовнішнім подією, наприклад, браком для бази даних вільного місця на диску або виходом з ладу сервера. Ці випадки будуть розглянуті далі.


При неявній транзакції користувач або додаток не видає явно оператора BEGIN TRANSACTION до видачі оператора T-SQL. Однак, оскільки всі зміни в базі даних повинні бути оформлені в транзакцію, модуль сховищ прихованим чином автоматично запускає транзакцію. По завершенні виконання оператора T-SQL модуль сховищ автоматично фіксує транзакцію, запущену для створення оболонки для користувача оператора.


Вам може здатися, що в цьому немає необхідності, оскільки один оператор T-SQL не може генерувати велику кількість змін в структурах сховища бази даних, але розгляньте, наприклад, оператор ALTER INDEX REBUILD. Хоча цей оператор не може міститися в явній транзакції, він може генерувати величезне число змін в базі даних. Тому необхідний механізм, що забезпечує в разі неправильного розвитку подій (наприклад, якщо скасовується виконання оператора) належне виконання звернення змін.


Як приклад розглянемо, що відбувається, якщо в неявній транзакції оновлюється один рядок таблиці. Уявімо собі просту невпорядковану таблицю, яка містить стовпець c1 з цілочисельними даними і стовпець c2 з символьними даними. У таблиці є 10 000 рядків, і користувач відправляє запит на оновлення наступним чином:

UPDATE SimpleTable SET c1 = 10 WHERE c2 LIKE “%Paul%”; 

Виконуються наступні операції:



Зверніть увагу, що я не зазначив кроку, на якому три оновлених сторінки даних записуються назад на диск. Це пов’язано з тим, що в такій операції немає необхідності; до тих пір, поки записи журналу, описують зміни, присутні в журналі транзакцій на диску, дані зміни захищені. Якщо після внесення змін ці сторінки потрібно прочитати або знову змінити, остання актуальна копія сторінки вже знаходиться в пам’яті, а не на диску (поки що). Сторінки даних будуть записані на диск при такій операції контрольної точки або якщо пам’ять, займана ними в буферному пулі, буде потрібно для зображення іншої сторінки.


Контрольні точки існують з двох причин – для групування операцій введення / виводу з метою підвищення продуктивності і для скорочення вермені, необхідного для відновлення після збою. У термінах продуктивності, якби сторінка даних витеснялясь на диск при кожному її оновлення, число операцій введення / виводу в активно використовуваної системі могло б перевищити можливості підсистеми введення / виведення. Розумніше з деякою періодичністю записувати на диск “брудні” сторінки (ті, які були змінені з моменту їх зчитування з диска), ніж записувати на диск сторінки негайно після внесення до них змін. Трохи нижче я розгляну контрольні точки з точки зору відновлення.


Одна з поширених помилок щодо контрольних точок полягає в тому, що вони виконують запис змінених сторінок із зафіксованих транзакцій. Це не так – контрольна точка завжди записує на диск все “брудні” сторінки, незалежно від того, зафіксована чи ні транзакція, яка змінила сторінку.


Ведення журналу в попереджувальних записом є механізмом, в якому записи журналу, що описують зміни, записуються на диск до запису на диск самих змін. Це забезпечує частину властивостей ACID, що відповідає за стійкість. До тих пір, поки записи журналу, що описують зміни, знаходяться на диску, записи журналу (а, отже, самі зміни) у разі збою можуть бути відновлені, і результати транзакції не будуть втрачені.


У чому полягає відновлення?


Ведення журналу передбачено для підтримки безлічі операцій в SQL Server. Це забезпечує, у разі виникнення збою, правильність відображення зафіксованої транзакції в базі даних після збою. Цим гарантується, що відкат незафіксованою транзакції буде виконаний належним чином, і вона не буде відображена в базі даних після збою. Цим же забезпечується можливість скасування незавершеною транзакції і відкату всіх її операцій. Ведення журналу дозволяє проводити резервне копіювання журналу транзакцій таким чином, щоб було можливе відновлення бази даних і відтворення резервних копій журналу транзакцій з метою повернення бази даних в стан, що відповідає конкретному моменту часу і з дотриманням транзакційної узгодженості. Крім цього, забезпечується підтримка функцій, заснованих на читанні журналу транзакцій, таких як реплікація, дзеркальне відображення бази даних і збір даних змін.


Більшість таких застосувань журналу тягне використання механізму, називаного відновленням. Відновлення являє собою процес відтворення в базі даних змін, описаних в записах журналу, або повернення бази даних до стану до цих змін. Відтворення записів журналу називається фазою REDO (або накату) відновлення. Звернення змін записів журналу називається фазою UNDO (або відкоту) відновлення. Іншими словами, процедура відновлення забезпечуєте для транзакції і всіх відповідних записів журналу або повне відтворення, або повне скасування.


Відновлення приймає просту форму в разі скасування окремої транзакції, коли вона відкочується, і база даних не відчуває жодних наслідків. Більш складну форму має поновлення у випадку збою, коли виходить з ладу SQL Server (з якої б то не було причини), і журнал транзакцій необхідно відновити з метою повернення бази даних в стан, узгоджене з точки зору транзакцій. Це означає, що для всіх транзакцій, зафіксованих на момент збою, необхідно виконати накат, щоб результати цих транзакцій були відображені в базі даних. А для всіх незавершених на момент збою транзакцій необхідно виконати відкат, щоб результати цих транзакцій не були записані в базу даних.


Це обумовлено тим, що в SQL Server не існує засобів продовження транзакції після збою. Таким чином, якщо б для результатів частково завершеної транзакції не був виконаний відкат, база даних виявилася б в неузгодженому стані (можливо, навіть з ушкодженнями структури, в залежності від операції, що виконувалася транзакцією в момент збою).


Яким чином процедура відновлення дізнається, що слід робити? Всі процедури відновлення залежать від того факту, що кожен запис журналу позначена реєстраційним номером транзакції в журналі (LSN). Реєстраційний номер транзакції в журналі є зростаючим номером з трьох частин, однозначно визначає положення записи журналу в журналі транзакцій. Всі записи журналу в транзакції зберігаються в послідовному порядку в журналі транзакцій і містять код транзакції і LSN попереднього запису транзакції. Іншими словами, кожна операція, зареєстрована в якості частини транзакції, має зворотну “Посилання” на операцію, безпосередньо їй передує.


У простому випадку відкоту однієї транзакції механізм відновлення може швидко і без праці пройти по ланцюжку записаних в журнал операцій, від самої останньої до першої операції, і звернути результати всіх операцій в зворотному їх виконанню порядку. Сторінки бази даних, які зазнали впливу транзакції, перебувають або все ще в буферному пулі, або вже на диску. У будь-якому випадку гарантується, що доступне зображення сторінки несе на собі наслідки виконання транзакції, і їх необхідно скасувати.


Під час відновлення після збою механізм складніший. Той факт, що сторінки бази даних не записуються на диск при фіксації транзакції, означає, що немає гарантії того, що набір сторінок бази даних на диску точно відображає набір змін, описаних в журналі транзакцій – як для зафіксованих, так і для незафіксованих транзакцій. Однак, є останній шматочок пазла, про який я ще не згадував – в заголовку сторінки всіх сторінок бази даних є поле (96-байтним частина 8192-байтной сторінки, що містить метадані з інформацією про сторінку), що містить LSN останній запис журналу, що зробила вплив на сторінку. Це дає можливість системі відновлення прийняти рішення щодо конкретної записи журналу, яку необхідно відновити.



Механізм відновлення після збою прочитує журнал транзакцій і забезпечує збереження всіх результатів зафіксованих транзакцій в базі даних, а результати всіх не зафіксованих транзакцій не зберігаються в базі даних – виконуються фази REDO і UNDO, відповідно. По завершенні відновлення після збою база даних стає узгодженої з точки зору транзакцій і доступною для використання.


Раніше згадувалося, що одним із застосувань операції контрольної точки є скорочення кількості часу, займаного процедурою відновлення після збою. Періодичне скидання на диск всіх “брудних” сторінок скорочує число сторінок, змінених зафіксованими транзакціями, але зображень яких ще немає на диску. Це, в свою чергу, скорочує число сторінок, до яких потрібно застосовувати відновлення REDO під час відновлення після збою.


Журнал транзакцій


Відновлення після збою можливо тільки в тому випадку, якщо не постраждав журнал транзакцій. На ділі журнал транзакцій є найважливішою частиною бази даних – це єдине місце, в якому у разі збою гарантується наявність описів всіх змін бази даних.


Якщо журнал транзакцій відсутній або пошкоджений після збою, тоді відновлення після збою виконати неможливо, в результаті чого база даних стає сумнівною. В цьому випадку базу даних необхідно відновлювати з резервних копій або використовувати для відновлення менш бажані режими, такі як аварійне відновлення. (Ці процедури виходять за рамки цієї статті, але будуть глибоко обговорюватися в наступних статтях протягом цього року.)


Журнал транзакцій є спеціальний файл, необхідної будь-якій базі даних для належного функціонування. В ньому містяться записи журналу, створювані в процесі ведення журналу, і журнал використовується для повторного читання цих записів під час відновлення (або будь-якого іншого, згадуваного раніше, використання процедури ведення журналу). Так само, як простір, зайняте власне записами журналу, транзакція в журналі транзакцій резервує також простір для будь-яких потенційних записів журналу, які потрібні були б у разі необхідності скасувати транзакцію і виконати відкат. Цим пояснюється поведінка, яке можна спостерігати, коли, наприклад, для транзакції, відновлюючої 50 МБ даних в базі даних, на ділі в журналі транзакцій може знадобитися простір в 100 МБ.


Коли створюється нова база даних, журнал транзакцій, по суті, порожній. У міру виникнення транзакцій записи журналу послідовно записуються в журнал транзакцій, з чого випливає, що створення декількох файлів журналу транзакцій не дає ніякого виграшу в продуктивності, що є широко поширеною помилкою. Журнал транзакцій буде використовувати всі файли журналу по черзі.


В журналі транзакцій можуть перемежовуватися записи журналу для паралельних транзакцій. Слід пам’ятати про те, що записи журналу для однієї транзакції зв’язані за допомогою своїх LSN, тому немає необхідності всі записи журналу, що відносяться до однієї транзакції, групувати в одному журналі. Практично, номера LSN можна уявляти собі як мітку часу.


Фізична архітектура журналу транзакцій показана на рис. 1. Внутрішньо він розбитий на невеликі частини, звані віртуальними файлами журналів (або файлами VLF). Це просто допоміжні засоби для полегшення внутрішнього управління журналом транзакцій. Коли файл VLF заповнюється, процедура ведення журналу автоматично переходить до наступного VLF в журналі транзакцій. Можна було б подумати, що, врешті-решт, журнал транзакцій зіткнеться з браком місця, але саме в цьому питанні журнал транзакцій рішуче відрізняється від файлів даних.

Рис. 3 Циклічний характер журналу транзакцій


Перевірка того, чи можливо усічення журналу за будь-якого з таких умов:



Слід пам’ятати, що усічення журналу може виявитися неможливим, оскільки існує багато причин, за якими запис журналу повинна залишатися активною. Якщо усічення журналу неможливо, файли VLF НЕ можуть бути відкинуті, і, в кінцевому рахунку, журнал повинен збільшити свій розмір (або повинен бути доданий ще один журнал транзакцій). Надмірне розростання журналу транзакцій може привести до проблем з продуктивністю внаслідок ефекту, відомого під назвою фрагментація VLF. Усунення фрагментації VLF іноді може призвести до вражаючого підвищення продуктивності дій, пов’язаних з журналом.


Усікання журналу можуть перешкодити дві широко відомі проблеми:



Якщо журнал транзакцій вичерпав весь обсяг і не може продовжити подальше збільшення, надходить повідомлення про помилку 9002, і вам буде потрібно зробити кроки для надання додаткового простору, наприклад збільшити обсяг файлу журналу, додати ще один файл журналу або усунути все, що заважає усікання журналу.


Ні за яких обставин не слід видаляти журнал транзакцій, намагатися відновити його за допомогою недокументованих команд або просто обрізати його за допомогою параметрів NO_LOG або TRUNCATE_ONLY команди BACKUP LOG (яка вилучена з SQL Server 2008). Ці параметри приведуть або до неузгодженості з точки зору транзакцій (і, що більш імовірно, до пошкодження файлу), або позбавлять можливості належного відновлення бази даних.


Моделі відновлення


Як ви бачите, поведінка журналу транзакцій частково залежить від моделі відновлення, використовуваної базою даних. Існують три моделі відновлення, і всі вони впливають на поведінку журналу транзакцій і спосіб реєстрації операцій, або на і на те, і на інше.


Модель відновлення FULL увазі, що реєструється кожна частина кожної операції, і це називається повною реєстрацією. Після виконання повного резервного копіювання бази даних в моделі відновлення FULL в журналі транзакцій не проводитиметься автоматичне усічення до тих пір, поки не буде виконано резервне копіювання журналу. Якщо ви не мають наміру використовувати резервні копії журналу і можливість відновлення стану бази даних на конкретний момент часу, не слід використовувати модель відновлення FULL. Однак, якщо ви припускаєте використовувати дзеркальне відображення бази даних, тоді у вас немає вибору, оскільки воно підтримує тільки модель відновлення FULL.


Модель відновлення BULK_LOGGED володіє такою ж семантикою усікання журналу транзакцій, як і модель відновлення FULL, але допускає часткову реєстрацію деяких операцій, що називається мінімальної реєстрацією. Прикладами є повторне створення індексу і деякі операції масової завантаження – в моделі відновлення FULL реєструється вся операція.


Але в моделі відновлення BULK_LOGGED реєструються тільки зміни розподілу, що радикально скорочує число створюваних записів журналу і, в свою чергу, скорочує потенціал розростання журналу транзакцій.


Модель відновлення SIMPLE, фактично веде себе з точки зору ведення журналу так само, як і модель відновлення BULK_LOGGED, але має зовсім іншу семантику усікання журналу транзакцій. У моделі відновлення SIMPLE неможливі резервні копії журналу, що означає, що журнал може бути усічений (якщо ніщо не утримує записи журналу в активному стані) при виникненні контрольної точки. Для кожної з цих моделей є доводи за і проти, виражені в термінах можливих (чи необхідних) варіантів резервних копій і можливості відновлення стану на різні моменти часу (ці питання будуть обговорюватися пізніше в цьому році в іншій статті).


Висновок


Насправді ця стаття була радше академічним обговоренням того, як працює найважливіша частина SQL Server. Сподіваюся, мені вдалося позбавити вас від помилок, які, можливо, у вас були. Якщо для вас це перше знайомство з веденням журналу і процедурою відновлення, мені б хотілося, щоб з цієї статті ви усвідомили такі важливі моменти:


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*