File Group Association while Snapshop Replication
-
15-01-2021 - |
해결책
The information text in the description of the item property provides you with the solution to your question:
(emphasis mine)
Copy file group associations
Determines whether to script the associations between file groups and published objects. The file groups must already exist at the Subscriber.
If the file groups don't exist at the Subscriber and you set the option Copy file group associations to True, then the replication will fail, because it will expect the Subscriber to have identical file groups. All transferred objects will be transferred with an additional ...filegroup...
parameter, depending on the object that has to be transferred.
If this option is set to false then the objects will be transferred without an additional ...filegroup...
parameter, depending on the object being transferred. The replication will succeed, even if the Subscriber has different file groups, because the objects will be replicated to the default file group.
Proving It
I created a StackExchange database with the following files and file groups and added a new file group for this question:
CREATE DATABASE [StackExchange] CONTAINMENT = NONE ON PRIMARY ( NAME = N'StackExchange', FILENAME = N'C:\SQL\SQL_DATA\StackExchange.mdf' , SIZE = 56320KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), FILEGROUP [DEFAULTRO] ( NAME = N'StackExchange_DefRO', FILENAME = N'C:\SQL\SQL_DATA\StackExchangeRO.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ), FILEGROUP [PUBL_SNAP_DBASE] DEFAULT ( NAME = N'StackExchange_PUBL_SNAP', FILENAME = N'C:\SQL\SQL_DATA\StackExchange_PUBL_SNAP.ndf' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'StackExchange_log', FILENAME = N'C:\SQL\SQL_LOGS\StackExchange_log.ldf' , SIZE = 112384KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO
This database already contains various tables and stored procedures from answering previous questions on DBA.SE. They were created in the PRIMARY
file group. Here an extract:
Input
SELECT DS.name AS DataSpaceName ,AU.type_desc AS AllocationDesc ,AU.total_pages / 128 AS TotalSizeMB ,AU.used_pages / 128 AS UsedSizeMB ,AU.data_pages / 128 AS DataSizeMB ,SCH.name AS SchemaName ,OBJ.type_desc AS ObjectType ,OBJ.name AS ObjectName ---,IDX.type_desc AS IndexType ---,IDX.name AS IndexName FROM sys.data_spaces AS DS INNER JOIN sys.allocation_units AS AU ON DS.data_space_id = AU.data_space_id INNER JOIN sys.partitions AS PA ON (AU.type IN (1, 3) AND AU.container_id = PA.hobt_id) OR (AU.type = 2 AND AU.container_id = PA.partition_id) INNER JOIN sys.objects AS OBJ ON PA.object_id = OBJ.object_id INNER JOIN sys.schemas AS SCH ON OBJ.schema_id = SCH.schema_id ---LEFT JOIN sys.indexes AS IDX ----ON PA.object_id = IDX.object_id ----AND PA.index_id = IDX.index_id WHERE OBJ.type = 'U' AND OBJ.type_desc = 'USER_TABLE' AND OBJ.name LIKE 'Q%' ORDER BY DS.name ,SCH.name ,OBJ.name --,IDX.name
Output
+---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+ | DataSpaceName | AllocationDesc | TotalSizeMB | UsedSizeMB | DataSizeMB | SchemaName | ObjectType | ObjectName | +---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+ | DEFAULTRO | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196719_Filegroup_2 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q117478_Encryption_Provider | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q153379_TestTable | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_Customer | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_DVD | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_DVD_Purchase | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q190497_Stats_Hash | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196570_Unicode | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196719_Filegroup_2 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q206094_shift | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar_collation | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar_collation_ws | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Qxxxxx_Join_Question_1 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Qxxxxx_Join_Question_2 | +---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+
Observations
As you can see all my tables related to questions on DBA.SE have been created in the PRIMARY
filegroup. (Ok, nearly all of them.)
If I were to create a new table, then it would be created in the DEFAULT
file group, which is no longer PRIMARY
but the one named [PUBL_SNAP_DBASE]
.
Snapshot Replication
I have created a snapshot replication on my local machine which will replicate any changes from the StackExchange
database to the StackExchangeSubscriber
database.
The settings for the All Tables Properties - Copy file group associations has been set to TRUE
, which should result in an error in the replication.
The Subscriber Database
CREATE DATABASE [StackExchangeSubscriber] CONTAINMENT = NONE ON PRIMARY ( NAME = N'StackExchangeSubscriber', FILENAME = N'C:\SQL\SQL_DATA\StackExchangeSubscriber.mdf' , SIZE = 56320KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = N'StackExchangeSubscriber_log', FILENAME = N'C:\SQL\SQL_LOGS\StackExchangeSubscriber_log.ldf' , SIZE = 112384KB , MAXSIZE = 2048GB , FILEGROWTH = 10%) GO
The subscriber database doesn't have the [DEFAULTRO]
file group, nor does it contain the newly created [PUBL_SNAP_DBASE]
one.
Verifying the Replication Status
Everything looks good. Let's continue with a modification...
Modifying the Published Database
Let's go ahead and create a new table in the published database StackExchange
using DDL. First we'll check the objects in the target/subscriber database with the same script from above.
Output
+---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+ | DataSpaceName | AllocationDesc | TotalSizeMB | UsedSizeMB | DataSizeMB | SchemaName | ObjectType | ObjectName | +---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+ | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q117478_Encryption_Provider | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q153379_TestTable | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_Customer | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_DVD | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_DVD_Purchase | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q190497_Stats_Hash | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196570_Unicode | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196719_Filegroup_2 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q206094_shift | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar_collation | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar_collation_ws | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Qxxxxx_Join_Question_1 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Qxxxxx_Join_Question_2 | +---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+
Looks the same except for the object that was created in the [DEFAULTRO]
file group, which wasn't replicated. Hmmm. I think that is a hint of things to come.
Create Table via DDL
USE StackExchange
GO
CREATE TABLE Q221890 (Q221890_ID INT, Q221890_Text VARCHAR(20))
I didn't define the file group, so it should be created in the current DEFAULT file group, which is? Exactly.
+-----------------+----------------+-------------+------------+------------+------------+------------+------------+ | DataSpaceName | AllocationDesc | TotalSizeMB | UsedSizeMB | DataSizeMB | SchemaName | ObjectType | ObjectName | +-----------------+----------------+-------------+------------+------------+------------+------------+------------+ | PUBL_SNAP_DBASE | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q221890 | +-----------------+----------------+-------------+------------+------------+------------+------------+------------+
I did not define the file group which means the table will be created in the newly defined
[PUBL_SNAP_DBASE]
file group, because it is the new default.The replication will not replicate the new table, because of the Copy file group associations setting of True in the All Tables Properties.
Insert Data
USE [StackExchange] GO INSERT INTO [dbo].[Q221890] ([Q221890_ID] ,[Q221890_Text]) VALUES (1 ,'Test') GO
Check Data
+------------+--------------+ | Q221890_ID | Q221890_Text | +------------+--------------+ | 1 | Test | +------------+--------------+
Checking StackExchangeSubscriber Database in Replication Monitor
As can be seen in the monitor error message, the new object is created with the reference to the non-existing file group [PUBL_SNAP_DBASE]
which causes an error at the subscriber.
Turn Off the Setting and Retry
We'll turn of the file group setting Copy file group associations and re-initialize the snapshot replication. Let's check the list of objects with the script:
+---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+ | DataSpaceName | AllocationDesc | TotalSizeMB | UsedSizeMB | DataSizeMB | SchemaName | ObjectType | ObjectName | +---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+ | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q117478_Encryption_Provider | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q153379_TestTable | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_Customer | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_DVD | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q184469_DVD_Purchase | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q190497_Stats_Hash | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196570_Unicode | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q196719_Filegroup_2 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q206094_shift | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar_collation | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q214251_nvarchar_collation_ws | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Q221890 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Qxxxxx_Join_Question_1 | | PRIMARY | IN_ROW_DATA | 0 | 0 | 0 | dbo | USER_TABLE | Qxxxxx_Join_Question_2 | +---------------+----------------+-------------+------------+------------+------------+------------+-------------------------------+
Yes, the new table in the file group has been replicated.
Answering Your Question
I want to know how can I save filegroup structure during snapshot replication in SQL Server?
You can't. (See answer further down)
Does this property solve my problem?
No, which was proved with the above procedure
I want the same filegroups in publishers be created in the subscriber.
You will have to create the file groups at the target/subscriber before you create the objects in those file groups.
Turning on the option will cause errors, if the file groups do not exist.