Чому журнал транзакцій продовжує рости в простому режимі відновлення з нічними резервними копіями


24

Перш ніж негайно позначити як дублікат , я прочитав «Майк Уолш», чому журнал транзакцій постійно росте чи не вистачає місця? , але я не думаю, що це дало відповідь на мою ситуацію. Я переглянув десяток подібних запитань, але відповідні здебільшого просто сказав "дублікат" і вказав на запитання Майка.

Докладніше: У мене є маса баз даних ~ 500 Мб на SQL Server 2008 R2, всі в режимі ПРОСТОГО відновлення (не мій вибір), нічних повних резервних копій, з ~ 200 МБ файлів даних та ~ 300 МБ файлів журналу. Журнал не зростає до 300 МБ відразу, а досить повільно протягом декількох місяців. Немає жодних відкритих транзакцій, принаймні відповідно до sp_who2 та монітора активності. Якщо я клацніть правою кнопкою миші на базі даних та виберіть властивості, це скаже мені, що немає ~ 50 Мб безкоштовно. Не повинен весь журнал бути вільним після резервного копіювання? Чи в режимі SIMPLE журнал не повинен бути вільним, якщо немає відкритої транзакції?

log_reuse_wait_descз sys.databasesсказаного говорить "НІЧОГО", який, грунтуючись на вищезазначеному запитанні та відповіді, говорить, що не слід чекати нічого, щоб повторно використовувати простір.

Якщо я роблю 'DBCC SHRINKFILE', файл журналу скорочується до 1 МБ, тому він готовий повернути пробіл. Я можу налаштувати щось, що скорочує журнали щотижня, і не дає можливості вийти з-під контролю, але я збентежений, чому SQL Server змусив би мене це зробити.

Я можу зрозуміти, чи була якась божевільна транзакція, для якої потрібно було 300 Мб, щоб записати її, але ми не робимо нічого екстремального, просто базовий OLTP. З запитання / відповіді Майка:

Проста модель відновлення - Отже, з вищенаведеним вступом найпростіше спочатку поговорити про просту модель відновлення. У цій моделі ви говорите на SQL Server - я добре з вами, використовуючи файл журналу транзакцій для аварійного завершення та відновлення відновлення (у вас дійсно немає вибору там. Знайдіть властивості ACID, і це має мати сенс швидко), але як тільки ви ні більше потрібен для цілі відновлення / відновлення відновлення, продовжуйте і повторно використовуйте файл журналу.

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

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

Що я пропускаю? Чи щось заважає SQL Server розпізнавати дані як «загартовані» та звільняти журнал?

(редагувати) Звіт після дій - AKA трохи знань небезпечно

Дізнавшись, що це "популярне питання", мені здалося, що я зобов'язаний пояснити те, що сталося 7 місяців тому, і що я навчився сподіватися врятувати інших людей деяке горе.

По-перше, доступний простір, який ви бачите в SSMS при перегляді властивостей бази даних, - це простір, наявний у файлі даних. Ви можете переглянути це, виконавши наступне в базі даних, і ви знайдете доступний простір, про який повідомляє SSMS, - це різниця між FileSizeMB і UsedSpaceMB:

SELECT
    DB.name,
    MF.physical_name,
    MF.type_desc AS FileType,
    MF.size * 8 / 1024 AS FileSizeMB,
    fileproperty(MF.name, 'SpaceUsed') * 8/ 1024 AS UsedSpaceMB,
    mf.name LogicalName
FROM
    sys.master_files MF
    JOIN sys.databases DB ON DB.database_id = MF.database_id
WHERE   DB.name = 'yourdatabasename'

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

По-друге, моє сприйняття вирощування колод було повільним з часом. Однак насправді журнали швидко зростали вночі, коли хлопець, відповідальний за застосування патчів для цієї сторонньої програми, застосовував патчі. Патч робився як одна транзакція, тому залежно від патчу для даних 200 Мб потрібно було 300 МБ журналу. Ключовим моментом у відстеженні цього запиту став запит від Аарона Бертран за адресою https://sqlblog.org/2007/01/11/reviewing-autogrow-events-from-the-default-trace

DECLARE @path NVARCHAR(260);

