Як я можу додати стовпчик "реверсія" до великої таблиці з мінімальним простоєм


21

Використовуючи SQL Server 2008 і пізніші версії, я хочу додати стовпчик версії до великої таблиці, проте просто

ALTER TABLE [Tablename]
ADD Rowversion [Rowversion] NOT NULL

Тоді таблиця занадто довго недоступна для оновлень.

Які стратегії я можу використовувати для скорочення цього простою? Я буду розглядати що завгодно. Чим простіше, тим краще, але я розглядаю будь-яку стратегію.

Думаю, що в крайньому випадку я міг би підтримувати таблицю постановки копій, підтримувану тригерами, а потім перейменувати таблицю постановки в оригінальну таблицю. Але я сподіваюся на щось простіше / легше.

Відповіді:


26

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

Вставки слід надсилати до нової таблиці, оновлення повинні переміщувати дані до нової таблиці, а до обох таблиць слід застосовувати видалення.

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

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

Щоб уникнути запуску тригерів під час міграції даних партіями, подивіться кількість рядків у видалених / вставлених таблицях на тригері та пропустіть дії, якщо вони близькі до кількості рядків у вашій партії.


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


7

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

Довгі блокування майже напевно викликані розбиттями сторінок на рівні зберігання. Тому примушуйте їх до власного розкладу.

  1. Додайте тимчасовий стовпець, що підтримує NULL, з типом даних VARBINARY(8).
  2. Знайдіть у базі даних доступний час в режимі слабкого оновлення для оновлення пакетів існуючих записів з дійсним значенням для поля. ( 0x0000000027F95A5Bнаприклад)
  3. Оновлення змусять необхідні розбиття сторінки та виділяють більше місця для таблиці.
  4. Коли вас наздожене, опустіть тимчасовий стовпець (не торкається виділеного сховища) та додайте стовпець rowversion.
  5. Жодна сторінка не розпадається, а блокування потрібно лише досить довго, щоб заповнити значення.

Я успішно використовував це, щоб додати стовпчик "rowversion" до таблиці 150M рядків протягом менш ніж 10 хвилин.

Caveat ... якщо у вас є таблиця з великими варчарними полями (особливо varchar(max)), SQL Server вирішує відновити таблицю замість повторного використання наявного простору. Ще намагаюся розібратись із тим способом.


Цікаво, я думаю, я не вказав, що означає "занадто довго" у моєму запитанні. Якщо> 30 хвилин занадто довге для вашого сценарію і 10 хвилин терпимо, це рішення спрацює. Мій сценарій передбачав спробу досягти нульового простою або конкретніше <10 секунд, що досягається відповіддю Брента.
Michael J Swart

1

Якщо TIMESTAMPви додаєте NULLABLE:

  1. Додати VARBINARY(8)стовпчик
  2. Населяйте дані.

Після того, як вона населена, в спина до спини заяви SQL, стовпець ви тільки що додали і заселена, і додати стовпець.DROPVARBINARY(8)TIMESTAMP NULL


Якщо TIMESTAMPви додаєте NOT NULLABLE:

  1. Додати BINARY(8)стовпчик
  2. Населяйте дані.

Після того, як вона населена, в спина до спини заяви SQL, стовпець ви тільки що додали і малонаселених і стовпець.DROPBINARY(8)ADD THE TIMESTAMP NOT NULL

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