server 大家好,很長時間沒寫東西了,最近在浩方幹星際,真是輸的連媽都不認,算了,還是回來搞資料庫有前途一點,起碼在這裡我還能勉強找到那麼點自信!!!
做備份就像買保險一樣,你可以不做,每天提心弔膽的過日子,你也可以做,讓系統啟動並執行通常無阻,有頑強的再生能力,同時大家也會忽略你的存在,總是要出下亂子,然後你再來扮演下救世主,這樣大家才會知道你的存在是有價值的,你的工資應該是×××的,所以個人感覺做備份是件不大討好的事!!!
MICROSOFT SQL SERVER的備份機制比SYBASE的真是強大的好多,首先sybase不支援資料庫的部分恢複,SQL SERVER的檔案與檔案組備份很好的實現了這一點,sybase對於錯誤刪除記錄的操作顯得有點力不從心,因為load tran不支援指定時間點或命名事務,sybase也不存在恢複模型,這樣對於不同企業間恢複機制的確定沒有一個直觀的尺度.我會在下面的文字中逐個說明SQL SERVER的這些優點(也許是下篇文章)
恢複模型:
SQL SERVER有3個恢複模型,簡單恢複,完全恢複和大容量日誌恢複,每個模型各有自己的特點,也適用於不同的企業備份需求,模型之間可以相互切換,這也是個比較容易出問題的地方
簡單恢複:
就像其名字一樣,這種恢複模型是最簡單的,他只支援資料庫完整備份和差異備份,另外對於節省記錄檔空間也有很好的支援,因為在檢查點處會自動截斷日誌,所以記錄檔幾乎不會增長,但提交較大的事務時情況令當別論,由於備份能力有限,其風險指數也是很高的,如果資料庫損壞,只能恢複到上次完整備份或最後一次差異備份,對於後面的交易處理就無能為力了,準確一點應該是非活動的交易記錄都被刪除了
大容量日誌恢複:
這個模型很像後面將提到的完全恢複,但還是有很多不同,他支援資料庫完整,差異和記錄備份,對於諸如SELECT INTO,BULK INSERT,BCP等操作大容量的日誌操作提供了效能上的最佳化,在完全復原模式下,日誌會記錄上述操作的具體細節,而本模式中只會在日誌中記載有這麼一回事,具體細節忽略不計,這樣儲存速度就有很大提高,也節約了日誌空間,問題也就出現了,由於日誌記錄中包含有忽略細節的最小日誌更改,所以大容量恢複模型不支援具體時間點的恢複,也就是說不能在restore log中指定stopat子句,下面是操作和出錯資訊
/*大容量日誌恢複模型
restore database chj733 from disk = 'e:\chj733_dat.bck' with norecovery
go
restore log chj733 from disk = 'e:\chj733_log.bck' with file = 1,stopat = '2004-11-09 15:06:04.810',recovery
go
已處理 2016 頁,這些頁屬於資料庫 'chj733' 的檔案 'chj733'(位於檔案 1 上)。
已處理 1 頁,這些頁屬於資料庫 'chj733' 的檔案 'chj733_log'(位於檔案 1 上)。
RESTORE DATABASE 操作成功地處理了 2017 頁,花費了 3.687 秒(4.479 MB/秒)。
伺服器: 訊息 4327,層級 16,狀態 1,行 1
此備份組中的日誌包含最小日誌記錄更改。禁止進行時間點復原。RESTORE 將前滾到日誌的結尾,而不恢複資料庫。
已處理 7152 頁,這些頁屬於資料庫 'chj733' 的檔案 'chj733'(位於檔案 1 上)。
已處理 1736 頁,這些頁屬於資料庫 'chj733' 的檔案 'chj733_log'(位於檔案 1 上)。
RESTORE LOG 操作成功地處理了 8888 頁,花費了 6.668 秒(10.919 MB/秒)。
*/
同時在大容量記錄模式下備份交易記錄需要訪問資料檔案,而很多災難發生後基本上資料檔案就沒法訪問了,所以採用這種模式時你的防著這一點,很有可能你會丟失自前次交易備份以後所有的資料,一般可以在準備進行大量資料裝載或建立比較龐大的索引時將模型切換到大容量日誌方式,操作完成後在切換回完全模式。
完全恢複:
這種模式風險是最小的,線上說明上宣稱這種模式可以將資料庫恢複到任何即時點,理論上可以將資料丟失的可能性減至0(事實上並非如此),上述兩個模型中打NO的在這裡基本上可以打YES,他支援所有的備份和恢複方式,支援指定即時點,日誌對BCP等大資料裝載操作有詳細記載,等等,這些特性也引發了一些問題,記錄檔開銷較大,需要頻繁轉存日誌
恢複模型就講到這,大家可以試著用BCP載入一些資料看看,在各個模式下觀察下記錄檔的大小變化是不是符合上面的說法,做之前最好先壓縮下記錄檔,如果記錄檔裡面有足夠的空間,你載入的資料份量又不夠的話,你會看不到檔案的變化的,省得到時候又來罵我在這裡胡說八道!!!
備份類型:
先拋開檔案備份,SQL SERVER有3種備份類型,完整備份,差異備份,記錄備份,你必須先明白每種備份從哪裡開始,從哪裡結束,他裡面的內容是什麼
完整備份是資料庫的一個完整拷貝,包括交易記錄,資料庫中的所有對象,等等
差異備份從上次完整備份之後開始,建立所有修改頁的拷貝,注意,他是從上次完整備份後開始的,所以應用差異備份時只需最後的一次備份,而不是逐個應用所有的差異備份,當然你有這個閑功夫,也可以這麼幹
記錄備份是備份上次記錄備份後所有的事務記錄,記住,不是上次完整備份。在應用交易記錄備份時將前滾所有的事務記錄,並且這些記錄應該是連續的,另外也會復原沒有COMMIT的日誌記錄
這些老掉牙的話應該好好的理解,最起碼在面試的時候應該很流利的背出來,下面看一個比較常見的錯誤。
問題1:
/*
伺服器: 訊息 4305,層級 16,狀態 1,行 2
此備份組中的日誌開始於 LSN 641000000005900001,該 LSN 太晚,無法應用到資料 庫。包含 LSN 641000000005600001 的較早的記錄備份可以還原。
伺服器: 訊息 3013,層級 16,狀態 1,行 2
RESTORE LOG 操作異常終止。
*/
相信這個資訊只要是做過備份的人都知道,在應用完整備份+記錄備份恢複資料庫時提示只能應用程式資料庫備份,而記錄備份由於LSN太早或太晚無法應用,這是怎麼回事阿???LSN表示交易記錄記錄的唯一序號,SQL SERVER會記錄對資料庫的每次操作,這些操作總有個先來後到的,LSN就是系統發給他們的順序號,記錄備份恢複時要求所有的備份組疊加時能產生一個連續的LSN鏈,這個就是問題所在(如果對上述日誌概念不瞭解的話可以閱讀精華區SQL日誌概念這一篇,或是看BOL)。查看下備份檔案就可以知道答案
restore headeronly from disk = 'e:\chj733_dat.bck' ――Database Backup
restore headeronly from disk = 'e:\chj733_log.bck' ――記錄備份
結果(我只列出了比較有用的幾項)
―――――――――――――――――――――――――――――――――――――
Position FirstLsn LastLsn
1 641000000005400001 641000000005600001 ――資料備份
1 641000000005900001 641000000006100001 ――記錄備份
―――――――――――――――――――――――――――――――――――――
position表示這個裝置中備份組的位置,不是可以在一個裝置裡多次備份的嗎?每備份一次就產生一個備份組,按先後順序一直排列下來,Position就可以定位你想應用那個備份組,對應於restore中的with file的值,這裡我只備份了一次,所以就只有一個集
FirstLsn和LastLsn:分別標識這個備份組中的起始事務鏈號和終止事務鏈號
當你運用這兩個備份還原資料庫時,系統會讀取備份組的頭資訊,判斷這些鏈號是不是連續的,很顯然資料備份最後的是641000000005600001,日誌開頭的是641000000005900001,中間差了一截,所以從這個以後的所有記錄備份都不能運用了,就像火車車廂一樣,前面斷了,你後面連得再好也跑不起來,你會發現有時候日誌的FirstLsn會小於資料的LastLsn,這個也徵實了記錄備份是從上次記錄備份結尾處開始的說法,但記錄備份的LastLsn不能小於資料備份的LastLsn
一般容易出現像這種日誌脫節的操作是切換恢複模型,從簡單切換到完全恢複,很多新手都是這樣,資料庫建好了用了幾天,做個完整備份,然後在做記錄備份,結果報錯說簡單模型不能做記錄備份,於是切換到完全模型繼續記錄備份,這樣日誌鏈就脫節了,解決方案是備份後用restore headeronly查看下日誌鏈是否完整,不完整的話需要重做完整備份或差異備份,再繼續記錄備份,如果到資料庫出現故障時再檢查,那你就準備捲鋪蓋走人吧
這應該比較細的東西了,沒有真正做過又怎會知道裡面的來龍去脈呢?記得公司有個同事曾對我說:“備份很簡單阿,就是幾條load語句嘛,記住就搞定啦”我從不說備份很難,但我敢肯定,叫他來做備份,不哭爹喊娘才怪!!!另外如果你只是在像pubs這種只有50M的資料庫上非常流暢的運行了上面所說的各種語句的話,你就可以對大家說你會寫備份語句,但不要說你會備份,遇到一個900多G的資料庫,情況就大不一樣了,就像打星際一樣,掌握如何造兵,是怎麼個順序,每個兵的攻擊範圍很容易,但如何在短時間既要偵察敵情,防止敵人騷擾,又要造出數量可觀的兵種,靈活搭配應付各種各樣的戰爭場面就難了
最後的話題:
也許有人對恢複語句後面的with file子句不大理解,或是對於備份組,家族成員,媒體集這些概念混淆不清,其實這些概念不需要記住,你只要知道備份是以什麼個形式存在就可以了,當備份到一個裝置上時,可以追加備份,也可以覆蓋以前的備份,每追加一次,這個裝置上的檔案就多了一個,這個檔案就是說說的備份組,with file = 2就標識你要應