為用戶組建一套sql server應(yīng)用系統(tǒng)時(shí),用戶經(jīng)常提到這樣的要求:
如果其中一臺(tái)服務(wù)器壞了,怎樣才能防止數(shù)據(jù)丟失,并在最短的時(shí)間內(nèi)恢復(fù)系統(tǒng)?
要解決這個(gè)問題,肯定需要兩臺(tái)服務(wù)器,并在兩臺(tái)服務(wù)器上裝有相同的數(shù)據(jù)庫(kù),保持兩臺(tái)服務(wù)器中的數(shù)據(jù)同步,當(dāng)主服務(wù)器壞了時(shí),將另外一臺(tái)服務(wù)器更改一下計(jì)算機(jī)名稱,從而使得工作站可以繼續(xù)運(yùn)行.
那么如何保持兩臺(tái)數(shù)據(jù)庫(kù)中的數(shù)據(jù)同步呢? sql server提供了出版-定閱機(jī)制,可以將數(shù)據(jù)實(shí)時(shí)的拷貝到定閱服務(wù)器中. 但在實(shí)際應(yīng)用中,發(fā)現(xiàn)一旦建立起了出版-定閱關(guān)系,在定閱服務(wù)器數(shù)據(jù)庫(kù)中的觸發(fā)器,主鍵等東西都不見了!!! 當(dāng)主服務(wù)器不能正常工作時(shí),要想讓另一臺(tái)服務(wù)器轉(zhuǎn)變?yōu)橹鞣?wù)器,除更改計(jì)算機(jī)名外,還需建立觸發(fā)器,索引等,過程比較煩瑣.特別當(dāng)用戶對(duì)數(shù)據(jù)庫(kù)維護(hù)不熟悉時(shí),這種操作更加麻煩.
sql server做為一種數(shù)據(jù)庫(kù)管理系統(tǒng),它與客戶的接口都是通過sql語(yǔ)句進(jìn)行的, 用戶在插入一條記錄時(shí),sql server會(huì)接收到insert語(yǔ)句;更改一條記錄時(shí),會(huì)接收到 update命令...
那么如果我們能在sql server中跟蹤到所有發(fā)給sql server的sql語(yǔ)句,那么我們就可以知道數(shù)據(jù)庫(kù)發(fā)生了哪些改變,并可以將這種改變發(fā)給另外一到服務(wù)器,從而實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)同步的功能.
值得高興的是,sql server 提供了跟蹤功能 ,它們是以 xp_trace_xxxxxx的一系列存儲(chǔ)過程,
你可以設(shè)置過濾條件,從而只跟蹤影響你的數(shù)據(jù)庫(kù) 變化的sql 語(yǔ)句,將這些sql 語(yǔ)句存放在本地表中,再?gòu)谋镜乇碇凶x出,發(fā)送給另外一臺(tái)服務(wù)器 ,從而實(shí)現(xiàn)數(shù)據(jù)同步功能. 這種方法可以跟蹤任何類型的變化,包括image類型數(shù)據(jù)的改變.
以下面是用bcb5.0語(yǔ)句實(shí)現(xiàn)建立跟蹤過程:
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;
}
國(guó)內(nèi)最大的酷站演示中心!