首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 數據同步全方案:復制技術原理、配置步驟與手工同步存儲過程

     編輯:關於SqlServer

SQL Server 復制架構核心概念

角色職責關鍵對象
發布服務器 (Publisher)數據源頭,定義發布內容發布、文章 (表/視圖/存儲過程)
分發服務器 (Distributor)中轉站,存儲事務/快照分發數據庫 (distribution)
訂閱服務器 (Subscriber)數據消費端訂閱 (推式/拉式)

三大復制類型選型指南

類型延遲一致性適用場景限制
快照復制高 (按排程)最終一致數據量小、頻率低、只讀報表、初始化其他復制全量覆蓋、鎖表、帶寬敏感
事務復制低 (秒級)事務一致OLTP 異構同步、報表分流、異地災備、P2P 多主DDL 傳播需配置、大事務延遲
合並復制可配置最終一致 (衝突解決)離線客戶端 (手持設備/分支機構)、雙向寫入衝突解決複雜、性能開銷大

圖形化配置全流程 (企業管理器 / SSMS)

  1. 配置分發服務器:工具 → 復制 → 配置發布/訂閱/分發 → 選擇分發服務器 (可自為) → 完成,生成 `distribution` 數據庫與復制監視器。
  2. 創建發布:工具 → 復制 → 創建和管理發布 → 選擇發布數據庫 → 創建發布向導 → 選擇類型 (建議事務復制) → 指定訂閱者類型 (SQL Server) → 勾選文章 (表/視圖/函數) → 設置快照代理排程 → 完成。
  3. 創建訂閱:在訂閱服務器 → 工具 → 復制 → 請求訂閱 → 選擇發布服務器/發布 → 選擇訂閱數據庫 → 設置分發代理排程 (持續運行/定時) → 完成。

驗證復制健康度

  • 復制監視器 → 發布 → 右鍵 → 查看詳細信息 → 狀態:運行中、最後同步時間、未分發命令數、延遲 (ms)。
  • 文件系統檢查:`C:\Program Files\Microsoft SQL Server\MSSQL\ReplData\unc\__\` 下每分鐘生成新快照/事務文件夾。
  • 數據抽樣:訂閱端執行 `SELECT COUNT(*) FROM dbo.KeyTable` 對比發布端。

手工同步方案:異構/跨域/無復制權限場景

適用於:無法建立復制拓撲、跨防火牆、版本差異大、需自定義衝突邏輯。

核心機制:鏈接服務器 + 觸發器標記 + 定時作業

-- 1. 創建鏈接服務器 (遠程目標)
IF EXISTS (SELECT 1 FROM master..sysservers WHERE srvname = 'SRV_LNK')
    EXEC sp_dropserver 'SRV_LNK', 'droplogins';
GO
EXEC sp_addlinkedserver 'SRV_LNK', '', 'SQLOLEDB', 'RemoteServerIP';
EXEC sp_addlinkedsrvlogin 'SRV_LNK', 'false', NULL, 'sync_user', 'StrongP@ss';
GO

-- 2. 本地表增加狀態列 (NULL=新增, 1=修改, 0=同步済)
ALTER TABLE dbo.[User] ADD SyncState BIT NULL;
GO

-- 3. 觸發器維護狀態
CREATE TRIGGER trg_User_SyncState ON dbo.[User]
AFTER INSERT, UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    UPDATE u SET SyncState = 1
    FROM dbo.[User] u
    JOIN inserted i ON u.ID = i.ID
    WHERE u.SyncState IS NOT NULL; -- 僅標記已同步過的行,首次插入保持 NULL
END;
GO

-- 4. 同步存儲過程 (分布式事務保證一致性)
CREATE PROC dbo.sp_Sync_User
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON; -- 確保分布式事務原子性

    BEGIN DISTRIBUTED TRANSACTION;

    -- 4.1 同步刪除 (遠程有、本地無)
    DELETE FROM SRV_LNK.TargetDB.dbo.[User]
    WHERE ID NOT IN (SELECT ID FROM dbo.[User]);

    -- 4.2 同步新增 (本地 SyncState IS NULL)
    INSERT INTO SRV_LNK.TargetDB.dbo.[User] (ID, Number, Name)
    SELECT ID, Number, Name FROM dbo.[User] WHERE SyncState IS NULL;

    -- 4.3 同步修改 (本地 SyncState = 1)
    UPDATE r SET
        r.Number = l.Number,
        r.Name   = l.Name
    FROM SRV_LNK.TargetDB.dbo.[User] r
    JOIN dbo.[User] l ON r.ID = l.ID
    WHERE l.SyncState = 1;

    -- 4.4 重置本地狀態
    UPDATE dbo.[User] SET SyncState = 0 WHERE SyncState IN (1, NULL);

    COMMIT TRANSACTION;
END;
GO

-- 5. Agent 作業定時調用 (每 5 分鐘/業務定義)
EXEC msdb.dbo.sp_add_job @job_name = N'Sync_User_Data';
EXEC msdb.dbo.sp_add_jobstep @job_name = N'Sync_User_Data', @step_name = N'RunSync', @subsystem = N'TSQL', @command = N'EXEC dbo.sp_Sync_User;';
EXEC msdb.dbo.sp_add_jobschedule @job_name = N'Sync_User_Data', @name = N'Every5Min', @freq_type = 4, @freq_subday_type = 8, @freq_subday_interval = 5;

手工同步關鍵注意點

  1. 主鍵不可變:同步邏輯依賴 PK 關聯,業務禁止更新 PK。
  2. 分布式事務 (MSDTC) 必須雙向通信:防火牆開放 135 (RPC Endpoint Mapper) + 動態端口範圍,或配置固定端口。
  3. 大批量優化:分批次 (如 5000 行) 循環同步,避免長事務鎖升級、日誌暴漲、MSDTC 超時。
  4. 衝突檢測:若雙向寫入,需引入 `RowVersion`/`Timestamp` 列,比較版本號決定勝者或記錄衝突表人工介入。
  5. 監控告警:作業歷史失敗、同步行數異常波動、遠程鏈接失敗 → 郵件/短信告警。

方案選型建議

場景推薦方案理由
同版本、同網段、高實時、單向事務復制原生、低延遲、可監控、支持 DDL 傳播
異構 (Oracle/MySQL/PostgreSQL)異構復制 / CDC + Kafka / 手工同步原生復制支持有限
跨公網/雲上、防火牆受限手工同步 + 鏈接服務器 / Data Sync Service僅需單向 TCP 端口
離線/移動端、雙向寫入合並復制 / Sync Framework / 自定義 API內建衝突解決器
極簡需求、一次性/低頻BCP/SSIS/導入導出向導零配置、即時生效
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved