sqlserver關於釋出訂閱replication_subscription的總結

lusklusklusk發表於2019-03-28

官方文件


Replicaiton的報錯程式碼說明及解決方法說明的官方文件



同步資料是指在訂閱伺服器上應用初始快照後,在釋出伺服器和訂閱伺服器之間傳播資料和架構更改的過程。 同步可按下列方式發生:
    連續,這是事務複製的典型方式。
    按需,這是合併複製的典型方式。
    根據計劃,這是快照複製的典型方式。

同步訂閱時,根據您所使用的複製型別的不同,將發生不同的過程。
    快照複製。 同步是指分發代理在訂閱伺服器上重新應用快照,以便訂閱資料庫與釋出資料庫上的架構和資料一致。
    如果在釋出伺服器上修改了資料或架構,則必須生成一個新快照,以便將修改傳播到訂閱伺服器。
    事務複製。 同步是指分發代理將更新、插入、刪除及其他更改從分發資料庫傳輸到訂閱伺服器。
    合併複製。 同步是指合併代理從訂閱伺服器向釋出伺服器上載更改,然後再從釋出伺服器向訂閱伺服器下載更改。 將檢測並解決衝突(如果有)。 資料被收斂,釋出伺服器和所有訂閱伺服器將最終達到相同的資料值。 如果檢測到衝突並解決了衝突,則一些使用者已提交的工作將更改為根據您定義的策略來解決衝突。



事務複製的工作機制
事務複製是由 SQL Server 快照代理、日誌讀取器代理和分發代理實現的。
快照代理準備快照檔案(其中包含了已釋出表和資料庫物件的架構和資料),然後將這些檔案儲存在快照資料夾中,並在分發伺服器中的分發資料庫中記錄同步作業。
日誌讀取器代理監視為事務複製配置的每個資料庫的事務日誌,並將標記為要複製的事務從事務日誌複製到分發資料庫中,分發資料庫的作用相當於一個可靠的儲存-轉發佇列。
分發代理將快照資料夾中的初始快照檔案和分發資料庫表中的事務複製到訂閱伺服器中。
在釋出伺服器中所做的增量更改根據分發代理的計劃流向訂閱伺服器,分發代理可以連續執行以儘量減少滯後時間,也可以按預定的時間間隔執行。

因為日誌讀取器代理(對應如下3的TESTDB1-replicate2-2)會把釋出資料庫的事務日誌複製一份到分發資料庫中, 所以 釋出資料庫並不需要在完整恢復模式下,如果日誌讀取器沒能完成複製就發生釋出資料庫的事務日誌又將要截斷時,則釋出資料庫的事務日誌狀態sys.databases.log_reuse_wait_desc會顯示為Replication以阻止釋出資料庫的事務日誌發生截斷


事務複製原理通俗理解:
原始基礎資料對應快照(快照代理生成存放在快照目錄中)+增量資料對應日誌(日誌讀取器代理捕獲存放在分發伺服器的distribution資料庫中)
快照+日誌都是透過分發代理(通俗意義上的訂閱job)傳送到訂閱伺服器的,也就是官方文件這句話:分發代理將快照資料夾中的初始快照檔案和分發資料庫表中的事務複製到訂閱伺服器中。

快照代理(通俗解釋就是生成快照的那個job,每個釋出都有一個這樣的job)
日誌讀取器代理(通俗解釋就是監視日誌並把日誌寫入到distribution資料庫的那個job, 同一個資料庫下所有的釋出共用同一個這樣的job,也就是說這個job數量只和釋出資料庫有多少個有關,和有多少個釋出沒有關係)
分發代理(通俗解釋就是訂閱job):對於推送訂閱,分發代理在分發伺服器上執行;對於請求訂閱,分發代理在訂閱伺服器上執行。 該代理將事務從分發資料庫移動到訂閱伺服器中。
快照檔案和distribution資料庫中記錄什麼時候清理,都是distribution.dbo.sp_MSdistribution_cleanup在做,預設清理3天前的,也就是說一般快照檔案會在3天后自動消失
重新生成快照,只會把生成快照前新加入釋出的表同步到訂閱端,而不會對釋出下面的訂閱進行初始化,如果釋出的表產生的日誌很多很頻繁的情況下導致分發代理總是很慢從而導致訂閱伺服器資料總是落後於釋出伺服器,想透過定期重新生成快照來定期使訂閱伺服器資料追上釋出伺服器,這種方式是不可能成功的,只有定期對訂閱執行初始化才能實現這一目的

對於事務複製,是否生成快照取決於釋出屬性 MSpublications.immediate_sync 的設定。 如果該屬性設定為 TRUE(使用新建釋出嚮導時的預設設定),則每當執行快照代理時都會生成快照,而且可以隨時將其應用到訂閱伺服器。 如果該屬性設定為 FALSE(使用 sp_addpublication 時的預設設定),則僅當自上次快照代理執行以來新增了新訂閱時,才會生成快照;訂閱伺服器必須等待快照代理完成,才能實現同步。

快照複製和事務複製,當發生重新初始化時,訂閱伺服器上所做的但尚未與釋出伺服器同步的任何更改都將在應用新快照時被覆蓋。
訂閱標記為要重新初始化時,可以選擇下列選項之一:
使用當前快照:選擇此項可以在分發代理或合併代理下一次執行時將當前快照應用於訂閱伺服器。 如果無法獲得有效快照,將無法選定此選項。
使用新快照:選擇此項可以用新的快照來重新初始化訂閱。 只有在快照代理已經生成新快照之後,才能將其應用於訂閱伺服器。 如果快照代理設定為按計劃執行,則直到下一個計劃的快照代理執行後才能重新初始化訂閱。 “使用新快照”選項下面還有一個子選項“立即生成新快照”,選擇 “立即生成新快照” 可以立即啟動快照代理。

問題1:事務複製,一旦釋出重新生成快照,是不是就是自動對釋出下面的訂閱進行初始化了?
現象1.1:釋出端釋出了A1、A2、A3張表,已經同步到了訂閱端,訂閱端刪除A2表,釋出端重新生成這3張表的快照,發現訂閱端並沒有新增A2表
現象1.2:釋出端釋出了A1、A2、A3張表,已經同步到了訂閱端,訂閱端刪除A2表,釋出端再新增A4表並重新生成這4張表的快照,發現訂閱並沒有新增A2表但是新增了A4表
結論1:重新生成快照,只會把生成快照前新加入釋出的表同步到訂閱端,而不會對釋出下面的訂閱進行初始化
結論2:如果釋出的表產生的日誌很多很頻繁的情況下導致分發代理總是很慢從而導致訂閱伺服器資料總是落後於釋出伺服器,想透過定期重新生成快照來定期使訂閱伺服器資料追上釋出伺服器,這種方式是不可能成功的
結論3:如果釋出的表產生的日誌很多很頻繁的情況下導致分發代理總是很慢從而導致訂閱伺服器資料總是落後於釋出伺服器,如果想定期使訂閱伺服器資料追上釋出伺服器,只有定期對訂閱執行初始化才能實現這一目的,官方文件有這麼一句話:快照複製和事務複製,當發生重新初始化時,訂閱伺服器上所做的但尚未與釋出伺服器同步的任何更改都將在應用新快照時被覆蓋。

問題2:事務複製,如果釋出伺服器的快照檔案都已經應用到了訂閱伺服器,訂閱伺服器已經開始使用釋出端產生的日誌了,那麼釋出伺服器的快照檔案什麼時候被清理?
現象1:釋出端生成的快照檔案會存放在一個目錄,發現3天后這些快照檔案自動消失了
現象2:釋出端生成的快照檔案會存放在一個目錄,12小時候,執行EXEC distribution.dbo.sp_MSdistribution_cleanup @min_distretention = 0, @max_distretention = 12,發現這些快照檔案也消失了
結論1:快照檔案的消失時間和distribution.dbo.sp_MSdistribution_cleanup清理事務日誌時間一樣,也就是說distribution.dbo.sp_MSdistribution_cleanup會同時清理快照檔案和清理事務日誌一樣,快照檔案
結論2:右鍵釋出--屬性--Subcription Options--snapshot always available,此選項和釋出端的快照檔案什麼時候被清理沒有任何關係,此選項只是在建立釋出的時候勾選“Create a snapshot immediately and keep the snapshot available to initialize subscription”有關,如果勾選了,則snapshot always available為true,否則false,也就是sp_addpublication.@immediate_sync =ture則釋出--屬性--Subcription Options--snapshot always available,意思就是每次執行快照代理時建立或重新建立同步檔案。


問題3:為什麼"Distribution clean up: distribution"作業會報錯was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction

解釋:清理分發資料庫中MSrepl_commands的job作業"Distribution clean up: distribution"和log reader agent日誌讀取器代理job作業會互相堵塞,兩個job一個delete刪除MSrepl_commands一個insert寫MSrepl_commands,所以如果有事務量過大或複製條目過多的表,因為兩個job直接的互相堵塞會造成嚴重的等待,一旦log reader agent日誌讀取器代理job被堵塞,這所有的釋出都要等待,這樣replication延遲越來越嚴重。


問題4:拿掉一個釋出上的表後,不重新生成快照或初始化,對該表進行寫入,該表會重新同步到訂閱端嗎?後面把這個表重新加入釋出,需要重新生成快照或初始化嗎?
已經實驗,不重新生成快照或初始化的情況下,對該表進行寫入,新資料不會同步到到訂閱端,訂閱端的資料也沒被刪除,訂閱端保持該表從釋出中拿掉之前的狀態
已經實驗1:把這個表重新加入釋出,在釋出端對這張表的寫入不會同步到訂閱端,而釋出端其他表的資料會同步到訂閱端
已經實驗2:需要重新生成快照或初始化,這張表的資料才會從釋出端正常同步到訂閱端

問題5:現有一個釋出,後面往這個釋出中新增一張表,這個新增的表會自動同步到訂閱庫嗎?
已經實驗:不會,只有初始化訂閱或重新生成快照才會同步到訂閱庫

問題6:現有釋出中有一張表,有10個欄位,只發布了3個欄位,後面新增一個釋出欄位,這個新增的釋出欄位會自動同步到訂閱庫嗎?
已經實驗:會,因為一旦在釋出裡面增加一個欄位,就自動提示需要reinitialized subscription初始化訂閱,所以新增欄位成功的話,該欄位就會自動同步到訂閱庫

問題7:
一個資料庫下6個釋出訂閱,一個釋出訂閱的同步出現問題,會影響其他5個釋出訂閱的同步嗎?
已經實驗:不會

問題8:
一個釋出下面有兩個訂閱,一個訂閱出現問題,會影響另一個訂閱嗎?
已經實驗:不會




快照代理、log reader、分發代理這些的job 查詢


查詢某個釋出對應的snapshot agent快照代理job的名稱
select publication,name snapshot_agent_job from distribution.dbo.MSsnapshot_agents

select a.name publication_name,b.name job_name from wondb.dbo.syspublications a inner join msdb.dbo.sysjobs b on a.snapshot_jobid=b.job_id

查詢某個釋出資料庫對應的log reader agent日誌讀取器代理job的名稱
Select name job_name,publisher_db,publication  from distribution.dbo.MSlogreader_agents
備註:同一個資料庫下所有的釋出共用同一個這樣的job,見publication欄位值預設是ALL

查詢分發代理job的名稱,推送訂閱,分發代理在分發伺服器上執行;對於請求訂閱,分發代理在訂閱伺服器上執行
推送訂閱:在分發伺服器上分發資料庫預設是distribution上執行
Select name,subscriber_job,publisher_db,publication from distribution.dbo.MSdistribution_agents a where a.subscriber_db<>'virtual' and a.local_job=1 and a.subscription_type=0
請求訂閱:在訂閱伺服器上的訂閱庫上執行
select publisher,publisher_db,publication,subscription_type,distribution_agent distribution_agent_job  from MSreplication_subscriptions




同步延遲的判斷和查詢,釋出端-->分發端-->訂閱端
關鍵點:[distribution].[dbo].MSlogreader_history需要確定延遲究竟是指歷史時刻點的已經發生的延遲,還是歷史時刻點開始的延遲?
比如現在是3點,記錄訊息的時間time是1點,delivery_latency是30分鐘,如果是歷史時刻點的已經發生的延遲,那麼就是說截止1點,已經延遲了30分鐘了,也就是從12點30開始就開始延遲了。如果是歷史時刻點開始的延遲,那麼就是從1點開始延遲,會延遲30分鐘,預計到1點30分鐘延遲結束。透過launch replication monitor圖形介面+sql語句,得出結論是歷史時刻點的已經發生的延遲,因為當時透過圖形介面已經檢視到分發端未傳輸到訂閱端的命令有60萬條,預計需要11分鐘傳遞到訂閱端了,當時sql語句查詢表[distribution].[dbo].MSdistribution_status發現有60萬條記錄沒有傳輸到訂閱端,但是表[distribution].[dbo].MSdistribution_history查詢下來發現沒有延遲,11分鐘後再查,發現表[distribution].[dbo].MSdistribution_history的延遲是11分鐘了

監控replication事務複製延遲的過程和系統表
distribution.dbo.sp_replcounters --無須引數
distribution.dbo.sp_replmonitorhelpsubscription  --只需特點引數,比如 @publisher_db ='wondb',@publication_type=0
distribution.dbo.sp_replmonitorsubscriptionpendingcmds --需要提供所有引數
distribution.dbo.MSdistribution_status
distribution.dbo.MSreplication_monitordata

監控replication事務複製延遲的圖形介面工具
SSMS-右鍵點選發布--Launch Replication Monitor--Replication Monitor--My Publishers--伺服器名稱--釋出名稱--第二列跟蹤令牌--插入跟蹤器
Tracer Tokens measure latency from Publisher to Distributor,Distributor to Subscriber
每點選一次插入跟蹤器就會記錄當前的延遲,1點的時候點選一次則記錄1點的延遲,2點的時候點選一次則記錄2點的延遲

釋出端到分發端的延遲,最近2小時內某個歷史時刻點已經發生的延遲資訊
select delivery_latency/1000 latency_seconds,getdate() now,time, * from [distribution].[dbo].MSlogreader_history(nolock) where [time] >= DATEADD(HOUR, -2, GETDATE()) order by 1 desc
表MSlogreader_history意思:The MSlogreader_history table contains history rows for the Log Reader Agents associated with the local Distributor
欄位delivery_latency意思:命令從進入釋出資料庫到進入分發資料庫之間的滯後時間。 以毫秒為單位。
欄位time意思:記錄訊息的時間。

分發端到訂閱端的延遲,最近2小時內某個歷史時刻點已經發生的延遲資訊
select delivery_latency/1000 latency_seconds,current_delivery_latency/1000 current_latency_seconds,
getdate() now,a.time,b.publication,b.publisher_db,b.name,a.*,b.* from [distribution].[dbo].MSdistribution_history(nolock) a
inner join [distribution].[dbo].MSdistribution_agents(nolock) b on a.agent_id=b.id
and a.[time] >= DATEADD(HOUR, -2, GETDATE()) order by 2 desc
表MSdistribution_history意思:The MSdistribution_history table contains history rows for the Distribution Agents associated with the local Distributor
欄位delivery_latency意思:命令從進入分發資料庫到應用於訂閱伺服器之間的滯後時間。 以毫秒為單位。
欄位current_delivery_latency意思:自從最後一個歷史記錄條目後,命令從進入分發資料庫到應用於訂閱伺服器之間的滯後時間。 以毫秒為單位。
欄位time意思:記錄訊息的時間。

釋出端到訂閱端的延遲
exec Wondadb3.distribution.dbo.sp_replmonitorhelpsubscription @publisher_db ='wondb',@publication_type=0
返回結果的latency欄位意思:The highest latency, in seconds, for data changes propagated by the Log Reader or Distribution Agents for a transactional publication.在事務釋出中,由日誌讀取器代理或分發代理傳播的資料更改的最長滯後時間,以秒為單位

釋出端沒有傳輸到分發端的命令列資訊
目前沒有找到方法可以查出釋出端沒有傳輸到分發端的命令列資訊

分發端沒有傳輸到訂閱端的命令列資訊,記錄的是此刻沒有傳輸到訂閱端的資訊
select b.publication,b.publisher_db,b.name,c.article,a.* from [distribution].[dbo].MSdistribution_status(nolock) a
inner join [distribution].[dbo].MSdistribution_agents(nolock) b on a.agent_id=b.id
inner join [distribution].[dbo].MSarticles(nolock)  c on a.article_id=c.article_id and b.publisher_db=c.publisher_db order by UndelivCmdsInDistDB desc
檢視MSdistribution_status意思:The MSdistribution_status view exposes(公開,披露) additional information on the status commands in the distribution database.
備註:查到了沒有傳輸到訂閱端的命令對應的agent_id或article,不代表這些agent_id或article在此刻有延遲,即這些agent_id或article在系統表[distribution].[dbo].MSdistribution_history可能查到delivery_latency=0




關於replication_subscription常用的SQL查詢語句


分發庫中的MSrepl_commands表的行數
select count(*) from distribution.dbo.MSrepl_commands with (nolock)

分發庫中的MSrepl_commands表的行數和表的容量大小
EXEC distribution..sp_spaceused 'MSrepl_commands'

監控釋出訂閱是否有異常,執行以下5條語句即可
select * from [distribution].[dbo].[MSlogreader_history] WHERE error_id != 0 AND [time] >= DATEADD(HOUR, -1, GETDATE())
select * from [distribution].[dbo].[MSdistribution_history] WHERE error_id != 0 AND [time] >= DATEADD(HOUR, -1, GETDATE())
select * from [distribution].[dbo].[MSsnapshot_history] WHERE error_id != 0 AND [time] >= DATEADD(HOUR, -1, GETDATE())
select * from [distribution].[dbo].MSrepl_errors order by 2 desc
select * from msdb.dbo.sysreplicationalerts order by 7 desc

查詢某個釋出XX,釋出的資料庫物件的2種方法
1、釋出資料庫上執行(資料來源這三張表distribution.dbo.MSpublications、distribution.dbo.MSarticles、sysarticlecolumns)
select a.article,a.source_object,a.destination_object,b.colid from
(select article,article_id,source_object,destination_object
from [distribution].[dbo].MSarticles where publication_id in
( select publication_id from
[distribution].[dbo].MSpublications where publication='XX'
)
) a
inner join
(select * from replicate1.dbo.sysarticlecolumns) b
on a.article_id=b.artid order by a.article
2、訂閱資料庫上執行  
select distinct article from MSreplication_objects where publication='XX'

