快照前和快照後複製腳本未執行且無錯誤
我在伺服器 1 上設置了快照複製發布。伺服器 2 訂閱了伺服器 1 上的發布。數據複製成功。
伺服器 2 的訂閱伺服器的分發伺服器代理和代理作業在伺服器 1(分發伺服器數據庫所在的位置)上執行。
我在伺服器 2 上創建了一個儲存過程,以在伺服器 2 的訂戶數據庫上刪除(預複製)和創建(複製後)模式綁定實體。(我過去成功地做到了這一點,因為如果訂閱數據庫中存在綁定到複製實體的模式的實體,快照複製可能會停止。)
我還創建了一個腳本,該腳本通過連結伺服器從伺服器 1 到伺服器 2 執行此儲存過程。(我已驗證連結伺服器設置正確,我可以從伺服器查詢數據並通過連結伺服器手動執行儲存過程1 到伺服器 2。)我已將此腳本添加到快照發布的“快照”屬性中:
最初我在快照代理作業中收到錯誤,因為我的快照代理沒有對腳本中路徑的文件共享訪問權限,但我添加了該帳戶,然後錯誤消失了,快照作業現在成功完成。
但是 SQL 腳本中的實體不會被刪除或創建,而且我在任何地方都沒有看到錯誤。我還嘗試將之前和之後的腳本文件移動到伺服器 1 本地的文件夾共享並使用 UNC 路徑(與螢幕截圖中的網路路徑相反)引用它,但行為仍然沒有變化。
我已經使用以下程式碼使用非常簡單的測試更新了 TEST.sql 腳本:
INSERT INTO DatabaseA.dbo.Table1 (Field1) -- DatabaseA is on Server1, so it should insert to the local table SELECT 'Test' AS Field1
當我重新執行快照代理時,它仍然成功執行,但表沒有插入(在伺服器 1 上)。
為什麼我的前置腳本和後置腳本無法執行,但我也沒有收到任何錯誤?
(我在伺服器 1 上還有另一個事務複製發布,它將數據同步到與快照複製相同的數據庫中的伺服器 2。但即使我在“快照”屬性上設置了前置和後置腳本伺服器 1 上的事務性發布,我仍然沒有收到任何錯誤,並且 SQL 沒有執行。)
編輯:我也只是嘗試將腳本文件移動到伺服器 1 的本地文件夾,授予快照代理對該文件夾和腳本文件的讀取權限,然後重新執行快照代理,但仍然沒有。沒有執行腳本,也沒有錯誤。
但有趣的是,如果我手動修改訂閱代理作業本身並添加一個步驟來執行相同的確切 SQL 查詢,它確實可以工作。
我還注意到 SQL 代理作業在不同的 SQL 帳戶“sqlmin”下執行,然後我期望某些步驟(我創建的新步驟,或者稱為“快照代理啟動消息”的作業的第一步 - 我猜是因為這些步驟不是t 類型為“REPL-Distributor”)。但是其他預先存在的步驟作為我指定的 SQL 代理執行,即“DBReplication”。我知道的“sqlmin”帳戶在伺服器 1 和伺服器 2 上都具有非常小的 SQL 權限,這可能是為什麼當我沒有執行複制前和複製後腳本的原因(但我也沒有在任何地方收到錯誤)在快照發布 - 快照屬性的前置和後置欄位上設置腳本?
還有關於分發者帳戶(也是我的快照代理帳戶)的其他詳細資訊:分發者是 Windows AD 帳戶,在伺服器 1 和伺服器 2 上都有 SQL LOGIN,並且在複製的源和目標中都具有 db_owner 的 SQL 角色數據庫以及分發數據庫(位於伺服器 1 上)上的 db_owner。
重新發布我的評論作為答案
從 BoL 中摘錄“您可以在應用快照之前或之後指定要在訂閱者(我的重點,又名 Server2)處執行的腳本。腳本可用於多種原因,例如在以下位置創建登錄名和模式(對象所有者)每個訂閱者。”
在分析各種選項時,我會嘗試一些事情的快速總結……
您是否嘗試過在腳本中傳遞四部分對象標識符?
而不是使用:
... Database.Schema.Table ...
嘗試使用:
... Server.Database.Schema.Table ...
或者在您使用連結伺服器的情況下,它將是:
... LinkedServerName.Database.Schema.Table ...
您將值定義為:
LinkedServerName : The name of the linked server as you defined in the Linked Server connection. Database ........: The name of the database Schema ..........: The name of the schema Table ...........: The name of the table
這取決於腳本必須在哪裡修改數據。這在您的描述中不是很清楚,但是看到您確實提到了連結伺服器,我想我會提到它。
該腳本在訂閱伺服器上執行,如下所述:
您可以指定在應用快照之前或之後在訂閱伺服器上執行的腳本。可以出於多種原因使用腳本,例如在每個訂閱伺服器上創建登錄名和模式(對象所有者)。
此處提供的其他資訊非常重要:
該腳本通過啟動 sqlcmd 實用程序執行。**在部署腳本之前,使用sqlcmd執行它以確保它按預期執行。**應用快照前後執行的腳本內容必須是可重複的。例如,如果您在腳本中創建一個表,您應該首先檢查它是否存在,如果存在則採取適當的措施。該腳本必須是可重複的,因為如果您需要重新初始化已應用該腳本的訂閱,則在重新初始化期間應用新快照時將再次應用該腳本。
參考: 修改 SQL 複製的快照初始化選項(Microsoft | SQL Docs)
如果腳本不能與用於訂閱代理的帳戶一起使用並且不能與sqlcmd一起使用,那麼它在訂閱中將無法使用。
提示在腳本中每一行的末尾
使用。在行之間 添加。
;
GO
然後,您可能想查看文章疑難解答:查找 SQL Server 事務複製錯誤。我不是說你還沒有這樣做,但你沒有說你有。誰知道呢,也許你可以在複製代理的工作歷史中找到問題…