Чи ALTER INDEX ALL REBUILD використовує більше простору журналу транзакцій з простою моделлю відновлення, ніж перебудовує кожен індекс окремо?


18

Операція "ALTER INDEX ALL REBUILD" на SQL Server 2012 не вдалася, оскільки в журналі транзакцій не вистачало місця. Індекси ніколи не були реорганізовані та не перебудовані, тому фрагментація майже на 80% майже всіх.

БД використовує просту модель відновлення. Я припускав, що після кожної операції з індексом, виконаної командою "ВСЕ", дані журналу транзакцій будуть очищені до наступної перебудови індексу. Це, як воно насправді працює, чи відновлення індексу реєструється так, ніби вони є частиною однієї транзакції?

Іншими словами, чи можу я зменшити зростання журналу транзакцій, написавши сценарій, щоб виконати кожну перебудову окремо? Чи варто враховувати інші фактори?


2
Якщо забороняти явні дані навпаки, я би припустив, що певна команда SQL вважається однією атомною транзакцією двигуном БД. У цьому випадку можна досить легко перевірити теорію. Візьміть свій найбільший індекс і спробуйте просто відновити його. Якщо це вдасться, то розумно припустити, що журнал акумулює інформацію з декількох перебудов. Якщо це не вдається, вам потрібно додати простір для журналу (оскільки у вас є проблема в будь-якому випадку), або вам потрібно спробувати реорганізувати цей індекс, а не перебудовувати (якщо ви не можете збільшити простір для t- журнал).
RDFozz

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

Відповіді:


16

Я припускав, що після кожної операції з індексом, виконаної командою "ВСЕ", дані журналу транзакцій будуть очищені до наступної перебудови індексу. Це, як воно насправді працює, чи відновлення індексу реєструється так, ніби вони є частиною однієї транзакції?

1) Промивання журналу: модель SIMPLE відновлення не очищає журнал після кожної транзакції, але на контрольних точках. ( посилання для отримання додаткової інформації)

2а) ВІДНОСНУЙТЕ ВСІ: так, ПОВЕРНУТИСЯ ВСІХ працює як одна операція. Поновлення індексу всередині мають свої власні транзакції, але загальна операція не повністю здійснена до кінця. Так, так, ви можете обмежити зростання файлів журналів, переробивши окремі індекси (і, можливо, видавши команди CHECKPOINT).

2б) Доказ! Тут є демонстраційний сценарій. (Побудовано у 2016 р.) По-перше, встановіть тестовий db із таблицею та індексами:

USE master
GO

CREATE DATABASE Test_RebuildLog
GO

ALTER DATABASE Test_RebuildLog
SET RECOVERY SIMPLE
GO

USE Test_RebuildLog
GO

CREATE TABLE IndexTest
(ID int identity(1,1),
a char(1),
b char(1))

CREATE CLUSTERED INDEX CIX_IndexTest_ID ON IndexTest(ID)
CREATE INDEX IX_IndexTest_a ON IndexTest(a)
CREATE INDEX IX_IndexTest_b ON IndexTest(b)

INSERT IndexTest
(a,b)
VALUES ('a','b'),('z','y'),('s','r')

Тепер ви можете порівняти активність журналу між REBUILD ALL і відновленням індивідуально

CHECKPOINT
GO
ALTER INDEX ALL ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

CHECKPOINT
GO
ALTER INDEX CIX_IndexTest_ID ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_a ON IndexTest REBUILD
ALTER INDEX IX_IndexTest_b ON IndexTest REBUILD

SELECT *
FROM sys.fn_dblog(NULL,NULL)
WHERE Operation = 'LOP_COMMIT_XACT'
OR Operation = 'LOP_BEGIN_XACT'
GO

Зверніть увагу, як перша відкрита транзакція (ID транзакції 0000: 000002fa для мене) не вчиняється до кінця ВИСТАВКИ ВСІХ, але для відновлення індексу за індексом вони послідовно виконуються.


Вау, дякую за дійсно детальну відповідь! Це прекрасний спосіб побачити, що відбувається під капотом, так би мовити.
Google Fail

Приємно пояснив.
Рамакант Дадхічі

4

На сьогодні це одна операція.


6
Ласкаво просимо на DBA.SE! Загалом, найкращі відповіді - це не прості твердження, а підкріплені інформацією з документації чи статей, або (часто навіть краще) особистим досвідом, що підтверджує заявлену відповідь. Чи можете ви розширити свою відповідь, щоб надати таку підтримку?
RDFozz

2
@RDFozz Справедливий коментар, але ви подивилися профіль Педро ? Доступ до вихідного коду, ймовірно, може вважатися авторитетнішим, ніж особистий досвід чи документація. :-)
Аарон Бертран