查詢某個釋出物件比如表XX,存在那個釋出,訂閱到哪個資料庫中
select a.publisher_db,d.id publisher_database_id,b.publication,a.article,a.article_id,c.subscriber_db,a.destination_object,c.article_id,c.subscription_time
from [distribution].[dbo].MSarticles(nolock) a
inner join [distribution].[dbo].MSpublications(nolock) b
on a.publication_id=b.publication_id
inner join [distribution].[dbo].MSsubscriptions(nolock) c
on a.publication_id=c.publication_id and a.article_id=c.article_id
inner join [distribution].[dbo].MSpublisher_databases(nolock) d
on a.publisher_db=d.publisher_db
and a.article='XX'

查詢最近哪張表產生了最多的釋出事務
select publisher_database_id,article_id,count(*) from [distribution].[dbo].[MSrepl_commands](nolock) group by publisher_database_id,article_id order by count(*) desc
select b.publication,a.publisher_db, a.article,a.article_id
from [distribution].[dbo].MSarticles  a
inner join [distribution].[dbo].MSpublications b
on a.publication_id=b.publication_id
inner join [distribution].[dbo].MSpublisher_databases(nolock) c
on a.publisher_db=c.publisher_db
and c.id=XX and a.article_id=YY

查詢沒有分發的命令和複製的延遲(感覺還是distribution.dbo.MSdistribution_status和distribution.dbo.sp_replmonitorhelpsubscription兩者更簡單)
邏輯:一個publication,只要MSrepl_commands裡的事務序列號大於MSdistribution_history的事務序列號,就算作是還沒分發的commands,即程式碼中的MSrepl_commands.xact_seqno>MSdistribution_history.maxseq
SELECT
    @@SERVERNAME as server_name,
    mda.publisher_db,
    mp.publication as publication_name,
    mda.name as agent_name,
    mda.subscriber_db,
    CASE
        WHEN mda.subscription_type = '0' THEN '0, Push'
        WHEN mda.subscription_type = '1' THEN '1, Pull'
        WHEN mda.subscription_type = '2' THEN '2, Anonymous'
    END subscription_type,
    CASE
        WHEN de2.runstatus = '1' THEN '1, Start'
        WHEN de2.runstatus = '2' THEN '2, Succeeded'
        WHEN de2.runstatus = '3' THEN '3, In Progress'
        WHEN de2.runstatus = '4' THEN '4, Idle'
        WHEN de2.runstatus = '5' THEN '5, Retry'
        WHEN de2.runstatus = '6' THEN '6, Failed'
    END runstatus,
    ISNULL(und.undelivered_commands,0) as undelivered_commands,
    de2.agent_id,
    de2.start_time,
    de2.time as last_time,
    de2.duration,
    de2.comments,
    de2.current_delivery_rate,
    de2.current_delivery_latency,
    de2.delivered_transactions,
    de2.delivered_commands
FROM
    distribution.dbo.MSpublications mp
LEFT JOIN
    distribution.dbo.MSdistribution_agents mda on mp.publication = mda.publication
    AND mda.subscriber_db <> 'virtual'
LEFT JOIN
    (
    SELECT
        mdh.agent_id,
        mdh.start_time,
        mdh.time,
        mdh.duration,
        mdh.comments,
        mdh.current_delivery_rate,
        mdh.current_delivery_latency,
        mdh.delivered_transactions,
        mdh.delivered_commands,
        mdh.runstatus
    FROM
        distribution.dbo.MSdistribution_history mdh
    INNER JOIN
        (
        SELECT
            agent_id,
            max(time) as last_time
        FROM
            distribution.dbo.MSdistribution_history mdh
        GROUP BY
            agent_id
        ) de ON de.agent_id = mdh.agent_id
            AND de.last_time = mdh.[time]
    ) de2 on mda.id = de2.agent_id
LEFT JOIN
  (SELECT
        s.agent_id,
        MaxAgentValue.[time],
        SUM(CASE WHEN t.xact_seqno > MaxAgentValue.maxseq THEN 1 ELSE 0 END) AS undelivered_commands
  FROM distribution.dbo.MSrepl_commands t
  INNER JOIN distribution.dbo.MSsubscriptions AS s ON (t.article_id = s.article_id AND t.publisher_database_id=s.publisher_database_id )
  INNER JOIN
    (SELECT hist.agent_id, MAX(hist.[time]) AS [time], h.maxseq
    FROM distribution.dbo.MSdistribution_history hist
    JOIN (SELECT agent_id,ISNULL(MAX(xact_seqno),0x0) AS maxseq
    FROM distribution.dbo.MSdistribution_history
    GROUP BY agent_id) AS h
    ON (hist.agent_id=h.agent_id AND h.maxseq=hist.xact_seqno)
    GROUP BY hist.agent_id, h.maxseq
    ) AS MaxAgentValue
  ON MaxAgentValue.agent_id = s.agent_id
  GROUP BY s.agent_id, MaxAgentValue.[time]
  ) und
ON mda.id = und.agent_id AND und.time = de2.time
WHERE mda.subscriber_db <> 'virtual'
ORDER BY
    mda.publisher_db,
    mp.publication,
    mda.name




1、如果操作釋出訂閱的客戶端SSMS版本比伺服器端版本低,會報錯,比如service是sqlserver2016,ssms使用sqlserver2014會報錯

2、只建立分發時,會新增7個相關job;初次建立釋出的同時建立分發,會新增9個相關job

3、後面每新增一個釋出名,釋出伺服器上會新增兩個釋出的job如下,前一個是不停的生成釋出資料,該job不停執行,後一個是初始化釋出資料(生成unc目錄下的檔案和檔案),執行一次就可以了

TESTDB1-replicate2-2

TESTDB1-replicate2-pub_replicate2-2

釋出例項名--資料庫名--釋出名的序號

釋出例項名--資料庫名--釋出名--釋出名的序號

4、釋出伺服器-複製-本地釋出-釋出名-右鍵-屬性-snapshot,選擇put files in the following folder,可以把檔案放到共享路徑

5、訂閱,可以在訂閱伺服器建立,也可以在釋出伺服器建立,釋出伺服器-複製-本地釋出-釋出名,右鍵選擇new subscriptions

6、後面每新增一個訂閱,如果是推送訂閱,主庫增加一個job,如果是請求訂閱,從庫增加一個job

TESTDB1-replicate2-replicate2-TESTDB2-6(推送訂閱,釋出例項名-釋出資料庫名-釋出名-訂閱例項名-編號)

TESTDB1-replicate1-pub_replicate1-TESTDB2-replicate_01-CD7A365E-2DE7-47A3-B31E-70F785FA71F2(請求訂閱)

7、釋出job或訂閱job,都可以根據需要修改scheduler

8、本地釋出或本地訂閱下面的訂閱圖示有小圈圈,表示在當前例項下,是對方主動而不是當前例項主動,訂閱的job在對方那邊

推送訂閱,在主庫釋出下面的訂閱圖示沒有藍色小圈圈,在從庫訂閱下面的訂閱圖示有藍色小圈圈

請求訂閱,在主庫釋出下面的訂閱圖示有藍色小圈圈,在從庫訂閱下面的訂閱圖示沒有藍色小圈圈

--也適用於本地釋出又是本地訂閱的情況,比如本地一個庫資訊傳輸到本地另一個庫,則本地釋出或本地訂閱下面都有訂閱,如果是推送訂閱,則釋出下面的訂閱圖示沒有藍色小圈圈,訂閱下面的訂閱圖示有藍色小圈圈,如果是請求訂閱,則釋出下面的訂閱圖示有藍色小圈圈,訂閱下面的訂閱圖示沒有藍色小圈圈

9、訂閱的刪除,根據推送訂閱和請求訂閱的不同,有不同操作方式,統一的操作方法就是直接刪除主庫釋出下面的訂閱。

推送訂閱的情況下,如果只在從庫刪除訂閱,則主庫的釋出下面的訂閱資訊還在,主庫上的訂閱job也還在(但是資訊不會同步到訂閱庫了),還需要在主庫再刪除一遍

推送訂閱的情況下,在主庫刪除訂閱的話,主庫上的訂閱job也不在了,從庫的訂閱資訊也自動刪除了

請求訂閱的情況下,在主庫刪除訂閱的話,從庫上的訂閱job也不在了,從庫的訂閱資訊也自動刪除了

請求訂閱的情況下,在從庫刪除訂閱的話,從庫上的訂閱job不在了,主庫上的釋出下面的訂閱資訊也不在了

--也適用於本地釋出又是本地訂閱的情況,比如本地一個庫資訊傳輸到本地另一個庫,則本地釋出或本地訂閱下面都有訂閱

10、釋出的job在msdb.dbo.sysjobs正常記錄,但是這些job執行時在sysprocesses.program_name都是顯示Microsoft SQL Server,不顯示為具體的job名稱,如下語句查詢job,不適用於訂閱複製

select * from msdb.dbo.sysjobs where name='jobname'

select a.program_name,a.* from master..sysprocesses a where a.program_name like '%0D1CE57E8AC5%'

11、訂閱的job在msdb.dbo.sysjobs正常記錄,但是這些job執行時在sysprocesses.program_name都是顯示為空

12、刪除訂閱資料庫時,出現如下,解決方法是把訂閱的job停掉再把訂閱資料庫offline,再刪除

Cannot drop the database ‘XXX’because it is being used for replication

13、刪除釋出,如果釋出下面有訂閱,則刪除釋出的時候,訂閱就失效了

請求訂閱的情況下,從庫的本地訂閱下面還有訂閱和job,但是失效了,還需要手工刪除一下訂閱,此時會自動刪除job

推送訂閱的情況下,主庫的釋出和job都刪除了,從庫的本地訂閱下面還有訂閱,但是失效了,還需要手工刪除一下

--也適用於本地釋出又是本地訂閱的情況,比如本地一個庫資訊傳輸到本地另一個庫,則本地釋出或本地訂閱下面都有訂閱

14、訂閱庫,可以執行DML,執行delete不會有什麼後遺症,執行update或insert的話,如果後面收到釋出庫傳過來的資料,可能會產生衝突

15、釋出訂閱相關的儲存過程

EXEC distribution.dbo.sp_replmonitorhelppublisher --釋出庫上執行,檢查釋出伺服器上的本地釋出的情況

16、釋出建立好後,釋出伺服器上有一個linked sever指向分發伺服器,名稱一般為repl_distributor,disable publishing and distribution後,該linked server會自動刪除

訂閱建立後(不管是請求訂閱還是推送訂閱),會在釋出伺服器上自動建立一個linked server指向訂閱伺服器。刪除釋出或disable publishing and distribution,該linked server都不會自動刪除

17、如果訂閱的job的schedules沒有明確指定,只是start automaticaly when SQL Server Agent starts,那麼一旦把這個job停止,後面不會再同步了,在Replication Monitor裡面的Subscription Watch List看到這個訂閱的status就是not running

18、推送訂閱:到釋出伺服器下面的本地釋出-釋出名稱-訂閱名,右鍵選擇view Synchronization Status可以看到訂閱狀態

請求訂閱:到訂閱伺服器下面的本地訂閱-訂閱名,右鍵訂閱,選擇view Synchronization Status可以看到訂閱狀態,並可以看到訂閱job的執行情況

19、複製-本地訂閱-訂閱名,右鍵選擇view Synchronization Status檢視到狀態是No replicated transactions are available,則到釋出端,複製-本地釋出-釋出名,右鍵釋出,選擇如下兩者,檢視job狀態是否start執行中,如果是,再count(*)主從表資料是否一致,如果一致,說明此時確實沒有DML事務產生新的資料

View Snapshot Agent Status檢視快照代理狀態,對應的job其實是"例項名-釋出資料庫名-釋出名稱-釋出序號",一般只執行一次,生成存放在unc中的初始化資料

View Log Reader Agent Status檢視日誌讀取器代理狀態,對應的job其實是"例項名-釋出資料庫名-釋出序號",一般一直執行

20、所謂的分發服務,就是建立一個分發資料庫預設是distribution,並建立snapshot目錄,如果沒有建立分發,初次建立釋出的時候,會自動建立分發服務,第二次建立釋出的時候,會使用原來的分發服務。建立釋出時,必須要先有分發,要不釋出的資料存放在哪呢?分發就是存放這些要釋出的資料的地方

21、分發伺服器是釋出伺服器與訂閱伺服器之間的橋樑,起著儲存區的作用,負責複製與一個或多個釋出伺服器相關聯的特定資料。每個釋出伺服器都與分發伺服器上的單個資料庫(稱作分發資料庫)相關聯。分發資料庫從釋出伺服器獲得要釋出的資料後將儲存複製狀態資料和有關釋出的後設資料,並且在某些情況下為從釋出伺服器向訂閱伺服器移動的資料起著排隊的作用。在大多數情況下,一個資料庫伺服器例項充當釋出伺服器和分發伺服器兩個角色。當釋出伺服器和分發伺服器在同一個資料庫例項中時,稱為“本地分發伺服器”。當釋出伺服器和分發伺服器按各自的資料庫伺服器例項配置時,把分發伺服器稱為“遠端分發伺服器”

22、沒有建立過分發時,右鍵replication時,有configure distribution,選擇configure distribution表示只配置分發,不做其他動作,在此過程中如果在Publishers頁面勾選了publisher和distribution database,則右鍵replication時,沒有了configure distribution,取而代之的是publisher properties、distributor properties、disable publishing and distribution;如果在Publishers頁面沒有勾選publisher和distribution database,則右鍵replication時,沒有了configure distribution,取而代之的是Distributor Properties、Disabled Publishing and Distribution Wizard。其實右鍵replication選擇configure distribution時勾選了publisher和distribution database,就是選擇哪些釋出伺服器可以使用這個分發伺服器(enable servers to use this distributor when they become publishers),其中distribution database沒得選,就是分發的資料庫,預設是distribution

23、右鍵Replicattion選擇Disabled Publishing and Distribution Wizard,禁用訂閱釋出,所有的訂閱釋出資訊都丟失了包括system databases裡的distribution資料庫也包括unc目錄下的所有目錄和檔案,所以執行之前需要對訂閱釋出資訊進行備份或截圖

24、要初始化訂閱,即重新把釋出端的資料推送到訂閱端,可以選擇推送到這個釋出的單個訂閱(釋出端--釋出名稱--訂閱名稱--右鍵--reinitialize),也可以選擇推送到這個釋出的所有訂閱(釋出端--釋出名稱--右鍵--reinitialize all subscriptions)。再在釋出伺服器-複製-本地釋出-釋出名,右鍵選擇View Snapshot Agent Status選擇start,或執行job"例項名-釋出資料庫名-釋出名稱-釋出序號"

25、在訂閱端的表裡手工先insert一條語句,後面釋出端同步一條一樣資料過來的時候,訂閱端會報錯

Violation of PRIMARY KEY constraint 'PK_XX'. Cannot insert duplicate key in object 'dbo.TXX'. The duplicate key value is (33583).

26、bug問題:右鍵Replicattion選擇Disabled Publishing and Distribution Wizard後,最後一步會報錯,但是確實把釋出和分發都刪除了

27、匯出訂閱複製的指令碼的方法:右鍵Replication選擇Generate Scripts(匯出指令碼里面有註釋,在釋出端執行還是訂閱端執行)
以上會匯出當前伺服器下的分發、釋出、訂閱,如果在Generate Scripts跳出的介面勾選了distributor properties則會匯出分發;勾選了publications in the following data sources則會匯出釋出;如果勾選了subscriptions in the following data sources則會匯出訂閱。

28、某個釋出XX丟失了,但是請求訂閱還在的處理方法
訂閱端執行如下,找到釋出的資料庫物件,再在釋出端建立釋出,再重建訂閱
select distinct article  from MSreplication_objects where publication='XX'
如下方法不行
把釋出資料庫恢復到丟失以前看能不能找回釋出資訊,發現釋出資料庫執行如下報錯
select * from sysarticlecolumns
Invalid object name 'sysarticlecolumns'.
29、釋出訂閱需要新增一張表時,只需要右鍵釋出名稱選擇articles專案在裡面勾選需要新增的表即可,再右鍵釋出名稱--view snapshot agent status--start即可,在釋出端的日誌讀取job(右鍵釋出名稱--view log reader agent status)正常執行的情況下,訂閱job(右鍵訂閱名稱--view sysnchronization status)也正常執行的情況,訂閱資料庫上可以馬上看到新增的表
30、SSMS圖形介面,新建釋出到第四步articles專案時或已經存在的釋出右鍵選擇articles專案時,介面很慢一直無法正常顯示資料庫物件比如表檢視儲存過程等,說明有堵塞,SSMS點開一些介面其實就是一個select的動作,找到堵塞源殺掉後,就可以正常顯示了
31、例項--replication--Local Subscriptions--訂閱名稱--右鍵--View Synchronization Status報錯:An error occurred connecting to server 'XX'.SQL Server repliaction requires the actual server name to nake a connection to the server.
原因:可能修改了計算機名,SSMS連線的是新的計算機名,但是資料庫沒有修改Servername,導致這個報錯,SSMS連線使用老的計算機名或修改資料庫修改Servername為新的計算機名即可
32、A伺服器ADB1庫的資料做了replication到B伺服器的ADB1資料庫,A伺服器和A1伺服器搭建了AG,並把ADB1加入了AG,但是A1上的AG對應的資料庫ADB1不正常,右鍵A伺服器ADB1對應的釋出名稱--View Log Reader Agent Status發現ADB1的釋出報錯:Replicated transaction are waiting for next log backup or for mirror partner to catch up(複製的事務正等待下一次日誌備份或等待映象夥伴更新)
解決方法
    方法1、確保A1的AG中ADB1正常(首選方法)
    方法2、在A伺服器上把該資料庫ADB1從AG中移除
    方法3、在A伺服器上執行
DBCC TRACEON (1448, -1)     --不希望replication受到alwayson 其他node的影響
原因:
    我們知道always on的輔助副本secondary是獲取了primary的日誌資訊而進行的redo動作實現了資料庫的同步工作。當secondary異常當機後,為了保證secondary起來時能夠繼續上次讀取日誌的地方做redo動作,db的transaction log就不會進行備份,而一直增大,最壞的情況導致磁碟爆滿,無法使用。如當前01為primary,02為secondary,為了避免failover後,02切換為主副本,而此節點卻沒有獲取到和01一樣新的replication資訊,導致異常。所以所有的always on node都要知道同步的情況,否則不繼續進行同步。即所有node都獲取replication資訊後,才允許replication繼續進行
