首页 > 开发 > 综合 > 正文

解决两相同数据库数据同步的问题

2024-07-21 02:09:09
字体:
来源:转载
供稿:网友

为用户组建一套sql server应用系统时,用户经常提到这样的要求:
 
  如果其中一台服务器坏了,怎样才能防止数据丢失,并在最短的时间内恢复系统?

要解决这个问题,肯定需要两台服务器,并在两台服务器上装有相同的数据库,保持两台服务器中的数据同步,当主服务器坏了时,将另外一台服务器更改一下计算机名称,从而使得工作站可以继续运行.

那么如何保持两台数据库中的数据同步呢? sql server提供了出版-定阅机制,可以将数据实时的拷贝到定阅服务器中. 但在实际应用中,发现一旦建立起了出版-定阅关系,在定阅服务器数据库中的触发器,主键等东西都不见了!!! 当主服务器不能正常工作时,要想让另一台服务器转变为主服务器,除更改计算机名外,还需建立触发器,索引等,过程比较烦琐.特别当用户对数据库维护不熟悉时,这种操作更加麻烦.

sql server做为一种数据库管理系统,它与客户的接口都是通过sql语句进行的, 用户在插入一条记录时,sql server会接收到insert语句;更改一条记录时,会接收到 update命令...
那么如果我们能在sql server中跟踪到所有发给sql server的sql语句,那么我们就可以知道数据库发生了哪些改变,并可以将这种改变发给另外一到服务器,从而实现数据实时同步的功能.

值得高兴的是,sql server 提供了跟踪功能 ,它们是以 xp_trace_xxxxxx的一系列存储过程,
你可以设置过滤条件,从而只跟踪影响你的数据库 变化的sql 语句,将这些sql 语句存放在本地表中,再从本地表中读出,发送给另外一台服务器 ,从而实现数据同步功能. 这种方法可以跟踪任何类型的变化,包括image类型数据的改变.

以下面是用bcb5.0语句实现建立跟踪过程:
bool tform1 :: buildtrace(int dbid,
                        ansistring appfilter,
                        ansistring sqlfilter,
                        ansistring dsttable,
                        int &tracehandle)
{
    char tempbuf[512];

    query1 -> close();
    query1 -> sql -> clear();
    tstrings *psql = query1 -> sql;


    psql -> add("use master");
    psql -> add("declare @queue_handle int");
    psql -> add("declare @column_value int");
    psql -> add("set @column_value = 67108864|1|512|1024|10384");
    psql -> add("exec  xp_trace_addnewqueue 1000,5,95,90,@column_value,@queue_handle output");
    psql -> add("exec xp_trace_seteventclassrequired @queue_handle, 41,1 ");
  
    wsprintf(tempbuf,"exec xp_trace_setappfilter @queue_handle,'%s',null", appfilter.c_str());
    psql -> add(ansistring(tempbuf));

    wsprintf(tempbuf,"exec xp_trace_setdbidfilter @queue_handle,%d",dbid);
    psql -> add( ansistring(tempbuf));

    wsprintf( tempbuf,"exec xp_trace_settextfilter @queue_handle,'%s',null", sqlfilter.c_str());
    psql -> add(ansistring(tempbuf));

 

   

    wsprintf( tempbuf,
              "exec xp_trace_setqueuedestination @queue_handle,4,1,null,'%s'",
              dsttable.c_str()
            );
    psql -> add( ansistring(tempbuf));

    psql -> add("exec xp_trace_startconsumer @queue_handle");
    psql -> add("select @queue_handle queuehandle");

    try
    {
        query1 -> open();
    }
    catch(...)
    {
        return false;
    }
    tracehandle = query1 -> fieldbyname("queuehandle") -> asinteger;
    return true;
}


 
国内最大的酷站演示中心!
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表