Вставка в реплицированную таблицу не выполняется - проверка диапазона идентификаторов

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

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, за исключением того, что он ничего не сделал.

Я выполнил указанную выше команду как у издателя, так и у подписчика.