Chỉnh sửa chính
Đây là bản viết lại hoàn chỉnh của câu trả lời này (đưa ra lời chỉ trích hợp lệ rằng phiên bản trước dễ bị lỗi và sẽ gây ra sự cố)
Đồng thời đăng một bản demo về cách áp dụng điều này vào: Youtube - Sao chép máy chủ SQL: Cách thêm một bài viết mà không cần chụp nhanh .
QUAN TRỌNG: Đây KHÔNG phải là cách tiếp cận được đề xuất từ Microsoft, vì vậy bạn sẽ tự mình liên quan đến việc làm cho nó hoạt động, KHÔNG áp dụng trực tiếp vào môi trường sản xuất của bạn mà không có thử nghiệm tách biệt đáng kể và làm cho bạn thoải mái với các bước!
Các bước để làm theo:
Planning steps:
* Choose Publication that article will be added to
* Gather information about the publication
exec sp_helppublication '[Name of Publication]'
https://msdn.microsoft.com/en-us/library/ms189782(v=sql.105).aspx
- replication frequency = 0 - this is Transactional replication (THIS IS A REQUIREMENT FOR THIS METHOD)
- replicate_ddl = 1 - means ALTER TABLES will apply SQL Server generated repl procs
- independent_agent = 1 - means that you will only affect tables in this publication when deploying
* Identify which subscribers are going to be affected
Pre-deployment steps (can be done at any time)
1. Create table on subscribers
2. Create custom replication procs on subscribers
(Customisation will ignore if the IUD has already been applied to subscriber - because you have manually sync'd the data)
Deployment/Potential impact:
3. Stop Distribution Agents to all subscribers for this publication
4. Add article to publication on publisher
5. Sync data from publisher to subscriber
6. Start Distribution Agents to all subscribers for this publication
7. Monitor/Verify all data has arrived
Optional follow on:
8. Apply standard repl procs (removing if not exists checks)
This is optional as the generated repl scripts should be fine for the most part
Note: When ALTER table scripts are applied on the Publisher (when replicate_ddl = 1) repl procs will automatically be recreated by the Distribution Agent (so any customisation will be lost)
Để xác minh:
- thực hiện chèn vào nhà xuất bản - xác minh hàng đến trên thuê bao
- thực hiện cập nhật trên nhà xuất bản - xác minh thay đổi đến trên thuê bao
- thực hiện xóa trên nhà xuất bản - xác minh hàng đã xóa trên thuê bao
- xác minh rằng n hàng cuối cùng đã đến và khớp giữa nhà xuất bản và người đăng ký
VÍ DỤ Quy trình
A) Tạo cho mình một bảng trên nhà xuất bản của bạn:
/* Deliberately applying IDENTITY, DEFAULT & INDEX to demonstrate usage on subscriber */
CREATE TABLE [dbo].[TableNotUsingSnap](
[Id] [int] NOT NULL IDENTITY(1,1),
[Note_Text] [varchar](4096) NOT NULL,
[CreatedDate] [datetime] NULL,
[LoggedDate] [datetime] NOT NULL CONSTRAINT DF_TableNotUsingSnap_LoggedDate DEFAUlT GETUTCDATE(),
CONSTRAINT [PK_TableNotUsingSnap] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IDX_NC_TableNotUsingSnap_LoggedDate] ON [dbo].[TableNotUsingSnap]
(
[LoggedDate] ASC
) INCLUDE ([Note_Text])
GO
B) Tạo cho mình một công việc / Proc / script để thực hiện một số thao tác chèn / cập nhật / xóa trên [TableNotUsingSnap] (sau đó bạn có thể sử dụng điều này để xác thực cách thức thuê bao được đồng bộ hóa chính xác bằng phương pháp này.
Bước trước:
1. Tạo bảng của bạn trên thuê bao
/* example script to add a table to a publication without running the snapshot agent
Steps:
Pre steps:
1. Create table on subscribers
2. Create replication procs on subscribers
Deployment/Potential impact:
3. Stop Distribution Agents to all subscribers for this publication
4. Add article to publication on publisher
5. DTS data from publisher to subscriber
6. Start Distribution Agents to all subscribers for this publication
7. Monitor/Verify all data has arrived
=========================================================
Notes:
* Drop unnecessary FK's, Indexes
* Do NOT have IDENTITY(1,1), DEFAULTS
* Do have a Clustered PK
* Create appropriate indexes for your subscribers use case */
-- RUN ON SUBSCRIBER
IF OBJECT_ID('dbo.TableNotUsingSnap') IS NOT NULL
exec sp_rename 'dbo.TableNotUsingSnap', 'TableNotUsingSnap_20170127'
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[TableNotUsingSnap](
[Id] [int] NOT NULL,
[Note_Text] [varchar](4096) NOT NULL,
[CreatedDate] [datetime] NULL,
[LoggedDate] [datetime] NOT NULL,
CONSTRAINT [PK_TableNotUsingSnap] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
2. Tạo các thủ tục lưu trữ sao chép của bạn (cập nhật / chèn / xóa) - trên Người đăng ký
Bạn có thể tạo procs thay thế:
- Thủ công (hãy cẩn thận vì rất dễ phạm sai lầm!)
- Thêm bài viết bằng phương pháp Chụp nhanh MS trên máy Dev và tắt đoạn mã thay thế (sẵn sàng để bạn thêm các chỉnh sửa của mình)
- Tạo / Tìm một số loại máy phát điện
Thay đổi bạn sẽ cần phải áp dụng:
- sp_MSins_ [Schema] [TableName] - Thêm vào
IF NOT EXISTS (SELECT 'row already exists' FROM [Schema].[TableName] dest WITH (NOLOCK) WHERE dest.Id = @c1)
để không chèn nếu nó đã có
- sp_MSupd_ [Lược đồ] [Tên bảng] - Nhận xét việc
IF @@rowcount = 0 ... exec sp_MSreplraiserror ...
bỏ qua bản cập nhật không được áp dụng (vì bản ghi có thể đã bị xóa trên nhà xuất bản trước khi bạn đồng bộ hóa dữ liệu)
- sp_MSdel_ [Schema] [TableName] - Nhận xét việc
IF @@rowcount = 0 ... exec sp_MSreplraiserror ...
bỏ qua việc xóa không được áp dụng (vì bản ghi có thể đã bị xóa trên nhà xuất bản trước khi bạn đồng bộ hóa dữ liệu)
sp_MSins_dboTableNotUsingSnap:
/* Customised Replication insert proc utilized to support adding to replication without a snapshot. */
create procedure [dbo].[sp_MSins_dboTableNotUsingSnap]
@c1 int,
@c2 varchar(4096),
@c3 datetime
AS
BEGIN
IF NOT EXISTS (SELECT 'row already exists' FROM [dbo].[TableNotUsingSnap] dest WITH (NOLOCK) WHERE dest.Id = @c1)
BEGIN
insert into [dbo].[TableNotUsingSnap]
([Id],
[Note_Text],
[Repl_Upsert_UTC])
values
(@c1,
@c2,
@c3)
END
END
GO
sp_MSupd_dboTableNotUsingSnap:
/* Customised Replication insert proc utilized to support adding to replication without a snapshot. */
create procedure [dbo].[sp_MSupd_dboTableNotUsingSnap]
@c1 int = NULL,
@c2 varchar(4096) = NULL,
@c3 datetime = NULL,
@pkc1 int = NULL,
@bitmap binary(1)
AS
BEGIN
declare @primarykey_text nvarchar(100) = ''
if (substring(@bitmap,1,1) & 1 = 1)
begin
update [dbo].[TableNotUsingSnap]
set [Id] = case substring(@bitmap,1,1) & 1 when 1 then @c1 else [Id] end,
[Note_Text] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [Note_Text] end,
[Repl_Upsert_UTC] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [Repl_Upsert_UTC] END
WHERE [Id] = @pkc1
/* Commented out while adding to publication
if @@rowcount = 0
if @@microsoftversion>0x07320000
Begin
set @primarykey_text = @primarykey_text + '[id] = ' + convert(nvarchar(100),@pkc1,1)
exec sp_MSreplraiserror @errorid=20598, @param1=N'[dbo].[TableNotUsingSnap]', @param2=@primarykey_text, @param3=13233
End */
END
ELSE
BEGIN
update [dbo].[TableNotUsingSnap]
set [Note_Text] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [Note_Text] end,
[Repl_Upsert_UTC] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [Repl_Upsert_UTC] END
WHERE [Id] = @pkc1
/* Commented out while adding to publication
if @@rowcount = 0
if @@microsoftversion>0x07320000
Begin
set @primarykey_text = @primarykey_text + '[id] = ' + convert(nvarchar(100),@pkc1,1)
exec sp_MSreplraiserror @errorid=20598, @param1=N'[dbo].[TableNotUsingSnap]', @param2=@primarykey_text, @param3=13233
End */
end
END
GO
sp_MSdel_dboTableNotUsingSnap:
/* Customised Replication insert proc utilized to support adding to replication without a snapshot. */
create procedure [dbo].[sp_MSdel_dboTableNotUsingSnap]
@pkc1 int
as
begin
declare @primarykey_text nvarchar(100) = ''
delete [dbo].[TableNotUsingSnap]
where [Id] = @pkc1
/* ignore if the record doesn't exist when deleting it
if @@rowcount = 0
if @@microsoftversion>0x07320000
Begin
set @primarykey_text = @primarykey_text + '[Id] = ' + convert(nvarchar(100),@pkc1,1)
exec sp_MSreplraiserror @errorid=20598, @param1=N'[dbo].[TableNotUsingSnap]', @param2=@primarykey_text, @param3=13234
End */
end
GO
CÁC BƯỚC TIỀN GỬI
3. Dừng đại lý phân phối - Trên Nhà phân phối (Đẩy) hoặc Thuê bao (Kéo)
/* example script to add a table to a publication without running the snapshot agent
Steps:
Pre steps:
1. Create table on subscribers
2. Create replication procs on subscribers
Deployment/Potential impact:
** 3. Stop Distribution Agents to all subscribers for this publication
4. Add article to publication on publisher
5. DTS data from publisher to subscriber
6. Start Distribution Agents to all subscribers for this publication
7. Monitor/Verify all data has arrived
=========================================================
Note: check your publication settings:
if @independent_agent = N'false'
you will need to stop the distribution agent which will affect ALL
publications going to that subscriber
if @independent_agent = N'true'
you will need to stop the publication specific distribution agent
(to each subscriber)
Plan your live release around that knowledge!
*/
-- IF PUSH REPLICATION: RUN ON DISTRIBUTION SERVER
-- IF PULL REPLICATION: RUN ON SUBSCRIBER SERVER
/* disable the Job first */
exec msdb..sp_update_job @job_name = '[Distribution agent job]', @enabled = 0
GO
/* wait for 10 seconds - precaution ONLY */
WAITFOR DELAY '00:00:10.000'
GO
/* now stop the job */
exec msdb..sp_stop_job @job_name = '[Distribution agent job]'
GO
/*
NOTE: You might recieve an error about stopping a job that is already stopped. You can ignore that error.
It is up to you to verify that the job has been stopped correctly!
*/
4. Bây giờ thêm bài viết vào ấn phẩm - Trên Nhà xuất bản
Các thông số quan trọng:
sp_addarticle
- @pre_creation_cmd = N'none'
được sử dụng để báo cho tác nhân phân phối không thả và tạo các đối tượng của chính nó
sp_addsubscription
- @sync_type = N'none'
được sử dụng để nói với Distributer rằng nó không cần tạo ảnh chụp nhanh mới, nó chỉ có thể xếp hàng các lệnh IUD lên
sp_addarticle:
exec sp_addarticle
@publication = N'Publication Name',
@article = N'TableNotUsingSnap',
@source_owner = N'dbo',
@source_object = N'TableNotUsingSnap',
@type = N'logbased',
@description = N'',
@creation_script = N'',
@pre_creation_cmd = N'none', /* this is a critical flag - tells SQL Server to not drop/recreate the repl procs/object on the subscriber */
@schema_option = 0x0000000008004093,
@identityrangemanagementoption = N'none',
@destination_table = N'TableNotUsingSnap',
@destination_owner = N'dbo',
@status = 16,
@vertical_partition = N'false',
@ins_cmd = N'CALL [sp_MSins_dboTableNotUsingSnap]',
@del_cmd = N'CALL [sp_MSdel_dboTableNotUsingSnap]',
@upd_cmd = N'SCALL [sp_MSupd_dboTableNotUsingSnap]'
GO
-- Adding the transactional subscriptions
exec sp_addsubscription @publication = N'Publication Name',
@subscriber = N'Subscriber Server',
@destination_db = N'Subscriber DB',
@subscription_type = N'Push',
@sync_type = N'none', /* tell SQL Server not to sync/snapshot this change to the publication */
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0
GO
5. Đồng bộ hóa dữ liệu của bạn trên
Bây giờ bạn cần sao chép dữ liệu của mình sang thuê bao của mình, bạn có thể:
- Tạo một Máy chủ được liên kết và sao chép nó qua
- Sử dụng thuật sĩ xuất / nhập
- Khôi phục bản sao lưu và áp dụng khác
- Trích xuất bảng bằng cách sử dụng SSMS Toolpack 'Tạo câu lệnh chèn ...'
Phương pháp chính xác mà bạn sử dụng tôi để lại cho người đọc, nó cũng sẽ phụ thuộc vào thời gian bạn sẵn sàng để Đại lý phân phối của bạn dừng lại trong bao lâu.
EXTRA: Là một bước được thêm vào trong các thử nghiệm của bạn, đây là một điểm tốt để chạy tập lệnh của bạn (từ Bước (B)) để tạo các hành động IUD trên [TableNotUsingSnap] để bạn có thể tin tưởng vào phương pháp này.
6. Khởi động lại đại lý phân phối - Trên Nhà phân phối (Đẩy) hoặc Thuê bao (Kéo)
/* example script to add a table to a publication without running the snapshot agent
Steps:
Pre steps:
1. Create table on subscribers
2. Create replication procs on subscribers
Deployment/Potential impact:
3. Stop Distribution Agents to all subscribers for this publication
4. Add article to publication on publisher
5. DTS data from publisher to subscriber
** 6. Start Distribution Agents to all subscribers for this publication
7. Monitor/Verify all data has arrived
=========================================================
Note: check your publication settings:
if @independent_agent = N'false'
you will need to stop the distribution agent which will affect ALL
publications going to that subscriber
if @independent_agent = N'true'
you will need to stop the publication specific distribution agent
(to each subscriber)
Plan your live release around that knowledge!
*/
-- IF PUSH REPLICATION: RUN ON DISTRIBUTION SERVER
-- IF PULL REPLICATION: RUN ON SUBSCRIBER SERVER
/* disable the Job first */
exec msdb..sp_update_job @job_name = 'Distribution agent job', @enabled = 1
GO
/* wait for 10 seconds - precaution ONLY */
WAITFOR DELAY '00:00:10.000'
GO
/* now stop the job */
exec msdb..sp_start_job @job_name = 'Distribution agent job'
GO
/*
Now go and make sure everything is working ok!
*/