熱點推薦:
您现在的位置: 電腦知識網 >> 電腦故障 >> 正文

解決兩相同數據庫數據同步的問題

2013-11-11 23:58:21  來源: 電腦故障 

  為用戶組建一套SQL Server應用系統時用戶經常提到這樣的要求:
  
   如果其中一台服務器壞了怎樣才能防止數據丟失並在最短的時間內恢復系統?
  
  要解決這個問題肯定需要兩台服務器並在兩台服務器上裝有相同的數據庫保持兩台服務器中的數據同步當主服務器壞了時將另外一台服務器更改一下計算機名稱從而使得工作站可以繼續運行
  
  那麼如何保持兩台數據庫中的數據同步呢? SQL Server提供了出版定閱機制可以將數據實時的拷貝到定閱服務器中 但在實際應用中發現一旦建立起了出版定閱關系在定閱服務器數據庫中的觸發器主鍵等東西都不見了!!! 當主服務器不能正常工作時要想讓另一台服務器轉變為主服務器除更改計算機名外還需建立觸發器索引等過程比較煩瑣特別當用戶對數據庫維護不熟悉時這種操作更加麻煩
  
  Sql Server做為一種數據庫管理系統它與客戶的接口都是通過SQL語句進行的 用戶在插入一條記錄時SQL Server會接收到Insert語句;更改一條記錄時會接收到 Update命令
  那麼如果我們能在SQL Server中跟蹤到所有發給SQL Server的SQL語句那麼我們就可以知道數據庫發生了哪些改變並可以將這種改變發給另外一到服務器從而實現數據實時同步的功能
  
  值得高興的是SQL Server 提供了跟蹤功能 它們是以 xp_trace_XXXXXX的一系列存儲過程
  你可以設置過濾條件從而只跟蹤影響你的數據庫 變化的SQL 語句將這些SQL 語句存放在本地表中再從本地表中讀出發送給另外一台服務器 從而實現數據同步功能 這種方法可以跟蹤任何類型的變化包括Image類型數據的改變
  
  以下面是用BCB語句實現建立跟蹤過程:
  bool TForm :: BuildTrace(int DBID
              AnsiString AppFilter
              AnsiString SQLFilter
              AnsiString DstTable
              int &TraceHandle)
  {
    char tempBuf[];
  
    Query > Close();
    Query > SQL > Clear();
    TStrings *pSQL = Query > SQL;
  
  
    pSQL > Add(USE master);
    pSQL > Add(DECLARE @queue_handle int);
    pSQL > Add(DECLARE @column_value int);
    pSQL > Add(SET @column_value = ||||);
    pSQL > Add(EXEC xp_trace_addnewqueue @column_value@queue_handle OUTPUT);
    pSQL > Add(EXEC xp_trace_seteventclassrequired @queue_handle );
   
    wsprintf(tempBufEXEC xp_trace_setappfilter @queue_handle%sNULL AppFilterc_str());
    pSQL > Add(AnsiString(tempBuf));
  
    wsprintf(tempBufEXEC xp_trace_setdbidfilter @queue_handle%dDBID);
    pSQL > Add( AnsiString(tempBuf));
  
    wsprintf( tempBufExec xp_trace_settextfilter @queue_handle%sNULL SQLFilterc_str());
    pSQL > Add(AnsiString(tempBuf));
    wsprintf( tempBuf
         EXEC xp_trace_setqueuedestination @queue_handleNULL%s
         DstTablec_str()
        );
    pSQL > Add( AnsiString(tempBuf));
  
    pSQL > Add(EXEC xp_trace_startconsumer @queue_handle);
    pSQL > Add(SELECT @queue_handle QueueHandle);
  
    try
    {
      Query > Open();
    }
    catch()
    {
      return false;
    }
    TraceHandle = Query > FieldByName(QueueHandle) > AsInteger;
    return true;
  }
  

From:http://tw.wingwit.com/Article/Fault/201311/10382.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.