通过备份初始化合并复制时的报错的解决 (转载)
由于关系数据库的机制要求合并复制数据同步时需要有良好的自治性,SQL Server的合并复制的应用场景相对比较少。一些典型的应用场景比如异地数据同步,跨洋的数据同步等。由于网络延时以及该种业务有相对比较大的数据独立性,因此在合并复制在某些场景会比较合适。
在一些情况下,合并复制如果由于某些原因坏掉,需要重新初始化,而由于网络带宽的限制,用快照重新初始化稍微大一点的库基本不现实,因此需要考虑使用通过备份初始化,在初始化过程中,我遇到了如下错误:
{call sp_MSsetconflicttable (N'__UserSyncOptions', N'MSmerge_conflict_Main___UserSyncOptions', N'DB\MAIN', N'DB1', N'Main')} Incorrect syntax near 'Id'.
后来通过排查发现,疏忽了关键步骤,因此在此写下从备份初始化合并复制的正确姿势:
1.为需要合并复制的表添加唯一的RowGuid列(如果表中没有RowGuid列,在建立发布端时,合并复制会自动给表创建一个RowGuid列),该列是合并复制用于确认行的唯一依据,因此该列有如下要求:
- 有唯一约束
- 有唯一索引
- 有GUID的默认值Newid()或newsequentialid()
- 该列Not Null
- 这里顺便说一下,合并复制中,Replication实际上不是用表的主键来做发布端和订阅端的数据同步的,而是用的发布端和订阅端每一张表的RowGuid列来进行数据同步的,因为试想一下如果数据库中有的表没有主键,那对于这些表,合并复制怎么做发布端和订阅端的数据同步呢,所以这就是为什么合并复制会在发布端和订阅端的表上都生成一个RowGuid列的原因,它是发布端和订阅端数据同步的关键。
该列的添加脚本为:
BEGIN TRANSACTION SET QUOTED_IDENTIFIER ON SET ARITHABORT ON SET NUMERIC_ROUNDABORT OFF SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON COMMIT BEGIN TRANSACTION GO ALTER TABLE 表名称 ADD ROWGUID uniqueidentifier NOT NULL ROWGUIDCOL CONSTRAINT MSmerge_df_rowguid_ DEFAULT (newid()) GO ALTER TABLE 表名称 SET (LOCK_ESCALATION = TABLE) GO COMMIT
2. 备份需要初始化的数据库。 (在此期间,请不要备份日志,以防日志链断裂!)
3. 创建发布,并手动生成发布的快照。该步骤十分重要,虽然订阅服务器不需要快照初始化订阅,但是需要快照的元数据!
4. 在订阅端还原数据库备份。注意,不能指定KEEP_REPLICATION选项。
5. 创建订阅,选项请指定不立即初始化,如果是脚本创建订阅,请指定:@sync_type = N'None'
6. 手动启动合并代理,以便从发布端同步元数据。至此整个过程完成。