
以11g來分析
數據庫實例包括:SGA和一系列后台管理、監控簡稱
數據庫包括三種文件:數據文件、控制文件、重做日志文件
數據庫實例和數據庫是Orale數據庫體系的核心部分
Oracle服務器和實例
實例:由一些在內存區和后台進程組成
這些內存區包括 數據庫高速緩存、重做日志緩存、共享池、流池及其他可選區域,如JAVA池,這些池稱為數據庫的內存結構
后台進程包括系統監控進程SMON,進程監控PMON,數據庫寫進程DBWR,日志寫進程LGWR,檢驗點進程CKPT及其他進程(如歸檔進程,REco進程),這些數據庫系統進程忠於職守、相互協作地完成數據庫管理任務
要訪問數據庫,則必須先啟動實例,啟動實例,則先分配內存區,然后啟動后台進程。
在數據庫啟動過程中,5個進程是必須啟動的:SMON、PMON/DBWR、LGWR、CKPT,在告警日志中alterSID.ora可以看到數據庫的啟動過程
Oracle服務器
Oracle服務器是由實例和數據庫文件組成。
Oracle除了維護實例和數據文件外,還在用戶與服務器連接時啟動服務器進程並分配PGA
Oracle數據庫的物理結構(文件組成):
數據文件:數據文件寶內涵數據庫中的實際數據,是數據庫操作系統中數據的最終存儲位置
控制文件:包含維護數據庫和驗證數據庫完整性的信息,它是二進制文件
重做日志文件:重做日志文件包含數據庫發生變化的記錄,在發生故障時用於數據恢復
Oracle參數文件和密碼文件
雖然不是Oracle的數據庫文件,但是是不可缺少的兩個文件
參數文件:定義了數據庫實例特性,在參數文件中包含SGA內存結構分配空間的參數,如分配數據庫高速緩沖區的大小等,參數文件是正文文件,可以使用編輯器查看。
密碼文件:授予用戶啟動和關閉數據庫實例,Oracle默認用戶名和密碼存儲在文件中,可以根據這個判斷用戶的操作權限
數據庫連接與會話
數據庫連接
連接有3中方式
1 基於主機方式:服務器和客戶端運行在同一台計算機上,用戶可以直接連接數據庫服務器
2 基於客戶機:數據庫服務器和客戶端運行在不同計算機上,客戶通過網絡連接數據庫服務器。經常使用此種方式
3 用戶-應用服務器-數據庫服務器:此種方法稱為三成訪問模式。用戶先訪問應用服務器,應用在訪問數據庫服務器,應用服務器類似中介,完成客戶和數據庫的交互
會話
一個明確的數據庫連接,用戶采用3種的任意一種方式連接,就稱為一個會話
用戶通過某種工具,在專用連接情況下訪問數據,服務器就會自動創建一個與該用戶進程對應的服務器進程,二者是一對一關系,用戶退出或發生異常時,會話結束
專有連接,指用戶和服務器進程之間是一對一關系,而共享服務器配置情況下,多個用戶進程可以同時共享服務器進程,此時就不是專有服連接,而是多對一關系
一個用戶可以並發發起多個會話
SQL> select serial#,username,status,process,program,logon_time from v$session where username='SYS'; SERIAL# USERNAME STATUS PROCESS PROGRAM LOGON_TIM ---------- ------------------------------ -------- ------------------------ ------------------------------------------------ --------- 24691 SYS ACTIVE 27448 sqlplus@gzxbi01 (TNS V1-V3) 18-MAR-17 28528 SYS INACTIVE 27443 sqlplus@gzxbi01 (TNS V1-V3) 18-MAR-17
可以看到,有兩個會話,當前執行的指令的會話為ACTIVE,一個用戶可以建立多個會話
一個連接,可以有多個會話(即服務器進程和數據庫服務器見,可以建立多個會話)
SQL> select sid,serial#,paddr from v$session where username='SYS'; SID SERIAL# PADDR ---------- ---------- ---------------- 125 24691 00000000D1B5A9B8 357 28528 00000000D1B4B448 SQL> set autotrace on statistics; SQL> select sid,serial#,paddr,port from v$session where username='SYS'; SID SERIAL# PADDR PORT ---------- ---------- ---------------- ---------- 125 24691 00000000D1B5A9B8 0 132 14042 00000000D1B5A9B8 0 357 28528 00000000D1B4B448 0 Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 850 bytes sent via SQL*Net to client 552 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 3 rows processed
從PADDR和PORT可以看到是一個連接,但是有兩個會話通過SID和SERIAL#來確認。
查詢會話是否存在,可以
SQL> select pname,username from V$PROCESS WHERE ADDR=HEXTORAW('00000000D1B5A9B8'); PNAME USERNAME ----- --------------- oracle Statistics ---------------------------------------------------------- 36 recursive calls 0 db block gets 67 consistent gets 0 physical reads 0 redo size 614 bytes sent via SQL*Net to client 552 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL> select pname,username from V$PROCESS WHERE ADDR=HEXTORAW('00000000D1B4B448'); PNAME USERNAME ----- --------------- oracle Statistics ---------------------------------------------------------- 1 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 614 bytes sent via SQL*Net to client 552 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL> select pname,username from V$PROCESS WHERE ADDR=HEXTORAW('00000000D1B4B448'); -- 在另一個終端將這個會話退出后執行這條查詢發現,連接不存在 no rows selected Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 411 bytes sent via SQL*Net to client 541 bytes received via SQL*Net from client 1 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 0 rows processed
Oracle 數據庫的內存結構
由SGA和PGA組成
PGA:程序全局區,程序全局區不是實例的一部分。當服務器啟動時,才分配PGA
SGA:系統全局區,是數據庫實例的一部分,當數據庫實例啟動時,首先分配系統全局區,在系統全局區包含幾個重要的內存區(數據庫高速緩存、重做日志緩存、共享池、大池、Java池等)
共享池Shard Pool
用用共享池的目的就是共享SQL和PL/SQL代碼。即把解析到的SQL代碼結果放到這里緩存,PL/SQL不僅在這里緩存,同時在這里共享。共享池由兩部分組成
庫高速緩存
存儲的是可執行SQL語句和PL/SQL代碼,包括 共享的SQL區和PL/SQL區,以及像鎖和庫緩存句柄這樣的控制結果(一個SQL執行,在LC中有對應的執行計划,這個執行計划可以共享使用,稱為軟解析,反之硬解析,執行大量硬解析,會消耗大量的CPU資源)
LC容量有限,采用LRU算法管理LC,LC設置的越大,則可以共享更多的SQL或者PL/SQL代碼,但並沒有專門設置的指令,只能通過設置共享池SP大小間接改變。而SP又是SGA的部分,所以SP不能超過SGA大小
SQL> ALTER SYSTEM SET shared_pool_size = 16M;
System altered.
SQL> SHOW PARAMETER shared_pool_size;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
shared_pool_size big integer 16M
12c推薦內存自動管理方式。即設置MEMORY_TARGET和MEMEORY_MAX_TARGET,這個時候,SGA和PGA會自動調整。但在特殊情況下,需要手動設置PGA和SGA值,使得PGA和SGA不會低於設置的大小,這種情況是Oracle內存抖動,因為應用需要SGA和PGA頻繁的調整,這往往會導致數據庫短期HANG。此時需要注意,SGA和PGA的和不能接近MEMORY_MAX_TARGET.否則,一旦發生PGA需要擴充但是沒有足夠的內存空間則會觸發ora_04301
注:為會話分配私有SQL區 共享服務器連接模式:私有SQL區在SGA 專有服務器連接模式:PGA 私有SQL中相同的SQL語句可以指向共享池中同一個SQL語句
Oracle清除共享池中共享的SQL語句,一面硬解析發生
1 收集統計數據后 2 數據庫對象被DDL修改 3 修改全局數據庫名
在同一個用戶下,不同環境,相同的SQL各自發生硬解析,生成自由表,共享池會分配他們各自的空間
[oracle@gzxbi01 ~]$ sqlplus sys/testttt8 as sysdba SQL*Plus: Release 12.1.0.2.0 Production on Wed Mar 22 14:04:41 2017 Copyright (c) 1982, 2014, Oracle. All rights reserved. Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL> create table myt(id integer); Table created. SQL> insert into myt values(100); 1 row created. SQL> commit; Commit complete. SQL> alter system flush shared_pool; System altered. SQL> select * from myt; ID ---------- 100 SQL> alter session set optimizer_mode = first_rows; Session altered. SQL> select * from myt; ID ---------- 100 SQL> alter session set sql_trace=true; Session altered. SQL> select * from myt; ID ---------- 100
查詢SQL語句和SQL_ID
SQL> col SQL_TEXT FOR A50 SQL> select sql_id,sql_text from v$sql where sql_text like 'select * from myt'; SQL_ID SQL_TEXT ------------- -------------------------------------------------- gff382536kduk select * from myt gff382536kduk select * from myt gff382536kduk select * from myt
可以看到,三條SQL語句中的SQL_ID是一樣的,也就是Oracle進行SQL哈希計算得到的結果是一樣的,但是環境發生變化,Oracle認為不共享該SQL執行計划。會產生游標
SQL> select sql_id,sql_text,address,child_address,child_number from v$sql where sql_text like 'select * from myt'; SQL_ID SQL_TEXT ADDRESS CHILD_ADDRESS CHILD_NUMBER ------------- -------------------------------------------------- ---------------- ---------------- ------------ gff382536kduk select * from myt 00000000C43F68F8 00000000C78C7E80 0 gff382536kduk select * from myt 00000000C43F68F8 00000000BF7E4FB8 1 gff382536kduk select * from myt 00000000C43F68F8 00000000C59C83D8 2
可以看到,SQL_ID是一樣,但是從CHILD_ADDRESS中可以了解,生成了兩個子游標,生成子游標會發生SQL重新解析,生成自己的執行計划,同樣占用PGA內存空間,同時硬解析消耗資源
SQL> select sql_id,sql_text,address,parse_calls from v$sql where sql_text like 'select * from myt'; SQL_ID SQL_TEXT ADDRESS PARSE_CALLS ------------- -------------------------------------------------- ---------------- ----------- gff382536kduk select * from myt 00000000C43F68F8 1 gff382536kduk select * from myt 00000000C43F68F8 1 gff382536kduk select * from myt 00000000C43F68F8 1
可以看到,發生了硬解析,在環境未發生變化時
SQL> select * from myt; ID ---------- 100 SQL> select sql_id,sql_text,address,parse_calls from v$sql where sql_text like 'select * from myt'; SQL_ID SQL_TEXT ADDRESS PARSE_CALLS ------------- -------------------------------------------------- ---------------- ----------- gff382536kduk select * from myt 00000000C43F68F8 1 gff382536kduk select * from myt 00000000C43F68F8 1 gff382536kduk select * from myt 00000000C43F68F8 2
可以看到,最后一個環境花生變化的SQL語句,共享了執行計划,所以變成了2,進行了軟解析
數據字典高速緩存
是與數據字典相關的一段緩沖區。在DDC中存儲了數據文件、表、索引、列、用戶、權限信息和其他一些數據庫對象的定義
在SQL語句的解析階段,數據庫服務武器需要把這些信息來解析用戶名和用戶的訪問權限。如果Oracle緩存額這些信息,將會縮短查詢的響應時間
DDC也稱為字典緩存或者行緩存。作用就是把相關的數據字典信息放入緩存,以提高查詢的響應時間
DDC緩存的大小取決於SP尺寸的大小。如果設置太小,但查詢需要數據字典信息時,Oracle將不斷馮文數據字典表來獲得所需要的信息。由於DD也是存儲在磁盤上的一類數據文件,頻繁的IO會降低
數據庫的查詢速度,如果要設置DDC的大小,需要通過設置SP間接實現
數據庫高速換緩沖區 DataBase Buffer Cache DbBC
存儲了最近從數據文件讀入的數據庫信息或用戶更改后需要協會數據庫的數據信息,此時沒有提交給數據庫更改后的數據稱為臟數據,當用戶執行查詢語句,如果數據塊在DbBC中,Oracle不需要從磁盤
中讀取,而是直接從DbBC中讀取,這些緩存的數據由LRU算法管理。
使用參數DB_BLOCK_SIZE和DB_BLOCK_BUFFERS設置高速緩存大小。DB_BLOCK_SIZE是Oracle數據塊大小,而DB_BLOCK_BUFFERS是數據庫的個數,二者的乘積就是庫高速緩存的大小
SQL> show parameter db_block_size; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_block_size integer 8192
9i以上的產品,提供了DB_CACHE_SIZE參數來設置Oracle數據庫高速緩存區的大小。可動態更改
SQL> show parameter db_cache_size; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_cache_size big integer 0
如果是自動管理的,則為0,在運行12c,數據庫高速緩存是一定已經分配好的。
SQL> sho sga; Total System Global Area 1912602624 bytes Fixed Size 2925792 bytes Variable Size 469764896 bytes Database Buffers 1426063360 bytes Redo Buffers 13848576 bytes
查看SGA內存動態大小
SQL> select * from v$sgainfo; NAME BYTES RES CON_ID -------------------------------- ---------- --- ---------- Fixed SGA Size 2925792 No 0 Redo Buffers 13848576 No 0 Buffer Cache Size 1426063360 Yes 0 In-Memory Area Size 0 No 0 Shared Pool Size 419430400 Yes 0 Large Pool Size 33554432 Yes 0 Java Pool Size 16777216 Yes 0 Streams Pool Size 0 Yes 0 Shared IO Pool Size 100663296 Yes 0 Data Transfer Cache Size 0 Yes 0 Granule Size 16777216 No 0 Maximum SGA Size 1912602624 No 0 Startup overhead in Shared Pool 164637416 No 0 Free SGA Memory Available 0 0 14 rows selected.
可以看到,數據庫高速緩存是 1426063360B(1360M),雖然是自動掛你,但是用戶可以設置組件的大小
SQL> alter system set db_cache_size = 700M; System altered. SQL> show parameter db_cache_size NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_cache_size big integer 704M
Oracle引入了緩沖區顧問參數(Buffer Cache Advisory Parameter),可以讓Oracle對數據庫緩沖區的內存分配提供一些建議,緩沖區顧問用於啟動或關閉統計信息,這些信息用於預測不同緩沖區
大小導致的不同行為特性,DBA可以參考這些統計信息,基於當前數據庫負載設置優化的數據庫高速緩存
有三個狀態
OFF:關閉,不分配緩存顧問的工作內存
ON:打開,分配工作內存
READY:打開,但不分配緩存顧問的工作內存
SQL> show parameter db_cache_advice; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_cache_advice string ON
可以看到,默認是打開的
SQL> col id for 99 SQL> select id,name,block_size,size_factor,size_for_estimate from v$db_cache_advice; ID NAME BLOCK_SIZE SIZE_FACTOR SIZE_FOR_ESTIMATE --- -------------------- ---------- ----------- ----------------- 3 DEFAULT 8192 .0989 144 3 DEFAULT 8192 .1978 288 3 DEFAULT 8192 .2967 432 3 DEFAULT 8192 .3956 576 3 DEFAULT 8192 .4945 720 3 DEFAULT 8192 .5934 864 3 DEFAULT 8192 .6923 1008 3 DEFAULT 8192 .7912 1152 3 DEFAULT 8192 .8901 1296 3 DEFAULT 8192 .989 1440 3 DEFAULT 8192 1 1456 3 DEFAULT 8192 1.0879 1584 3 DEFAULT 8192 1.1868 1728 3 DEFAULT 8192 1.2857 1872 3 DEFAULT 8192 1.3846 2016 3 DEFAULT 8192 1.4835 2160 3 DEFAULT 8192 1.5824 2304 3 DEFAULT 8192 1.6813 2448 3 DEFAULT 8192 1.7802 2592 3 DEFAULT 8192 1.8791 2736 3 DEFAULT 8192 1.978 2880 21 rows selected.
SIZE_FACTOR為1為當前數據庫高速緩存大小,在數據庫高峰時期可以通過該視圖提供的參考值設置DB_CACHE_SIZE大小。如果是自動管理系統運行的很好的,則沒有必要進行手工
重做日志高速緩沖區 redo buffer cache
Redo Log Buffer記錄DML和DDL操作,用來重建、重做數據庫的變化,數據庫進程將在用戶內存中的Redo實體復制到Redo Log Buffer中,Redo實體在Redo Log Buffer中占用連續且順序的內存
空間,后台LGWR負責將Redo Log Buffer中的Redo實體寫入在線日志文件。
LGWR將Redo順序寫入在線日志,與DBWR進程的離散寫相比速度要快很多,LGWR進程先寫原則,使得數據庫的變化得到保護,用戶不需要等到DBWR進程將臟數據寫入到磁盤即可繼續操作
重做日志緩沖區大小可動態調節,即數據庫運行期間可修改這塊內存大小,Oracle提供了一個初始化參數LOG_BUFFER,在數據庫啟動時就分配好重做日志緩沖區的尺寸
SQL> show parameter log_buffer; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ log_buffer big integer 13016K
這是靜態參數,不能直接用alter修改,靜態修改的方法如下