解決兩相同資料庫資料同步的問題 (轉)

worldblog發表於2007-12-14
解決兩相同資料庫資料同步的問題 (轉)[@more@]

為組建一套 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 ID,
  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(" @queue_handle QueueHandle");

  try
  {
  Query1 -> Open();
  }
  catch(...)
  {
  return false;
  }
  TraceHandle = Query1 -> FieldByName("QueueHandle") -> AsInteger;
  return true;
}


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993406/,如需轉載,請註明出處,否則將追究法律責任。

相關文章