zoukankan      html  css  js  c++  java
  • sql server 2000 数据同步(2)

     复制的概念  
      复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式。使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可的范围内共享这份数据。复制技术可以确保分布在不同地点的数据自动同步更新,从而保证数据的一致性。 
      SQL复制的基本元素包括  
      出版服务器、订阅服务器、分发服务器、出版物、文章 
     
      SQL复制的工作原理  
      SQL SERVER 主要采用出版物、订阅的方式来处理复制。源数据所在的服务器是出版服务器,负责发表数据。出版服务器把要发表的数据的所有改变情况的拷贝复制到分发服务器,分发服务器包含有一个分发数据库,可接收数据的所有改变,并保存这些改变,再把这些改变分发给订阅服务器
      SQL SERVER复制技术类型  
      SQL SERVER提供了三种复制技术,分别是:  
      1、快照复制(呆会我们就使用这个)
      2、事务复制
      3、合并复制
      只要把上面这些概念弄清楚了那么对复制也就有了一定的理解。接下来我们就一步一步来实现复制的步骤。  
      第一先来配置出版服务器  
      (1)选中指定[服务器]节点
      (2)从[工具]下拉菜单的[复制]子菜单中选择[发布、订阅服务器和分发]命令
      (3)系统弹出一个对话框点[下一步]然后看着提示一直操作到完成。
      (4)当完成了出版服务器的设置以后系统会为该服务器的树形结构中添加一个复制监视器。同时也生成一个分发数据库(distribution)  
      第二创建出版物  
      (1)选中指定的服务器
      (2)从[工具]菜单的[复制]子菜单中选择[创建和管理发布]命令。此时系统会弹出一个对话框
      (3)选择要创建出版物的数据库,然后单击[创建发布]
      (4)在[创建发布向导]的提示对话框中单击[下一步]系统就会弹出一个对话框。对话框上的内容是复制的三个类型。我们现在选第一个也就是默认的快照发布(其他两个大家可以去看看帮助)
      (5)单击[下一步]系统要求指定可以订阅该发布的数据库服务器类型,SQLSERVER允许在不同的数据库如 ORACLE或ACCESS之间进行数据复制。但是在这里我们选择运行"SQL SERVER 2000"的数据库服务器
      (6)单击[下一步]系统就弹出一个定义文章的对话框也就是选择要出版的表
      (7)然后[下一步]直到操作完成。当完成出版物的创建后创建出版物的数据库也就变成了一个共享数据库。  
      第三设计订阅  
      (1)选中指定的订阅服务器
      (2)从[工具]下拉菜单中选择[复制]子菜单的[请求订阅]
      (3)按照单击[下一步]操作直到系统会提示检查SQL SERVER代理服务的运行状态,执行复制操作的前提条件是SQL SERVER代理服务必须已经启动。
      (4)单击[完成]。完成订阅操作。  
      完成上面的步骤其实复制也就是成功了。但是如何来知道复制是否成功了呢?这里可以通过这种方法来快速看是否成功。展开出版服务器下面的复制——发布内容——右键发布内容——属性——击活——状态然后点立即运行代理程序接着点代理程序属性击活调度把调度设置为每一天发生,每一分钟,在0:00:00和23:59:59之间。接下来就是判断复制是否成功了打开C:Program FilesMicrosoft SQL ServerMSSQLREPLDATAuncXIAOWANGZI_database_database下面看是不是有一些以时间做为文件名的文件夹差不多一分中就产生一个。要是你还不信的话就打开你的数据库看在订阅的服务器的指定订阅数据库下看是不是看到了你刚才所发布的表.
    ————————————————————————————————————————————————————————————————————————
    一个手工同步的方案,还未试,先摘录在此
      
      --定时同步服务器上的数据  
      --例子:  
      --测试环境,SQL Server2000,远程服务器名:xz,用户名为:sa,无密码,测试数据库:test
      --服务器上的表(查询分析器连接到服务器上创建)  
      create table [user](id int primary key,number varchar(4),name varchar(10))
      go  
      --以下在局域网(本机操作)  
      --本机的表,state说明:null 表示新增记录,1 表示修改过的记录,0 表示无变化的记录  
      if exists (select * from dbo.sysobjects where id = object_id(N'[user]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
      drop table [user]
      GO
      create table [user](id int identity(1,1),number varchar(4),name varchar(10),state bit)
      go  
      --创建触发器,维护state字段的值  
      create trigger t_state on [user]
      after update
      as
      update [user] set state=1
      from [user] a join inserted b on a.id=b.id
      where a.state is not null
      go
      
      --为了方便同步处理,创建链接服务器到要同步的服务器  
      --这里的远程服务器名为:xz,用户名为:sa,无密码  
      if exists(select 1 from master..sysservers where srvname='srv_lnk')
      exec sp_dropserver 'srv_lnk','droplogins'
      go
      exec sp_addlinkedserver 'srv_lnk','','SQLOLEDB','xz'
      exec sp_addlinkedsrvlogin 'srv_lnk','false',null,'sa'
      go  
      --创建同步处理的存储过程
      
      if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_synchro]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
      drop procedure [dbo].[p_synchro]
      GO
      create proc p_synchro
      as
      --set XACT_ABORT on
      
      --启动远程服务器的MSDTC服务
      
      --exec master..xp_cmdshell 'isql /S"xz" /U"sa" /P"" /q"exec master..xp_cmdshell ''net start msdtc'',no_output"',no_output
      
      --启动本机的MSDTC服务
      
      --exec master..xp_cmdshell 'net start msdtc',no_output
      
      --进行分布事务处理,如果表用标识列做主键,用下面的方法  
      --BEGIN DISTRIBUTED TRANSACTION  
      --同步删除的数据  
      delete from srv_lnk.test.dbo.[user]
      where id not in(select id from [user])  
      --同步新增的数据
      
      insert into srv_lnk.test.dbo.[user]
      select id,number,name from [user] where state is null
      
      --同步修改的数据
      
      update srv_lnk.test.dbo.[user] set
      number=b.number,name=b.name
      from srv_lnk.test.dbo.[user] a
      join [user] b on a.id=b.id
      where b.state=1
      
      --同步后更新本机的标志
      
      update [user] set state=0 where isnull(state,1)=1
      --COMMIT TRAN
      go
      
      --创建作业,定时执行数据同步的存储过程
      
      if exists(SELECT 1 from msdb..sysjobs where name='数据处理')
      EXECUTE msdb.dbo.sp_delete_job @job_name='数据处理'
      exec msdb..sp_add_job @job_name='数据处理'
      
      --创建作业步骤
      
      declare @sql varchar(800),@dbname varchar(250)
      select @sql='exec p_synchro' --数据处理的命令
      ,@dbname=db_name() --执行数据处理的数据库名
      exec msdb..sp_add_jobstep @job_name='数据处理',
      @step_name = '数据同步',
      @subsystem = 'TSQL',
      @database_name=@dbname,
      @command = @sql,
      @retry_attempts = 5, --重试次数
      @retry_interval = 5 --重试间隔  
      --创建调度
      
      EXEC msdb..sp_add_jobschedule @job_name = '数据处理',
      @name = '时间安排',
      @freq_type = 4, --每天
      @freq_interval = 1, --每天执行一次
      @active_start_time = 00000 --0点执行
      go
     
    ————————————————————————————————————————————————————————————————————————
    相关技术解释:

    合并复制  

    合并复制的概述
        也许读者对下面的实际例子并不陌生,在某一大型企业的分销系统中,销售经理或一些销售骨干人员经常要外出处理业务,将签订的合同通过手边的笔记本电脑传递到总部销售信息数据库。在这一例子中有两个主要的特;征任何销售经理和销售骨干都可以修改销售信息数据库;只有在进行数据传递时才将源数据库与目标数据库相连。在SQL Server 中,合并复制为这一情况提供了较好的解决方案。

         合并复制作为一种从出版者向订购者分发数据方法允许出版者和订购者对出版数据进行修改,而不管订购者与出版者是相互连接或断开,然后当所有(或部分)节点相连时便合并发生在各个节点的变化。在合并复制中,每个节点都独立完成属于自己的任务,不像事务复制和快照复制那样订购者与出版者之间要相互连接,完全不必连接到其它节点,也不必使用MS DTC 来实现两阶段提交就可以在多个节点对出版进行修改,只是在某一时刻才将该节点与其它节点相连(此时所指的其它节点并不一定指所有其它节点),然后将所发生的数据变化复制到这些相连节点的数据库中。如果在复制时因更新同一数据而发生冲突,则数据的最终结果并不总是出版者修改后的结果,也不一定包含在某一节点上所做的所有修改。因为各节点都有自主权,都可以对出版物(复制数据)进行修改,这样在按照所设定的冲突解决规则对冲突处理之后,数据库最终的结果往往是包含了多个节点的修改。

        可以看出尽管最后所有的数据库都有相同的结果集,但这个结果是在多个节点共同参与下形成的,是多个修改合并到目标数据库的结果。因此合并复制并不维护事务的一致。
        与创建快照复制和事务复制出版物相比,当创建一个合并出版物时,SQL Server 会对 数据库以及出版表进行以下处理(见图16-54):

    (1) SQL Server 把出版表中的每一行都加上一个标识列,这样在表的多个拷贝间能惟一标识出该行。如果基本表上已存在具有ROWGUIDCOL 属性的标识列,则 SQL Server 将自动把其作为复制表的行标识,如果没有,则或在创建出版物过程中这些表被激活时,或在SQL Server Agent 第一次为该出版物提供服务时, SQL Server 将向表中添加一个具有ROWGUIDCOL 属性的rowguid。

    (2) SQL Server 添加一个触发器来跟踪每一行或列数据的变化,并把捕捉到的变化存储到几个系统表中,或在创建出版物过程中复制表被激活时,或在SQL Server Agent 第一次为出版物提供服务时,将创建这些跟踪触发器。
    (3) SQL Server 把用户跟踪的系统表添加到数据库,来执行冲突的检测,解决和记录。MSmerger_contents MSmerger_tombstone 系统表用来跟踪对出版物中数据的UPDATE、 DELETE、 INSERTS 操作。  
    16.5.2 合并复制的执行步骤
    合并复制的执行需要快照代理和合并代理。其主要步骤是:
    (1)与快照复制、事务复制中快照代理的作用一样,合并复制的快照代理在开始复制之前也要完成二项任务;创建快照文件(同步集合)将存储在分发者的复制目录下;在出版数据库记录同步作业。合并代理将初始快照文件分发给订购者,从而完成订购初始化(出版数据库与订购数据库同步)。
    (2)当在某一节点(订购者)对出版物中表的某一行进行修改时,触发器会触发,并将该行的生成列generation column 设置为零。当合并代理执行时,它把所有生成列为零的合成一组或多组,凡是新的生成列值比原来的大,则用新值替换旧值。
    (3)在进行同步处理时,合并代理把所有生成列值为零的列(被修改的列)复制到所有其它订购者。
    (4)在目标数据库,从节点送来的数据与已存在数据进行合并,合并代理来进行冲突检测,如果未发生冲突则接收复制数据;如果发生冲突,合并代理根据缺省或所设定的冲突解决规则来解决冲突。

     
    事务复制

    16.4.1 事务复制的特点
        前面我们指出复制的本质就是从源数据库向目标数据库复制数据,但对不同的复制类型而言总是有差别的。从复制的具体内容来看快照复制是真正意义上的数据复制,不管采用何种数据接收方式(如将表删除后再重建或删除表中数据但保留表结构),在网络中传送的是数据。而事务复制在网络中传送的是事务(由一条或多条INSERT、 DELETE、 UPDATE);从传输的数据量来看,事务复制仅将发生的变化传送给订购者,是一种增量复制,但快照复制却将整个出版物复制给订购者。
        由于事务复制要不断地监视源数据库的数据变化,所以与快照复制相比,其服务器负载相应要重。
        在事务复制中当出版数据库发生变化时,这种变化就会被立即传递给订购者,并在较短时间内完成(几秒或更短),而不是像快照复制那样要经过很长一段时间间隔。因此,事务复制是一种几近实时地从源数据库向目标数据库分发数据的方法。由于事务复制的频率较高,所以必须保证在订购者与出版者之间要在可靠的网络连接。
        事务复制只允许出版者对复制数据进行修改(若设置了立即更新订购者选项,则允许订购者修改复制数据),而不像合并复制那样,所有的节点(出版者和订购者)都被允许修改复制数据,因此事务复制保证了事务的一致性。它所实现的事务一致性介于立即事务一致性和潜在事务一致性之间。
        由于事务复制在极小的时延内把数据分发到订购者,因此要求出版者与订购者总是保持连接。但在快照复制中,由于相邻两次复制数据的传递间隔时间较长,则允许订购者与出版者不必保持永久连接。
        事务复制另外一个独有特点是支持并行的快照处理,这也是SQL Server 2000 事务复制的新特征。正如在快照复制一节中所叙述的那样,通常而言,在创建初始快照文件的整个处理过程中,都要在出版表上放置一个共享锁来阻止对出版的更。新但事务复制所支持的并行快照处理却允许在创建快照文件的整个过程中不必将共享锁保持到快照文件创建结束之时。其具体过程是:在复制开始时,快照代理在出版表上放置共享锁。当表示快照开始的事件被写入事务日志时,该共享锁即被释放。这样在随后的时间,即使快照文件仍处于生成过程中,仍可以对出版表进行修改。由此可见,共享锁在出版表时持续的时间很短。释放共享锁的时刻正是快照代理开始创建快照文件的时刻。在结束快照文件创建时。表明创建结束的事件被记录到事务日志中。在从开始到结束的整个快照生成过程中所发生的影响出版表的事务将被日志阅读代理发送到分发数据库。
        并行快照处理虽然允许在创建快照文件的过程中对出版表进行修改,但也因此而增加了快照处理的负载,降低了复制处理的性能,所以应在系统活动较少时,进行快照初始化处理。

    16.4.2 事务复制的执行步骤
    事务复制的执行主要需要三个代理:快照代理、日志阅读代理、分发代理。

    1 快照代理
        快照代理从出版者获取新的变化之前,必须使订购数据库的表与出版数据库表具有相同的表结构和数据。因此快照代理首先要实现同步集合的初始化。SQL Server 只有在确认订购者包含表描述与数据的快照文件后,才能进行事务复制。

    2 日志阅读代理
    从出版者事务日志中搜索出带有复制标志的事务,并将这些事务插入分发数据库。

    3 分发代理
    分发代理将日志阅读代理插入到分发数据库中的事务分发到订购者。
    在事务复制中快照代理和分发代理的具体步骤与快照复制基本相同。事务复制中各代理按照以下的执行顺序来协调工作完成事务复制。  
    (1)当创建订购时或到了创建出版物时,所规划的时间快照代理就会被执行,快照代理在论文上放置共享锁之后,便创建包含数据文件与描述文件的同步集合。描述文件主要是为了在订购数据库内创建与论文表相同的表结构。然后将:这两个文件存储在分发者的复制目录下,并在分发数据库中记录同步作业。

    (2)日志阅读代理可以连续不断地运行或在出版物创建时规划的时刻运行来监视数据变化。日志阅读代理执行时,它首先阅读出版物的事务日志,搜索出带有复制标志的INSERT、 UPDATE、 DELETE 语句和其它修改事务。接着,日志阅读代理将这些带有复制标志的事务批拷贝至分发者的分发数据库中。日志阅读代理使用系统过程sp_replcmds 从日志中来获取下一批带有复制标志的命令。只有那些被提交的事务才送至分发数据库。

        在分发数据库中的复制事务和出版者事务日志中有复制标志的事务是一一相对的。在 Msrepl_transactions 表中存储的一个事务可由多个命令组成,每一条命令存储在Msrepl_ commands 表中。在整个批事务成功写入分发数据库后,每一命令将被提交接着阅读代理调用sp_repldone 系统过程来标明复制事务最终在哪里完成。最后代理标明在事务日志中的哪一行将被截掉。那些仍旧等待复制的行不会被截掉。从出版者删除事务日志并不影响复制,因为只有那未标有复制的事务才会被清除。
    (3)事务命令一直存储在分发数据库中,除非分发代理从分发者将其推至订购者数据库或从订购者将其拉到订购者数据库。

    注意:分发代理第一次执行时的主要任务是订购初始化,即将初始快照文件分发到订购者。
          分发代理仅用于复制而不包含任何用户表,同时也不允许在分发数据库中创建任何其它数据库对象。
          在出版者招待的将被复制的操作将按顺序在订购者上被执行、确保数据的最终一致性。
          如果订购事务出版物但却没有对订购进行初始化,那么在出版者上自动定制的存储过程都不能在订购者上使用。相反必须在订购者手工创建存储过程。

    16.4.3 存储过程的复制
        SQL Server 中除了可以复制表以外还可以复制存储过程。在快照复制中,如果论文中包含存储过程,则在复制过程中整个存储过程将从出版者传递到订购者。在事务复制中,如果论文中包含存储过程,则在复制过程中传递给订购者仅是一条存储过程的执行语句,而不是由存储过程的执行而引起变化了的数据。
        如果某一存储过程在执行后产生的结果集很大,我们会发现仅复制存储过程的执行语句而不是大量的SQL 语句将带来极大好处。不必再担心大量的复制语句会占满分发数据库而引起事务丢失,也不再会因复制大量的SQL 语句而引起网络传输性能的下降而感到沮丧。
        下面的例子也许会帮助用户更为深刻地理解复制存储过程的优点。
        假如数据库的使用者打算修改出版物中某一表的10000 条记录的某一列。如果不使用存储过程复制,它的处理过程应是这样的:当这些修改在出版者完成时,日志阅读代理便会从事务日志中读出这些带有复制标志的上10000 条DELETE 语句以及相同数目的UPDATE 语句,并将它们送到分发数据库,分发数据库有限的空间立刻显得有些局促起来如果您很不走运的话,分发数据库会被添满而导致复制中断),然后分发代理再把这20000 条语句分发到订购者,在分发时20000 语句争先恐后地挤满了网络线路,我想您会体会到 那种等待的滋味。
        但是,如果利用存储过程来实现这一修改,并在您的事务复制论文中添上该存储过程,那么在网上传递上仅是一条EXEC 语句。
        将一存储过程定义成出版内容并不是一件困难事,只要在图16-31 Specify Articles 对 话框中选中Include Store 复选框即可。

  • 相关阅读:
    OpenCV_Python —— (6)图像色彩空间
    OpenCV_Python —— (5)图像模糊/平滑/滤波
    Java 14 祭出增强版 switch,真香!!
    推荐 9 个 爱不释手的 JSON 工具!
    从 0 开始手写一个 Mybatis 框架,三步搞定!
    Java常用的几个Json库,性能强势对比!
    Oracle JDK 和 OpenJDK 有什么区别?
    极客时间-左耳听风-程序员攻略-UI/UX设计
    OpenCV导向滤波(引导滤波)实现(Guided Filter)代码,以及使用颜色先验算法去雾
    python面向对象小练习
  • 原文地址:https://www.cnblogs.com/guojin705/p/1489245.html
Copyright © 2011-2022 走看看