亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Replication的犄角旮旯(五)--關于復制identit

系統 1669 0
原文: Replication的犄角旮旯(五)--關于復制identity列

?

?

《Replication的犄角旮旯》系列導讀

Replication的犄角旮旯(一)--變更訂閱端表名的應用場景

Replication的犄角旮旯(二)--尋找訂閱端丟失的記錄

Replication的犄角旮旯(三)--聊聊@bitmap

Replication的犄角旮旯(四)--關于事務復制的監控

Replication的犄角旮旯(五)--關于復制identity列

Replication的犄角旮旯(六)-- 一個DDL引發的血案(上)(如何近似估算DDL操作進度)

Replication的犄角旮旯(七)-- 一個DDL引發的血案(下)(聊聊logreader的延遲)

Replication的犄角旮旯(八)-- 訂閱與發布異構的問題

Replication的犄角旮旯(九)-- sp_setsubscriptionxactseqno,賦予訂閱活力的工具

---------------------------------------華麗麗的分割線--------------------------------------------

?

今天被群友問到復制環境中identity屬性的問題。在此通過幾個測試說明一下identity列是如何在復制環境中實現的;

以下測試均是基于SQLSERVER 2012 SP1下的事務復制環境;

先拋出幾個測試目的;

1、identity列和not for replication的關系,發布端及訂閱端何時添加not for replication屬性

2、快照初始化、備份初始化、不初始化訂閱對not for replication參數的依賴

3、如何添加not for replication,在哪添加not for relication,以及替代not for replication的方法

?

先解釋一下not for replication

NOT FOR REPLICATION

在 CREATE TABLE 語句中,可為 IDENTITY 屬性、FOREIGN KEY 約束和 CHECK 約束指定 NOT FOR REPLICATION 子句。 如果為 IDENTITY 屬性指定了該子句,則復制代理執行插入時,標識列中的值將不會增加。 如果為約束指定了此子句,則當復制代理執行插入、更新或刪除操作時,將不會強制執行此約束。

http://msdn.microsoft.com/zh-cn/library/ms174979.aspx

簡單說,對于identity、外鍵約束、check約束,可以通過指定not forreplication避免訂閱端寫入數據失敗;

?

測試開始:

  先在同一個實例下創建兩個庫test_byxl_1、test_byxl_2,分別作為本次測試的發布庫和訂閱庫;

  test_byxl_1下創建tb_ident_1表,結構如下

        
          1
        
        
          create
        
        
          table
        
         test_byxl_1.dbo.tb_ident_1 (id 
        
          int
        
        
          primary
        
        
          key
        
        
          identity
        
         ,name 
        
          varchar
        
        (
        
          10
        
        ))
      
View Code

  添加這個表的發布,只創建publication、添加article即可;

  注意:默認的article屬性中對identity的管理是手動的,這里默認即可;

  然后再來看一下這個表的屬性,已經開啟了發布表的not for replication屬性;

  這時候再添加訂閱,并通過快照初始化,訂閱端也同樣有這個屬性

  這種按照默認配置并通過快照方式初始化的情況,可以滿足identity列的同步問題;這也是最常見的情況;

===================華麗麗的分割線========================

但如果是備份初始化或者不初始化呢?

由于通過備份初始化的訂閱端,不會主動添加not for replication子句,因此需要手動添加not for replication子句

      
        alter
      
      
        table
      
       tb_ident_1 
      
        alter
      
      
        column
      
       id 
      
        add
      
      
        not
      
      
        for
      
      
        replication
      
    

對于不初始化的情況,要么在create table的時候對identity列添加not for replication屬性,要么同備份初始化一樣,在同步前通過alter table 的方式添加not for replication屬性;

?

===================華麗麗的分割線========================

?

有同學繼續問到:那發布端一定需要not for replication屬性么?

答案是no!

但為什么添加發布的時候,系統會在發布表上添加not for replication屬性呢?

答案是為了方便今后通過快照初始化的訂閱可以順利擁有not for replication屬性。因為在創建publication并添加article時,發布服務器并不需要也沒有必要知道你即將在這個publication里添加什么類型的訂閱;因此為了方便,就在創建publication的時候,檢查每個article是否擁有identity列,并自動加上not for publication屬性;

為此,我做了個測試來驗證第一個問題(發布端一定需要not for replication屬性么?)

測試開始:

  首先,在發布端刪掉not for publication屬性

      
        alter
      
      
        table
      
       test_byxl_1.dbo.tb_ident_1 
      
        alter
      
      
        column
      
       id 
      
        drop
      
      
        not
      
      
        for
      
      
        replication
      
    

  觀察一下發布表和訂閱表的屬性,可以看到發布端的not for replication已經被刪掉,而這個語句并沒有被復制到訂閱端,因此訂閱端的not for replication屬性仍然存在;

