當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]數(shù)據(jù)庫(kù)的作用就是實(shí)現(xiàn)對(duì)數(shù)據(jù)的管理和查詢。任何一個(gè)數(shù)據(jù)庫(kù)系統(tǒng),必然存在對(duì)數(shù)據(jù)的大量讀或者寫或者兩中操作都大量存在。IO問題也往往是導(dǎo)致數(shù)據(jù)庫(kù)性能問題的重要原因。在這篇文章中,主要幫助大家在理解Oracl

數(shù)據(jù)庫(kù)的作用就是實(shí)現(xiàn)對(duì)數(shù)據(jù)的管理和查詢。任何一個(gè)數(shù)據(jù)庫(kù)系統(tǒng),必然存在對(duì)數(shù)據(jù)的大量讀或者寫或者兩中操作都大量存在。IO問題也往往是導(dǎo)致數(shù)據(jù)庫(kù)性能問題的重要原因。在這篇文章中,主要幫助大家在理解Oracle的讀寫操作機(jī)制的基礎(chǔ)上,靈活解決遇到的各種常見的IO問題。

1 Oracle中IO的產(chǎn)生

IO當(dāng)然包括了讀、寫兩部分,先介紹Oracle中寫操作的產(chǎn)生。

1.1 寫

介紹寫操作之前,先簡(jiǎn)單的看下Oracle的物理結(jié)構(gòu):oracle的物理文件包括以下三種文件:控制文件(Control Files)、重做日志文件(Redo Log Files)、數(shù)據(jù)文件(datafiles)。而數(shù)據(jù)文件中,根據(jù)功能的不同,還可以分為系統(tǒng)數(shù)據(jù)文件、臨時(shí)空間文件、回滾段文件和用戶數(shù)據(jù)文件。另外,如果數(shù)據(jù)庫(kù)的Archive Log模式被激活,還存在歸檔日志文件。Oracle的IO產(chǎn)生,就是對(duì)這些文件的數(shù)據(jù)讀、寫操作。下面再詳細(xì)看下幾種主要寫操作的產(chǎn)生及其過程。

1.1.1 控制文件

控制文件中記錄了整個(gè)數(shù)據(jù)庫(kù)的物理結(jié)構(gòu)信息,如數(shù)據(jù)庫(kù)名字、數(shù)據(jù)文件及日志文件名字和位置、事件戳信息等等。任何數(shù)據(jù)庫(kù)的結(jié)構(gòu)變化(如果創(chuàng)建新的數(shù)據(jù)文件)都會(huì)引起Oracle修改控制文件。同時(shí)控制文件還記錄系統(tǒng)和各個(gè)數(shù)據(jù)文件的SCN(System Change Number,關(guān)于SCN可以參見文章《Oracle SCN機(jī)制詳解》)信息,以用于數(shù)據(jù)恢復(fù),因此數(shù)據(jù)文件上的SCN變化后,Oracle也會(huì)相應(yīng)修改控制文件上的SCN信息。

1.1.2 用戶數(shù)據(jù)修改

由于內(nèi)存的讀寫效率比磁盤的讀寫效率高萬(wàn)倍,因此,為了降低IO wait,oracle會(huì)將數(shù)據(jù)cache在內(nèi)存(Buffer Cache,對(duì)Buffer Cache的詳細(xì)介紹可以參見《Oracle內(nèi)存全面分析》)中,對(duì)數(shù)據(jù)的讀寫盡量在內(nèi)存中完成。當(dāng)Buffer Cache中的數(shù)據(jù)緩存塊被修改過了,它就被標(biāo)記為“臟”數(shù)據(jù)。根據(jù)LRU(Least Recently Used)算法,如果一個(gè)數(shù)據(jù)塊最近很少被使用,它就稱為“冷”數(shù)據(jù)塊。進(jìn)程DBWn(系統(tǒng)中可以存在多個(gè)DBW進(jìn)程,n為序號(hào))負(fù)責(zé)將“冷”的“臟”數(shù)據(jù)寫入數(shù)據(jù)文件中去。DBWn進(jìn)程會(huì)在以下兩種情況下將“臟”數(shù)據(jù)寫入磁盤中去:

當(dāng)服務(wù)進(jìn)程掃描一定數(shù)量(閥值)的Buffer Cache后還沒有找到干凈、可重用的緩存塊后,它會(huì)通知DBWn進(jìn)程將“臟”數(shù)據(jù)寫入文件中去,以釋放出空閑緩存;當(dāng)發(fā)生檢查點(diǎn)(Checkpoint)時(shí)。1.1.3 Redo Log

在非直接寫(Direct Write)的情況下,事務(wù)中的寫操作都會(huì)產(chǎn)生Redo Log,作為數(shù)據(jù)塊異常關(guān)閉時(shí)的恢復(fù)記錄。同樣,和寫用戶數(shù)據(jù)類似,Redo Log也不會(huì)被直接寫入Redo Log文件,而是先寫入Log Buffer中。

Log Buffer是一個(gè)可以循環(huán)重用的緩存區(qū)。LGWR進(jìn)程負(fù)責(zé)將Log Buffer中的記錄寫入Redo Log File中去。一旦Log Buffer中的條目被寫入了Redo Log文件中,就可以被重用了。

為了保證事務(wù)盡快獲得Log Buffer,LGWR進(jìn)程一般會(huì)盡快將Log Buffer中的數(shù)據(jù)寫入Redo Log文件中去。在以下幾種情況下,LGWR回將一個(gè)連續(xù)的Log Buffer寫入Redo Log文件中去:

當(dāng)一個(gè)事務(wù)提交(COMMIT)時(shí);每3秒鐘寫一次Log Buffer;當(dāng)Log Buffer到達(dá)1/3滿時(shí);當(dāng)DBWn進(jìn)程將“臟”數(shù)據(jù)寫入磁盤時(shí);1.1.4 Archive Log

當(dāng)據(jù)庫(kù)的Archive Log模式被激活后,所有Redo Log數(shù)據(jù)都會(huì)被寫入Archive Log文件中以便日后進(jìn)行恢復(fù)。當(dāng)發(fā)生日志組切換時(shí),ARCn(Archive進(jìn)程,可以存在多個(gè))進(jìn)程就會(huì)Redo Log文件拷貝到指定存儲(chǔ)目錄中去,成為Archive Log文件。

1.1.5 臨時(shí)表空間

當(dāng)Oracle在執(zhí)行一些SQL時(shí),會(huì)需要一些臨時(shí)空間來存儲(chǔ)執(zhí)行語(yǔ)句時(shí)產(chǎn)生的中間數(shù)據(jù)。這些臨時(shí)空間由Oracle從指定的臨時(shí)表空間中分配給進(jìn)程。主要有三種情況會(huì)占用臨時(shí)空間:臨時(shí)表/索引操作、排序和臨時(shí)LOB操作。

臨時(shí)表/索引

在會(huì)話中,當(dāng)?shù)谝淮螌?duì)臨時(shí)表進(jìn)行INSERT(包括CTAS)時(shí),Oracle會(huì)從臨時(shí)表空間中為臨時(shí)表及其索引分配臨時(shí)空間一存儲(chǔ)數(shù)據(jù)。

排序

任何會(huì)使用到排序的操作,包括JOIN、創(chuàng)建(重建)INDEX、ORDER BY、聚合計(jì)算(GROUP BY)以及統(tǒng)計(jì)數(shù)據(jù)收集,都可能使用到臨時(shí)表空間。

排序操作首先會(huì)選擇在內(nèi)存中的Sort Area進(jìn)行(Sort In Memory),一旦Sort Area不足,則會(huì)使用臨時(shí)空間進(jìn)行排序操作(Sort In Disk)??匆韵吕樱?/p>

臨時(shí)LOB對(duì)象

LOB對(duì)象包括BLOB、CLOB、NCLOB、和BFILE。在PLSQL程序塊中,如果定義了LOB變量,則這些LOB變量就是臨時(shí)LOB對(duì)象。臨時(shí)LOB對(duì)象被創(chuàng)建在臨時(shí)表空間上,直到LOB數(shù)據(jù)被釋放,或者會(huì)話結(jié)束。

1.1.6 回滾段

我們知道,一個(gè)事務(wù)在未被提交前,其做的任何修改都是可以被回滾(Rollback)的。這些回滾數(shù)據(jù)就被放到回滾段(Rollback Segment)上。此外,一致性讀(Read Consistency)、數(shù)據(jù)庫(kù)恢復(fù)(Recover)都會(huì)用到回滾段。