33、SSMS對DB1建立釋出時報錯:this database is not enabled for publication不允許此資料庫用於釋出。 (Microsoft SQL Server,錯誤: 14013)
手工執行對DB1建立釋出
USE master
EXEC sp_replicationdboption @dbname = 'DB1',@optname = 'publish',@value = 'true'
GO
報錯
連結伺服器"repl_distributor"的 OLE DB 訪問介面 "SQLNCLI" 返回了訊息 "Login timeout expired"。
連結伺服器"repl_distributor"的 OLE DB 訪問介面 "SQLNCLI" 返回了訊息 "An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections."。
該例項是Enterprise企業版,不是Express開發版,可以建立釋出,所以不是版本問題
原因: 發現存在一個名為repl_distributor的linked server,且無法刪除該linked server,查詢該linked server發現它已經用於釋出,即master.sys.servers.is_distributor=1
解決方法:USE master;  
          EXEC sp_serveroption 'repl_distributor', 'dist', 'false';
34、錯誤號:18483
could not connect to server "XX" because 'distributor_admin' is not defined as a remote login at the server
未能連線到'XX'伺服器,因為distributor_admin未在該伺服器上定義為遠端登入
Could not connect to server 'XX' because 'YY' is not defined as a remote server.
未能連線到'XX'伺服器,因為'YY'沒有定義為遠端伺服器
原因:hostname和servername不一致導致,hostname是XX,但是servername是YY,這時候不能透過圖形介面來完成建立分發伺服器的操作
解決方法:使用圖形介面嚮導,最後選擇不配置分發,而是生成指令碼,使用指令碼的程式碼,修改指令碼中程式碼,把XX修改為YY即可
35、replication到不同的schema,比如A庫的dbo.table1可以複製到B庫的repl.table1,不過無法使用圖形介面來操作,需要使用指令碼來操作,當然也可以使用圖形介面來操作但是最後不點確定,而是從圖形介面匯出指令碼,再修改指令碼中的schema資訊,如下案例把dbo這個schema的表base複製到repl這個schema下:
use [PatternRecDB]
exec sp_addarticle @publication = N'PatternRecDB_Base', @article = N'Base', @source_owner = N' dbo', @source_object = N'Base', @type = N'logbased', @description = N'', @creation_script = N'', @pre_creation_cmd = N'truncate', @schema_option = 0x000000000803509F, @identityrangemanagementoption = N'manual', @destination_table = N'Base', @destination_owner = N' repl', @status = 24, @vertical_partition = N'false', @ins_cmd = N'CALL [sp_MSins_dboBase]', @del_cmd = N'CALL [sp_MSdel_dboBase]', @upd_cmd = N'SCALL [sp_MSupd_dboBase]'
GO
36、修改資料庫名報錯can not rename the database name because it is published or it is a distribution database,解決方法:sp_removedbreplication @dbname=XXX
37、修改servername報錯There are still remote logins or linked logins for the server 'DBMASTER'
解決思路
37.1、檢視哪些使用者遠端連線了DBMASTER伺服器
sp_helpremotelogin 'DBMASTER'
server    local_user_name    remote_user_name    options
DBMASTER    distributor_admin    distributor_admin
37.2、刪除遠端連線,繼續出現的錯誤表示該伺服器是訂閱複製的釋出伺服器
exec sp_dropserver 'DBMASTER', @droplogins = 'droplogins'
繼續報錯Cannot drop server 'DBMASTER' because it is used as a Publisher in replication.
37.3、刪除訂閱複製的釋出資訊
sp_dropdistpublisher @publisher ='DBMASTER'
繼續報錯Cannot drop the local distribution Publisher because there are Subscribers defined.
37.4、刪除訂閱資訊
sp_dropdistributor
繼續報錯Could not drop the Distributor 'DBMASTER'. This Distributor has associated distribution databases.
37.5、最後刪除訂閱資訊再重新把DBMASTER修改為DBMASTERNEW,成功
EXEC sp_dropdistributor @no_checks = 1, @ignore_distributor = 1
exec sp_dropserver 'DBMASTER', @droplogins = 'droplogins'
sp_addserver 'DBMASTERNEW','local'
38、當我們用SSMS配置分發伺服器或用T-SQL執行sp_adddistributor時, 會自動建立一個名稱為distributor_admin的登入名,這個登入名不要手工建立。當我們SSMS禁用分發伺服器或T-SQL執行sp_dropdistributor會自動刪除distributor_admin登入名
39、釋出伺服器上某個釋出已經被刪除了,但是釋出伺服器查詢select * from [distribution].[dbo].MSrepl_errors order by 2 desc還是報錯說釋出找不到The publication 'XXX' does not exist.
故障原因:刪除釋出的時候,沒有先刪除釋出下面的訂閱,直接刪除的釋出,導致訂閱伺服器上訂閱和訂閱job都在,而訂閱job跑一次,發現訪問不到釋出,所以分發資料庫中表MSrepl_errors就記錄訪問不到釋出的故障
解決方法:直接在訂閱伺服器上警用或刪除訂閱job就不會再有報警,當然更穩妥的方式是刪除訂閱,因為刪除訂閱的時候會自動刪除訂閱job
40、always on AG 中搭建replication的限制
40.1、不支援本地分發伺服器。 例如,釋出伺服器和分發伺服器必須為不同的 SQL Server 例項。 這些例項可以託管在同一組節點上。 使用自身作為分發伺服器(也稱為 本地分發伺服器)的釋出伺服器無法支援 AG 中的分發資料庫。
40.2、託管分發資料庫副本的所有 SQL Server 2017 例項必須是 SQL Server 2017 CU 6 或更高版本。託管分發資料庫副本的所有 SQL Server 2016 例項必須是 SQL Server 2016 SP2-CU3 或更高版本。
40.3、在 AG 中設定分發資料庫需要是新的複製配置。 不支援將現有分發資料庫切換到 AG。 同樣,一旦將分發資料庫從 AG 中移除,它就不能再作為有效的分發資料庫執行,應該將其棄用。
41、同一個釋出下面有兩個訂閱,透過distribution.dbo.sp_replmonitorsubscriptionpendingcmds查到一個訂閱正常,一個訂閱很慢總是延遲的很嚴重,如何定位這個慢的訂閱
41.1、透過SSMS的圖形介面Tracer Tokens跟蹤令牌,插入跟蹤器來記錄資訊,檢視是釋出端到分發端慢還是分發端到訂閱端慢,不過這種同一個釋出下一個訂閱快一個訂閱慢的情況,一般都是分發端到訂閱端慢
41.2、可以從這個慢的訂閱伺服器本身的cpu、memory、disk等資源來定位,檢視訂閱伺服器是否有資源瓶頸
41.3、檢視這個分發伺服器和慢的訂閱伺服器之間的網路傳輸是否有瓶頸
42、Replication的結構,wondadb3-->dbprod131a-->idbmmsql
wondadb3:釋出端和分發端都是wondadb3,wondadb3是AG主節點,把wondadb3資料同步到了dbprod131a
dbprod131a:是wondadb3的訂閱端,又是ibdmmsql的釋出端,其中分發端是dbprod129,dbprod131a是AG主節點,dbprod129是單節點,把dbprod131a資料同步了ibdmmsql
idbmmsql:是dbprod131a的訂閱端,ibdmmsql是單節點
dbprod129:是釋出端dbprod131a-->訂閱端idbmmsql,此兩者的分發端
在dbprod131a中,新增發布使用圖形介面還是下面的語句,都有報錯
use [Wondb]
exec sp_addpublication @publication = N'Security', @description = N'Transactional publication of database ''Wondb'' from Publisher ''DBPROD82''.', @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
報錯:Cannot promote the transaction to a distributed transaction because there is an active save point in this transaction.
原因:是因為dbprod131a的引數 'remote proc trans'每10分鐘就會變成1,這樣的話我們就無法新增發布、修改釋出、在釋出下新增訂閱、重啟快照代理
解決方法:在dbprod131a上執行如下語句,當然執行後,只有10分鐘的操作時間,因為10分鐘後又會自動設定回去
EXEC sp_configure 'remote proc trans', 0
GO
RECONFIGURE
GO

