Почему CREATE INDEX… WITH ONLINE = ON блокирует доступ к таблице в течение минут?

22

У меня есть существующая таблица:

CREATE TABLE dbo.ProofDetails
(
    ProofDetailsID int NOT NULL 
        CONSTRAINT PK_ProofDetails 
        PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , ProofID int NULL
    , IDShownToUser int NULL
    , UserViewedDetails bit NOT NULL 
        CONSTRAINT DF_ProofDetails_UserViewedDetails 
        DEFAULT ((0))
);

Эта таблица имеет 150 000 000 строк. Система работает 24x7x365, поэтому нет регулярных периодов обслуживания.

Я хочу добавить индекс к таблице, и с выпуском SQL Server для предприятия я смогу сделать это, не блокируя доступ для записи в таблицу. Команда, которую я использовал, была:

CREATE INDEX IX_ProofDetails_ProofID_Etc 
ON dbo.ProofDetails (ProofID, IDShownToUser)
INCLUDE (UserViewedDetails)
WITH (ONLINE=ON
    , ALLOW_ROW_LOCKS=ON
    , ALLOW_PAGE_LOCKS=ON
    , FILLFACTOR=100
    , MAXDOP=4
);

Я выполнил заявление самостоятельно в SSMS, нажав F5. Он работал более минуты, затем начал блокировать другие сеансы. Затем я немедленно отменил CREATE INDEXкоманду, поскольку не могу заблокировать другие сеансы.

В течение первой минуты ничто не блокировало мою CREATE INDEXкоманду, sys.dm_exec_requestsпоказывало процесс с типом ожидания CXPACKET- конечно. Я не думаю, что это плохо, поскольку операция была распараллелена.

У меня не было много времени, чтобы проверить результаты sys.dm_exec_requests. В запросе была возвращена только одна строка WHERE session_id = xxx. Блокированные сеансы пытались вставить строки в целевую таблицу.

Я не знаю, как долго длились блокировки, за исключением того, что я отменил выполнение оператора примерно через 2 минуты после его начала. Блоки происходили около минуты в этот момент.

Я неправильно понимаю реализацию WITH (ONLINE=ON)? Или мне нужно знать что-то еще?

Сервер представляет собой довольно мощную машину с 2 четырехъядерными процессорами Xeon E5-2643 с тактовой частотой 3,3 ГГц, 192 ГБ ОЗУ и хранилищем SAN, способным поддерживать более 5000 iops. Процессор обычно ниже 20%, ОЗУ используется на 93%, в основном SQL Server. На коробке больше ничего не работает, только Windows Server 2012 и SQL Server 2012.

Макс Вернон
источник

Ответы:

23

При создании индекса с online = on процесс создания индекса не будет блокироваться при создании самого объекта индекса, но когда он приближается к концу процесса, он получает блокировку модификации схемы * на период, чтобы фактически Если добавить индекс в таблицу, этот тип блокировки будет блокировать все внешние операции до тех пор, пока блокировка не будет снята, что может объяснить ваши проблемы с блокировкой.

* Sch-MБлокировка не требуется для онлайн-сборки нового некластеризованного индекса, хотя она требуется во всех других случаях. Новый некластеризованный индекс требует только общей блокировки на уровне таблицы на заключительном этапе, так же, как это было необходимо на этапе подготовки.

Смотрите эту Белую книгу для деталей:

Операции индексирования в Интернете в SQL Server 2005

Как предложено Муштаком Мухаммедом в комментарии к вопросу, также см .:

Единороги, радуги и операции с индексами онлайн Пол Рэндал

steoleary
источник