?

  發布端寫入一條測試數據,并檢查發布端、訂閱端數據,可以發現可以正常同步到訂閱端;因此驗證了上面的問題(發布端一定需要not for replication屬性么?);

      
        set
      
      
        identity_insert
      
       test_byxl_1.dbo.tb_ident_1 
      
        on
      
      
        insert
      
      
        into
      
       test_byxl_1.dbo.tb_ident_1(id,name) 
      
        values
      
      (
      
        10
      
      ,
      
        '
      
      
        beijing
      
      
        '
      
      
        )

  
      
      
        set
      
      
        identity_insert
      
       test_byxl_1.dbo.tb_ident_1 
      
        off
      
      
        select
      
      
        *
      
      
        from
      
      
          test_byxl_1.dbo.tb_ident_1

  
      
      
        select
      
      
        *
      
      
        from
      
        test_byxl_2.dbo.tb_ident_1
    

?

===================華麗麗的分割線========================

?

我們再來做個測試;先驗證一下,當訂閱端沒有not for replication時,會發生什么情況;

為此,我分別在發布、訂閱端創建了了一個tb_ident_2表,并創建不初始化的訂閱

      
        create
      
      
        table
      
       test_byxl_1.dbo.tb_ident_2 (id 
      
        int
      
      
        primary
      
      
        key
      
      
        identity
      
       ,name 
      
        varchar
      
      (
      
        10
      
      
        ))


      
      
        create
      
      
        table
      
       test_byxl_2.dbo.tb_ident_2 (id 
      
        int
      
      
        primary
      
      
        key
      
      
        identity
      
       ,name 
      
        varchar
      
      (
      
        10
      
      ))
    

發布端自動添加了not for replication屬性,而訂閱端由于手動創建,沒有這個屬性

  插入測試數據

      
        set
      
      
        identity_insert
      
       test_byxl_1.dbo.tb_ident_2 
      
        on
      
      
        insert
      
      
        into
      
       test_byxl_1.dbo.tb_ident_2(id,name) 
      
        values
      
      (
      
        11
      
      ,
      
        '
      
      
        shanghai
      
      
        '
      
      
        )

  
      
      
        set
      
      
        identity_insert
      
       test_byxl_1.dbo.tb_ident_2 
      
        off
      
      
        select
      
      
        *
      
      
        from
      
      
          test_byxl_1.dbo.tb_ident_2

  
      
      
        select
      
      
        *
      
      
        from
      
        test_byxl_2.dbo.tb_ident_2
    

  大約1分鐘以后,分發代理job開始重試

  檢查distribution.dbo.msrepl_errors表,出現identity_insert的錯誤

  手動添加訂閱端的not for replication屬性,為了能快速看到效果,再手動啟停一下分發代理作業;  

      
        alter
      
      
        table
      
       test_byxl_2.dbo.tb_ident_2 
      
        alter
      
      
        column
      
       id 
      
        add
      
      
        not
      
      
        for
      
      
        replication
      
    

  檢測訂閱端數據,發現數據已同步到訂閱端;

?

===================華麗麗的分割線========================

?

最后一個測試,有沒有替代not for replication的方法?

我們先去掉tb_ident_2訂閱端的not for replication屬性

      
        alter
      
      
        table
      
       test_byxl_2.dbo.tb_ident_2 
      
        alter
      
      
        column
      
       id 
      
        drop
      
      
        not
      
      
        for
      
      
        replication
      
    

然后修改訂閱端對tb_ident_2表的ins存儲過程,手動在insert語句前后添加identity_insert開關;

  執行保存后,再寫入測試數據;訂閱端已接收到最新數據;

?

===================華麗麗的分割線========================

結論:

1、not for replication只有在訂閱表上添加時才有效,發布表在創建發布時由系統添加只是為了快照初始化訂閱時可以方便表結構同步;

2、not for replication屬性,可以在create table時創建,也可以通過alter table XXX alter column ident_col add not for replication的方式后期添加;

3、通過快照初始化訂閱時,不必關心identity列的同步問題,默認設置就好;

4、可以通過其他方法替代alter table XXX alter column ident_col add not for replication(如修改訂閱端存儲過程),但強烈不推薦;原因,你懂的……

?

歡迎拍磚

?

Replication的犄角旮旯(五)--關于復制identity列


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 综合亚洲欧美日韩一区二区 | 久久首页| 亚洲一区二区三区免费观看 | 毛片大| 伊人成人在线视频 | 久久国产首页 | 色婷婷天天综合在线 | 亚洲一区二区三区不卡在线播放 | 99免费视频| 欧美一区在线观看视频 | 欧美激情(一区二区三区) | 清纯唯美亚洲综合日韩第 | 欧美洲大黑香蕉在线视频 | 亚洲日韩在线视频 | 国产成人久久久精品一区二区三区 | 五月婷婷久久综合 | 欧美一级毛片在线一看 | 国产美女一级高清免费观看 | 欧美精品h在线播放 | 国产精品一区在线播放 | 亚洲一区二区三区高清视频 | 国产午夜不卡 | 春色www视频在线观看 | 成人国产一区二区三区 | 日本高清视频一区二区 | 性新婚a大黄毛片 | 一级毛片免费观看不收费 | 国产中的精品一区的 | 国产精品99re | 亚洲免费视频一区二区三区 | 午夜窝窝 | 高清一级毛片一本到免费观看 | 国产精品福利自产拍网站 | 99re热久久精品这里都是精品 | 国产成人一区二区三区高清 | 正在播放一区二区 | 日本永久视频 | 男女一级毛片 | 亚洲网在线 | 久久99爰这里有精品国产 | 亚洲一区二区三区在线免费观看 |