43、一臺伺服器上有很多釋出,就某一個釋出對應的UndelivCmdsInDistDB出現很多沒有推送到訂閱端的命令,重新對這個釋出訂閱進行初始化後,發現這個釋出對應的UndelivCmdsInDistDB依舊,檢查了釋出端的快照代理對應的job和日誌讀取器代理對應的job都正常執行,訂閱型別是pull請求訂閱,瞭解到分發代理對應的job是存放在訂閱伺服器,查到該job失敗後一直沒執行,重新執行該分發代理對應的job,這個釋出對應的UndelivCmdsInDistDB很快變成了0






建立分發

複製-右鍵-配置分發

1、選擇分發伺服器

2、選擇snapshot目錄

3、建立分發資料庫(資料庫名稱預設為distribution、資料庫檔案目錄、資料庫日誌名稱)

4、選擇哪些釋出伺服器可以使用這個分發伺服器,enable servers to use this distributor when they become publishers,其中distribution database沒得選,就是分發的資料庫,預設是distribution

--如果上面第四步勾選了publisher和distribution database,右鍵Replicattion有Publisher Properties、Distributor Properties、Disabled Publishing and Distribution Wizard。如果不勾選,右鍵Replicattion則沒有Publisher Properties,有Distributor Properties、Disabled Publishing and Distribution Wizard

分發建立好後,有如下job

1、Agent history clean up: distribution

2、Distribution clean up: distribution

3、Expired subscription clean up

4、Monitor and sync replication agent jobs

5、Reinitialize subscriptions having data validation failures

6、Replication agents checkup

7、Replication monitoring refresher for distribution.



建立釋出

複製-本地釋出-右鍵-新建釋出


建立釋出1:還沒有分發時,建立釋出的同時建立分發(雖然沒有了上面"建立分發"的第3、4步,但是也預設建立了資料庫distribution)

右鍵local publications(本地釋出)--選擇new publication(新的釋出)

1、選擇分發伺服器

2、選擇snapshot目錄

3、選擇要釋出的資料庫

4、選擇釋出型別

5、選擇要釋出的物件,比如表、檢視、儲存過程

6、選擇snapshot代理,snapshot是立即建立還是定期建立,snapshot代理的安全性是使用使用者名稱密碼還是使用sqlserver agent服務,snapshot代理怎麼連線釋出伺服器,是OS域帳戶還是DB帳戶

7、建立釋出名稱

釋出建立好後,有如下job

1、Agent history clean up: distribution

2、Distribution clean up: distribution

3、Expired subscription clean up

4、Monitor and sync replication agent jobs

5、Reinitialize subscriptions having data validation failures

6、Replication agents checkup

7、Replication monitoring refresher for distribution.

8、WONCNTESTDB1-replicate1-1

9、WONCNTESTDB1-replicate1-pub_replicate1-1


建立釋出2:已經建立了分發時,只建立釋出

1、選擇要釋出的資料庫

2、選擇釋出型別

3、選擇要釋出的物件,比如表、檢視、儲存過程

4、選擇snapshot代理,snapshot是立即建立還是定期建立,snapshot代理的安全性是使用使用者名稱密碼還是使用sqlserver agent服務,snapshot代理怎麼連線釋出伺服器,是OS域帳戶還是DB帳戶

5、建立釋出名稱

釋出建立好後,有如下job

1、WONCNTESTDB1-replicate1-1

2、WONCNTESTDB1-replicate1-pub_replicate1-1



建立訂閱

1、選擇釋出伺服器,選擇釋出

2、選擇推送訂閱還是請求訂閱

3、選擇訂閱伺服器,選擇訂閱資料庫

4、選擇訂閱代理伺服器,分發代理使用怎麼連線,是OS域帳戶還是DB帳戶,分發伺服器使用怎麼連線,是OS域帳戶還是DB帳戶,訂閱伺服器使用怎麼連線,是OS域帳戶還是DB帳戶

5、訂閱同步是持續性還是按需求

6、是否馬上初始化訂閱物件

訂閱建立好後,有如下job,此job名稱的前半段和訂閱名稱一樣即WONCNTESTDB1-replicate1-pub_replicate1

WONCNTESTDB1-replicate1-pub_replicate1-WONCNTESTDB2-replicate_01-CD7A365E-2DE7-47A3-B31E-70F785FA71F2

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30126024/viewspace-2639648/,如需轉載,請註明出處,否則將追究法律責任。

相關文章