1. 背景
UNIX/Linux系統上,oracle用多進程模型。例如:linux上一個常規安裝的數據庫會有如下進程列:
$ ps -ef | grep [o]ra_
oracle 15356 1 0 10:53 ? 00:00:00 ora_pmon_db12c
oracle 15358 1 0 10:53 ? 00:00:00 ora_psp0_db12c
oracle 15360 1 8 10:53 ? 00:01:27 ora_vktm_db12c
oracle 15364 1 0 10:53 ? 00:00:00 ora_gen0_db12c
oracle 15366 1 0 10:53 ? 00:00:00 ora_mman_db12c
oracle 15370 1 0 10:53 ? 00:00:00 ora_diag_db12c
oracle 15372 1 0 10:53 ? 00:00:00 ora_dbrm_db12c
oracle 15374 1 0 10:53 ? 00:00:00 ora_dia0_db12c
oracle 15376 1 0 10:53 ? 00:00:00 ora_dbw0_db12c
oracle 15378 1 010:53 ? 00:00:00 ora_lgwr_db12c
oracle 15380 1 0 10:53 ? 00:00:00 ora_ckpt_db12c
oracle 15382 1 0 10:53 ? 00:00:00 ora_smon_db12c
oracle 15384 1 0 10:53 ? 00:00:00 ora_reco_db12c
oracle 15386 1 0 10:53 ? 00:00:00 ora_lreg_db12c
oracle 15388 1 0 10:53 ? 00:00:03 ora_mmon_db12c
oracle 15390 1 0 10:53 ? 00:00:00 ora_mmnl_db12c
oracle 15392 1 0 10:53 ? 00:00:00 ora_d000_db12c
oracle 15394 1 010:53 ? 00:00:00 ora_s000_db12c
oracle 15407 1 0 10:54 ? 00:00:00 ora_tmon_db12c
oracle 15409 1 0 10:54 ? 00:00:00 ora_tt00_db12c
oracle 15411 1 0 10:54 ? 00:00:00 ora_smco_db12c
oracle 15413 1 0 10:54 ? 00:00:00 ora_fbda_db12c
oracle 15415 1 0 10:54 ? 00:00:00 ora_aqpc_db12c
oracle 15419 1 0 10:54 ? 00:00:00 ora_p000_db12c
oracle 15421 1 0 10:54 ? 00:00:00 ora_p001_db12c
oracle 15423 1 0 10:54 ? 00:00:00 ora_p002_db12c
oracle 15425 1 0 10:54 ? 00:00:00 ora_p003_db12c
oracle 15435 1 0 10:54 ? 00:00:00 ora_cjq0_db12c
oracle 15459 1 0 10:54 ? 00:00:00 ora_qm02_db12c
oracle 15463 1 0 10:54 ? 00:00:00 ora_q002_db12c
oracle 15465 1 0 10:54 ? 00:00:00 ora_q003_db12c
oracle 15612 1 0 11:04 ? 00:00:00 ora_w000_db12c
oracle 15679 1 0 11:10 ? 00:00:00 ora_j000_db12c
oracle 15681 1 0 11:10 ? 00:00:00 ora_j001_db12c
oracle 15683 1 0 11:10 ? 00:00:00 ora_w001_db12c
$
即使在多進程模型中,某些個別進程內部運行在多線程模式。
相反,在windows系統上,Oracle數據庫作為一個多線程進程運行,而每個UNIX/Linux下的進程作為一個或多個線程運行。Oracle12c可以在UNIX/Linux上運行在多線程模式下,就像運行在window上那樣。
2. THREADED_EXECUTION參數
線程模型通過初始化參數THREADED_EXECUTION指定。
1) THREADED_EXECUTION=FALSE:為默認值,oracle運行在多進程模式下。
2) THREADED_EXECUTION=TRUE: Oracle以多線程模式運行。
如果想切換到多線程模式,隻需設置THREADED_EXECUTION參數並重啟數據庫就可以。
CONN sys AS SYSDBA
ALTER SYSTEM SET threaded_execution=TRUESCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
一旦數據庫被重啟,我們會發現操作系統進程數減少了很多。
$ ps -ef | grep [o]ra_
oracle 15839 1 0 11:26 ? 00:00:00 ora_pmon_db12c
oracle 15841 1 0 11:26 ? 00:00:00 ora_psp0_db12c
oracle 15843 1 8 11:26 ? 00:00:03 ora_vktm_db12c
oracle 15847 1 0 11:26 ? 00:00:00 ora_u004_db12c
oracle 15853 1 34 11:26 ? 00:00:13 ora_u005_db12c
oracle 15859 1 0 11:26 ? 00:00:00 ora_dbw0_db12c
$
另外,需將如下參數添加至"$ORACLE_HOME/network/admin/listener.ora"檔案中,以允許產生新線程來支援監聽產生的連接,記得要用正確監聽名替換
DEDICATED_THROUGH_BROKER_=ON
當需要切換回多進程模型時,隻需切換該初始化參數值並重啟數據庫。
CONN sys AS SYSDBA
ALTER SYSTEM SET threaded_execution=FALSESCOPE=SPFILE;
SHUTDOWN IMMEDIATE;
STARTUP;
記得清楚"listener.ora"檔案中的參數。
3. OS認證
多線程模型不支援OS認證,這是一個特點而不是bug。看前面的例子,使用線程模型時,通過"SYS ASSYSDBA"而不是 "/ AS SYSDBA"連接數據庫。試着以OS認證連接庫會報錯。
$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.1.0 Production onThu Jul 4 11:28:16 2013
Copyright (c) 1982, 2013, Oracle. All rights reserved.
ERROR:
ORA-01017: invalid username/password;logon denied
Enter user-name: sys as sysdba
Enter password:
Connected to:
Oracle Database 12c Enterprise EditionRelease 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, AdvancedAnalytics and Real Application Testing options
SQL>
文檔上說會報錯ORA-01031 "insufficientprivileges" 。
4. 殺會話
視圖V$PROCESS包括一個叫STID的新列,該列顯示會話的線程ID。
SET LINESIZE 140
COLUMN username FORMAT A15
COLUMN osuser FORMAT A15
COLUMN spid FORMAT A10
COLUMN stid FORMAT A10
SELECT s.username,
s.osuser,
s.sid,
s.serial#,
p.spid,
p.stid,
s.status
FROM v$session s,
v$process p
WHERE s.paddr = p.addr
AND s.username IS NOT NULL
ORDER BY s.username, s.osuser;
USERNAME OSUSER SID SERIAL# SPID STID STATUS
--------------- --------------- -------------------- ---------- ---------- --------
SYS oracle 35 3 18844 18901 ACTIVE
TEST oracle 40 37 18844 19020 INACTIVE
SQL>
在Oracle內殺會話的方法沒變,因為你還是可以找到SID和SERIAL#。
SQL> ALTER SYSTEM KILL SESSION '40,37';
System altered.
SQL>
但一定不要用UNIX/Linux指令殺掉會話進程(SPID)對應的OS進程,否則,我們會殺掉多個會話,而不是我們真正想殺的會話。
$ ps -ef | grep 18844 | grep -v grep
oracle 18844 1 1 16:27 ? 00:00:22 ora_u005_db12c
$
5. 總結
1) 使用該特點的唯一可信理由是將多個實例內建到一個服務器上,同時,沒用多宿主數據庫選項。因為,如果不用多線程模型,OS進程數將會很高。
2) 如果你的硬體架構相對進程而言,更適合處理線程,那麼,該特點也許會帶來一些好處。
3) RAC環境中,各節點必須都用同樣的線程模型。