Q1 : 交易式複寫中 , 發行集內的Table若是Partition Table , 可以使用ALTER TABLE SWITCH語句將分區資料映射至具有相同資料表結構的目的表嗎?
A1 : 可以。
Q2 : 若已經建好的交易式複寫下的Table但沒有切PARTITION , 可以直接對這張表做PARTITION嗎?
A2 : 不可以。
Q3 : 若建立好的交易式複寫且底下Table也是Partition Table , 我對該表執行ALTER TABLE SWITCH語句後 , 訂閱端的資料表同時也會執行相同的指令嗎?
A3 : 可以做到 , 依照設定可選擇傳遞 OR 不傳遞。
資料庫架構 :
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 。
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)
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
7. 光是允許 SWITCH 可能還不夠 , 某些管理者或許覺得我連 ALTER TABLE ... SWITCH 這個指令都要一併傳遞到訂閱端 , 讓訂閱端的 TABLE 也同時執行 ALTER TABLE ... SWITCH 我才爽 , 這時你還可以執行以下的sp , 這次把參數替換成 replicate_partition_switch , 這就回應了上述的 Q3。
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)
反應快的各位已經想到 , 複寫指令就算不同步到訂閱端也無所謂呀 , 我在訂閱端自行執行 SWITCH 也可以 , 這個答案無疑是沒有錯的 , 管理到企業級別資料庫的DBA身懷絕技 , 至於Q2有沒有繞道而行的方法也絕對是有的 , 若有興趣的各位可以試試看這一題 , 敲碗我再另外寫一篇回應 Q2 , 若有錯誤請直接糾正。