|
一般的公司通常會(huì)在他們的信息系統(tǒng)架構(gòu)中引入多種數(shù)據(jù)庫(kù)平臺(tái),同時(shí)引入三到四種不同的RDBMS解決方案的中大型公司也并不少見(jiàn),當(dāng)然這些公司里面的DBA們通常也需要同時(shí)擁有管理多種不同平臺(tái)的技能了。
只在一種平臺(tái)上展開(kāi)工作的數(shù)據(jù)庫(kù)專家們也通常會(huì)期待著在他們的下一份工作中能學(xué)到點(diǎn)不一樣的東西,那些有勇氣的人們則愿意花時(shí)間、金錢和精力去學(xué)習(xí)新的東西,也有其他因?yàn)閾Q了新公司或者是為了找新的工作而去學(xué)習(xí)新的系統(tǒng)的人們,毋庸置疑的一點(diǎn)就是公司老板和人力專家們會(huì)更加青睞于那些擁有多個(gè)領(lǐng)域經(jīng)驗(yàn)的求職者。
依我個(gè)人的經(jīng)驗(yàn)來(lái)看,在學(xué)習(xí)一個(gè)新的數(shù)據(jù)平臺(tái)的時(shí)候,最好的方法就是在新的環(huán)境中去發(fā)現(xiàn)那些你已知的東西,這樣學(xué)習(xí)起來(lái)會(huì)簡(jiǎn)單很多。當(dāng)然,當(dāng)中也會(huì)遇到一些全新的概念需要去學(xué)習(xí),或者是忘掉一些你現(xiàn)在已知的概念,但不管怎么說(shuō)你不是從零開(kāi)始的。比如說(shuō)一個(gè)做SQL Server開(kāi)發(fā)人員在要寫Oracle存儲(chǔ)過(guò)程的時(shí)候可能會(huì)先去找那些內(nèi)置的函數(shù)然后比較它們之間不同點(diǎn),她也可能會(huì)去比較變量聲明以及錯(cuò)誤處理的異同。
本系列文章中我將嘗試對(duì)Microsoft SQL Server和Oracle RDBMS(以10g及以后的版本為主)進(jìn)行一個(gè)深入的比較。我會(huì)主要集中于這兩種數(shù)據(jù)庫(kù)之間架構(gòu)上的比較,當(dāng)然不要期望我會(huì)給你一個(gè)詳盡的比較清單,但是我會(huì)盡我所能的讓你看清這兩種當(dāng)今世上應(yīng)用最廣的數(shù)據(jù)庫(kù)之間的相同和相異之處。本文是以一個(gè)SQL Server DBA的角度去構(gòu)思和寫作的,不過(guò)相信這對(duì)Oracle專家門了解SQL Server這一面也是很有參考價(jià)值的。
廢話少說(shuō),開(kāi)工吧。
top操作系統(tǒng)的支持 Microsoft SQL Server向來(lái)都從屬于Windows大家族中的一員,要讓Microsoft發(fā)布一個(gè)支持其它操作系統(tǒng)版本的可能性當(dāng)然是小之又小的了。當(dāng)前來(lái)說(shuō)SQL Server可以在XP、Vista、Windows Server 2000、2003、2008上運(yùn)行,同時(shí)也有針對(duì)于32位和64位版本W(wǎng)indows的數(shù)據(jù)庫(kù)版本。 對(duì)Oracle來(lái)說(shuō),它支持多種不同的操作系統(tǒng)平臺(tái),包括Windows(32位和64位),另外還有支持Linux和不同分支的Unix(Solaris、HP-UX、AIX等等)
top版本和發(fā)行版 在本寫作時(shí),Microsoft數(shù)據(jù)庫(kù)產(chǎn)品的最新版本是SQL Server 2008,即將推出的下一版本是SQL Server 2008 R2,現(xiàn)在已經(jīng)在CTP階段了,它的上一個(gè)版本,SQL Server 2005,相對(duì)于再之前的SQL Server 2000的一個(gè)大升級(jí)。不過(guò)對(duì)很多公司來(lái)說(shuō)SQL Server 2005還是有點(diǎn)新,因?yàn)樗麄儸F(xiàn)在還是在大量的使用著SQL Server 2000. 另一方面Oracle一路走來(lái)最新版本已經(jīng)到了11gR2了,現(xiàn)在主流應(yīng)用的版本10gR2已經(jīng)發(fā)行有一段時(shí)間,已經(jīng)是公認(rèn)的領(lǐng)頭羊了。Oracle在10g中第一次提出“網(wǎng)格計(jì)算”的概念。當(dāng)然現(xiàn)在還有公司依然在依賴于Oracle 9i處理業(yè)務(wù)。
說(shuō)到發(fā)行版,SQL Server 2008 R2現(xiàn)在提供下面這么些版本:
企業(yè)版
企業(yè)版包含所有的高級(jí)特性,適用于大規(guī)模、高容量的數(shù)據(jù)庫(kù)需求。 標(biāo)準(zhǔn)版 標(biāo)準(zhǔn)版為那些不需要包含企業(yè)版高級(jí)特性的公司提供了一個(gè)相對(duì)便宜的數(shù)據(jù)庫(kù)平臺(tái),大部分公司使用的都是標(biāo)準(zhǔn)版的數(shù)據(jù)庫(kù)。 工作組版 工作組版適用于小的部門級(jí)別的應(yīng)用。 Web版 這個(gè)適用于作為Web應(yīng)用的低成本的后臺(tái)解決方案。 Express版 這是一個(gè)很小的內(nèi)嵌式的SQL Server引擎,通常用于本地?cái)?shù)據(jù)存儲(chǔ)或是小規(guī)模的系統(tǒng)開(kāi)發(fā)。Express版可以免費(fèi)下載并且自由分發(fā)。 Compact版 Compact版可以讓用戶開(kāi)發(fā)Windows桌面或者是手持設(shè)備的應(yīng)用。 開(kāi)發(fā)版 所有企業(yè)版所擁有的功能開(kāi)發(fā)版都有,不過(guò)它僅僅授權(quán)單個(gè)用戶訪問(wèn),主要用于開(kāi)發(fā)或是測(cè)試目的。 除了企業(yè)版,SQL Server 2008 R2還為數(shù)據(jù)中心和數(shù)據(jù)倉(cāng)庫(kù)提供兩個(gè)“白金版”,這兩個(gè)版本分別稱為數(shù)據(jù)中心版(Datacenter Edition)和并行數(shù)據(jù)倉(cāng)庫(kù)版(Parallel Data Warehouse Edition)。 對(duì)于Oracle 11g R2,發(fā)行版是這么樣的:
企業(yè)版
這個(gè)版本提供了頂級(jí)的性能,同時(shí)價(jià)錢也是頂級(jí)的。像SQL Server的企業(yè)版一樣,所有這個(gè)產(chǎn)品能提供的特性在這個(gè)版本里面都有。 標(biāo)準(zhǔn)版 這個(gè)和SQL Server標(biāo)準(zhǔn)版很像,Oracle標(biāo)準(zhǔn)版包含了大部分業(yè)務(wù)應(yīng)用所需要的大部分特性。 標(biāo)準(zhǔn)版1 這個(gè)版本為小型工作組應(yīng)用而設(shè)計(jì),授權(quán)最小的用戶為5。 Express版 這個(gè)目標(biāo)客戶是小規(guī)模應(yīng)用或者是數(shù)據(jù)庫(kù)開(kāi)發(fā)入門,可以免費(fèi)分發(fā)?,F(xiàn)在Express版還處于10g R2版本。 下表提供了SQL Server和Oracle數(shù)據(jù)庫(kù)發(fā)行版的直觀的對(duì)比: SQL Server Oracle
Enterprise Edition Enterprise Edition Standard Edition Standard Edition Workgroup Edition Standard Edition One Express edition Express Edition Web Edition X Compact Edition X Developer Edition Enterprise Edition top實(shí)例、數(shù)據(jù)庫(kù)和表空間 SQL Server和Oracle之間第一個(gè)架構(gòu)級(jí)別的差異就在于對(duì)實(shí)例(instance)和數(shù)據(jù)庫(kù)(database)概念的定義了。 SQL Server中,實(shí)例一詞用來(lái)代表一個(gè)包含了操作系統(tǒng)文件、內(nèi)存結(jié)構(gòu)、后臺(tái)進(jìn)程以及注冊(cè)表信息的獨(dú)立的應(yīng)用服務(wù)。在Windows系統(tǒng)中用一個(gè)存在著停止和運(yùn)行狀態(tài)的服務(wù)來(lái)代表一個(gè)實(shí)例,當(dāng)處于運(yùn)行狀態(tài)時(shí),實(shí)例要占用一定的服務(wù)器內(nèi)存以及生成一定數(shù)量的后臺(tái)進(jìn)程。
SQL Server實(shí)例的中心是數(shù)據(jù)庫(kù)。一個(gè)SQL Server數(shù)據(jù)庫(kù)指的是一個(gè)資料庫(kù)以及操作數(shù)據(jù)所需要的程序代碼,當(dāng)實(shí)例沒(méi)有運(yùn)行時(shí),實(shí)例中的數(shù)據(jù)庫(kù)就不能夠訪問(wèn)。
SQL Server有兩種數(shù)據(jù)庫(kù):系統(tǒng)數(shù)據(jù)庫(kù)(system databases)和用戶數(shù)據(jù)庫(kù)(user databases)。在一個(gè)SQL Server實(shí)例安裝完成之后,將會(huì)自動(dòng)創(chuàng)建5個(gè)系統(tǒng)數(shù)據(jù)庫(kù):master, model, msdb, tempdb和resource。如果一個(gè)機(jī)器上面安裝了多個(gè)SQL Server實(shí)例時(shí),沒(méi)有實(shí)例都會(huì)有自己?jiǎn)为?dú)的一套系統(tǒng)數(shù)據(jù)庫(kù)。除了msdb數(shù)據(jù)庫(kù)之外,其它數(shù)據(jù)庫(kù)不能訪問(wèn)或是被損壞都會(huì)導(dǎo)致實(shí)例無(wú)法啟動(dòng)。相比之下用戶數(shù)據(jù)庫(kù)由DBA或者是開(kāi)發(fā)人員在數(shù)據(jù)庫(kù)實(shí)例安裝完畢、系統(tǒng)數(shù)據(jù)庫(kù)都啟動(dòng)之后所創(chuàng)建的,這些數(shù)據(jù)庫(kù)中保存著公司的業(yè)務(wù)資料。
簡(jiǎn)而言之,一個(gè)SQL Server實(shí)例總是要包含一些數(shù)據(jù)庫(kù)(盡管有時(shí)只是那些系統(tǒng)數(shù)據(jù)庫(kù)),一個(gè)數(shù)據(jù)庫(kù)也總是要有一個(gè)(且僅有一個(gè))與之關(guān)聯(lián)的實(shí)例。
從物理角度說(shuō),一個(gè)SQL Server數(shù)據(jù)庫(kù)表現(xiàn)為存儲(chǔ)于磁盤上面的一組操作系統(tǒng)文件的集合。數(shù)據(jù)庫(kù)文件分為兩種:數(shù)據(jù)文件(data file)和事務(wù)日志文件(transaction log file)。一個(gè)數(shù)據(jù)庫(kù)至少要包含一個(gè)數(shù)據(jù)文件和一個(gè)事務(wù)日志文件,SQL Server數(shù)據(jù)庫(kù)的資料主要是存在于數(shù)據(jù)文件中,事務(wù)日志文件用來(lái)記錄發(fā)生在這些數(shù)據(jù)上面的變更記錄,SQL Server在執(zhí)行系統(tǒng)恢復(fù)的時(shí)候要用到它。一個(gè)數(shù)據(jù)文件或事務(wù)日志文件只能隸屬于一個(gè)特定的數(shù)據(jù)庫(kù),不存在兩個(gè)數(shù)據(jù)庫(kù)共用一個(gè)數(shù)據(jù)文件或者是日志文件的情況。一個(gè)數(shù)據(jù)量很大的數(shù)據(jù)庫(kù)可以使用多個(gè)數(shù)據(jù)文件,這些數(shù)據(jù)文件能夠被邏輯的組合成一個(gè)稱為文件組(file group)的邏輯組。
在Oracle中,這一切看起來(lái)都有點(diǎn)反著來(lái)了。當(dāng)Oracle啟動(dòng)時(shí),它和SQL Server一樣要先占用一些服務(wù)器內(nèi)存用于執(zhí)行操作,這個(gè)內(nèi)存區(qū)域——著名的SGA(System Global Area)——被分為數(shù)個(gè)不同的結(jié)構(gòu),在創(chuàng)建SGA的同時(shí)也會(huì)啟動(dòng)一系列的后臺(tái)進(jìn)程用于和SGA進(jìn)行交互,在這里這些分配的內(nèi)存空間和后臺(tái)進(jìn)程組合起來(lái)就是Oracle實(shí)例了。請(qǐng)注意現(xiàn)在我們沒(méi)有見(jiàn)到數(shù)據(jù)庫(kù)的影子還,實(shí)際上Oracle實(shí)例在沒(méi)有數(shù)據(jù)庫(kù)或是數(shù)據(jù)庫(kù)不能訪問(wèn)時(shí)也是跑的很好的,在安裝Oracle時(shí),我們可以選擇只安裝軟件,完了之后再安裝數(shù)據(jù)庫(kù)。
Oracle中的數(shù)據(jù)包含了一組操作系統(tǒng)文件。不像SQL Server數(shù)據(jù)庫(kù),Oracle數(shù)據(jù)庫(kù)并不能代表數(shù)據(jù)庫(kù)對(duì)象的邏輯分組,它更像是表示包含多個(gè)存在于磁盤上的用來(lái)保存數(shù)據(jù)的文件的一個(gè)單個(gè)的集合名詞。
組成Oracle數(shù)據(jù)庫(kù)的文件可以分成三個(gè)類型:數(shù)據(jù)文件(data file)、重做日志文件(redo log file)和控制文件(control file)。數(shù)據(jù)文件保存數(shù)據(jù),Oracle中可以存在任意數(shù)量的數(shù)據(jù)文件;重做日志文件跟SQL Server的事務(wù)日志文件一樣用來(lái)保存對(duì)數(shù)據(jù)更改的記錄,在系統(tǒng)恢復(fù)階段需要用到;控制文件是一些特別的小文件,用來(lái)保存一些至關(guān)重要的關(guān)于數(shù)據(jù)庫(kù)的信息,沒(méi)有這個(gè)文件的話,實(shí)例就無(wú)法打開(kāi)數(shù)據(jù)庫(kù)。
除了數(shù)據(jù)文件、重做日志文件、控制文件之外,數(shù)據(jù)庫(kù)還包含參數(shù)文件(parameter file)、密碼文件(password file)和可選的歸檔日志文件(archive log files),后面很快會(huì)對(duì)這些文件類型展開(kāi)討論。
Oracle系統(tǒng)啟動(dòng)時(shí),首先在內(nèi)存中創(chuàng)建數(shù)據(jù)庫(kù)實(shí)例,然后由實(shí)例找到保存在磁盤中的數(shù)據(jù)庫(kù),最后打開(kāi)數(shù)據(jù)庫(kù)讓用戶操作。當(dāng)系統(tǒng)關(guān)閉時(shí),實(shí)例會(huì)從內(nèi)存中清除掉:整個(gè)內(nèi)存結(jié)構(gòu)和后臺(tái)進(jìn)程都會(huì)消失,但是數(shù)據(jù)庫(kù)依然存在于磁盤上,只是處于關(guān)閉的狀態(tài)。之前也說(shuō)過(guò),Oracle實(shí)例可以在不打開(kāi)數(shù)據(jù)庫(kù)的情況下運(yùn)行——這是與SQL Server數(shù)據(jù)庫(kù)最大的不同,SQL Server實(shí)例是不能夠離開(kāi)系統(tǒng)數(shù)據(jù)庫(kù)而運(yùn)行的。不過(guò)和SQL Server一樣Oracle數(shù)據(jù)庫(kù)在實(shí)例沒(méi)有啟動(dòng)的情況下也是不能訪問(wèn)的。
一般來(lái)說(shuō)Oracle實(shí)例和數(shù)據(jù)庫(kù)之間是一對(duì)一的關(guān)系。一個(gè)實(shí)例對(duì)應(yīng)著一個(gè)數(shù)據(jù)庫(kù),但是一個(gè)數(shù)據(jù)庫(kù)卻可以同時(shí)由多個(gè)實(shí)例去訪問(wèn)它。一個(gè)獨(dú)立的Oracle安裝包含一個(gè)實(shí)例和一個(gè)供實(shí)例操作的數(shù)據(jù)庫(kù),而配置成RAC(Real Application Cluster)的安裝則可以允許多個(gè)存在于不同機(jī)器上的實(shí)例訪問(wèn)存在于一個(gè)共享磁盤上面的數(shù)據(jù)庫(kù)。
那Oracle中數(shù)據(jù)庫(kù)對(duì)象的邏輯分組在那兒呢?在SQL Server中邏輯分組由數(shù)據(jù)庫(kù)自己來(lái)完成,而在Oracle中,這項(xiàng)工作由表空間(tablespace)完成,Oracle表空間是用來(lái)對(duì)表、視圖、索引和其他數(shù)據(jù)庫(kù)對(duì)象進(jìn)行分組的邏輯結(jié)構(gòu)。例如,你的Oracle產(chǎn)品庫(kù)可以給HR應(yīng)用一個(gè)單獨(dú)的表空間,支付應(yīng)用則使用另外一個(gè)。一個(gè)數(shù)據(jù)庫(kù)可以邏輯的分成若干個(gè)表空間,這些表空間在物理上則由一個(gè)或者多個(gè)數(shù)據(jù)文件組成。因此在Oracle中與SQL Server數(shù)據(jù)庫(kù)等價(jià)的是表空間。
由于這兩種結(jié)構(gòu)在功能上相當(dāng)類似,在SQL Server中建立數(shù)據(jù)庫(kù)的過(guò)程和在Oracle中建立表空間的過(guò)程也非常相似。不管是建立數(shù)據(jù)庫(kù)還是表空間,DBA都要首先指定一個(gè)名字,然后給新建的數(shù)據(jù)庫(kù)或者表空間分配一個(gè)或多個(gè)數(shù)據(jù)文件,并為每個(gè)數(shù)據(jù)文件指定初始大小和數(shù)據(jù)增長(zhǎng)情況。
在SQL Server中可以做到讓一個(gè)用戶數(shù)據(jù)庫(kù)離線或是只讀,Oracle的用戶表空間也一樣可以。在SQL Server中可以讓一個(gè)用戶數(shù)據(jù)庫(kù)中的一個(gè)或者多個(gè)數(shù)據(jù)文件只讀,而Oracle用戶表空間中的一個(gè)或者多個(gè)數(shù)據(jù)文件也同樣能標(biāo)記為離線。
不過(guò)數(shù)據(jù)庫(kù)和表空間在某些方面還是有差別的:
SQL Server中,數(shù)據(jù)文件可以用文件組邏輯的進(jìn)行分組,而Oracle表空間就沒(méi)有類似的概念。
SQL Server的每個(gè)數(shù)據(jù)庫(kù)都有自己的事務(wù)日志文件,而且在創(chuàng)建數(shù)據(jù)庫(kù)的時(shí)候就要指定這些日志文件的屬性。而在Oracle中整個(gè)數(shù)據(jù)庫(kù)(意為所有的表空間)的事務(wù)日志都是記錄在同樣的一樣重做日志中,因此也不存在說(shuō)給每個(gè)表空間建立一個(gè)單獨(dú)的日志文件的說(shuō)法。 SQL Server中,數(shù)據(jù)庫(kù)可以設(shè)置成簡(jiǎn)單恢復(fù)模式(simple recovery mode),簡(jiǎn)單恢復(fù)模式指的是活動(dòng)的數(shù)據(jù)庫(kù)日志在checkpoint操作完成之后就會(huì)截?cái)?。Oracle也有類似的概念,這個(gè)稍后會(huì)說(shuō)到,不過(guò)不能在表空間級(jí)別上進(jìn)行這樣的設(shè)置。 top實(shí)例名和SID
SQL Server和Oracle都允許在同一個(gè)機(jī)器上面同時(shí)運(yùn)行多個(gè)實(shí)例,多個(gè)實(shí)例的執(zhí)行環(huán)境是完全獨(dú)立的:就單個(gè)的數(shù)據(jù)庫(kù)引擎而言,它并不知道也不關(guān)心有沒(méi)有其他的實(shí)例在這個(gè)機(jī)器上運(yùn)行著。 在SQL Server中這種機(jī)制通過(guò)實(shí)例這個(gè)概念來(lái)實(shí)現(xiàn),SQL Server可以作為一個(gè)命名的(named) 或是 默認(rèn)(default) 的實(shí)例來(lái)運(yùn)行,默認(rèn)實(shí)例的名字和運(yùn)行它的Windows服務(wù)器的名字一樣,顯然一個(gè)系統(tǒng)的默認(rèn)實(shí)例只可能存在一個(gè),不過(guò)在一個(gè)機(jī)器上可以存在多個(gè)命名的實(shí)例,命令實(shí)例的名字格式為 HOSTNAME\INSTANCE_NAME ,同一個(gè)主機(jī)上每個(gè)運(yùn)行實(shí)例的 INSTANCE_NAME 必須是唯一的,每個(gè)實(shí)例都有著自己的一套程序文件以及一些與其它實(shí)例共享的通用組件。
而Oracle也差不多,在安裝Oracle的時(shí)候,DBA就需要指定一個(gè) 全局?jǐn)?shù)據(jù)庫(kù)名(Global Database Name)和系統(tǒng)標(biāo)識(shí)符(SID, System Identifier)。Oracle中實(shí)例和數(shù)據(jù)庫(kù)是完全不同的東西,一個(gè)全局?jǐn)?shù)據(jù)庫(kù)名用來(lái)在網(wǎng)絡(luò)上唯一的識(shí)別一個(gè)數(shù)據(jù)庫(kù)的存放位置,一個(gè)完整的名字通常是下面的格式database_name.network_domain_name。SID則是用來(lái)識(shí)別一個(gè)與數(shù)據(jù)庫(kù)關(guān)聯(lián)的實(shí)例,大都數(shù)情況下一個(gè)實(shí)例關(guān)聯(lián)一個(gè)單個(gè)的數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)名和SID名字會(huì)是一樣。RAC環(huán)境中就不一樣了,RAC允許多個(gè)實(shí)例訪問(wèn)放在共享存儲(chǔ)中的同一個(gè)數(shù)據(jù)庫(kù),此時(shí)的實(shí)例名和數(shù)據(jù)庫(kù)名字將不一樣。當(dāng)然和SQL Server一樣,一個(gè)Oracle數(shù)據(jù)庫(kù)服務(wù)器上面是不允許兩個(gè)實(shí)例使用同一個(gè)SID的,另外一點(diǎn)類似的就是在安裝時(shí)一旦指定,不管是SQL Server實(shí)例名還是Oracle SID都是不能再修改了(譯注:實(shí)際上Oracle從9i開(kāi)始就提供一個(gè)叫nid的工具用來(lái)修改數(shù)據(jù)庫(kù)名了)。
SQL Server DBA可以通過(guò)下面的語(yǔ)句查詢當(dāng)前登錄系統(tǒng)的實(shí)例名:
1 SELECT @@SERVERNAME
Oracle DBA用來(lái)查詢實(shí)例名和數(shù)據(jù)名的語(yǔ)句如下:
1 SELECT INSTANCE_NAME, HOST_NAME, VERSION, DATABASE_STATUS FROM V$INSTANCE; 2 SELECT NAME, DATABASE_ROLE, CREATED FROM V$DATABASE;
top系統(tǒng)數(shù)據(jù)庫(kù)和系統(tǒng)表空間 一個(gè)SQL Server實(shí)例需要有5個(gè)系統(tǒng)數(shù)據(jù)庫(kù)(2005之前的是4個(gè)):master, model, msdb, tempdb和resource,一個(gè)Oracle數(shù)據(jù)庫(kù)則最少需要3個(gè)系統(tǒng)表空間才能正常操作,它們是:SYSTEM, SYSAUX和TEMP。 master和resource數(shù)據(jù)庫(kù)集中保存了SQL Server自身管理所需要的所有信息,里面保存了諸如系統(tǒng)配置,數(shù)據(jù)庫(kù)列表和文件路徑、終結(jié)點(diǎn)、連接服務(wù)器和用戶帳戶(或“登錄”信息),系統(tǒng)級(jí)別的對(duì)象存儲(chǔ)在只讀的數(shù)據(jù)庫(kù)”資源(resource)”中。
在Oracle中,SYSTEM表空間等價(jià)于master數(shù)據(jù)庫(kù),SYSTEM表空間包含了數(shù)據(jù)字典(data dictionary),也就是關(guān)于Oracle自身的元數(shù)據(jù)(metadata),這里的數(shù)據(jù)字典可以和SQL Server中的resource數(shù)據(jù)庫(kù)進(jìn)行類比。到這里你也許猜到了:如果SYSTEM不存在或是損壞了的話Oracle數(shù)據(jù)庫(kù)是打不開(kāi)的。
對(duì)于一個(gè)SQL Server實(shí)例,model數(shù)據(jù)庫(kù)用作這個(gè)實(shí)例中所有新建的數(shù)據(jù)庫(kù)的“模板”,對(duì)model數(shù)據(jù)庫(kù)的任何修改都會(huì)反應(yīng)到之后新建的其它數(shù)據(jù)庫(kù)里面。在Oracle中就沒(méi)有這樣的模板,不過(guò)在你新建一個(gè)表空間的時(shí)候,你可以指定這是一個(gè)永久的表空間或者是其他類似TEMP和UNDO一樣的表空間,永久表空間才是用來(lái)保存用戶數(shù)據(jù)的。
SQL Server的tempdb用作整個(gè)實(shí)例的“試驗(yàn)田”,每次實(shí)例重新啟動(dòng)的時(shí)候tempdb都會(huì)重新創(chuàng)建。Oracle的TEMP表空間的作用類似:用來(lái)包括大的排序操作的中間結(jié)果。當(dāng)然SQL Server的tempdb還能用來(lái)保存行版本(row versioning)所需要的信息,當(dāng)行版本啟用后,行版本特性可以保證數(shù)據(jù)庫(kù)引擎能將數(shù)據(jù)行的每次的修改記錄保留下來(lái),修改之前的行會(huì)保存在tempdb里面的版本庫(kù)中,一般查詢會(huì)返回一個(gè)數(shù)據(jù)行上最后提交的版本,當(dāng)一個(gè)使用了特定隔離級(jí)別的依賴行版本的讀操作不再會(huì)阻塞其它修改同樣數(shù)據(jù)的事務(wù),這是因?yàn)樽x操作不會(huì)在數(shù)據(jù)行上使用共享鎖。不過(guò)這個(gè)特性需要在單個(gè)數(shù)據(jù)庫(kù)上單獨(dú)啟用。
Oracle中使用一個(gè)單獨(dú)的表空間——著名的UNDO表空間——來(lái)達(dá)成同樣目的。UNDO表空間保存著被DML語(yǔ)句修改的數(shù)據(jù)塊的讀一致性的副本。當(dāng)用戶開(kāi)始對(duì)數(shù)據(jù)進(jìn)行修改的時(shí)候,修改之前的數(shù)據(jù)塊會(huì)被保存到UNDO表空間中,當(dāng)另外一個(gè)用戶需要查詢這些數(shù)據(jù)的時(shí)候,他取到的實(shí)際上是UNDO表空間中查出來(lái)的讀一致性的版本。不像SQL Server的行版本,Oracle的UNDO不需要啟用——因?yàn)樗菍儆贠racle并行訪問(wèn)機(jī)制的一部分。
最后一個(gè)要介紹的SQL Server中的msdb數(shù)據(jù)庫(kù),SQL Server代理服務(wù)需要操作這個(gè)庫(kù)。SQL Server代理負(fù)責(zé)計(jì)劃任務(wù)、警告、復(fù)制、日志傳送以及其它的很多東西,代理服務(wù)的正常運(yùn)行離不開(kāi)msdb數(shù)據(jù)庫(kù)。
在Oracle沒(méi)有明確與mdsb數(shù)據(jù)對(duì)應(yīng)的東西。SYSAUX表空間也是一個(gè)系統(tǒng)表空間,在安裝過(guò)程中(譯注:準(zhǔn)確說(shuō)應(yīng)該為“數(shù)據(jù)庫(kù)創(chuàng)建過(guò)程中”)創(chuàng)建,它里面保存了諸如Oracle AWR(Automatic Workload Repository)信息、多維數(shù)據(jù)和多媒體數(shù)據(jù),XML數(shù)據(jù)庫(kù)等等。
v數(shù)據(jù)庫(kù)實(shí)例結(jié)構(gòu)
當(dāng)Oracle實(shí)例啟動(dòng)之后,所看到的就是在服務(wù)器內(nèi)存上的一個(gè)個(gè)不同內(nèi)存塊加上產(chǎn)生的與這些內(nèi)存交互的后臺(tái)進(jìn)程。Oracle文檔將這些內(nèi)存結(jié)構(gòu)和進(jìn)程收的很詳細(xì)。
由Oracle實(shí)例所占用的內(nèi)存塊成為SGA(System Global Area),它的大小可以通過(guò)調(diào)整Oracle初始化參數(shù)(initialisation parameter)進(jìn)行修改,在SGA里邊至少會(huì)創(chuàng)建3個(gè)不同的區(qū)域,它們分別是:
數(shù)據(jù)塊緩存區(qū)(Database Buffer Cache)
這里緩存的是數(shù)據(jù)塊。和SQL Server一樣,用戶不會(huì)直接的訪問(wèn)數(shù)據(jù)文件上的數(shù)據(jù):當(dāng)讀取數(shù)據(jù)時(shí),相關(guān)的數(shù)據(jù)塊會(huì)從數(shù)據(jù)文件中拷貝到內(nèi)存中;修改數(shù)據(jù)時(shí)也是修改內(nèi)存中的數(shù)據(jù),然后再由單獨(dú)的進(jìn)程將數(shù)據(jù)緩存區(qū)中被修改的數(shù)據(jù)寫入到數(shù)據(jù)庫(kù)中。 重做日志緩存(Redo Log Buffer) SGA中的這個(gè)區(qū)域連續(xù)的記錄著數(shù)據(jù)緩存區(qū)數(shù)據(jù)修改的記錄,重做日志緩存中的內(nèi)容會(huì)被寫入到在線日志文件中去。 共享池(Shared Pool) SGA中有一大塊的內(nèi)存用作共享池,共享池等價(jià)于SQL Server中的執(zhí)行緩存(Procedure Cache)。它的主要作用就是緩存數(shù)據(jù)庫(kù)中最近執(zhí)行過(guò)的SQL語(yǔ)句。共享池由下面的模塊組成: 數(shù)據(jù)字典緩存(Dictionary Cache) 數(shù)據(jù)字典緩存緩存了Oracle最近使用的數(shù)據(jù)字典信息。 庫(kù)緩存(Library Cache) 這個(gè)區(qū)域包含了最近執(zhí)行的SQL和PL/SQL語(yǔ)句和對(duì)應(yīng)的執(zhí)行計(jì)劃。SQL區(qū)還能進(jìn)一步分成共享區(qū)和私有區(qū):共享SQL區(qū)保存的語(yǔ)句可以由多個(gè)用戶使用而私有區(qū)保存的則是跟各個(gè)連接對(duì)應(yīng)的綁定變量的信息。PL/SQL是Oracle對(duì)于行業(yè)標(biāo)準(zhǔn)SQL的程序擴(kuò)展,當(dāng)PL/SQL程序執(zhí)行時(shí),它的代碼會(huì)拷貝到庫(kù)緩存中的共享PL/SQL區(qū)中。除了緩存執(zhí)行代碼和執(zhí)行計(jì)劃外,庫(kù)緩存還包含鎖、閥以及字符集等信息。 根據(jù)你所使用的組件的不一樣,Oracle的SGA中也可能存在其它一些可選的內(nèi)存區(qū)域。在Oracle中使用Java應(yīng)用時(shí)要使用到Java池(Java Pool),Oracle內(nèi)置的備份恢復(fù)工具RMAN(Recovery Manager)要用到大池(Large Pool),當(dāng)使用Oracle高級(jí)隊(duì)列機(jī)制時(shí)要用到流池(Steams Pool)。 上面介紹的各個(gè)內(nèi)存區(qū)域都是屬于SGA的一部分,它們是通過(guò)一序列的進(jìn)程(process)來(lái)和數(shù)據(jù)庫(kù)進(jìn)行交互。下面就開(kāi)始介紹包括用戶進(jìn)程和服務(wù)器進(jìn)程在內(nèi)的Oracle進(jìn)程了。
當(dāng)用戶或者是應(yīng)用連接到Oracle數(shù)據(jù)庫(kù)時(shí)就會(huì)產(chǎn)生一個(gè)用戶進(jìn)程(user process)。在一個(gè)兩層的系統(tǒng)架構(gòu)中,用戶進(jìn)程存在于客戶端機(jī)器上;而在一個(gè)三層的系統(tǒng)架構(gòu)中,用戶進(jìn)程由中間層產(chǎn)生。一旦用戶進(jìn)程連接到Oracle監(jiān)聽(tīng)服務(wù)(Listener Service)時(shí),監(jiān)聽(tīng)器就會(huì)為這個(gè)用戶會(huì)話產(chǎn)生一個(gè)服務(wù)器進(jìn)程(server process)。再說(shuō)詳細(xì)點(diǎn)就是,Oracle監(jiān)聽(tīng)器是一個(gè)負(fù)責(zé)為Oracle處理近來(lái)連接的網(wǎng)絡(luò)組件,監(jiān)聽(tīng)器本身是一個(gè)單獨(dú)的進(jìn)程,負(fù)責(zé)監(jiān)視著從客戶端過(guò)來(lái)的連接請(qǐng)求,如果監(jiān)聽(tīng)器沒(méi)有運(yùn)行的話,數(shù)據(jù)庫(kù)也就無(wú)法連接了。一旦連接建立,由監(jiān)聽(tīng)器產(chǎn)生的服務(wù)器進(jìn)程就開(kāi)始接手處理用戶操作數(shù)據(jù)庫(kù)的請(qǐng)求了。大多情況下每個(gè)用戶連接會(huì)產(chǎn)生一個(gè)獨(dú)立的服務(wù)器進(jìn)程,不過(guò)Oracle也能配置成一個(gè)運(yùn)行著多個(gè)預(yù)先創(chuàng)建好的服務(wù)器進(jìn)程池的模式,此時(shí)用戶進(jìn)程連接到數(shù)據(jù)庫(kù)實(shí)例之后將會(huì)直接從進(jìn)程池中分配一個(gè)進(jìn)程。
任何時(shí)候Oracle實(shí)例中都會(huì)有多個(gè)后臺(tái)進(jìn)程在運(yùn)行著,不過(guò),有5個(gè)必須要有的。
寫數(shù)據(jù)庫(kù)(Database Writer)進(jìn)程或稱DBWn負(fù)責(zé)將數(shù)據(jù)緩存區(qū)中被修改的數(shù)據(jù)庫(kù)寫入到數(shù)據(jù)文件中。為提高系統(tǒng)系能Oracle可以最多創(chuàng)建20個(gè)這樣的進(jìn)程,DBWn中的n代表著一個(gè)單獨(dú)的進(jìn)程:n取值范圍是0到9和a到j(luò)。
在DBWn進(jìn)程將臟塊寫入到數(shù)據(jù)文件的同時(shí),一個(gè)叫日志寫入(Log Writer, LGWR)的進(jìn)程也在降日志緩存中的日志寫入到在線日志中去。LGWR執(zhí)行的要比DBWn進(jìn)程頻繁得多,主要原因有兩點(diǎn):首先是要盡快的將事務(wù)信息寫入到磁盤當(dāng)中,以保證當(dāng)意外宕機(jī)等事件發(fā)生時(shí)數(shù)據(jù)庫(kù)能正?;謴?fù),在一個(gè)就是日志緩存中的日志信息記錄的不是實(shí)際的變化的數(shù)據(jù),但是卻是能夠反應(yīng)數(shù)據(jù)的變化——因此相比之下也就要小得多了。
檢查點(diǎn)(Checkpoint, CKPT)進(jìn)程負(fù)責(zé)定期的將SGA中的內(nèi)容同步到數(shù)據(jù)庫(kù)中。當(dāng)執(zhí)行檢查點(diǎn)時(shí),它會(huì)調(diào)用DBWn進(jìn)程將所有的臟塊寫入到數(shù)據(jù)文件中,同時(shí)將重做日志緩存中的內(nèi)容寫入到在線日志文件中,然后更新數(shù)據(jù)文件頭和控制文件的相關(guān)信息。
如果某個(gè)訪問(wèn)數(shù)據(jù)庫(kù)的進(jìn)程意外的死掉的話,那進(jìn)程監(jiān)視器(Process Monitor, PMON)就會(huì)在后臺(tái)悄悄的清理掉這個(gè)死掉的進(jìn)程,所進(jìn)行的操作包括釋放相應(yīng)的鎖、回收分配的資源已經(jīng)將這個(gè)進(jìn)程從活動(dòng)進(jìn)程中清理出去。PMON進(jìn)程有點(diǎn)像一個(gè)UNIX的daemon進(jìn)程:它會(huì)定期的喚醒以檢查看是否有清理工作要做。在必要的時(shí)候也能啟動(dòng)一個(gè)別的進(jìn)程或被其他的后臺(tái)進(jìn)程使喚。
在一個(gè)實(shí)例崩潰之后重啟時(shí),Oracle會(huì)自動(dòng)的調(diào)用系統(tǒng)監(jiān)視器(System Monitor, SMON)進(jìn)程,SMON會(huì)利用在線日志文件來(lái)完成崩潰恢復(fù)操作。
歸檔進(jìn)程(Archiver, ARCn)是Oracle實(shí)例中可選的幾種進(jìn)程之一,這里的n和之前說(shuō)的一樣都是代表著單個(gè)的進(jìn)程。只有在數(shù)據(jù)庫(kù)開(kāi)啟了歸檔模式(archive log mode)之后才會(huì)啟動(dòng)ARCn進(jìn)程,在在線日志中的內(nèi)容滿了之后,在Oracle覆蓋這些記錄之前ARCn進(jìn)程會(huì)將這些內(nèi)存保存到磁盤上,這些文件稱為歸檔日志(archive log),這樣的話在線日志內(nèi)容就不會(huì)丟掉了。
下圖顯示的是Oracle實(shí)例結(jié)構(gòu)的一個(gè)簡(jiǎn)化版。
最后,你可以通過(guò)下面語(yǔ)句來(lái)查看SGA各個(gè)組件的情況:
1 SELECT * FROM V$SGAINFO
下面的命令用來(lái)查看分配給Oracle實(shí)例的總內(nèi)存數(shù):
1 SHOW PARAMETER SGA_MAX_SIZE;
要查看一個(gè)實(shí)例上運(yùn)行的Oracle進(jìn)程情況可以使用下面的語(yǔ)句:
1 SELECT NAME, DESCRIPTION FROM V$BGPROCESS ORDER BY NAME
在一個(gè)運(yùn)行著的Microsoft SQL Server實(shí)例上,同樣維護(hù)者一些內(nèi)部的內(nèi)存結(jié)構(gòu)和后臺(tái)進(jìn)程,不過(guò)不像Oracle那樣,SQL Server并沒(méi)有公開(kāi)的詳細(xì)解釋內(nèi)部工作和架構(gòu)的文檔。
自2005版以后,SQL Server引入了一個(gè)叫SQLOS(SQL Operating System)的東西,不過(guò)跟名字所顯示的不一樣的是,這個(gè)東西既不是一個(gè)操作系統(tǒng),也不是對(duì)于OS API的一個(gè)封裝。它并不是一個(gè)通向非Windows平臺(tái)的橋梁或是一個(gè)用于框架開(kāi)發(fā)的類庫(kù)。
SQLOS是一套用于通過(guò)優(yōu)化與Windows系統(tǒng)接口而為SQL Server存儲(chǔ)和數(shù)據(jù)庫(kù)引擎提供關(guān)鍵服務(wù)的軟件,Windows是一個(gè)通用的OS:它并沒(méi)有為SQL Server而做特別的優(yōu)化。SQLOS則擔(dān)當(dāng)替代Windows而為SQL Server和管理核心系統(tǒng)服務(wù)的,SQLOS提供的服務(wù)包括:
內(nèi)存管理
資源管理 檢測(cè)和管理死鎖 異常處理 CLR組件托管 包括專用管理連接(Dedicated Administrator Connection, DAC)和動(dòng)態(tài)管理視圖(Dynamic Management Views, DMV)在內(nèi)的診斷功能 調(diào)度管理(馬上開(kāi)講) Windows下的應(yīng)用程序都是運(yùn)行在獨(dú)立的、受保護(hù)的內(nèi)存空間上,這些內(nèi)存空間被稱為虛擬地址空間(Virtual Address Spaces, VAS)。因?yàn)槊總€(gè)應(yīng)用的VAS都是不一樣的,因此一個(gè)應(yīng)用是不能往另外一個(gè)應(yīng)用的地址空間做寫入操作的,這樣保證了程序不會(huì)因?yàn)閲?yán)重的違規(guī)訪問(wèn)而崩潰。分配給應(yīng)用的VAS可能來(lái)自于物理內(nèi)存或者是頁(yè)面文件,又或者是兩者都有。頁(yè)面文件(paging file)又稱交換文件(swap file)是一個(gè)被Windows內(nèi)存管理器用來(lái)存放那些無(wú)法放進(jìn)物理內(nèi)存的數(shù)據(jù)的,這些數(shù)據(jù)被寫入到交換文件中,在應(yīng)用需要的時(shí)候被讀取出來(lái)。當(dāng)中所涉及到的虛擬內(nèi)存地址與物理內(nèi)存地址之間的轉(zhuǎn)換(在RAM和頁(yè)面文件中)時(shí)由Windows內(nèi)存管理器完成。從應(yīng)用的角度來(lái)說(shuō),它并不關(guān)心它的內(nèi)存究竟是存在什么地方的。對(duì)32位的Windows系統(tǒng),OS所能尋址的最大的VAS地址空間是4GB,默認(rèn)情況下這當(dāng)中的2G供操作系統(tǒng)內(nèi)核使用,剩下的2G提供給像SQL Server之類的應(yīng)用使用。不過(guò)通過(guò)修改boot.ini中的開(kāi)關(guān)(3G開(kāi)關(guān))設(shè)置可以讓W(xué)indows只給自己分配1G而剩下3G給應(yīng)用使用。要想在32位的機(jī)器上使用超過(guò)4GB內(nèi)存的話,SQL Server可以通過(guò)地址窗口化擴(kuò)展插件(Adress Windowing Extension, AWE)機(jī)制利用超出限制的內(nèi)存。在64位的系統(tǒng)上面Windows的內(nèi)存尋址通常就不是個(gè)問(wèn)題了,因?yàn)榇藭r(shí)的Windows可尋址的VAS空間達(dá)16TB。 作為同樣是Windows應(yīng)用的SQL Server,自然也是無(wú)法獨(dú)立于VAS規(guī)則之外的了。當(dāng)SQL Server啟動(dòng)之后,數(shù)據(jù)庫(kù)引擎就只能看到自己的VAS空間,緩存池(buffer pool)也就放在這個(gè)空間里面。緩存池緩存的是SQL Server數(shù)據(jù):它由8KB大小緩存組成,緩存了來(lái)自數(shù)據(jù)文件的數(shù)據(jù)頁(yè),這個(gè)類似于Oracle的數(shù)據(jù)塊緩存區(qū)。在VAS中的數(shù)據(jù)庫(kù)引擎由SQLSERVER.EXE程序,各個(gè)DLL庫(kù)以及線程結(jié)構(gòu)組成。
緩存池的大小受限于兩個(gè)組件:機(jī)器可用的物理內(nèi)存和SQL能訪問(wèn)的VAS。為避免緩存池?zé)o限擴(kuò)展最終會(huì)吃掉所有的VAS而導(dǎo)致SQL Server意外死掉,SQL Server會(huì)讓緩存池留下一部分VAS內(nèi)存作為“保留區(qū)”。另外SQLOS內(nèi)存管理器還保證緩存池可以滿足其他SQL Server內(nèi)部組件需要:緩存池中的內(nèi)存頁(yè)可以用來(lái)緩存連接數(shù)據(jù)、SQL優(yōu)化器數(shù)據(jù)、還要做最重要的執(zhí)行緩存之用。因?yàn)榉峙浣o這些組件的內(nèi)存是不能再用作存儲(chǔ)數(shù)據(jù)了,因此這些頁(yè)又叫做被盜用頁(yè)(stolen pages)。
下圖簡(jiǎn)要的展示了SQL Server VAS的各個(gè)組件。
前面提到的資源監(jiān)視器(resource monitor)屬于SQLOS的一個(gè)組件。資源監(jiān)視器的工作之一就是檢查和監(jiān)聽(tīng)操作系統(tǒng)發(fā)出的低內(nèi)存通知,當(dāng)資源監(jiān)視器檢測(cè)到低內(nèi)存情況時(shí),它會(huì)將這一情況記錄到一個(gè)稱為環(huán)緩沖區(qū)(Ring Buffer)的結(jié)構(gòu)中,然后再將這個(gè)信息廣播給SQL Server引擎,這樣所有SQL相關(guān)的組件接到廣播之后能減少它們的內(nèi)存使用。SQLOS的內(nèi)存管理器(Memory Manager)組件也同樣會(huì)監(jiān)視可用的虛擬內(nèi)存和物理內(nèi)存以及通過(guò)一個(gè)叫內(nèi)存專員(memory clerk)的通知機(jī)制對(duì)內(nèi)存壓力做出響應(yīng)。
在涉及到任務(wù)執(zhí)行(查詢編譯、執(zhí)行等等)的時(shí)候,SQLOS使用到一個(gè)叫做調(diào)度器的機(jī)制。調(diào)度器(scheduler)可以看成是SQL Server對(duì)于每個(gè)單個(gè)CPU的抽象表示,舉個(gè)例子來(lái)說(shuō),一個(gè)運(yùn)行SQL Server的機(jī)器有2顆4核的CPU的話那就能看到8個(gè)調(diào)度器。每個(gè)調(diào)度器都會(huì)和一定數(shù)量的工作線程(worker thread)相關(guān)聯(lián)。例如在數(shù)據(jù)庫(kù)上面執(zhí)行的一個(gè)查詢?nèi)蝿?wù),這個(gè)任務(wù)會(huì)被分割成解析、編譯、生成執(zhí)行計(jì)劃等一序列的子任務(wù),每個(gè)這樣的子任務(wù)都會(huì)由不同的線程來(lái)執(zhí)行。
當(dāng)SQL Server啟動(dòng)的時(shí)候,只會(huì)啟動(dòng)有限數(shù)量的線程。線程的總數(shù)取決于運(yùn)行SQL Server的機(jī)器的CPU數(shù)量以及架構(gòu)(x86還是x64)。一個(gè)少于4個(gè)CPU的x86系統(tǒng),所創(chuàng)建的線程數(shù)量為256;超過(guò)4個(gè)CPU之后每個(gè)增加的CPU會(huì)多創(chuàng)建8個(gè)線程。對(duì)于少于4個(gè)CPU的x64系統(tǒng),初始線程數(shù)量為512;超過(guò)4個(gè)CPU之后每個(gè)增加的CPU會(huì)多創(chuàng)建16個(gè)線程。也就是說(shuō)機(jī)器的CPU越強(qiáng)大,SQL Server創(chuàng)建的線程就會(huì)越多。
當(dāng)用戶連接到SQL Server系統(tǒng)執(zhí)行任務(wù)時(shí),每個(gè)任務(wù)都會(huì)被分配給一個(gè)調(diào)度器。在SQL Server 2005之前,任務(wù)是按照輪流的方式分配的。自SQL Server 2005開(kāi)始,任務(wù)分配則由SQLOS執(zhí)行:任務(wù)會(huì)分配給最閑的調(diào)度器。
和Oracle一樣,在SQL Server也是可以查看那些運(yùn)行中的后臺(tái)進(jìn)程的。只要在數(shù)據(jù)庫(kù)實(shí)例上執(zhí)行sp_who2命令就可以看到那些后臺(tái)運(yùn)行的進(jìn)程了。
當(dāng)中的CHECKPOINT進(jìn)程看名字就知道什么意思了。LOG WRITER進(jìn)程等價(jià)于Oracle的LGWR進(jìn)程:它負(fù)責(zé)將數(shù)據(jù)庫(kù)的變化寫到事務(wù)日志中。LAZY WRITER進(jìn)程等價(jià)于Oracle的DBWn進(jìn)程:它的任務(wù)是將數(shù)據(jù)頁(yè)的更改從緩存池中寫入到數(shù)據(jù)文件中。有一點(diǎn)和Oracle不同的時(shí)候,在這里只有一個(gè)lazy writer進(jìn)程負(fù)責(zé)寫數(shù)據(jù)文件。其它還有一些后臺(tái)進(jìn)程是和SQLOS關(guān)聯(lián)的:scheduler monitor,deadlock monitor和resource monitor等等。
top事務(wù)一致性(Transactional Consistency)和基于時(shí)間點(diǎn)的恢復(fù)(Point-in-time Recovery) Microsoft SQL Server和Oracle一樣內(nèi)置都有針對(duì)于事務(wù)的保護(hù)機(jī)制。事務(wù)一致性的基本思想就是對(duì)于數(shù)據(jù)的更改不會(huì)馬上反映到磁盤的文件當(dāng)中,實(shí)際上這兩者更新的都是被稱為數(shù)據(jù)緩沖區(qū)(buffer cache)的內(nèi)存區(qū),同時(shí)還在一個(gè)稱為日志緩存(log buffer)的內(nèi)存中連續(xù)的記錄對(duì)于數(shù)據(jù)所做的更改,這些內(nèi)存區(qū)域的內(nèi)容被不斷的寫入到磁盤文件當(dāng)中。用于將數(shù)據(jù)緩存區(qū)和日志緩存區(qū)中的內(nèi)容寫入到磁盤文件當(dāng)中的進(jìn)程是兩個(gè)不同的進(jìn)程,不過(guò)將日志緩存的寫入磁盤要比將數(shù)據(jù)緩沖寫入磁盤要頻繁的多了。 現(xiàn)在當(dāng)用戶成功的提交一個(gè)事務(wù)時(shí),他所做的更改并不會(huì)馬上寫入到數(shù)據(jù)文件中。不過(guò)這些變更會(huì)被記錄到日志緩沖中,同時(shí)在發(fā)送提交成功的信息給用戶之前這些相應(yīng)的日志緩存數(shù)據(jù)會(huì)被寫入到磁盤文件當(dāng)中。
正如之前所述,SQL Server將日志文件稱為事務(wù)日志(Transaction Log),Oracle則稱為重做日志(Redo Log)。在SQL Server術(shù)語(yǔ)中,保存數(shù)據(jù)更改記錄的內(nèi)存塊稱為日志緩存(Log Buffer),Oracle則稱為重做緩存(Redo Buffer)。拋開(kāi)命名的差異,實(shí)際日志文件的作用卻是一樣的:在服務(wù)器意外宕機(jī)之后,數(shù)據(jù)庫(kù)服務(wù)器會(huì)在服務(wù)重新啟動(dòng)之后檢查文件的內(nèi)容,如果在日志文件中發(fā)現(xiàn)已提交的事務(wù)而在數(shù)據(jù)文件中不存在時(shí),這些已提交的事務(wù)就會(huì)被重新應(yīng)用到數(shù)據(jù)文件中;如果日志文件中的記錄顯示事務(wù)沒(méi)有完成或者是回滾了,那反映到數(shù)據(jù)文件中的變化也同樣會(huì)回滾。在這個(gè)過(guò)程中的第一個(gè)部分稱為重做(REDO),第二個(gè)部分稱為撤銷(譯注:這里英文為undo,也許說(shuō)回滾合適些)。
SQL Server為每個(gè)數(shù)據(jù)庫(kù)單獨(dú)的維護(hù)了一份事務(wù)日志,一份數(shù)據(jù)庫(kù)事務(wù)日志可以存在有多個(gè)事務(wù)日志文件。事務(wù)日志文件在數(shù)據(jù)庫(kù)創(chuàng)建的同時(shí)創(chuàng)建,之后也可以繼續(xù)追加。對(duì)Oracle來(lái)說(shuō),數(shù)據(jù)庫(kù)指的是素有的物理文件和邏輯的表空間。Oracle的重做日志會(huì)記錄對(duì)于所有表空間的更改。一個(gè)Oracle數(shù)據(jù)庫(kù)至少需要2個(gè)日志文件才能正常操作,當(dāng)然日志文件可以多余2個(gè),但是決不能少于2個(gè)。
SQL Server事務(wù)日志和Oracle重做日志之間的一個(gè)重大的區(qū)別就在于事務(wù)日志沒(méi)有邏輯分組一說(shuō),而重做日志則可以被分組在2個(gè)或更多個(gè)日志分組當(dāng)中。每個(gè)Oracle數(shù)據(jù)庫(kù)至少需要有2個(gè)日志分組,每個(gè)分組里面必須要有一個(gè)或多個(gè)日志文件,日志組中的日志文件被稱為日志組成員(member)。
Oracle每次都是將日志緩存中的重做日志一次寫入到一個(gè)重做日志組中的所有文件中。在一個(gè)日志組中使用多個(gè)日志文件的容錯(cuò)技術(shù)稱為多路技術(shù)(multiplexing)。在一個(gè)日志組寫滿之后,Oracle就會(huì)轉(zhuǎn)到下一個(gè)日志組,這樣的操作稱為日志切換(log switching),在這個(gè)日志組滿了之后又再轉(zhuǎn)到下一個(gè)日志組,以此類推。當(dāng)所有的日志都寫滿之后(不管是存在2個(gè)還是多個(gè)日志組),Oracle就會(huì)將第一個(gè)組中的日志清理掉,然后開(kāi)啟一輪新的寫入循環(huán)。
SQL Server數(shù)據(jù)庫(kù)的事務(wù)日志一樣是順序?qū)懭氲?,只是如果?shù)據(jù)庫(kù)不是運(yùn)行在簡(jiǎn)單恢復(fù)模式或者是事務(wù)日志做了備份的話,日志是不會(huì)被自動(dòng)清除掉的。如果一個(gè)數(shù)據(jù)庫(kù)的邏輯事務(wù)日志空間滿了之后,它對(duì)應(yīng)的數(shù)據(jù)文件還無(wú)法增長(zhǎng)的話,數(shù)據(jù)將無(wú)法繼續(xù)處理用戶操作。不過(guò)如果事務(wù)日志做過(guò)備份的話,那么SQL Server就會(huì)讓新事務(wù)重用那些已備份日志所占用的空間,從這點(diǎn)上來(lái)說(shuō),SQL Server的邏輯事務(wù)日志是以一種“回環(huán)(wrap-around)”的方式使用的。另外要強(qiáng)調(diào)的一點(diǎn)是SQL Server的事務(wù)日志文件的大小可以配置成自動(dòng)擴(kuò)展,而Oracle的重做日志文件則是有一個(gè)預(yù)定義大小的,如果不是手工更改這個(gè)大小的話,日志文件是不會(huì)自動(dòng)增長(zhǎng)的。
就數(shù)據(jù)可用性而言,兩種平臺(tái)都提供了基于時(shí)間點(diǎn)恢復(fù)(point-in-time recovery)的選項(xiàng),當(dāng)然必要的話也可以禁止掉(這個(gè)在測(cè)試或開(kāi)發(fā)系統(tǒng)中是可行的)。要是SQL Server數(shù)據(jù)庫(kù)的基于時(shí)間點(diǎn)恢復(fù)的功能的話就必須是在完全恢復(fù)模式(full recovery mode)下。不管出于何種恢復(fù)模式,每次數(shù)據(jù)的修改都會(huì)被數(shù)據(jù)庫(kù)記錄在它對(duì)應(yīng)的事務(wù)日志里面,這些日志會(huì)一直保留到事務(wù)日志備份備份的時(shí)候。數(shù)據(jù)庫(kù)的恢復(fù)模式還能調(diào)整成簡(jiǎn)單恢復(fù)模式(simple recovery mode),這種情況下的產(chǎn)生的事務(wù)日志會(huì)在每次檢查點(diǎn)(checkpoint)發(fā)生時(shí)截?cái)?。檢查點(diǎn)操作會(huì)將所有數(shù)據(jù)緩沖中已修改的數(shù)據(jù)寫入到數(shù)據(jù)文件中,日志緩存中的日志信息寫入到日志文件中。如果數(shù)據(jù)庫(kù)運(yùn)行在簡(jiǎn)單恢復(fù)模式下,檢查點(diǎn)完成之后所有的檢查點(diǎn)之前完成的事務(wù)所產(chǎn)生的事務(wù)日志都會(huì)被刪除掉,因此SQL Server已經(jīng)確定這些舊的已提交的事務(wù)已經(jīng)確定被寫入到數(shù)據(jù)文件中去了。
現(xiàn)在假設(shè)數(shù)據(jù)庫(kù)檢測(cè)到一個(gè)錯(cuò)誤(物理的或邏輯的),這時(shí)都可以使用最后一個(gè)全備先還原數(shù)據(jù)庫(kù)然后使用備份的事務(wù)日志恢復(fù)到還原的數(shù)據(jù)庫(kù)上面,這種特性可以讓數(shù)據(jù)庫(kù)回到之前的任意一個(gè)時(shí)間點(diǎn)(譯注:當(dāng)然是指完全備份之后的任意一個(gè)時(shí)間點(diǎn)),只是這個(gè)特性只有在數(shù)據(jù)庫(kù)使用完全恢復(fù)模式的時(shí)候才可用。
Oracle中也有類似的概念。Oracle可以運(yùn)行在歸檔模式(ARCHIVELOG)或是非歸檔模式(NOARCHIVELOG)下。在非歸檔模式下,當(dāng)日志組鏈上的最后一個(gè)組寫滿之后就會(huì)覆蓋第一個(gè)日志組,這時(shí)因?yàn)镺racle的重做日志組是按照循環(huán)使用的方式運(yùn)作的。當(dāng)然這也就意味著數(shù)據(jù)庫(kù)是不能回到那些被刪除了的事務(wù)記錄所對(duì)應(yīng)的時(shí)間點(diǎn)的。所以從功能上說(shuō),這就相當(dāng)于SQL Server的簡(jiǎn)單恢復(fù)模式。
當(dāng)Oracle數(shù)據(jù)庫(kù)運(yùn)行在歸檔模式下時(shí),它同時(shí)也會(huì)在后臺(tái)啟動(dòng)一個(gè)或者多個(gè)歸檔進(jìn)程(archiver),歸檔進(jìn)程的作用就是在一個(gè)日志組滿了之后將日志組的內(nèi)容備份到放在磁盤上的文件中,這些保存的日志文件被稱為歸檔日志(archived log),日志組在歸檔之后就可以放心的被覆蓋了。自己想想就會(huì)發(fā)現(xiàn)Oracle重做日志組歸檔的功能其實(shí)和SQL Server事務(wù)日志備份是一樣的,也是說(shuō)Oracle的歸檔模式和SQL Server的完全恢復(fù)模式是一樣的。
Oracle和SQL Server一樣,在還原全備之后可以使用歸檔日志進(jìn)行還原。不同的時(shí)候SQL Server的事務(wù)日志備份需要手工的配置而Oracle只要配置了歸檔模式之后歸檔進(jìn)行就會(huì)自動(dòng)的進(jìn)行日志歸檔備份操作。
最后,從恢復(fù)時(shí)間(recovery time)上面也能看到兩個(gè)平臺(tái)的相似之處。在之前也提到過(guò),在數(shù)據(jù)引擎啟動(dòng)時(shí)會(huì)經(jīng)過(guò)一個(gè)重做和撤銷的階段,這個(gè)階段所花費(fèi)的時(shí)候稱為恢復(fù)間隔(recovery interval)。很明顯的數(shù)據(jù)庫(kù)管理員是希望這個(gè)時(shí)間越短越好的,在SQL Server中DBA可以通過(guò)下面的命令來(lái)配置這個(gè)時(shí)間間隔:
1 sp_configure 'show advanced option', 1
2 reconfigure
3
4 sp_configure 'recovery interval', <time-in-minutes>
5 reconfigure
這個(gè)命令修改的是系統(tǒng)配置參數(shù)。設(shè)置好恢復(fù)間隔之后,SQL Server會(huì)自動(dòng)調(diào)整檢查點(diǎn)進(jìn)程執(zhí)行檢查點(diǎn)的時(shí)間來(lái)滿足這個(gè)設(shè)置的時(shí)間要求。設(shè)置這個(gè)恢復(fù)間隔的單位是分鐘。
Oracle中類似的設(shè)置就是平均恢復(fù)時(shí)間(Mean Time To Recovery, MTTR),可以通過(guò)修改初始化參數(shù)FAST_START_MTTR_TARGET來(lái)修改它,設(shè)置這個(gè)參數(shù)可以用來(lái)調(diào)整檢查點(diǎn)執(zhí)行的頻率。這個(gè)值決定了Oracle再執(zhí)行數(shù)據(jù)庫(kù)崩潰恢復(fù)時(shí)所花費(fèi)的時(shí)間,設(shè)置命令如下:
1 ALTER SYSTEM SET FAST_START_MTTR_TARGET=<number_of_seconds> SCOPE=spfile;
top系統(tǒng)元數(shù)據(jù) 不過(guò)是Oracle還是SQL Server,在數(shù)據(jù)庫(kù)軟件安裝和數(shù)據(jù)庫(kù)創(chuàng)建的時(shí)候,都會(huì)自動(dòng)創(chuàng)建一大堆表以及其他諸如視圖、函數(shù)、存儲(chǔ)過(guò)程之類的對(duì)象。這些系統(tǒng)級(jí)的表包含的是實(shí)例和實(shí)例所用到的物理和邏輯屬性的元數(shù)據(jù),Oracle把這些表統(tǒng)稱為數(shù)據(jù)字典(data dictionary),在SQL Server中則是稱為系統(tǒng)表(system tables)。 在SQL Server 2005及之后的版本,大部分的系統(tǒng)對(duì)象都保存在resource數(shù)據(jù)庫(kù)中,少部分保存在master數(shù)據(jù)庫(kù)中。Oracle中,數(shù)據(jù)字典表是保存在SYSTEM和SYSAUX表空間中。從SQL Server 2005開(kāi)始是無(wú)法再直接訪問(wèn)系統(tǒng)表了,目錄視圖(catalogue views)取代系統(tǒng)表作為新的訪問(wèn)系統(tǒng)元數(shù)據(jù)的統(tǒng)一的接口。在Oracle中數(shù)據(jù)字典表名都是加密過(guò)的,藉此來(lái)減少表被直接訪問(wèn)或修改,同樣的,Oracle也創(chuàng)建了一系列的視圖用于給DBA和開(kāi)發(fā)人員訪問(wèn)元數(shù)據(jù),Oracle稱這些視圖為數(shù)據(jù)字典視圖(data dictionary views)。
目錄視圖的定義存儲(chǔ)在SQL Server的resource數(shù)據(jù)庫(kù)中,這些系統(tǒng)視圖歸屬于一個(gè)特別的名為sys的用戶架構(gòu)之下(user schema)并能從任意數(shù)據(jù)庫(kù)中訪問(wèn)到。例如,要查看一個(gè)SQL Server實(shí)例中存在的所有的數(shù)據(jù)庫(kù),DBA就可以在任意數(shù)據(jù)庫(kù)下使用下面語(yǔ)句查詢:
1 SELECT * FROM sys.databases
要查出任意一個(gè)數(shù)據(jù)庫(kù)中的所有對(duì)象,則可以使用sys.objects目錄視圖:
1 SELECT * FROM sys.objects
Oracle中,數(shù)據(jù)字典從屬于Oracle用戶SYS。不過(guò)不同于SQL Server的時(shí)候每個(gè)數(shù)據(jù)字典視圖都存在有三種不同的形式,分別提供三個(gè)不同級(jí)別的信息。數(shù)據(jù)字典視圖也就存在三個(gè)不同的類型,從視圖名的前綴就能看出視圖能帶來(lái)什么樣的信息:
以USER_開(kāi)頭的視圖允許用戶查看他自己創(chuàng)建的對(duì)象的信息。
以ALL_開(kāi)頭的視圖允許用戶查看他自己創(chuàng)建的對(duì)象以及那些非他自己創(chuàng)建的卻有權(quán)限訪問(wèn)的對(duì)象的信息。 以DBA_開(kāi)頭的視圖是給DBA用的,這類的視圖可以查詢到數(shù)據(jù)庫(kù)中存在的所有對(duì)象的信息,普通的用戶是沒(méi)有權(quán)限訪問(wèn)這些視圖的。 下面的例子展示的兩個(gè)查詢返回的結(jié)果就是不一樣的: 1 SELECT TABLE_NAME, TABLESPACE_NAME FROM USER_TABLES;
2 SELECT TABLE_NAME, TABLESPACE_NAME FROM DBA_TABLES;
第一個(gè)只顯示執(zhí)行查詢的用戶自己創(chuàng)建的表而第二個(gè)則會(huì)顯示數(shù)據(jù)庫(kù)中存在的所有的表。
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/shiweijian1986/archive/2010/04/27/5533579.aspx
|
|
|