任何數(shù)據(jù)塊的修改都會(huì)被記錄在回滾段中,甚至Redo Log也會(huì)產(chǎn)生回滾記錄。當(dāng)任何一個(gè)非只讀(只有查詢)的事務(wù)開始時(shí),oracle會(huì)自動(dòng)為其指定下一個(gè)可用的回滾段。事務(wù)中任何數(shù)據(jù)變化都被寫入回滾段中。如果事務(wù)回滾,oracle根據(jù)回滾段中的回滾記錄將buffer cache中的“臟”數(shù)據(jù)恢復(fù),釋放回滾段空間。當(dāng)事務(wù)被提交,由于要保證一致性讀,oracle并不會(huì)立即釋放回滾段中的數(shù)據(jù),而是會(huì)保留一段時(shí)間。

1.1.7 Direct-Path Insert

這里,我們還要介紹一種特殊的寫操作——Direct-Path Insert(直接路徑插入)。Direct-Path Insert通過直接在表中已存在的數(shù)據(jù)后面添加數(shù)據(jù),直接將數(shù)據(jù)寫入數(shù)據(jù)文件中,而忽略掉了Buffer Cache。

我們前面提到,為了能在意外時(shí)恢復(fù)數(shù)據(jù),每一個(gè)數(shù)據(jù)修改都會(huì)被記錄到Redo Log中。然而,由于Redo Log需要寫入到物理文件中去,是一個(gè)比較消耗性能的操作。為了提高性能,我們?cè)谂繉懭霐?shù)據(jù)時(shí)就可以通過Direct-Path Insert的指定NOLOGING的方式來避免寫Redo Log。

有多種方法可以指定Direct-Path Insert:CTAS(CREATE TABLE AS SELECT);SQL*Loader指定Direct參數(shù);在語(yǔ)句中指定APPEND提示。

1.2???? 讀 1.2.1 物理讀

產(chǎn)生物理讀主要有以下幾種情況:

第一次讀取

當(dāng)數(shù)據(jù)塊第一次被讀取到,Oracle會(huì)先將其從磁盤上讀入Buffer Cache中,并將他們放在LRU(Last Recently Used)鏈表的MRU(Most Recently Used)端。再次訪問數(shù)據(jù)塊時(shí)就可以直接從Buffer Cache中讀取、修改了??匆韵吕樱?/p>

數(shù)據(jù)塊被重新讀入Buffer Cache

如果有新的數(shù)據(jù)需要被讀入Buffer Cache中,而Buffer Cache又沒有足夠的空閑空間,Oracle就根據(jù)LRU算法將LRU鏈表中LRU端的數(shù)據(jù)置換出去。當(dāng)這些數(shù)據(jù)被再次訪問到時(shí),需要重新從磁盤讀入。

全表掃描

當(dāng)發(fā)生全表掃描(Full Table Scan)時(shí),用戶進(jìn)程讀取表的數(shù)據(jù)塊,并將他們放在LRU鏈表的LRU端(和上面不同,不是放在MRU端)。這樣做的目的是為了使全表掃描的數(shù)據(jù)盡快被移出。因?yàn)槿頀呙枰话惆l(fā)生的頻率較低,并且全表掃描的數(shù)據(jù)塊大部分在以后都不會(huì)被經(jīng)常使用到。

而如果你希望全表掃描的數(shù)據(jù)能被cache住,使之在掃描時(shí)放在MRU端,可以通過在創(chuàng)建或修改表(或簇)時(shí),指定CACHE參數(shù)。

1.2.2 邏輯讀

邏輯讀指的就是從(或者視圖從)Buffer Cache中讀取數(shù)據(jù)塊。按照訪問數(shù)據(jù)塊的模式不同,可以分為即時(shí)讀(Current Read)和一致性讀(Consistent Read)。注意:邏輯IO只有邏輯讀,沒有邏輯寫。

即時(shí)讀

即時(shí)讀即讀取數(shù)據(jù)塊當(dāng)前的最新數(shù)據(jù)。任何時(shí)候在Buffer Cache中都只有一份當(dāng)前數(shù)據(jù)塊。即時(shí)讀通常發(fā)生在對(duì)數(shù)據(jù)進(jìn)行修改、刪除操作時(shí)。這時(shí),進(jìn)程會(huì)給數(shù)據(jù)加上行級(jí)鎖,并且標(biāo)識(shí)數(shù)據(jù)為“臟”數(shù)據(jù)。

一致性讀

Oracle是一個(gè)多用戶系統(tǒng)。當(dāng)一個(gè)會(huì)話開始讀取數(shù)據(jù)還未結(jié)束讀取之前,可能會(huì)有其他會(huì)話修改它將要讀取的數(shù)據(jù)。如果會(huì)話讀取到修改后的數(shù)據(jù),就會(huì)造成數(shù)據(jù)的不一致。一致性讀就是為了保證數(shù)據(jù)的一致性。在Buffer Cache中的數(shù)據(jù)塊上都會(huì)有最后一次修改數(shù)據(jù)塊時(shí)的SCN。如果一個(gè)事務(wù)需要修改數(shù)據(jù)塊中數(shù)據(jù),會(huì)先在回滾段中保存一份修改前數(shù)據(jù)和SCN的數(shù)據(jù)塊,然后再更新Buffer Cache中的數(shù)據(jù)塊的數(shù)據(jù)及其SCN,并標(biāo)識(shí)其為“臟”數(shù)據(jù)。當(dāng)其他進(jìn)程讀取數(shù)據(jù)塊時(shí),會(huì)先比較數(shù)據(jù)塊上的SCN和自己的SCN。如果數(shù)據(jù)塊上的SCN小于等于進(jìn)程本身的SCN,則直接讀取數(shù)據(jù)塊上的數(shù)據(jù);如果數(shù)據(jù)塊上的SCN大于進(jìn)程本身的SCN,則會(huì)從回滾段中找出修改前的數(shù)據(jù)塊讀取數(shù)據(jù)。通常,普通查詢都是一致性讀。

1.2.3 查找數(shù)據(jù)

在一個(gè)查詢操作中,大量的讀操作都產(chǎn)生于數(shù)據(jù)的查找過程中。減少查找過程是我們優(yōu)化IO性能問題的重要目標(biāo)。

下面介紹幾種主要的數(shù)據(jù)查找方式。

Full Table Scan

當(dāng)查詢條件無(wú)法命中任何索引、或者掃描索引的代價(jià)大于全表掃描代價(jià)的某一比例時(shí)(由參數(shù)optimizer_index_cost_adj設(shè)定),Oracle會(huì)采用全表掃描的方式查找數(shù)據(jù)。當(dāng)發(fā)生全表掃描時(shí),Oracle會(huì)自下向上一次讀取一定數(shù)量(由參數(shù)db_file_multiblock_read_count設(shè)定)的數(shù)據(jù)塊,一直讀取到高水位標(biāo)志(HWM,High Water Mark)下。Full Table Scan會(huì)引起db file scattered read事件。

INDEX UNIQUE SCAN

全表掃描查找數(shù)據(jù)的效率是非常低的。而索引能大幅提高查找效率。普通索引的數(shù)據(jù)結(jié)構(gòu)是B-Tree,樹的葉子節(jié)點(diǎn)中包含數(shù)據(jù)的ROWID,指向數(shù)據(jù)記錄,同時(shí)還有指針指向前一個(gè)/后一個(gè)葉子節(jié)點(diǎn)。索引掃描每次讀取一個(gè)數(shù)據(jù)塊,索引掃描是“連續(xù)的”(Sequential)。當(dāng)索引為UNIQUE索引時(shí),每個(gè)葉子節(jié)點(diǎn)只會(huì)指向一條數(shù)據(jù)。如果Oracle能預(yù)知掃描結(jié)果只有0或1條記錄時(shí),會(huì)采用INDEX UNIQUE SCAN。當(dāng)對(duì)Unique Index中的所有字段進(jìn)行完全匹配時(shí),會(huì)發(fā)生INDEX UNIQUE SCAN。

INDEX UNIQUE SCAN的查找過程如下:

從數(shù)的根節(jié)點(diǎn)數(shù)據(jù)塊開始查找;查找根節(jié)點(diǎn)塊中所有key值中大于或等于要查找的值的最小key值;如果key值大于查找值,則繼續(xù)查找這個(gè)key值之前一個(gè)key值所指向的子節(jié)點(diǎn)數(shù)據(jù)塊;如果key值等于查找值,則繼續(xù)查找這個(gè)key值所指向的子節(jié)點(diǎn)數(shù)據(jù)塊;如果沒有key值大于或等于查找值,則繼續(xù)查找最大key值所指向的子節(jié)點(diǎn)數(shù)據(jù)塊;如果繼續(xù)查找的節(jié)點(diǎn)數(shù)據(jù)塊是數(shù)一個(gè)分支節(jié)點(diǎn),則重復(fù)2~4步;如果查找的節(jié)點(diǎn)是葉子節(jié)點(diǎn)數(shù)據(jù)塊,則在數(shù)據(jù)塊中查找等于查找值的key值;如果找到相等的key值,則返回?cái)?shù)據(jù)和ROWID;如果沒找到相等的key值,則說明沒有符合條件的數(shù)據(jù),返回NULL。INDEX RANGE SCAN

