【深入解析--eygle】學習筆記
SGA指系統全局區(System Global Area),是一塊用於加載數據、對象並保存運行狀態和數據庫控制信息的一塊內存區域,在數據庫實例啟動時分配,當實例關閉時釋放,每個實例都擁有自己的SGA區。
在第一章曾經?到,當數據庫啟動到nomount狀態時,SGA已經分配,同時啟動後台進程,在SQL*Plus中通過show sga命令可以看到SGA的分配情況:
sys@felix SQL>show parameter sga NAME TYPE VALUE ---------------------------------------------------------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 400M sga_target big integer 0 16:12:56 sys@felix SQL>
連接到Oracle數據庫的用戶都可以共享SGA中的數據,通常為了更優化的性能,我們總是期望在物理內存允許的情況下,設置更高的SGA區,以減少物理I/O(SGA中數據緩沖區的增大可以有效地減少物理讀)。
下圖是最常見的數據庫實例體系結構圖,展現了SGA的結構:
Fixed Size 部分是SGA中的固定部分,包含幾千個變量和一些小的數據結構,如Latch或地址指針等,這部分內存分配和特定的數據庫版本以及平台有關,不受用戶控制,而且這些信息對於數據庫來說非常重要,但是通常我們用戶不需要關心。
固定部分只需要很小的內存,可以通過一個內部表X$KSMFSV([K]ernel [S]ervice Layer , [M]emoryManagement,Addresses of [F]ixed [S]GA [V]ariables)查詢。此外Oracle的內部表X$KSMMEM記錄了整個SGA的地址映射關系,通過X$KSMFSV和X$KSMMEM關聯,可以找出Fixed Area中每個變量的設置。
在32位平台上,X$KSMMEM表中每條記錄代表4 Bytes,在64位平台,每條記錄代表4 Bytes:
sys@felix SQL>select * from x$ksmmem whererownum <5; ADDR INDX INST_ID KSMMMVAL ---------------- ---------- -------------------------- 0000000060000000 0 1 00 0000000060000008 1 1 00 0000000060000010 2 1 00 0000000060000018 3 1 00 16:21:39 sys@felix SQL>
sys@felix SQL>select ksmfsnam,ksmfssiz from x$ksmfsv where ksmfsnam='kcsgscn_'; KSMFSNAM KSMFSSIZ ----------------- -------- kcsgscn_ 48 16:23:51 sys@felix SQL>
通過ORADEBUG工具可以得到當前內存中的SCN值:
16:23:51 sys@felix SQL>oradebug setmypid Statement processed. 16:26:19 sys@felix SQL>oradebug DUMPvar SGA kcsgscn_ kcslf kcsgscn_ [060019598, 0600195C8) = 00183004 00000000 00000000 00000000 000024AE 00000000 00000000 00000000 00000000 00000000 60019278 00000000 16:26:22 sys@felix SQL>
SCN值獲取如下:
sys@felix SQL>selectto_number('183004','xxxxxxxxxx') from dual; TO_NUMBER('183004','XXXXXXXXXX') -------------------------------- 1585156 16:27:05 sys@felix SQL>
Fixed Area包含很多控制信息,但是需要注意的是,查詢X$KSMFSV視圖可能會導致進程異常,需要謹慎使用
Buffer Cache-緩沖區高速緩存,用於存儲最近使用的數據塊,這些數據塊可能是被修改過的,也可能是未經修改的。我們知道,在Oracle對數據的處理過程中,代價最昂貴的就是物理I/O(Physical I/O)操作了,同樣的數據從內存中得到要比從磁盤上讀取快得多,所以將盡可能多的數據保存在內存中,可以減少磁盤I/O操作,從而提高數據庫的性能。
從Oracle9i開始,Oracle引入了一個新的初始化參數db_cache_size ,該參數用來定義主Block Size(db_block_size定義的塊大小)的Default緩沖池的大小
各內存組件所使用的Granule大小可以通過動態性能視圖來查詢:
16:36:00 sys@felix SQL>select component,granule_size from v$sga_dynamic_components; COMPONENT GRANULE_SIZE --------------------------------- ------------ shared pool 4194304 large pool 4194304 java pool 4194304 streams pool 4194304 DEFAULT buffer cache 4194304 KEEP buffer cache 4194304 RECYCLE buffer cache 4194304 DEFAULT 2K buffer cache 4194304 DEFAULT 4K buffer cache 4194304 DEFAULT 8K buffer cache 4194304 DEFAULT 16K buffer cache 4194304 DEFAULT 32K buffer cache 4194304 Shared IO Pool 4194304 ASM Buffer Cache 4194304 14 rows selected. 17:33:14 sys@felix SQL>
Oracle管理Buffer Cache使用的是LRU算法,但是這又帶來另外一個問題,很多批處理的操作(比如全表掃?等)可能會導致Buffer Cache的刷新,將經常使用的數據“擠出”Buffer Cache,在不同版本中,Oracle不停的改進LRU算法,以避免這類操作的過度影響。
但是在此之外,Oracle提供了BufferCache的多緩沖池技術從另外一個方面來解決這個問題。所謂的多緩沖池技術是指,根據不同數據的不同訪問方式,將Buffer Cache分為Default、Keep和Recycle池三個部分。對於經常使用的數據,我們可以在建表時就指定將其存放在Keep池中;對於經常一次性讀取使用的數據,可以將其存放在Recycle池中;Keep池中的數據傾向於一直保存,Recycle池中的數據傾向於即時老化,而Default池則存放未指定存儲池的數據,按照LRU算法管理。
默認情況下,所有表都使用DEFAULT池,它的大小就是數據緩沖區Buffer Cache的大小,由初始化參數db_cache_size(8i中是db_block_size*db_block_buffers)決定。
17:33:14 sys@felix SQL>show parameter db_cache_size NAME TYPE VALUE ------------------------------------ ---------------------- ------------------------------ db_cache_size big integer 0 17:37:24 sys@felix SQL>
如果我們在創建數據表或修改數據表時指定STORAGE (BUFFER_POOL KEEP)或者STROAGE(BUFFER_POOL RECYCLE)語句,就設置了這張表使用KEEP或者RECYCLE緩沖區。這兩個緩沖區的大小分別由初始化參數db_keep_cache_size和db_recycle_cache_size來決定。
17:39:03 sys@felix SQL>show parameter db_keep_cache_size NAME TYPE VALUE ------------------------------------ ---------------------- ------------------------------ db_keep_cache_size big integer 0