SELECT 
    @path = REVERSE(SUBSTRING(REVERSE([path]), 
    CHARINDEX('\', REVERSE([path])), 260)) + N'log.trc'
FROM    sys.traces
WHERE   is_default = 1;

SELECT 
   DatabaseName,
   [FileName],
    SPID,
    Duration,
    StartTime,
    EndTime,
    FileType = CASE EventClass 
       WHEN 92 THEN 'Data'
       WHEN 93 THEN 'Log'
    END
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE
    EventClass IN (92,93)
ORDER BY
    StartTime DESC;

Це показало, що журнал росте певними вечорами, коли клієнт не використовував базу даних. Це призвело до розмови з хлопцем, що застосовує патчі та відповідь на таємницю.

Ще раз дякую людям, які надали допомогу, щоб отримати відповідь.


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

Відповіді:


20

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

У будь-якому випадку, чому ви вважаєте, що вам потрібно скоротити файл журналу, коли він досяг 300 Мб? Ви насправді прочитали всі відповіді, ретельно, на запитання Майка ? Файл журналу НЕ збирається скорочуватися самостійно, тому що скорочення файлу журналу до 1 МБ - лише для того, щоб він міг знову зростати під час ваших найбільших транзакцій - це загальна витрата часу. Що ти будеш робити з усім тим вільним простором тим часом?


Я не думаю, що ми робимо щось, що вимагало б 300 МБ журналу, але навіть якби ми зробили це, як тільки це було зроблено, чи не з’явилося б це вільне місце в базі даних? Переглядаючи властивості бази даних у студії управління SQL Server, розмір - це розмір даних і журналу, і я б очікував, що вільним простором буде вільний простір для даних та журналу. Чи не відображається вільний простір у журналі? Це не виглядало так безкоштовно, як здається, воно все ще використовується, але в базі даних не було жодної активності.
DerekCate

1
Ні, як тільки це буде зроблено, він автоматично не стає вільним місцем. Вчинені транзакції не занулюються, їх простір просто позначається як доступний для повторного використання.
Аарон Бертран

1
@DerekCate "Я не думаю, що ми робимо що-небудь, що вимагало б 300 МБ журналу" ... Ви здивуєтеся, для повторного використання журналу транзакцій не потрібно багато. Не думайте про це з точки зору кількості завантаженості, оскільки це не завжди є причиною.
Томас Стрінгер

Гаразд, щоб просто підтвердити, що я правильно це розумію, журнал 300 Мб, навіть якщо він зараз не потрібен, не відображатиметься як вільний простір, але буде повторно використаний. І в якийсь момент для обробки якоїсь транзакції було потрібно 300 Мб. Гаразд, нові речі, на які слід звернути увагу. Дякую!
DerekCate

1
Ще одне, що слід врахувати: автоматична контрольна точка для простої бази даних відновлення ставиться в чергу лише після того, як журнал вже заповнений на 70%. Отже, вам може знадобитися не стільки активність журналу, щоб призвести до зростання, залежно від часу.
Пол Білий каже, що GoFundMonica

6

Усі ваші поточні тести ( DBCC SHRINKFILE,log_reuse_wait_desc ) просто доводять, що зараз ви належним чином використовуєте віртуальні файли журналу транзакцій належним чином. Але коли ваші події автоматичного зростання трапляються у вашому журналі журналу транзакцій, це реакція на неможливість повторного використання журналу.

Часто це не тривалий стан (саме так, як вам зараз здається, при відсутності симптомів, які ви зараз бачите). Навіть у простій моделі відновлення є кілька речей, які можуть спричинити таку поведінку.

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

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

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


Якщо він бачить 50MB безкоштовно, а журнал 300MB fn_DBLOG () дасть йому деяке розуміння того, що збільшує розмір його журналу?
Кеннет Фішер

0

Чи увімкнено автоматичне скорочення в БД? І / або у вас є планові плани технічного обслуговування, що виконують відновлення індексів?

Автоматичне скорочення з подальшим обслуговуванням індексів призведе до значного обсягу журналу.

Обслуговування індексів само по собі також призведе до значного обсягу журналу, якщо є проблеми проектування БД, як кластеризовані індекси на GUID.


Автоматичне скорочення не ввімкнено в БД, ми намагаємося уникати фрагментації індексу brentozar.com/archive/2009/08/… . У нас є щотижневі перевірки цілісності, але я не думаю, що в цьому складі є перебудова індексу, мені доведеться це вивчити. Крім цього, не має GUID, у кожній таблиці є стовпець ідентичності, який є первинним ключем.
DerekCate

-3
 create table #dblog (Databasename varchar(100),
                     logsize float,
                     logspace%] float,
                     [Status] int)

 insert into #dblog
 EXEC ('DBCC sqlperf(logspace)') 

 select * from #dblog

 alter table #dblog 
 add [lgspace used GB] float;

 update #dblog 
 set [lgspace used GB ] = (logsize*[logspace%]/1024)

 update #dblog 
 set [logsize] =([logsize]/1024)

 alter table #dblog 
 drop column [Status];

 select * from #dblog

 drop table #dblog
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.