如果通過索引查找數(shù)據(jù)時(shí),Oracle認(rèn)為會(huì)返回?cái)?shù)據(jù)可能會(huì)大于1,會(huì)進(jìn)行INDEX RANGE SCAN,例如Unique Index中字段不完全匹配查找時(shí)、非Unique Index查找時(shí)。

INDEX RANGE SCAN分為閉包(有前后查找邊界)和非閉包(只有一邊或者沒有邊界)。返回?cái)?shù)據(jù)會(huì)依據(jù)索引增序排序,多個(gè)相同值則會(huì)按照ROWID的增序排序。

閉包條件下的INDEX RANGE SCAN的查找過程如下:

從數(shù)的根節(jié)點(diǎn)數(shù)據(jù)塊開始查找;查找根節(jié)點(diǎn)塊中所有key值中大于或等于要查找的起始值的最小key值;如果key值大于起始值,則繼續(xù)查找這個(gè)key值之前一個(gè)key值所指向的子節(jié)點(diǎn)數(shù)據(jù)塊;如果key值等于起始值,則繼續(xù)查找這個(gè)key值所指向的子節(jié)點(diǎn)數(shù)據(jù)塊;如果沒有key值大于或等于起始值,則繼續(xù)查找最大key值所指向的子節(jié)點(diǎn)數(shù)據(jù)塊;如果繼續(xù)查找的節(jié)點(diǎn)數(shù)據(jù)塊是數(shù)一個(gè)分支節(jié)點(diǎn),則重復(fù)2~4步;如果查找的節(jié)點(diǎn)是葉子節(jié)點(diǎn)數(shù)據(jù)塊,則在數(shù)據(jù)塊中大于或等于要查找的起始值的最小key值;如果Key值小于或等于結(jié)束值,則:如果所有Key字段都符合WHERE字句中的查找條件,則返回?cái)?shù)據(jù)和ROWID;否則繼續(xù)查找當(dāng)前葉子節(jié)點(diǎn)所指向的右邊的葉子節(jié)點(diǎn)。

INDEX UNIQUE SCAN和INDEX RANGE SCAN都會(huì)引起db file sequential read事件。

TABLE ACCESS BY INDEX ROWID

當(dāng)發(fā)生索引掃描時(shí),如果需要返回的字段都在索引上,則直接返回索引上的數(shù)據(jù),而如果還需要返回非索引上的字段的值,Oracle則需要根據(jù)從索引上查找的ROWID到對(duì)應(yīng)的數(shù)據(jù)塊上取回?cái)?shù)據(jù),這時(shí)就是TABLE ACCESS BY INDEX ROWID。

INDEX FAST FULL SCAN & INDEX FULL SCAN

索引快速全掃描和全表掃描類似,一次讀取db_file_multiblock_read_count個(gè)數(shù)據(jù)塊來描所有索引的葉子節(jié)點(diǎn)。INDEX FAST FULL SCAN和其他索引掃描不同,它不會(huì)從樹的根節(jié)點(diǎn)開始讀取,而是直接掃描所有葉子節(jié)點(diǎn);也不會(huì)一次讀取一個(gè)數(shù)據(jù)塊,而是一次讀取db_file_multiblock_read_count個(gè)數(shù)據(jù)塊。INDEX FAST FULL SCAN會(huì)引起db file scattered read事件。

在某些情況下,如db_file_multiblock_read_count值過小、強(qiáng)制使用索引掃描時(shí),會(huì)發(fā)生INDEX FULL SCAN。INDEX FULL SCAN和INDEX FAST FULL SCAN不同,它是一種索引掃描,按照B-Tree的查找法從樹的根節(jié)點(diǎn)開始掃描,遍歷整棵樹,并且一次讀取一個(gè)數(shù)據(jù)塊。它會(huì)引起db file sequential read事件。

2 IO系統(tǒng)的設(shè)計(jì)和配置

要控制好數(shù)據(jù)庫(kù)的整體IO性能,在規(guī)劃數(shù)據(jù)庫(kù)架構(gòu)時(shí)就需要做好IO系統(tǒng)的設(shè)計(jì)和配置。例如,將對(duì)IO要求不同的文件放置在不同的存儲(chǔ)設(shè)備上;規(guī)劃數(shù)據(jù)文件的分布、均衡IO負(fù)擔(dān)等。

2.1???? OS和存儲(chǔ)相關(guān)

IO性能是直接和操作系統(tǒng)已經(jīng)硬件性能相關(guān)的。如果能利用操作系統(tǒng)的一些高級(jí)IO特性,或者采用更高速的磁盤設(shè)備,能大大提高IO性能。下面介紹一些OS的IO配置、不同的磁盤硬件設(shè)備以及存儲(chǔ)技術(shù)。

2.1.1 文件系統(tǒng)(File System)和裸設(shè)備(Raw Device)

我們知道,內(nèi)存的讀寫效率比磁盤高近萬(wàn)倍,因此Oracle在內(nèi)存中開辟了一片區(qū)域,稱為Buffer Cache,使數(shù)據(jù)的讀寫盡量在Buffer Cache中完成。同樣,在文件系統(tǒng)中,操作系統(tǒng)為了提高讀寫效率,也會(huì)為文件系統(tǒng)開辟一塊Buffer Cache用于讀寫數(shù)據(jù)的緩存。這樣,Oracle的數(shù)據(jù)會(huì)被緩存2次。為了避免OS的這次緩存,我們可以采用裸設(shè)備做為數(shù)據(jù)文件的存儲(chǔ)設(shè)備。裸設(shè)備,也稱為裸分區(qū)(Raw Partition),它是一個(gè)沒有被加載(Mount)到操作系統(tǒng)的文件系統(tǒng)上、也沒有加載到Oracle集群文件系統(tǒng)(OCFS Oracle Cluster File System)的磁盤分區(qū),它通過字符設(shè)備驅(qū)動(dòng)來訪問。裸設(shè)備的文件讀寫不由操作系統(tǒng)控制,而是由應(yīng)用程序(如Oracle RDBMS)直接控制。

2.1.2 IO方式

OS和文件系統(tǒng)對(duì)IO的控制存在多種方式,不同的IO方式下對(duì)于數(shù)據(jù)庫(kù)的IO性能影響也不同。

2.1.2.1? Direct IO & Concurrent IO

除了裸設(shè)備,某些文件系統(tǒng)可以支持Direct IO,以避開讀寫緩沖。如果要使用Direct IO,需要指定Oracle參數(shù)“filesystemio_options”來設(shè)置支持Direct IO。但是要注意,不同OS中的不同文件系統(tǒng)對(duì)Direct IO的支持也不同:

Windows ??? 在windows中不需要做特別設(shè)置可以直接使用Direct IO;AIX ?? 在AIX中,JFS文件系統(tǒng)需要通過設(shè)置“filesystemio_options”為“SETALL”或者“DIRECTIO”來支持Direct IO;LINUX Linux在內(nèi)核版本為2.4.9以上才支持Direct IO。NFS或者OCFS文件系統(tǒng)支持Direct IO。需要設(shè)置“filesystemio_options”為“SETALL”或者“DIRECTIO”;Solaris???? Solaris需要在操作系統(tǒng)中設(shè)置“forcedirectio”選項(xiàng),并設(shè)置“filesystemio_options”為“SETALL”或者“DIRECTIO”。

參數(shù)“filesystemio_options”支持4種值:

ASYNCH: 使Oracle支持文件的異步(Asynchronous)IO;DIRECTIO:使Oracle支持文件的Direct IO;SETALL:使Oracle同時(shí)支持文件的Asynchronous IO和Direct IO;NONE:使Oracle關(guān)閉對(duì)Asynchronous IO和Direct IO的支持。

在AIX的JFS2文件系統(tǒng)上,如果“filesystemio_options”為“SETALL”,則會(huì)支持Concurrent IO。CIO比DIO的性能更高,因?yàn)镴FS2的CIO支持多個(gè)進(jìn)程同時(shí)對(duì)一個(gè)文件進(jìn)行讀寫。

2.1.2.2? Asynchronous IO & Synchronous IO

通常,用的比較多的IO模型是同步IO(Synchronous IO)。在這種模式下,當(dāng)請(qǐng)求發(fā)出之后,應(yīng)用程序就會(huì)阻塞,直到請(qǐng)求滿足為止。這種模式最大好處就是調(diào)用應(yīng)用程序在等待 I/O 請(qǐng)求完成時(shí)不需要使用CPU資源。但是,對(duì)于一些強(qiáng)調(diào)高響應(yīng)速度的程序(如DB)來說,希望這種等待時(shí)間越短越好,我們這時(shí)就可以考慮采用異步IO(Asynchronous IO)模式。異步IO模式下,進(jìn)程發(fā)出IO請(qǐng)求后無(wú)需等待IO完成,可以去處理其它事情;IO請(qǐng)求被放入一個(gè)隊(duì)列中,一旦IO完成,系統(tǒng)會(huì)發(fā)出信號(hào)通知進(jìn)程。

異步IO可以使需要大量寫的Oracle進(jìn)程(如DBWn進(jìn)程)將IO請(qǐng)求隊(duì)列化,以充分利用硬件的IO帶寬,從而使它們能最大程度實(shí)現(xiàn)并行處理。異步IO還可以使那些需要進(jìn)行大量計(jì)算的操作(如排序)在它們發(fā)出IO請(qǐng)求前預(yù)先從磁盤取出數(shù)據(jù),以使IO和計(jì)算并行處理。

確認(rèn)操作系統(tǒng)已經(jīng)設(shè)置支持AIO后,還需要設(shè)置Oracle初始化參數(shù)"DISK_ASYNCH_IO"為“true”以支持異步IO。

2.1.3 負(fù)載均衡及條帶化(Striping)

當(dāng)多個(gè)進(jìn)程同時(shí)訪問一個(gè)磁盤時(shí),會(huì)出現(xiàn)磁盤沖突。大多數(shù)磁盤系統(tǒng)都對(duì)訪問次數(shù)(每秒的IO操作)和數(shù)據(jù)傳輸率(每秒傳輸?shù)臄?shù)據(jù)量)有限制。當(dāng)達(dá)到這些限制時(shí),后面要訪問磁盤的進(jìn)程就需要等待,這時(shí)就是所謂的磁盤沖突。

避免磁盤沖突是優(yōu)化IO性能的一個(gè)目標(biāo),這就需要將一個(gè)熱點(diǎn)磁盤上的IO訪問負(fù)載分擔(dān)到其他可用磁盤上,也就是IO負(fù)載均衡。在一些成熟的磁盤負(fù)載均衡技術(shù)出現(xiàn)之前,DBA需要了解/預(yù)測(cè)各系統(tǒng)的IO負(fù)載量,通過手工配置每個(gè)數(shù)據(jù)到不同存放位置以分擔(dān)IO負(fù)載來達(dá)到負(fù)載均衡的目的。

條帶化技術(shù)就是將數(shù)據(jù)分成很多小部分并把他們分別存儲(chǔ)到不同磁盤上的不同文件中去。這就能使多個(gè)進(jìn)程同時(shí)訪問數(shù)據(jù)的多個(gè)不同部分而不會(huì)造成磁盤沖突。很多操作系統(tǒng)、磁盤設(shè)備供應(yīng)商、各種第三方軟件都能做到條帶化。通過條帶化,DBA可以很輕松的做到IO負(fù)載均衡而無(wú)需去手工配置。

2.1.4 RAID

RAID的全稱是獨(dú)立磁盤冗余陣列(Redundant Array of Independent Disks)。它通過將多個(gè)相對(duì)比較便宜的磁盤組合起來,并相互連接,同時(shí)都連到一個(gè)或多個(gè)計(jì)算機(jī)上,以組成一個(gè)磁盤組,使其性能和容量達(dá)到或超過一個(gè)價(jià)格更昂貴的大型磁盤。RAID分為6級(jí)。

RAID-0

RAID-0只提供純粹的條帶化(Stripping)。條帶可以使一個(gè)大文件被多個(gè)磁盤控制器同時(shí)訪問,因此支持對(duì)數(shù)據(jù)的并發(fā)訪問。RAID-0不提供數(shù)據(jù)冗余和奇偶保護(hù),它只關(guān)注性能。如果RAID-0中任何一個(gè)磁盤出錯(cuò),整個(gè)數(shù)據(jù)庫(kù)都會(huì)崩潰。

RAID-1

RAID-1提供磁盤鏡像(Disk Mirror)。在RAID-1中,所有數(shù)據(jù)都會(huì)被寫入兩個(gè)獨(dú)立的磁盤中,以實(shí)現(xiàn)對(duì)數(shù)據(jù)的冗余保護(hù)。兩塊磁盤的數(shù)據(jù)是同時(shí)寫入的,以保證其速度不會(huì)低于寫入單獨(dú)磁盤的速度。RAID-1實(shí)現(xiàn)了數(shù)據(jù)的完全冗余,它提供了所有RAID級(jí)別中最安全可靠的數(shù)據(jù)保護(hù)。在這種模式下,寫的性能下降了,但讀的性能被提升了。此外,RAID-1也是最占用磁盤空間的模式

RAID 0+1

RAID-0能提供更好的性能,RAID-1提供最佳的數(shù)據(jù)保護(hù)。如果把兩者結(jié)合在一起就能同時(shí)提供高性能和數(shù)據(jù)保護(hù),但是也會(huì)同時(shí)提高磁盤陣列造價(jià)。

RAID-3

在RAID-3中,會(huì)有一塊專門的磁盤驅(qū)動(dòng)被用作存儲(chǔ)錯(cuò)誤修正或者奇偶校驗(yàn)數(shù)據(jù)。而其他的磁盤驅(qū)動(dòng)則被條帶化。RAID-3的并行處理能力比較低,它適合于主要是讀操作的系統(tǒng)(如決策分析系統(tǒng) DSS,但是DSS會(huì)存在大量復(fù)雜查詢,需要做JOIN,同樣也會(huì)存在一些臨時(shí)的寫操作),不適合存在大量寫操作的系統(tǒng)(OLTP)。

RAID-5

RAID-5不做全磁盤鏡像,但它會(huì)對(duì)每一個(gè)寫操作做奇偶校驗(yàn)計(jì)算并寫入奇偶校驗(yàn)數(shù)據(jù)。奇偶校驗(yàn)磁盤避免了像RAID-1那樣完全重復(fù)寫數(shù)據(jù)。當(dāng)一個(gè)磁盤失效,校驗(yàn)數(shù)據(jù)被用來重建數(shù)據(jù),從而保證系統(tǒng)不會(huì)崩潰。為避免磁盤瓶頸,奇偶校驗(yàn)和數(shù)據(jù)都會(huì)被分布到陣列中的各個(gè)磁盤。盡管讀的效率提高了,但是RAID-5需要為每個(gè)寫操作做奇偶校驗(yàn),因此它的寫的效率很差。

RAID-S

RAID-S是EMC公司的RAID-5的實(shí)施方案,它和純粹的RAID-5存在以下區(qū)別:

(1) 它條帶化奇偶校驗(yàn),但不條帶化數(shù)據(jù);

(2) 它與一個(gè)帶有寫緩存的異步硬件環(huán)境合并。

這個(gè)緩存主要是一種延遲寫的機(jī)制,因此它能讓系統(tǒng)在相對(duì)不忙的時(shí)候計(jì)算和寫奇偶校驗(yàn)信息。

RAID-7

RAID-7也同樣引入了緩存機(jī)制,這個(gè)緩存是被一個(gè)內(nèi)嵌式操作系統(tǒng)控制。但是,RAID-7中數(shù)據(jù)是被條帶化的,而奇偶校驗(yàn)不被條帶化。奇偶校驗(yàn)信息被存放著一個(gè)或者多個(gè)專門的磁盤上。

2.1.5 SAN

SAN(Storage?Area?Network,存儲(chǔ)區(qū)域網(wǎng))是一個(gè)高速的子網(wǎng),這個(gè)子網(wǎng)中的設(shè)備可以從你的主網(wǎng)卸載流量。通常SAN由RAID陣列連接光纖通道(Fibre?Channel)組成,SAN和服務(wù)器和客戶機(jī)的數(shù)據(jù)通信通過SCSI命令而非TCP/IP,數(shù)據(jù)處理是“塊級(jí)”(block?level)。

