У меня возникла странная проблема с транзакционной публикацией SQL Server 2005. Проблема заключается в следующем: если публикация содержит статью, которая является хранимой процедурой, содержащей оператор создания индекса, возникает ошибка при попытке реплицировать схему хранимой процедуры для подписчика.
Поведение очень странное, потому что даже если оператор создания индекса закомментирован , он по-прежнему выдает исключение и будет работать, только если он будет полностью удален.
Вот точная ошибка, которая возвращается:
Команда попыталась: GRANT EXECUTE ON
[dbo]. [usp_Test] TO
[CompanyDatabase_access]
(Порядковый номер транзакции:
0x00000170000008B9000500000000,
Идентификатор команды: 5)
Сообщения об ошибках: не удается найти объект
'usp_Test', потому что он не существует
или у вас нет разрешения.
(Источник: MSSQLServer, номер ошибки:
15151) Получить помощь: http://help/15151
Не удается найти объект «usp_Test»,
потому что он не существует или вы делаете
нет разрешения. (Источник:
MSSQLServer, номер ошибки: 15151) Получить
помощь: http://help/15151
Ошибка точная, потому что, когда я проверяю подписчика, хранимая процедура была создана не так, как ожидалось ... но это было целью публикации ...
Кроме того, я могу создать хранимую процедуру вручную на подписчике, но когда я создаю моментальный снимок, он удаляет существующую хранимую процедуру и затем возвращает это сообщение об ошибке.
А вот пример публикации, которая создает эту проблему.
Хранимая процедура:
USE [CompanyDatabase]
GO
CREATE PROCEDURE [dbo].[usp_Test]
AS
CREATE TABLE #TempTable(ID INT)
CREATE NONCLUSTERED INDEX [IX_TempTable] ON [dbo].[#TempTable](ID)
SELECT 'Test'
GO
GRANT EXECUTE ON [dbo].[usp_Test] TO [CompanyDatabase_access]
GO
Скрипт публикации:
-- Adding the transactional publication
use [CompanyDatabase]
exec sp_addpublication
@publication = N'Replication Test',
@description = N'Publication of database ''CompanyDatabase''.',
@sync_method = N'concurrent',
@retention = 0,
@allow_push = N'true',
@allow_pull = N'true',
@allow_anonymous = N'false',
@enabled_for_internet = N'false',
@snapshot_in_defaultfolder = N'true',
@compress_snapshot = N'false',
@ftp_port = 21,
@ftp_login = N'anonymous',
@allow_subscription_copy = N'false',
@add_to_active_directory = N'false',
@repl_freq = N'continuous',
@status = N'active', @independent_agent = N'true',
@immediate_sync = N'false',
@allow_sync_tran = N'false',
@autogen_sync_procs = N'false',
@allow_queued_tran = N'false',
@allow_dts = N'false',
@replicate_ddl = 1,
@allow_initialize_from_backup = N'false',
@enabled_for_p2p = N'false',
@enabled_for_het_sub = N'false'
GO
-- Adding the transactional articles
use [CompanyDatabase]
exec sp_addarticle
@publication = N'Replication Test',
@article = N'usp_Test',
@source_owner = N'dbo',
@source_object = N'usp_Test',
@type = N'proc schema only',
@description = N'',
@creation_script = N'',
@pre_creation_cmd = N'drop',
@schema_option = 0x0000000048000001,
@destination_table = N'usp_Test',
@destination_owner = N'dbo',
@status = 16
GO
-- Adding the transactional subscriptions
use [CompanyDatabase]
exec sp_addsubscription
@publication = N'Replication Test',
@subscriber = N'OtherDatabaseServer',
@destination_db = N'CompanyDatabase',
@subscription_type = N'Pull',
@sync_type = N'automatic',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0
GO
Сценарий подписки:
/****** Begin: Script to be run at Subscriber ******/
use [CompanyDatabase]
exec sp_addpullsubscription
@publisher = N'DatabaseServer',
@publication = N'Replication Test',
@publisher_db = N'CompanyDatabase',
@independent_agent = N'True',
@subscription_type = N'pull',
@description = N'',
@update_mode = N'read only',
@immediate_sync = 0
exec sp_addpullsubscription_agent
@publisher = N'DatabaseServer',
@publisher_db = N'CompanyDatabase',
@publication = N'Replication Test',
@distributor = N'DatabaseServer',
@distributor_security_mode = 1,
@distributor_login = N'',
@distributor_password = N'',
@enabled_for_syncmgr = N'False',
@frequency_type = 64,
@frequency_interval = 0,
@frequency_relative_interval = 0,
@frequency_recurrence_factor = 0,
@frequency_subday = 0,
@frequency_subday_interval = 0,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@alt_snapshot_folder = N'',
@working_directory = N'',
@use_ftp = N'False',
@job_login = null,
@job_password = null,
@publication_type = 0
GO
/****** End: Script to be run at Subscriber ******/
Опять же, странным является то, что публикация будет по-прежнему содержать ту же ошибку, если оператор создания индекса закомментирован, но она будет работать, если она будет полностью удалена.
На данный момент я только что удалил все хранимые процедуры, которые содержат эти операторы создания индекса, из публикации, но я бы хотел, чтобы они реплицировались на подписчиков, чтобы любые обновления DDL в процедурах автоматически отражались на подписчиках. .
- РЕДАКТИРОВАТЬ -
Глядя в каталог моментальных снимков, файл .sch для usp_Test содержит точно такой же блок кода, который я ранее разместил для хранимой процедуры ... на основании возвращенной ошибки агент моментальных снимков, похоже, решает не запускать CREATE PROCEDURE команда, если она содержит индекс создания, но затем продолжает работу и пытается выполнить команду GRANT EXECUTE, которая вызывает ошибку.
Кроме того, моя точная версия SQL Server:
Microsoft SQL Server 2005 -
9.00.5254.00 (2005 + SP4 Накопительное обновление 1)
- КОНЕЦ РЕДАКТИРОВАНИЯ -
Мой вопрос: почему это происходит? Есть ли проблема с настройкой моей публикации или подписки? Как кто-нибудь еще испытывал что-то подобное? С чего бы начать устранение этой проблемы?
- ОБНОВЛЕНИЕ -
Я разговаривал с Хилари Коттер по technet ... и до сих пор не повезло. Если я удалю разрешение GRANT EXECUTE для процедуры, она будет успешно создана с помощью CREATE INDEX. Так что он будет работать с GRANT EXECUTE ИЛИ CREATE INDEX, но не с обоими. Хилари предположила, что это может быть какой-то тип устройства для защиты от спама в моем домене, который препятствует правильной передаче моментального снимка, когда он содержит оба этих ключевых слова, но если я вручную скопирую файл .sch подписчику и проверим, что он содержит ожидаемое команды, я все еще получаю ту же проблему.