SQL Server обновил запись в файловой группе только для чтения?

8

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

Иногда наш процесс ETL пытается обновить старые записи, которые уже были перенесены в архив, и мы ожидаем, что они потерпят неудачу. Однако у меня есть как минимум два недавних примера, в которых тестовая запись обновляется, даже если она находится в разделе в группе файлов только для чтения в нашей тестовой среде (запрос sys.partition_functionsи sys.partition_range_values).

Идентичная запись в производстве вызывает ожидаемый сбой при попытке обновления записи. Два раза мы поймали это до сих пор, обновление завершается сбоем в работе, но успешно проходит тестирование (никогда наоборот).

Соответствующие факты окружающей среды:

  • SQL Server 2012 SP3 CU3 (сборка 11.0.6537.0)
  • Тест - версия для разработчиков, продукция - для предприятий
  • Можем предоставить другим по запросу: Серьезно озадачен прямо сейчас ...

ОБНОВЛЕНИЕ 2016-08-19

Были ли новые записи обновлены как-то за одну ночь. Подтвердил, что это было на файловой группе только для чтения. Обнаружено, что я могу обновлять записи, которые были вставлены в одно и то же время (т.е. также находятся в том же разделе в файловой группе только для чтения). Я идентифицировал одну запись в одном и том же разделе и смог обновить ее несколько раз. Попытки обновить запись, обновленную за одну ночь, приводят к ожидаемой ошибке.

ОБНОВЛЕНИЕ 2016-08-11

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

ОБНОВЛЕНИЕ 2016-08-04

Сегодня обнаружил, что она не ограничивается этой единственной таблицей, так как я обнаружил другое возникновение такого же поведения в другой таблице с использованием той же схемы секционирования.

ОБНОВЛЕНИЕ 2016-08-03

Запуск сценария из этого сценария MSDN подтверждает то, что я получаю при использовании представлений Kendra Little для вспомогательных разделов ph.FilegroupDetailи ph.ObjectDetailиз этой демонстрации . Соответствующая запись находится в разделе № 2 (значение столбца раздела для рассматриваемой записи: 2015-03-18)

Filegroup     Low Boundary     UpperBoundary
Archive  (RO) NULL             1900-01-01
Archive  (RO) 1900-01-01       2015-04-01
ActiveFG (RW) 2015-04-01       2015-07-01
ActiveFG (RW) 2015-07-01       2015-10-01
ActiveFG (RW) 2015-10-01       2015-01-01
ActiveFG (RW) 2016-01-01       2016-04-01
ActiveFG (RW) 2016-04-01       2016-07-01
ActiveFG (RW) 2016-07-01       2016-10-01
ActiveFG (RW) 2016-10-01       2017-01-01
ActiveFG (RW) 2017-01-01       2115-01-01
ActiveFG (RW) 2115-01-01       NULL

Код для размещения таблицы на разделах (других индексов нет)

ALTER TABLE [dbo].[TABLE_NAME] ADD  CONSTRAINT [pk_TABLE_NAME] PRIMARY KEY CLUSTERED 
(
    [ETL_VERS_START_DTM] ASC,
    [ACCT_NO] ASC,
    [ACCT_TYPE] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ps_SmallTablesDate(ETL_VERS_START_DTM)

Оператор обновления, который должен потерпеть неудачу (через Informatica):

UPDATE TABLE_NAME SET ETL_JOB_SEQ_NUM = ?, ETL_IUD_CD = ?, ETL_UPD_DTM = ?, ETL_DEL_DTM = ? WHERE ETL_VERS_START_DTM = ? AND ACCT_NO = ? AND ACCT_TYPE = ?
ETL_VERS_START_DTM (ETL_VERS_START_DTM:Date:): "03/17/2015 23:30:02.140000000"
ETL_JOB_SEQ_NUM (ETL_JOB_SEQ_NUM:Int:): "1173651"
ETL_IUD_CD (ETL_IUD_CD:Char.1:): "D"
ETL_UPD_DTM (ETL_UPD_DTM:Date:): "08/02/2016 02:32:45.000000000"
ETL_DEL_DTM (ETL_DEL_DTM:Date:): "08/02/2016 00:10:03.567000000"
ACCT_NO (ACCT_NO:Char.12:): "1234567890"
ACCT_TYPE (ACCT_TYPE:Char.3:): "OLN"

ОБНОВЛЕНИЕ 2017-02-21

Итак, по прошествии всего этого времени мы обнаружили, что каким-то образом, когда самый старый активный раздел был объединен с архивом, раздел записей на диске не перемещался из активной файловой группы в группу архивных файлов. Следующий запрос показывает, что записи из раздела 2 были сопоставлены с ActiveFG, а проверка действительной схемы разделения показывает, что эти же записи должны быть отсортированы в группу файлов архива с помощью функции раздела.

SELECT  OBJECT_NAME(P.[object_id]) ,
    P.index_id ,
    P.partition_number ,
    F.name ,
    F.filegroup_guid
FROM    sys.allocation_units AU
    JOIN sys.partitions P ON P.partition_id = AU.container_id
    JOIN sys.filegroups F ON F.data_space_id = AU.data_space_id
WHERE   P.partition_number IN ( 1, 2, 3 )
    AND P.[object_id] = OBJECT_ID('TABLE_NAME')
ORDER BY P.partition_number;

Я отказался от всех разделов в реальных используемых базах данных и сохранил версию той, которая была сломана для работы с билетом Microsoft. Мне нужно пересмотреть план разбиения с нашей командой DW, но я признаю, что не слишком стараюсь повторить попытку.

Microsoft не удалось продублировать это поведение, и в настоящее время это делается с помощью заявки. Кажется, они готовы просто отмахнуться от этого и предположить, что его нет в 2014/2016? Похоже, они не могут воспроизвести его в своих лабораториях, несмотря на то, что я могу сохранить его в базе данных даже после того, как я восстановлю его из резервной копии в моей системе.

toosuto
источник
Я отказался от всех разделов в реальных используемых базах данных и сохранил версию той, которая была сломана для работы с MS билетом. Мне нужно пересмотреть план разбиения с нашей командой DW, но я признаю, что я не очень
стараюсь

Ответы:

1

Я хотел бы в кое-чем признаться.

Однажды, когда я был молодым, я построил процесс ETL, начатый с изменения файловых групп только для чтения на чтение-запись, выполнения его работы ETL, а затем перевода их обратно в режим только для чтения.

Так что на случай, если у вас есть коллега, который был дьявольским, как я (я был молод, мне нужны деньги), вы можете проверить:

  1. Измените имя файловой группы только для чтения - таким образом, если у кого-то есть жестко запрограммированные сценарии, которые изменяют файловую группу по имени, их сценарии завершатся ошибкой, и вы поймаете виновника. Или немного сложнее:

  2. Используйте Profiler или Extended Events, чтобы отследить любого, кто выполняет ALTER DATABASE.

Брент Озар
источник
На самом деле мы предоставили сценарий команде DW для внесения этих изменений, чтобы им не приходилось будить нас ночью в редком, но ожидаемом случае, когда их работа не удалась. У нас также есть триггер аудита на уровне сервера (в DDL_SERVER_LEVEL_EVENTS), который устанавливает совпадения свойств чтения / записи группы файлов. Он отправляет нам сценарий SQL, пользователя и IP-адрес для проверки командой DBA.
toosuto
Хотя мне может показаться, что они достаточно хитры, чтобы использовать наш скрипт для изменения настроек группы файлов перед процессом ETL, они просто недостаточно технически осведомлены, чтобы искать и отключать наш триггер.
toosuto