3
@AaronBertrand - Зізнаюсь, я цього не зробив. Я, безумовно, думаю, що частина команди SQL Server справді може кваліфікуватися Все-таки варто посилатися на це у відповіді. +1, у будь-якому випадку.
RDFozz

3

Питання тривіальне для відновлення в режимі офлайн . Звичайно, це одна операція. Уявіть загрозу, яка настала б у випадку, якщо операція розділить кожен індекс на власну транзакцію, оскільки він повинен був би звільнити блокування під час здійснення, а потім знову придбати їх. У той час як блокування критичної таблиці SCH-M було випущено, індекси можуть бути відхилені та створити нові індекси, як би операція обробляла такі випадки? Не кажучи вже про те, що таблиця може бути відкинута і навіть заново створена між двома транзакціями! У тому числі, коли таблиця випадає і створюється інша таблиця з тим же ідентифікатором об'єкта (так, це може статися) ...

Що робити, якщо розширити питання, щоб сказати, що станеться, якщо відбудова індексів - це перебудова в Інтернеті ? Це одна операція чи багато? Відповідь складна, оскільки насправді задіяно кілька внутрішніх транзакцій . Однак ключовим моментом є те, що існує загальна операція архівації, яка охоплює всю операцію (оператор ALTER), і це закріплює журнал на місці (не може усікати), тому операція повинна бути відповідно спланована, щоб враховувати ~ 1.6x дані розмір для FULL режиму відновлення або 0,2x розмір даних у режимі BULK_LOGGED / SIMPLE. Докладнішу інформацію дивіться на зв'язаному папері.

Ви можете стверджувати, що чому офлайн-збірка не використовує ті самі внутрішні транзакції, які робить онлайн-режим, і не розділяє операцію? Питання, про які я згадував щодо зміни таблиці / відхилення таблиці між окремими операціями з індексом (тобто. Таблиця "стабільність схеми"), все ще вимагатимуть, щоб існувала обширна транзакція, яка містить SCH-S на столі протягом усього часу дії оператора. Оскільки ця транзакція повинна утримувати SCH-S також під час відновлення, вона повинна бути зареєстрована, і як така з'явиться запис журналу BEGIN XACT, який зафіксує журнал і запобіжить усікання протягом усієї тривалості оператора. Я знаю, що ця проблема вирішувалася в часові рамки SQL 2016-2017 (через проблеми розміру журналу SQL Azure), але я не впевнений, який прогрес був досягнутий . Схоже, зараз у попередньому перегляді:Відновлення індексного відновлення індексу відкрито для попереднього перегляду для SQL Server 2017 CTP 2.0 .


0

Так, у мене була ця сама проблема з дуже великою таблицею. Кожного разу, коли я видав ALTER INDEX ALL, журнал транзакцій зростатиме сильно, але якщо випускається ALTER INDEX окремо, використання простору журналу буде меншим.


0

Більш рання відповідь Ремуса про те, що для індексації в Інтернеті потрібно 1,6x розмір індексу в режимі ПОВНОГО відновлення, не є правильним. Частка простору журналу транзакцій, необхідна для відновлення індексу в Інтернеті під FULL, може бути набагато вищою, і ми багато разів спостерігали розмір індексу, особливо коли індекс, що відбудовується, стискається, коли журнал транзакцій не стискається. Це лише повинно дати зрозуміти, що реєстрація транзакцій під час відновлення в Інтернеті під FULL може бути принаймні у кілька разів більшим за розмір індексу. Додайте в накладні записи tlog, які Microsoft не повністю задокументовані, але часто оцінюються в 60 байт на рядок, і пропорційний розмір журналу під час відновлення індексу під час повного відновлення може бути в багато разів більшим, ніж розмір індексу, що відновлюється, особливо якщо індекс стискається


-1

Rdfozz правильний, це найкращий спосіб вирішити, чи можна найбільший індекс перебудувати на основі поточного сховища. Просто запустіть, dm_exec_requestsпоки відбувається операція (або SQL Profiler), щоб побачити, чи не відбудовуються всі індекси. Я б також розглядав можливість зміни моделі відновлення на масовий журнал. Це те, що я роблю, і ще є резервне копіювання журналу транзакцій під час вікна. Дивіться нижче статтю https://technet.microsoft.com/en-us/library/ms191484(v=sql.105).aspx


2
Зауважте, що ОП заявили, що їх БД вже використовує просту модель відновлення; це лише зберігає транзакції в журналі, достатньо довго, щоб транзакції завершилися. Поліпшення не було б, якби вони перейшли на груповий запис.
RDFozz

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