iT邦幫忙

1

SQL SERVER 的 REPLICATION 搭配 PARTITION TABLE 執行 ALTER TABLE SWITCH 時的錯誤

  • 分享至 

  • xImage
  •  

如題探討以下重點 :

Q1 : 交易式複寫中 , 發行集內的Table若是Partition Table , 可以使用ALTER TABLE SWITCH語句將分區資料映射至具有相同資料表結構的目的表嗎?
A1 : 可以。

Q2 : 若已經建好的交易式複寫下的Table但沒有切PARTITION , 可以直接對這張表做PARTITION嗎?
A2 : 不可以。

Q3 : 若建立好的交易式複寫且底下Table也是Partition Table , 我對該表執行ALTER TABLE SWITCH語句後 , 訂閱端的資料表同時也會執行相同的指令嗎?
A3 : 可以做到 , 依照設定可選擇傳遞 OR 不傳遞。

著重討論如何啟用傳遞指令功能 , 對於如何建立複寫、Partition Table則簡單敘述帶過

資料庫架構 :

  1. 發行端
    1. DB Name : WORLD
    2. Table Name : PS、PS_TMP
  2. 訂閱端
    1. DB Name : WORLD_REPORTS
    2. Table Name : PS、PS_TMP

實作開始

1. 在發行與訂閱端的資料庫分別執行以下指令建立出PARTITION FUNCTION、PARTITION SCHEME , 以年度做資料分類。


CREATE PARTITION FUNCTION [Pfn_Int_Year](int) AS RANGE RIGHT FOR VALUES (20210101, 20220101, 20230101, 20240101, 20250101)
GO

CREATE PARTITION SCHEME [Psh_Int_Year] AS PARTITION [Pfn_Int_Year] TO ([PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY], [PRIMARY])
GO

2. 在發行與訂閱端的資料庫分別執行以下指令建立出範例資料表 , [dbo].[PS] 當作主要使用資料表 [dbo].[PS_TMP] 為之後要映射的目的資料表 , 以 Work_Year 當作年度欄位。

CREATE TABLE [dbo].[PS](
	[c1] [int] NOT NULL,
	[c2] [uniqueidentifier] NOT NULL,
	[Work_Year] [int] NOT NULL,
 CONSTRAINT [PK_PS] PRIMARY KEY CLUSTERED 
(
	[c1] ASC,
	[Work_Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Psh_Int_Year]([Work_Year])
) ON [Psh_Int_Year]([Work_Year])
GO

CREATE TABLE [dbo].[PS_TMP](
	[c1] [int] NOT NULL,
	[c2] [uniqueidentifier] NOT NULL,
	[Work_Year] [int] NOT NULL,
 CONSTRAINT [PK_PS_TMP] PRIMARY KEY CLUSTERED 
(
	[c1] ASC,
	[Work_Year] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Psh_Int_Year]([Work_Year])
) ON [Psh_Int_Year]([Work_Year])
GO

3. 每個年度各寫入2筆測試資料 , 至於要同時寫進發行與訂閱或是只寫進發行端的資料庫 , 看各位後續同步複寫設定是僅同步連結或是套用快照 , 後續複寫建的出來兩端資料一樣即可。

INSERT INTO [dbo].[PS] VALUES (1, NEWID(), 20210101)
INSERT INTO [dbo].[PS] VALUES (2, NEWID(), 20211231)

INSERT INTO [dbo].[PS] VALUES (3, NEWID(), 20220101)
INSERT INTO [dbo].[PS] VALUES (4, NEWID(), 20221231)

INSERT INTO [dbo].[PS] VALUES (5, NEWID(), 20230101)
INSERT INTO [dbo].[PS] VALUES (6, NEWID(), 20231231)

INSERT INTO [dbo].[PS] VALUES (7, NEWID(), 20240101)
INSERT INTO [dbo].[PS] VALUES (8, NEWID(), 20241231)

INSERT INTO [dbo].[PS] VALUES (9, NEWID(), 20250101)
INSERT INTO [dbo].[PS] VALUES (10, NEWID(), 20251231)

4. 建立出 PS 這張表的交易式複寫 , 使用 PUSH 或 PULL 不影響本篇內容 , 發行集名稱與表同名為 PS 。

https://ithelp.ithome.com.tw/upload/images/20250604/20169860u2o9Keah6q.png

5. 執行 ALTER TABLE ... SWITCH 指令 , 把2021年度的資料從 [dbo].[PS] 映射至 [dbo].[PS_TMP] , 見紅字了 , 奇怪上述提問 Q1 不是說可以執行嗎?

ALTER TABLE [dbo].[PS] SWITCH PARTITION $PARTITION.[Pfn_Int_Year](20210101)
TO [dbo].[PS_TMP] PARTITION $PARTITION.[Pfn_Int_Year](20210101)

https://ithelp.ithome.com.tw/upload/images/20250604/20169860apJQca0JRd.png

6. 本篇重點在下圖 , 在發行資料庫執行該sp , 帶入 allow_partition_switch 參數可以允許該發行集內的 TABLE 執行 ALTER TABLE ... SWITCH , 注意對象是發行集哦 , 這個sp適合使用的時機用在已經建立好複寫情況下去啟用設定 ,
參考該連結還可以看見其實在建立複寫時就可以啟用該功能 , 只是一般管理者遇到情況時都已經是在建立好的情況下 , 所以本篇才介紹如何使用這支sp。

https://learn.microsoft.com/zh-tw/sql/relational-databases/replication/publish/replicate-partitioned-tables-and-indexes?view=sql-server-ver16

https://ithelp.ithome.com.tw/upload/images/20250604/20169860Rtaqj7Yuwh.png

7. 光是允許 SWITCH 可能還不夠 , 某些管理者或許覺得我連 ALTER TABLE ... SWITCH 這個指令都要一併傳遞到訂閱端 , 讓訂閱端的 TABLE 也同時執行 ALTER TABLE ... SWITCH 我才爽 , 這時你還可以執行以下的sp , 這次把參數替換成 replicate_partition_switch , 這就回應了上述的 Q3。

https://ithelp.ithome.com.tw/upload/images/20250604/20169860zp2Tz9qlCe.png

8. 設定好以上2個有關複寫 SWITCH 的相關設定後 , 試著在發行端再 SWITCH 一次 , 後續檢查發行與訂閱的資料結果都有在預期內 , 非常好。

ALTER TABLE [dbo].[PS] SWITCH PARTITION $PARTITION.[Pfn_Int_Year](20210101)
TO [dbo].[PS_TMP] PARTITION $PARTITION.[Pfn_Int_Year](20210101)

https://ithelp.ithome.com.tw/upload/images/20250604/2016986046414S3LFM.png

結論 :

反應快的各位已經想到 , 複寫指令就算不同步到訂閱端也無所謂呀 , 我在訂閱端自行執行 SWITCH 也可以 , 這個答案無疑是沒有錯的 , 管理到企業級別資料庫的DBA身懷絕技 , 至於Q2有沒有繞道而行的方法也絕對是有的 , 若有興趣的各位可以試試看這一題 , 敲碗我再另外寫一篇回應 Q2 , 若有錯誤請直接糾正。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言