Вставка в реплицированную таблицу не выполняется - проверка диапазона идентификаторов
Я пытаюсь вставить несколько тысяч строк в таблицу в базе данных, которая реплицируется на двух серверах. От издателя или подписчика я получаю ту же ошибку:
Msg 548, Level 16, State 2, Line 1
The insert failed. It conflicted with an identity range check constraint in database 'XXX', replicated table 'dbo.NODE_ATTRIB_RSLT', column 'ID'. If the identity column is automatically managed by replication, update the range as follows: for the Publisher, execute sp_adjustpublisheridentityrange; for the Subscriber, run the Distribution Agent or the Merge Agent.
The statement has been terminated.
Проверяя ограничение на таблицу, мне кажется, что я должен иметь возможность вставлять не менее 1000 строк за раз перед запуском в проблемы. Тем не менее, я получаю ту же ошибку при попытке вставить всего несколько десятков строк!
Вот как я пытаюсь вставить данные:
insert into NODE_ATTRIB_RSLT
([NODE_ID]
,[ATTRIB_ID]
,[STATE_ID]
,[PLAN_REVISION_ID]
,[TIMESTAMP]
,[VALUE]
,[VALUE_TEXT]
,[LAST_MODIFIED])
SELECT [NODE_ID]
,[ATTRIB_ID]
,[STATE_ID]
,[PLAN_REVISION_ID]
,[TIMESTAMP]
,[VALUE]
,[VALUE_TEXT]
,[LAST_MODIFIED] FROM [NODE_ATTRIB_RSLT_TEMP]
Столбец PK представляет собой автогенерируемый идентификатор, называемый идентификатором. Чтобы попытаться вставить меньше строк за раз, я добавил предложение WHERE в конце выбора так:
WHERE ID >= 1000 and ID <1100
но безрезультатно.
Запуск sp_adjustpublisheridentityange в Publisher выполняется успешно, но не имеет эффекта.
Как я могу исправить эту проблему со вставками?
Как изменить диапазоны ограничений диапазона отступов на более разумный уровень, оставив работу репликации?
Ответы
Ответ 1
Я думаю, что я решил, в чем проблема.
Посмотрев на свойства для реплицированной таблицы, у него был стандартный диапазон идентификаторов по умолчанию 10000 для Publisher и 1000 для Subcriber.
Однако проверка ограничения идентификации в фактической таблице (с использованием SP_HELPCONSTRAINT 'node_attrib_rslt') показала, что на обоих серверах был только пул из 1000 идентификаторов. Это привело к тому, что основная вставка завершилась неудачей, даже когда я ограничил количество строк для вставки - я предполагаю, что SQL Server даже не заходит так далеко, когда проверяет ограничение при запуске INSERT INTO.
Чтобы исправить это, мне пришлось сделать несколько вещей:
Измените диапазон идентификации таблицы. Я установил его для 20K для издателей и подписчиков.
- В издателе разверните узел Репликация → Локальные публикации
- Щелкните правой кнопкой мыши конкретную подписку и выберите "Свойства".
- Выберите страницу "Статьи".
- Выделите соответствующую таблицу.
- Нажмите Свойства статьи 'button' и выберите "Установить свойства выделенной таблицы".
- В окне "Свойства статьи" найдите параметры управления диапазонами идентификаторов.
- Измените соответствующие значения.
- Нажмите ОК и OK в диалоговых окнах.
Запустите sp_adjustpublisheridentityrange сохраненную proc в Publisher.
- Новое окно запроса на сервере
- Выберите правильную базу данных
- Выполнить sp_adjustpublisheridentityrange @table_name = 'node_attrib_rslt'
От подписчика принудительно синхронизировать серверы.
- В подписчике разверните узел Репликация → Локальные подписки
- Щелкните правой кнопкой мыши конкретную подписку и выберите "Просмотр статуса подписки".
- В появившемся диалоговом окне нажмите кнопку монитора.
- В появившемся окне "Монитор репликации" разверните конкретный издатель в левой панели.
- Нажмите на подзаголовок для редактирования.
- В правой панели щелкните правой кнопкой мыши статус подписки и выберите "Начать синхронизацию".
- Статус должен обновляться до "Синхронизация", пока он делает свою работу.
- По завершении нажмите вкладку "Предупреждения и агенты". У меня был "Агент мгновенного снимка", указанный в нижней панели. Щелкните правой кнопкой мыши на этом Агенте и запустите его. После того, как он работал некоторое время, изменение свойств на сервере должно было быть перенесено на клиент.
Возможно: вставьте несколько строк тестов в таблицу.
Изменить: мне нужно было выполнить эту задачу еще недавно, и ограничение в таблице не будет обновляться до тех пор, пока я не вставил кучу фиктивных данных в таблицу, чтобы исчерпать ограничение по умолчанию. Затем я повторно синхронизировал серверы, а ограничение было обновлено до нового значения.
После этого проверка ограничения идентификации показала, что у меня, наконец, был диапазон 20K ID для вставки как на Publisher, так и на Subcriber.
Ответ 2
У меня была такая же проблема, и вышеупомянутое решение ничего не делало для меня.
Вместо этого решение проблемы заключалось в установке новых, более крупных диапазонов идентификаторов в таблицах в публикации и затем сбросе ограничений идентификации на таблицу
И затем, наконец, запустить эту команду, которая устанавливает текущее значение.
DBCC CHECKIDENT ('TableName', RESEED, 1000000000);
Вместо того, чтобы устанавливать значение 1000000000, ограничение создается снова и устанавливается на правильное значение диапазона идентификации, указанное в таблице в публикации.
Похоже, команда CHECKIDENT заставляет ограничение каким-то образом обновляться.
Вышеупомянутое решение сработало для меня, но на самом деле я попытался просто отбросить ограничения и настроить издателя и подписчика на использование разных диапазонов идентификаторов, чтобы они могли вставлять строки в таблицы. К счастью, CHECKIDENT, похоже, обновил ограничение, из чего я ожидал, что хранится процедура sp_adjustpublisheridentityrange, за исключением того, что он ничего не сделал.
Я выполнил указанную выше команду как у издателя, так и у подписчика.