SAN通過特定的互連方式連接的若干臺(tái)存儲(chǔ)服務(wù)器組成一個(gè)單獨(dú)的數(shù)據(jù)網(wǎng)絡(luò),提供企業(yè)級(jí)的數(shù)據(jù)存儲(chǔ)服務(wù)。?SAN是一種特殊的高速網(wǎng)絡(luò),連接網(wǎng)絡(luò)服務(wù)器和諸如大磁盤陣列或備份磁帶庫(kù)的存儲(chǔ)設(shè)備,SAN置于LAN之下,而不涉及LAN。利用SAN,不僅可以提供大容量的存儲(chǔ)數(shù)據(jù),而且地域上可以分散,并緩解了大量數(shù)據(jù)傳輸對(duì)于局域網(wǎng)的影響。SAN的結(jié)構(gòu)允許任何服務(wù)器連接到任何存儲(chǔ)陣列,不管數(shù)據(jù)置放在哪里,服務(wù)器都可直接存取所需的數(shù)據(jù)。

2.1.6 NAS

NAS是Network Attached Storage(網(wǎng)絡(luò)附加存儲(chǔ))的簡(jiǎn)稱。在NAS存儲(chǔ)結(jié)構(gòu)中,存儲(chǔ)系統(tǒng)不再通過I/O總線附屬于某個(gè)服務(wù)器或客戶機(jī),而直接通過網(wǎng)絡(luò)接口與網(wǎng)絡(luò)直接相連,由用戶通過網(wǎng)絡(luò)訪問。它是連接到一個(gè)計(jì)算機(jī)網(wǎng)絡(luò)的文件層的數(shù)據(jù)存儲(chǔ),它可以為不同網(wǎng)絡(luò)客戶端提供數(shù)據(jù)存儲(chǔ)服務(wù)。NAS的硬件與傳統(tǒng)的專用文件服務(wù)器相似。它們的不同點(diǎn)在于軟件端。NAS中的操作系統(tǒng)和其他軟件只提供數(shù)據(jù)存儲(chǔ)、數(shù)據(jù)訪問功能,以及對(duì)這些功能的管理。與傳統(tǒng)以服務(wù)器為中心的存儲(chǔ)系統(tǒng)相比,數(shù)據(jù)不再通過服務(wù)器內(nèi)存轉(zhuǎn)發(fā),直接在客戶機(jī)和存儲(chǔ)設(shè)備間傳送,服務(wù)器僅起控制管理的作用。

2.2???? IO配置

在借助各種成熟的存儲(chǔ)技術(shù)的基礎(chǔ)上,合理配置系統(tǒng)的IO分布及系統(tǒng)IO配置能大量減少系統(tǒng)在生產(chǎn)運(yùn)行中出現(xiàn)IO性能及相關(guān)問題的幾率。當(dāng)然,這些配置是我們?cè)诓贾脭?shù)據(jù)庫(kù)系統(tǒng)時(shí)初始建議,對(duì)于復(fù)雜的系統(tǒng)來說,很多配置(如一些存儲(chǔ)相關(guān)的參數(shù))是需要根據(jù)系統(tǒng)的運(yùn)行狀況進(jìn)行調(diào)優(yōu)的。

在數(shù)據(jù)庫(kù)系統(tǒng)中,如果某個(gè)文件或者某塊磁盤上存在遠(yuǎn)遠(yuǎn)高于其他文件或磁盤的大量IO訪問,我們就稱這個(gè)文件或磁盤為熱點(diǎn)文件/磁盤。我們?cè)谧鯥O規(guī)劃時(shí)的一個(gè)重要目標(biāo)就是要消除系統(tǒng)中熱點(diǎn)文件/磁盤的存在,使整個(gè)系統(tǒng)的IO負(fù)載相對(duì)平衡。

2.2.1 條帶化的設(shè)置

由于現(xiàn)在的存儲(chǔ)技術(shù)成熟、成本降低,大多數(shù)系統(tǒng)都采用條帶化來實(shí)現(xiàn)系統(tǒng)的IO負(fù)載分擔(dān)。如果操作系統(tǒng)有LVM(Logical Volume Manager邏輯卷管理器)軟件或者硬件條帶設(shè)備,我們就可以利用這些攻擊來分布IO負(fù)載。當(dāng)使用LVM或者硬件條帶時(shí),決定因素是條帶深度(stripe depth)和條帶寬度(stripe width):

條帶深度指的是條帶的大小,也叫條帶單元;條帶寬度指的是條帶深度的產(chǎn)量或者一個(gè)條帶集中的驅(qū)動(dòng)數(shù);

需要根據(jù)系統(tǒng)的IO要求來合理的選擇這些數(shù)據(jù)。對(duì)于Oracle數(shù)據(jù)庫(kù)系統(tǒng)來數(shù),比較合理的條帶深度是從256K到1M。下面分析影響條帶深度和條帶寬度的影響因素。

2.2.1.1? 條帶深度

為了提高IO效率,我們要盡量使一次邏輯IO請(qǐng)求由一塊磁盤的一次物理IO請(qǐng)求。因而影響條帶的一個(gè)重要因素就是一次邏輯IO請(qǐng)求的大小。

此外,系統(tǒng)中IO的并發(fā)度不同我們對(duì)條帶的配置要求也不同。例如,在高并發(fā)度且IO請(qǐng)求的大小都比較小的情況下,我們希望一塊磁盤能同時(shí)響應(yīng)多個(gè)IO操作;而在那些存在大IO請(qǐng)求的低并發(fā)度系統(tǒng)中,我們可能就需要多塊磁盤同時(shí)響應(yīng)一個(gè)IO請(qǐng)求。無(wú)論是一個(gè)磁盤還是多個(gè)磁盤響應(yīng)IO請(qǐng)求,我們的一個(gè)原則是讓一次邏輯IO能被一次處理完成。

下面先看下影響IO大小的操作系統(tǒng)和Oracle的相關(guān)參數(shù):

db_block_size:Oracle中的數(shù)據(jù)塊大小,也決定了Oracle一次單個(gè)IO請(qǐng)求中的數(shù)據(jù)塊的大小;db_file_multiblock_read_count:在多數(shù)據(jù)塊讀時(shí),一次讀取數(shù)據(jù)塊的數(shù)量,它和參數(shù)db_block_size一起決定了一次多數(shù)據(jù)塊讀的大小,它們的乘積不能大于操作系統(tǒng)的最大IO大?。徊僮飨到y(tǒng)的數(shù)據(jù)塊大?。哼@個(gè)參數(shù)決定拉Redo Log和Archive Log操作時(shí)的數(shù)據(jù)塊大小,對(duì)于大多數(shù)Unix系統(tǒng)來說,該值為512K;最大操作系統(tǒng)IO大?。簺Q定了一次單個(gè)的IO操作的IO大小的上限,對(duì)于大多數(shù)Unix系統(tǒng)來說,由參數(shù)max_io_size設(shè)置;sort_area_size:內(nèi)存中sort area的大小,也決定了并發(fā)排序操作時(shí)的IO大??;hash_area_size:內(nèi)存中hash area的大小,也決定了哈希操作的IO大小。

其中,前面兩個(gè)是最關(guān)鍵的兩個(gè)參數(shù)。

在OLTP系統(tǒng)中,會(huì)存在大量小的并發(fā)的IO請(qǐng)求。這時(shí)就需要考慮選擇比較大的條帶深度。使條帶深度大于IO大小就稱為粗粒度條帶(Coarse Grain Striping)。在高并行度系統(tǒng)中,條帶深度為(n * db_block_size),其中n為大于1的整數(shù)。

通過粗粒度條帶能實(shí)現(xiàn)最大的IO吞吐量(一次物理IO可以同時(shí)響應(yīng)多個(gè)并發(fā)的邏輯IO)。大的條帶深度能夠使像全表掃描那樣的多數(shù)據(jù)塊讀操作由一個(gè)磁盤驅(qū)動(dòng)來響應(yīng),并提高多數(shù)據(jù)塊讀操作的性能。

在低并發(fā)度的DSS系統(tǒng)中,由于IO請(qǐng)求比較序列化,為了避免出現(xiàn)熱點(diǎn)磁盤,我們需要避免邏輯IO之由一塊磁盤處理。這是,粗粒度條帶就不適合了。我們選擇小的條帶深度,使一個(gè)邏輯IO分布到多個(gè)磁盤上,從而實(shí)現(xiàn)IO的負(fù)載均衡。這就叫細(xì)粒度條帶。條帶深度的大小為(n * db_block_size),其中n為小于多數(shù)據(jù)塊讀參數(shù)(db_file_multiblock_read_count)大小的整數(shù)。

另外,IO過程中,你無(wú)法保證Oracle數(shù)據(jù)塊的邊界能和條帶單元的大小對(duì)齊。如果條帶深度大小和Oracle數(shù)據(jù)塊大小完全相同,而它們的邊界沒有對(duì)齊的話,那么就會(huì)存在大量一個(gè)單獨(dú)的IO請(qǐng)求被兩塊磁盤來完成。

在OLTP系統(tǒng)中,為了避免一個(gè)邏輯IO請(qǐng)求被多個(gè)物理IO操作完成,條帶寬度就需要設(shè)置為兩倍或者兩倍以上于Oracle數(shù)據(jù)塊大小。例如,如果條帶深度是IO大小的N倍,對(duì)于大量并發(fā)IO請(qǐng)求,我們可以保證最少有(N-1)/ N的請(qǐng)求是由一塊磁盤來完成。

2.2.1.2? 條帶寬度

正如我們前面所述,無(wú)論是一個(gè)還是多個(gè)磁盤響應(yīng)一個(gè)邏輯IO,我們都要求IO能被一次處理。因而在確定了條帶深度的基礎(chǔ)上,我們需要保證條帶寬度 >= IO請(qǐng)求的大小 / 條帶深度。

此外,考慮到以后系統(tǒng)容量的擴(kuò)充,我們也需要規(guī)劃好條帶寬度。

如今大多數(shù)LVM都支持在線動(dòng)態(tài)增加磁盤。也就是在磁盤容量不足時(shí),我們可以隨時(shí)將新磁盤加入到一個(gè)已經(jīng)使用的邏輯卷中。這樣的話,我們?cè)谠O(shè)置邏輯卷時(shí)就可以簡(jiǎn)單地將所有磁盤都?xì)w入到一個(gè)卷中去。

但是,有些LVM可能還不支持動(dòng)態(tài)增加磁盤。這時(shí)我們就需要考慮以后的容量擴(kuò)充對(duì)IO均衡的影響了。因?yàn)槟阈略黾拥拇疟P無(wú)法加入原有卷,而需要組成一個(gè)新的卷。但一般擴(kuò)充的容量和原有容量比較相對(duì)比較小,如果原有卷的條帶寬度比較大的話,新增加的卷的條帶寬度無(wú)法達(dá)到其大小,這樣就會(huì)使新、舊卷之間出現(xiàn)IO失衡。

例如,一個(gè)系統(tǒng)的初始配置是一個(gè)包含64塊磁盤、每塊磁盤大小為16G的單一邏輯卷。磁盤總的大小是1T。隨著數(shù)據(jù)庫(kù)的數(shù)據(jù)增長(zhǎng),需要增加80G的空間。我們把新增加的5個(gè)16G磁盤再組成一個(gè)邏輯卷。這樣就會(huì)導(dǎo)致兩個(gè)卷上的IO失衡。為了避免這種情況。我們可以將原有磁盤配置成每個(gè)條帶寬度為8個(gè)磁盤的8個(gè)邏輯卷,這樣在新增加磁盤時(shí)可以也增加為8個(gè)磁盤的新卷。但必須要保證8個(gè)磁盤的條帶寬度能夠支持系統(tǒng)的每秒IO吞吐量。

如果你的條帶寬度設(shè)置得比較小,就需要估算出你的各個(gè)數(shù)據(jù)庫(kù)文件的IO負(fù)載,并根據(jù)負(fù)載量不同將他們分別部署到不同卷上一分擔(dān)IO負(fù)載。

2.2.2 人工條帶

如果系統(tǒng)不支持LVM或者硬件條帶,IO負(fù)載就必須由DBA根據(jù)數(shù)據(jù)庫(kù)文件的IO負(fù)載不同手工將他們分散到各個(gè)磁盤上去以保證整個(gè)系統(tǒng)的IO負(fù)載均衡。

有許多DBA會(huì)將哪些使用頻率非常高的表和它的索引分開存儲(chǔ)。但實(shí)際上這種做法并不正確。在一個(gè)事務(wù)中,索引會(huì)先被讀取到然后再讀取表,它們的IO操作是有前后順序的,因此索引和表存儲(chǔ)在同一個(gè)磁盤上是沒有沖突的。僅僅因?yàn)橐粋€(gè)數(shù)據(jù)文件即包含了索引又包含了數(shù)據(jù)表而將它分割是不可取的。我們需要根據(jù)文件上的IO負(fù)載是否已經(jīng)影響到了數(shù)據(jù)庫(kù)的性能來決定是否將數(shù)據(jù)文件分割。

為了正確分布文件,我們首先必須先了解各個(gè)數(shù)據(jù)庫(kù)文件的IO負(fù)載需求以及IO系統(tǒng)的處理能力。鑒定出每個(gè)文件的IO吞吐量。找出哪些文件的IO吞吐率最高而哪些IO量很少,將它們分散分布到所有磁盤上去以平衡IO吞吐率。

如果你不了解或者無(wú)法預(yù)計(jì)文件的IO負(fù)載,就只能先估計(jì)他們的IO負(fù)載來規(guī)劃文件分布,在系統(tǒng)運(yùn)行過程中再做調(diào)整。

2.2.3 文件分離

無(wú)論是采用操作系統(tǒng)條帶化還是手工IO分布方式,如果IO系統(tǒng)或者IO規(guī)劃布置無(wú)法滿足IO吞吐率的要求,我們就需要考慮將高IO吞吐率的文件和其他文件分離。我們可以在存儲(chǔ)規(guī)劃階段或者系統(tǒng)運(yùn)行階段找出那樣的文件。

除了IO吞吐率,在決定是否分割文件時(shí),我們還需要考慮可恢復(fù)性以及數(shù)據(jù)容量擴(kuò)張問題。

但是在分割文件之前,一定要確認(rèn)存在IO瓶頸,然后再根據(jù)產(chǎn)生IO瓶頸的數(shù)據(jù)定位到存在高IO吞吐率的文件(熱點(diǎn)文件)。

2.2.3.1? 表、索引和臨時(shí)表空間

如果具有高IO吞吐率的數(shù)據(jù)文件屬于包含表和索引的表空間,我們就需要找出這些文件的IO是否可以通過SQL語(yǔ)句調(diào)優(yōu)或者優(yōu)化應(yīng)用程序來降低。

如果具有高IO吞吐率的數(shù)據(jù)文件屬于臨時(shí)表空間,那我們就需要檢查是否可以通過避免或調(diào)優(yōu)SQL語(yǔ)句的排序操作來降低IO。

經(jīng)過應(yīng)用調(diào)優(yōu)后,如果IO分布仍然無(wú)法滿足IO吞吐的要求,我們就需要考慮分離高IO吞吐率的數(shù)據(jù)文件了。

2.2.3.2? Redo Log文件

如果具有高IO吞吐率的文件是Redo Log文件,則需要考慮將Redo Log文件與其他文件分離,可以通過以下配置來實(shí)現(xiàn):

將所有Redo Log文件放到?jīng)]有任何其他文件的磁盤上去??紤]到可恢復(fù)性,需要將一個(gè)Redo Log組中的成員文件分別放到不同的物理磁盤上去;將每個(gè)Redo Log組放到一個(gè)沒有任何其他文件的單獨(dú)磁盤上;通過操作系統(tǒng)條帶化工具,將Redo Log文件條帶化分布到多個(gè)磁盤上去;不要將Redo Log文件放到RAID 5上去

Redo Log文件是由LGWR進(jìn)程序列化的寫入的。如果在同一個(gè)磁盤上不存在并發(fā)的其他IO操作,寫入效率就更高。我們需要確認(rèn)已經(jīng)沒有其他優(yōu)化調(diào)整空間再考慮分割Redo Log文件。如果系統(tǒng)支持AIO但還沒有激活該特性,可以考慮激活A(yù)IO看是否能解決Redo Log的IO性能瓶頸。

2.2.3.3? 歸檔Redo Log

如果歸檔變慢,我們也許可以通過使LGWR的寫操作與Archive進(jìn)程的讀操作分離來避免LGWR進(jìn)程魚Archive進(jìn)程直接的IO沖突。我們可以同交替成組存放Redo Log文件來實(shí)現(xiàn)。

例如,我們有四組Redo Log,每組包含兩個(gè)Log文件:(A1,A2)、(B1,B2)、(C1,C2)、(D1,D2)。我們就可以以下面這種存放方式將它們分布存儲(chǔ)到四個(gè)磁盤上去來實(shí)現(xiàn)磁盤分離訪問:(A1,C1)、(A2、C2)、(B1,D1)、(B2,D2)。

當(dāng)LGWR進(jìn)程做日志切換時(shí),如從A組切換到B組,LGWR開始向B組寫Redo Log(第三、四塊磁盤),而Archive進(jìn)程則從B組讀取數(shù)據(jù)(第一、二塊磁盤)寫入歸檔文件中去,他們分別訪問的是不同磁盤,因而避免了IO沖突。

2.3???? 三種簡(jiǎn)單的配置方法

這里給出三種簡(jiǎn)單的操作系統(tǒng)IO配置的例子,包括如何簡(jiǎn)單地計(jì)算來決定磁盤的拓?fù)浣Y(jié)構(gòu)、條帶深度等等。

2.3.1 將所有文件條帶化到所有磁盤上去

IO配置最簡(jiǎn)單的方法就是建立一個(gè)大的邏輯卷,將所有磁盤都條帶化到這個(gè)卷中去??紤]到可恢復(fù)性,這個(gè)卷需要被鏡像(RAID 1)。每個(gè)磁盤的條帶深度必須大于頻繁執(zhí)行的IO操作的最大IO大小。這種配置對(duì)大多數(shù)情況都能提供足夠的性能支持。

2.3.2 將歸檔日志放到另外的磁盤上去

在歸檔模式下,如果歸檔文件也和其他文件放在同一個(gè)條帶化的卷中,那么當(dāng)歸檔進(jìn)程對(duì)Redo Log進(jìn)行歸檔時(shí),會(huì)大大增加磁盤的IO負(fù)載。將歸檔日志轉(zhuǎn)移到其他磁盤上有如下好處:

歸檔進(jìn)程效率提高;當(dāng)歸檔時(shí),其他進(jìn)程受到歸檔進(jìn)程的影響

歸檔日志的磁盤數(shù)由歸檔日志產(chǎn)生的頻率以及歸檔存儲(chǔ)容量決定。

2.3.3 將Redo Log文件放到另外的磁盤上去

在更新非常頻繁的OLTP系統(tǒng)中,Redo Log的寫操作非常頻繁。將Redo Log文件轉(zhuǎn)移到其他磁盤上可以有如下好處:

寫Redo Log的讀寫效率最高,因而事務(wù)的執(zhí)行也能獲得最佳性能;寫Redo Log操作不會(huì)影響任何其他IO操作

Redo Log的磁盤數(shù)量有Redo Log的大小決定。由于現(xiàn)在的磁盤容量都非常大,通常配置兩個(gè)磁盤(如果做鏡像則需要四塊)就足夠了。并且,根據(jù)我們前面的分析,將Redo Log文件交互的存放到兩塊磁盤上去能避免LGWR進(jìn)程的寫操作與ARCH進(jìn)程的讀操作之間的IO沖突。

3 Oracle中的IO問題及其解決思路

對(duì)于負(fù)載偏重點(diǎn)不同,我們可以簡(jiǎn)單的將數(shù)據(jù)庫(kù)系統(tǒng)分為CPU負(fù)載系統(tǒng)(CPU Bound System)和IO負(fù)載系統(tǒng)(IO Bound System)。顧名思義,CPU負(fù)載系統(tǒng)的資源瓶頸在于CPU,而IO負(fù)載系統(tǒng)的瓶頸在于磁盤IO。

我們可以通過操作系統(tǒng)的一些命令來確認(rèn)一個(gè)系統(tǒng)是否是存在IO負(fù)載。在UNIX下,可以使用"iostat"或者"sar -d"來看系統(tǒng)的IO情況;在windows下,可以通過系統(tǒng)的性能監(jiān)視器查看,但由于性能監(jiān)控器中看到的IO是靜態(tài)的IO總量信息,并不直觀,因此也可以用本站的TopShow工具來查看實(shí)時(shí)的IO信息。

在UNIX系統(tǒng)下,發(fā)現(xiàn)CPU IDLE很低并不一定代表這是一個(gè)CPU負(fù)載系統(tǒng)。一個(gè)IO負(fù)載系統(tǒng)在表面上看CPU的IDLE值也可能很低:

oracle@db01:/export/home/oracle>?sar?-u?1?10
?
HP-UX?hkhpdv45?B.11.23?U?ia64????10/24/07
?
09:43:05????%usr????%sys????%wio???%idle
09:43:06?43?25?30??1
09:43:07?44?36?19?1
09:43:08?23?27?44??6
09:43:09?12?37?50?1
09:43:10?1036?51?3
09:43:11?15?34?42??9
09:43:12?18?36?44?3
09:43:13?17?35?46?2
09:43:14?12?32?52?4
09:43:15?12?31?56?1
??
Average??21?33?43??3

我們可以注意到,實(shí)際上WIO是引起CPU IDLE過低的主要原因。WIO是當(dāng)一個(gè)進(jìn)程需要運(yùn)行或已經(jīng)運(yùn)行后,因?yàn)樾枰却齀O事件而被阻塞了。事實(shí)上CPU是處于IDLE狀態(tài)(在某些系統(tǒng)中,已經(jīng)將WIO取消并歸為IDLE),真正的原因是系統(tǒng)中存在IO瓶頸。

通過iostat或者sar -d我們可以找出存在IO瓶頸的磁盤設(shè)備,如果該磁盤設(shè)備是用于Oracle 數(shù)據(jù)庫(kù)存儲(chǔ)文件的,我們可以判斷出是數(shù)據(jù)庫(kù)存在IO問題。在windows下,可以通過TopShow來找出哪個(gè)進(jìn)程正在進(jìn)行大量IO傳輸,如果是Oracle進(jìn)程,也可以判斷為是數(shù)據(jù)庫(kù)存在IO問題。

確認(rèn)系統(tǒng)存在IO問題后,我們就需要定位到底是什么引起的IO問題,該采取什么措施來解決問題。根據(jù)我們前面的介紹,Oracle中存在各種IO,要定位IO,最好的工具是statspack(在10g以后,可以用AWR)。通過statspack report的Top 5 Events,我們可以看到對(duì)系統(tǒng)系能影響最大的5個(gè)等待event,而不同的IO問題會(huì)對(duì)應(yīng)不同Event,所以,我們可以根據(jù)這些event采取不同的措施來解決IO問題。下面是一個(gè)典型的IO負(fù)載系統(tǒng)的Top 5 Event:

Top?5?Timed?Events
~~~~~~~~~~~~~~~~~~?????%?Total
Event??Waits????Time?(s)?Ela?Time
--------------------------------------------?------------?-----------?--------
db?file?sequential?read???70,575,969?????344,200????53.34
db?file?scattered?read?11,240,748?????163,242????25.30
log?file?sync?????657,241?36,363?????5.64
CPU?time??35,290?????5.47
log?file?parallel?write???833,799?20,767?????3.22

可以看到,前兩個(gè)時(shí)間“db file sequential read”和“db file scattered read”分別占了總等待時(shí)間的53.34%和25.30%,而我們前面提到這兩個(gè)事件分別是由索引掃面和全表掃面(或快速索引掃面)引起的,因此,能解決索引掃面問題和全表掃面問題就能解決這個(gè)系統(tǒng)的IO瓶頸。

IO問題到底對(duì)CPU有多大影響呢?我們用以上例子中的數(shù)據(jù)分析一下。從等待時(shí)間統(tǒng)計(jì)數(shù)據(jù)中,我們看到的是時(shí)間在總等待時(shí)間中所占的比例。而系統(tǒng)的“總響應(yīng)時(shí)間 ”= “等待時(shí)間 ”+ “CPU工作時(shí)間”(注意,上面Top 5事件中的“CPU Time”不是指CPU的工作時(shí)間,而是指CPU的等待時(shí)間)?!癈PU工作時(shí)間”的數(shù)據(jù)我們可以在“Instance Activities Stats for DB”這一分類統(tǒng)計(jì)數(shù)據(jù)中找到:

Statistic?Total?????per?Second????per?Trans
---------------------------------?------------------?--------------?------------
CPU?used?by?this?session??17,136,868??396.7?15.5

先計(jì)算出“總等待時(shí)間” = 344,200 * 100% / 53.34% = 645,294s

“總響應(yīng)時(shí)間” = “總等待時(shí)間” + “CPU工作時(shí)間” = 645,294 + 17,136,868 = 17,782,162s

我們可以算出“CPU工作時(shí)間”、“db file sequential read”和“db file scattered read”分別在“總響應(yīng)時(shí)間中所占的比例為:

CPU工作時(shí)間 = 17,136,868 / 17,782,162 = 96.4%

“db file sequential read” = 344,200 / 17,782,162 = 1.9%

“db file scattered read” = 163,242 / 17,782,162 = 0.9%

可見,IO事件所引起的等待時(shí)間在總響應(yīng)時(shí)間所占比例并不大。因此,我們?cè)谧鱿到y(tǒng)優(yōu)化之前先分析系統(tǒng)是CPU負(fù)載系統(tǒng)還是IO負(fù)載系統(tǒng)對(duì)于我們的優(yōu)化方向和最終的優(yōu)化效果起很大的作用。

以下事件是可能由IO問題引起的等待事件,在IO負(fù)載系統(tǒng)中,我們要特別關(guān)注這些事件:

與數(shù)據(jù)文件相關(guān)的IO事件

'db file sequential read'????

'db file scattered read'

'db file parallel read'

'direct path read'???

'direct path write'??

'direct path read (lob)'

'direct path write (lob)'

與控制文件相關(guān)的IO事件

'control file parallel write'

'control file sequential read'

'control file single write'

與Redo日志相關(guān)的IO事件

'log file parallel write'????

'log file sync'?

'log file sequential read'

'log file single write'

'switch logfile command'

'log file switch completion'

'log file switch (clearing log file)'

'log file switch (checkpoint incomplete)'

'log switch/archive'

'log file switch (archiving needed)'

與Buffer Cache相關(guān)的IO事件

'db file parallel write'

'db file single write'

'write complete waits'

'free buffer waits'

下面我們就分別介紹如何解決IO問題。

3.1???? IO調(diào)優(yōu)的思路及常用手段

通過對(duì)statspack或者awr報(bào)告的分析,我們可以得知是那些IO相關(guān)事件引起的IO問題。針對(duì)不同的事件,可以采取不同的分析、處理方法。而有一些通用的方法并不是針對(duì)特定的事件的。我們這里先介紹一下這些方法。

3.1.1 通過SQL調(diào)優(yōu)來減少IO請(qǐng)求

一個(gè)沒有任何用戶SQL的數(shù)據(jù)庫(kù)幾乎不產(chǎn)生任何IO。基本上數(shù)據(jù)庫(kù)所有的IO都是直接或間接由用戶提交的SQL所導(dǎo)致的。這意味著我們可以通過控制單個(gè)SQL產(chǎn)生的IO來降低數(shù)據(jù)庫(kù)總的IO請(qǐng)求。而通過SQL調(diào)優(yōu)來降低SQL查詢計(jì)劃中的IO操作次數(shù)則是降低SQL產(chǎn)生IO的最好方法。數(shù)據(jù)庫(kù)的性能問題通常是由少數(shù)幾個(gè)SQL語(yǔ)句所導(dǎo)致的,它們產(chǎn)生了大量IO導(dǎo)致了整個(gè)數(shù)據(jù)庫(kù)的性能下降。優(yōu)化幾條問題語(yǔ)句往往就能解決整個(gè)數(shù)據(jù)庫(kù)的IO性能問題。

從Oracle 10g開始,ADDM能夠自動(dòng)檢測(cè)出問題語(yǔ)句,同時(shí),再通過查詢優(yōu)化建議器能夠自動(dòng)優(yōu)化語(yǔ)句并降低它們對(duì)IO的消耗。關(guān)于ADDM和查詢優(yōu)化建議器可以參考文章《Oracle 10G 新特性——ADDM和查詢優(yōu)化建議器》。

3.1.2 通過調(diào)整實(shí)例參數(shù)來減少IO請(qǐng)求

在這種方法中,主要有兩種途徑來實(shí)現(xiàn)對(duì)IO的優(yōu)化。

使用內(nèi)存緩存來減少IO

通過一些內(nèi)存緩存,如Buffer Cache、Log Buffer、Sort Area,可以降低數(shù)據(jù)庫(kù)對(duì)IO的請(qǐng)求。

當(dāng)Buffer Cache被增大到一定大小時(shí),絕大多數(shù)結(jié)果可以直接從緩存中獲取到,而無(wú)需從磁盤上讀取了。而在進(jìn)行排序操作時(shí),如果Sort Area足夠大,排序過程中產(chǎn)生的臨時(shí)數(shù)據(jù)可以直接放在內(nèi)存中,而無(wú)需占用臨時(shí)表空間了。

調(diào)整multiblock IO(多數(shù)據(jù)塊IO)的大小

控制Multiblock IO的參數(shù)叫DB_FILE_MULTIBLOCK_READ_COUNT,它控制在多數(shù)據(jù)塊讀時(shí)一次讀入數(shù)據(jù)塊的次數(shù)。適當(dāng)增加這個(gè)參數(shù)大小,能夠提高多數(shù)據(jù)塊操作(如全表掃描)的IO效率。例如,讀取100M數(shù)據(jù),如果每次讀取1M一共讀取100次的效率就比每次讀取100K一共讀取1000次更快。但是這個(gè)數(shù)字達(dá)到一定大小后,再增加就作用不大了:每次10M一共讀100次來讀取1G的數(shù)據(jù)的效率和單獨(dú)一次讀取1G數(shù)據(jù)的效率是沒有多大區(qū)別的。這是因?yàn)镮O效率受到2個(gè)因素的影響:IO建立時(shí)間和IO傳輸時(shí)間。

IO建立時(shí)間對(duì)于不同IO大小來說都是相同的,它決定了對(duì)小IO的總的IO時(shí)間,增大Multiblock IO大小可以減少IO建立時(shí)間;

IO傳輸時(shí)間與IO大小是成正比的,在小IO時(shí),IO傳輸時(shí)間一般比IO建立時(shí)間少,但對(duì)于大IO操作來說,IO傳輸時(shí)間決定了總的IO時(shí)間。因此Multiblock IO大小增大到一定大小時(shí),它對(duì)總的IO時(shí)間影響就不大了。

3.1.3 在操作系統(tǒng)層面優(yōu)化IO

如我們前面所介紹的,利用一些操作系統(tǒng)提供的提升IO性能的特性,如文件系統(tǒng)的異步IO、Direct IO等來優(yōu)化數(shù)據(jù)庫(kù)系統(tǒng)的IO性能。另外一種方法就是增加每次傳輸?shù)淖畲驣O大小的限制(大多數(shù)Unix系統(tǒng)中,由參數(shù)max_io_size控制)。

3.1.4 通過Oracle ASM實(shí)現(xiàn)對(duì)IO的負(fù)載均衡

ASM(Automatic Storage Manager自動(dòng)存儲(chǔ)管理)是從Oracle 10g開始引入的。它是一個(gè)建立在數(shù)據(jù)庫(kù)內(nèi)核中的文件系統(tǒng)和卷管理器。它能自動(dòng)將IO負(fù)載均衡到所有可用的磁盤啟動(dòng)器上去,一避免“熱區(qū)”。ASM能防止碎片,因此無(wú)需重建數(shù)據(jù)來回收空間。數(shù)據(jù)被均衡分布到所有硬盤上。

3.1.5 通過條帶化、RAID、SAN或者NAS實(shí)現(xiàn)對(duì)IO的負(fù)載均衡

這個(gè)方法通過一些成熟的存儲(chǔ)技術(shù),如條帶化、RAID、SAN和NAS,來將數(shù)據(jù)庫(kù)IO分布到多個(gè)可用的物理磁盤實(shí)現(xiàn)負(fù)載均衡,以避免在還存在空閑可用磁盤時(shí)出現(xiàn)的磁盤爭(zhēng)用和IO瓶頸問題。

關(guān)于這幾種存儲(chǔ)技術(shù),我們文章的前面部分都有做介紹。

3.1.6 通過手工布置數(shù)據(jù)庫(kù)文件到不同的文件系統(tǒng)、控制器和物理設(shè)備上來重新分布數(shù)據(jù)庫(kù)IO

當(dāng)數(shù)據(jù)庫(kù)系統(tǒng)中缺乏以上各種存儲(chǔ)技術(shù)手段時(shí),我們可以考慮使用這種方式。這樣做的目的是使數(shù)據(jù)庫(kù)的IO得到均勻分布,從而避免在還有空閑磁盤時(shí)出現(xiàn)磁盤爭(zhēng)用和IO瓶頸問題。當(dāng)然這種手工分布IO方法是無(wú)法達(dá)到以上的自動(dòng)分布IO的效果的。

3.1.7 其他手段

系統(tǒng)中總會(huì)存在一些IO是無(wú)法消除或降低的。如果采用以上手段還不能滿足IO性能要求的話,可以考慮這兩種方法:

將老數(shù)據(jù)移除你的生產(chǎn)數(shù)據(jù)庫(kù)(Housekeep)采用更多、更快的硬件3.2???? 數(shù)據(jù)文件相關(guān)的IO事件

數(shù)據(jù)庫(kù)系統(tǒng)中的大多數(shù)的IO請(qǐng)求都是針對(duì)數(shù)據(jù)文件的。因此大多數(shù)情況下,與數(shù)據(jù)文件相關(guān)的IO事件是引起系統(tǒng)IO性能的主要原因。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