AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 45600
Accepted
Jez
Jez
Asked: 2013-07-03 04:07:35 +0800 CST2013-07-03 04:07:35 +0800 CST 2013-07-03 04:07:35 +0800 CST

处理事务复制的身份范围

  • 772

我注意到,当您设置事务复制时,SQL Server 会将身份范围管理设置为手动。这意味着在我的订阅数据库中,当我尝试将新记录插入其 PK 是标识列的表中时,它会给我一个错误并说它试图插入一个 PK 为“1”、“2 "、"3" 等。这是因为订阅者上所有身份列的当前身份值都被重置为种子值(通常为 1),而不是保持在发布者上的值。

我理解 SQL Server 这样做的原因——您应该将订阅者表保留为只读。但是,我的情况有点不正统 - 我不时通过复制更新我的订阅者,立即备份该数据库,然后我想对订阅者进行一些不会被推回发布者的更新,然后当我再次更新订阅者时,我从早期的备份中恢复其数据库并提取最新更新。因为我想在这些更新之间对订阅者进行更新(“临时增量”,如果你愿意的话),我需要标识列正常工作,而不是在复制时重置为 1。

我在设置我的出版物时尝试打开自动身份范围管理,但是当我尝试向出版物添加表时,这只会给我以下错误:

消息 21231,级别 16,状态 1,过程 sp_MSrepl_addarticle,第 2243 行
自动标识范围支持仅对允许更新订阅者的发布有用。

有什么办法可以解决这个问题吗?我确实希望将此复制呈现给 SQL Server,就好像它在订阅者端是只读的一样,因为我不打算进行将推送回发布者的更新,但我确实想做临时更新将在下一次复制之前被删除。

对于我的使用模式,我还认为快照复制可能比事务复制更合适,但问题是快照复制需要在每次更新时发送整个该死的数据库;因为我计划在最近一次复制后立即备份数据库,所以我不需要每次都进行整个传输;只是自上次以来的变化。

sql-server sql-server-2008-r2
  • 3 3 个回答
  • 4585 Views

3 个回答

  • Voted
  1. Liam Confrey
    2013-07-04T05:09:20+08:002013-07-04T05:09:20+08:00

    假设您的发布者使用从 1 开始的 int 标识,您可以 DBCC CHECKIDENT('dbo.mytable', RESEED, -2147483648) 在订阅者处发布。然后,您可以使用从 -2147483648 到 0 的范围来保存“临时增量”。

    • 3
  2. Best Answer
    Jez
    2013-07-09T06:22:47+08:002013-07-09T06:22:47+08:00

    我最终做的是坚持基于拉的事务复制,并让我的程序在同步后立即更新订阅者身份值,使其与发布数据库上的值相同(我希望分发代理自行执行)。在伪代码中,它看起来有点像这样:

    synchronize databases with TransSynchronizationAgent
    
    equivalentTablesNotFound is a list of strings
    for each table in publisher tables:
        try:
            check table identity value (this is via functionality provided by .NET's Microsoft.SqlServer.Management.Smo.Server class)
            parse identity value as integer to newIdentity
            if the table's identity value was NULL, skip to next loop iteration
            (HACK) increment newIdentity value by 1
            if there is no subscriber table with the same name as this one:
                record its name in equivalentTablesNotFound and skip to next loop iteration
            set subscriber table with same name's identity value to newIdentity using TSQL: DBCC CHECKIDENT ("tableName", newIdentity)
        catch:
            if exception shows that the error was because the table doesn't have an identity column, drop the exception
    
    if equivalentTablesNotFound has more than zero entries, warn about tables on publisher without an equivalent name on subscriber
    

    似乎工作正常。HACK 位是因为,虽然在默认情况下和我所有的表中,标识值只是递增 1,但它可以进行不同的配置,所以从技术上讲,您应该在这里找出标识值如何在发布者表上递增并将其递增同样的方法。

    • 1
  3. Andrew Bickerton
    2013-07-04T06:32:57+08:002013-07-04T06:32:57+08:00

    我首选的处理方法是执行以下操作:

    一个。首先停止您的复制代理(这样您就不会将任何新数据输入您的订阅数据库)

    湾。第二次重命名您现有的表

    exec sp_rename '[CurrentTable]', '[BackupTableName]'
    

    C。使用 IDENTITY 集重新创建表

    CREATE TABLE [CurrentTable]
    (
       ID INT NOT NULL IDENTITY(1,1), 
       OtherField VARCHAR(10) NULL,
       ....
    )
    

    d。使用 SET IDENTITY_INSERT 回填表(来自 [BackupTableName])

    SET IDENTITY_INSERT [CurrentTable] ON
    INSERT INTO [CurrentTable] (ID, OtherField, ...)
    SELECT ID, OtherField, ....
    FROM [BackupTableName]
    SET IDENTITY_INSERT [CurrentTable] OFF
    

    一旦你的数据库上有IDENTITY约束,那么你可以进行自定义复制(即:将你的 insert repl proc 更改为 SET IDENTITY_INSERT [TableName] ON 或者你可以在表上设置 NOT FOR REPLICATION 标志(它告诉 SQL 服务器如果连接用户是复制代理,则期望提供 IDENTITY 值)(我更喜欢自定义复制方法,因为它给了我更多的灵活性)

    e. 修改您的插入复制存储过程(通常名为 sp_MSins_CurrentTable)以也使用插入SET IDENTITY INSERT

    ALTER procedure [dbo].[sp_MSins_CurrentTable]
        @c1 int, @c2 varchar(50), ...
    as
    begin
        /* allow replication to insert values for IDENTITY */
        SET IDENTITY_INSERT [CurrentTable] ON
        insert into [CurrentTable]
            ([ID], [OtherField], ...)
        values
            (@c1, @c2, ...)
        /* now turn off Identity insert */
        SET IDENTITY_INSERT [CurrentTable] OFF
    end
    

    F。现在您可以重新启动复制代理。

    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve