SQLServer數據庫的發佈訂閱讀寫分離主從複製對新增表的自動同步深究

此文背景、場景

此文背景:讀這篇文章的時候,假定您已經做了發佈訂閱的事了,但是在主庫中不斷的有新增的表產生,這時候新增的表不會自動同步到從庫中,我這裏主要解決這個問題的,在這裏不再探討如何從頭做SQLserver的發佈訂閱,如果您還不會如何做SQLserver發佈訂閱,可以移步網絡上其他文章。

SQLServer數據庫的主從複製時遇到的問題

最近搞SQLServer數據庫的主從複製時遇到一個問題,每個公司可能業務不一樣,對數據庫的架構也不一樣,我們公司的數據由於設備多,每臺設備每分鐘產生一條數據,數據庫採用的是每臺設備單獨生成一張表的數據,這樣一來在數據庫的讀寫分離的時候就遇到一個問題,因爲設備的增加不知道是什麼時候,設備增加了,會自動創建表,而做了發佈訂閱後,後來新增加的表,不會自動同步到從庫中,於是開始想解決方案。
在列出方案前,我先操作一下,發佈訂閱後手動新增表的操作

先說說發佈訂閱後手動新增表的操作

先回憶一下如果新增表時人工同步如何操作:
假如主庫中新增了一個表test06
右建發佈名->點擊屬性
sqlserver本地發佈
發佈屬性
在上面的發佈對象列中看不到新增的表test06 , 此時去掉勾選右側裏的 “僅顯示列表中已選中的項目”
點擊確定即可。
此時只是把這個表加入了發佈的隊列中,此時從庫中不會出現test06表,我們還要重新啓動一下複製監視器中的代理。
操作如下:

複製監視器
過一會兒,代理啓動完畢 100%時, 發現從庫中已經有了 test06了,這是手動去更新新增表的操作,如果你的業務中不經常新增表,那麼瞭解到此也已足夠了,然而,我的設備表是不定時的自動新增表的,就不能手動去同步了。這時候就得另一個解決方案了。

方案一、只同步主庫中的中間表,到了從庫在這張表上建立觸發器來分發到設備詳細表。

也就是說,在主庫中我建一箇中間表table1, 把所有設備發來的數據都存放在這個表中,使用設備ID來區分每臺設備的數據,從庫中只同步這個表table1即可,而在從庫中的table1表上建立觸發器,當新增數據的時候, 再分發到每臺設備的詳細表中。這樣不用操心發佈訂閱的新增表的問題了,可是後來想下這個方法解決了主從複製新增表的問題,但是新的問題又來了,在從庫中的觸發器中把數據insert 到每臺設備中,這很明顯對從數據庫來說又有寫入的操作了,本來做讀寫分離就是寫庫讀庫分離開,而現在又回到了從庫中有寫入的操作(且這個寫入操作很頻繁,每秒都會產生很多),所以不可取,還要繼續探究其他方案。

方案二、使用程序執行SQL語句來代替人工重新啓動複製監視器的代理。

在主庫中爲了能發現有新增設備表的情況 ,總得有一個地方可以監控到新增了設備表,要麼你使用存儲過程去輪循設備總表(就是記錄所有設備ID的一張表)和你記錄設備的表是不是有新增,要麼你使用其他方法,總之,要找到新增表的時刻。
我這裏使用的方案是 所有的設備數據過來後,都會入一張臨時表t1, 這張表中有觸發器再去建立設備詳細表,我就在此時下手腳了,在這個觸發器中判斷 如果有新增的設備時,執行如下語句 :

use Test --主庫
go

EXEC sp_addarticle @publication = N'test01',            --發佈名稱
                   @article = N'test06',                --新增的表名
                   @source_owner = N'dbo',
                   @source_object = N'test06',          --新增的表名
                   @type = N'logbased',
                   @description = NULL,
                   @creation_script = NULL,
                   @pre_creation_cmd = N'drop',
                   @schema_option = 0x000000000803509F,
                   @identityrangemanagementoption = N'manual',
                   @destination_table = N'test06',      --新增的表名
                   @destination_owner = N'dbo',
                   @vertical_partition = N'false', --是否要啓用篩選列,啓用時,刪除所有列,單獨配置相關列(必須包含主鍵列),不啓用時,自動添加所有列
                   @ins_cmd = N'CALL sp_MSins_dbo_test06', -- 觸發器命名規則,以新增的表名後輟
                   @del_cmd = N'CALL sp_MSdel_dbo_test06',
                   @upd_cmd = N'SCALL sp_MSupd_dbo_test06',
				   @force_invalidate_snapshot=1;
go
--重新啓動sqlserver中的複製監視器的代理
EXEC sys.sp_startpublication_snapshot @publication = N'test01' ; --發佈名稱
go

這樣就可以在新增表時,自動把新增的表同步到從庫中去了。

以下有關數據庫發佈訂閱的積累的問題也分享於此

一、主庫數據表中含有單引號‘ 引發的不同步的問題

主庫中一個字段內容中含有單引號’, 會導致從庫同步時出錯,解決方案,儘量使入庫的字段內容中不含有單引號,如含有,可進行轉義後再入庫。(也可能不是這個原因)

二、 主庫表會經常增加,新增表後如何操作?

新增表後,點擊分發服務器右鍵的屬性,點擊項目,勾選新增的表,點擊確定。再點擊查看複製監視器,點擊代理,重新啓動代理即可,此時,要注意一直跟蹤,直到數據真正正式同步纔可離開。

三、如何避免頻繁的新增表操作?

如果需要動態創建架構一樣的多個表,可使用一張中間表,數據都向這個中間表中插入,然後使用從庫中的中間表的觸發器在從庫中新建多個表。如你有 table01, table02,…等多個表,字段都一樣(有這種需求,分表操作),這時可以使用主庫中只建一張表,再向從庫中同步數據,然後這個從庫中的表建一個觸發器,使用這個觸發器來分發到多個數據表中。

四、如何根據事務序列號查找SQL語句?

use distribution
go
select * from
dbo.MSarticles m
where exists (select mc.article_id from MSrepl_commands mc where mc.xact_seqno=0x0000060700016FF6000D00000000 AND mc.article_id = m.article_id )

EXEC Sp_browsereplcmds
@xact_seqno_start='0x0000060700016FF6000D00000000',
@xact_seqno_end='0x0000060700016FF6000D00000000'

五、使用SQL Server發佈數據庫快照遇到錯誤:對路徑“xxxxx”訪問被拒絕的解決方法

開始-> 所有程序 -> SQL Server 配置管理器 -> 在左邊欄選擇”SQL Server服
務“->在右側面板中"SQL Server 代理”一行上右擊,選擇“屬性”,
在彈出的對話框中選擇"內置賬戶“->LocalSystem即可。

六、SQL Server 配置管理器不見了如何找到?

找到目錄:C:\Windows\SysWOW64,並且找到該目錄下的 SQLServerManager12.msc 文件,也有的是11文件,根據你安裝的版本不同而定。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章