複寫是將資料從一個來源複製分發到多個目的地的技術,確保分散式環境下資料的一致性與可用性。SQL Server 2000 採用「發行/訂閱」模型,包含五大核心元件:
| 類型 | 適用場景 | 同步機制 | 延遲 | 網路頻寬 | 衝突處理 |
|---|---|---|---|---|---|
| 快照式複寫 | 資料量小、變動少、定期重整 | 定時完整複製 | 高 (依排程) | 爆發式 | 無 (以發行者為準) |
| 交易式複寫 | 高一致性需求、OLTP 系統、即時報表 | 交易記錄讀取與重播 | 低 (秒級) | 持續平穩 | 發行者勝出 |
| 合併式複寫 | 離線用戶、多點更新、行動應用 | 觸發器追蹤變更、合併代理程式協調 | 可配置 | 間歇性 | 優先權/自訂解析器 |
| 維度 | 推式訂閱 (Push) | 拉式訂閱 (Pull) |
|---|---|---|
| 代理程式執行位置 | 散發者端 | 訂閱者端 |
| 散發者負載 | 較高 | 較低 |
| 訂閱者自主性 | 低 | 高 (可控制同步時間) |
| 防火牆穿透 | 需散發者存取訂閱者 | 需訂閱者存取散發者 |
| 適用場景 | 訂閱者少、集中管理 | 訂閱者多、異地/行動裝置 |
建議:先實作推式訂閱建立基線,再測試拉式訂閱比較效能差異。
-- 在散發者伺服器執行
EXEC sp_adddistributor @distributor = 'DIST_SVR', @password = 'StrongPwd123';
EXEC sp_adddistributiondb @database = 'distribution',
@data_folder = 'D:\MSSQL\Data', @log_folder = 'D:\MSSQL\Log';
EXEC sp_adddistpublisher @publisher = 'PUB_SVR',
@distribution_db = 'distribution', @working_directory = '\\DIST_SVR\ReplShare';
-- 建立交易式發行集
EXEC sp_addpublication @publication = 'Sales_Tran_Pub',
@status = 'active', @repl_freq = 'continuous',
@sync_method = 'native', @allow_push = 'true', @allow_pull = 'true';
-- 加入發行項 (篩選特定欄位/列)
EXEC sp_addarticle @publication = 'Sales_Tran_Pub',
@article = 'Orders', @source_object = 'Orders',
@type = 'logbased', @vertical_partition = 'true';
-- 只發行必要欄位
EXEC sp_articlecolumn @publication = 'Sales_Tran_Pub',
@article = 'Orders', @column = 'OrderID', @operation = 'add';
EXEC sp_articlecolumn @publication = 'Sales_Tran_Pub',
@article = 'Orders', @column = 'CustomerID', @operation = 'add';
-- ... 其他必要欄位
-- 散發者端建立訂閱
EXEC sp_addsubscription @publication = 'Sales_Tran_Pub',
@subscriber = 'SUB_SVR', @destination_db = 'Sales_Report',
@sync_type = 'automatic', @update_mode = 'read only',
@subscriber_type = 0; -- 0=推式
-- 設定散發代理程式排程 (每分鐘同步)
EXEC sp_addpushsubscription_agent @publication = 'Sales_Tran_Pub',
@subscriber = 'SUB_SVR', @subscriber_db = 'Sales_Report',
@frequency_type = 4, @frequency_interval = 1,
@frequency_subday = 4, @frequency_subday_interval = 1; -- 每 1 分鐘
sp_replmonitorsubscriptionpendingcmds 應接近 0MSmerge_conflict_* 資料表| 症狀 | 可能原因 | 解決方向 |
|---|---|---|
| Log Reader Agent 失敗 | 交易記錄截斷、資料庫鎖定 | 檢查復原模式、增加記錄檔大小 |
| 訂閱者資料不一致 | 快照過期、Schema 變更未傳播 | 重新初始化訂閱、使用 sp_repladdcolumn |
| 合併衝突頻發 | 優先權設定不當、無自訂解析器 | 調整發行項衝突解析器、業務邏輯介入 |
| 散發資料庫暴增 | 訂閱者離線過久、清理作業失效 | 檢查散發保留期限、手動執行 sp_MSdistribution_cleanup |
複寫不適合作為主要高可用性方案 (建議改用資料庫鏡像/AlwaysOn),但可輔助報表卸載、異地備份。若用於災難復原,需嚴格測試 RTO/RPO 並建立自動容錯移轉腳本。