教你如何成為Oracle 10g OCP - 第十一章 配置網路環境

tolywang發表於2010-09-10

第十一章   配置網路環境


11.1  使用者與Oracle資料庫建立連線

網路服務(Net Service) - Oracle 使用網路服務從客戶端或者中間層的應用伺服器與資料庫
伺服器建立連線。

監聽器 - 在客戶端, 網路服務是作為後臺執行的程式;在DB伺服器端,網路服務透過名為
監聽器的程式來體現。 還可以透過配置網路服務使異構資料庫進行通訊。

連線方式 - 兩種:專用連線,共享連線

專用連線 - 這種方式下,伺服器程式和使用者程式一一對應,一旦使用者程式中斷,對應的服務
器程式也被終止。


-- 客戶端段建立到伺服器端的連線過程 :
A. 客戶端發起連線,透過在客戶端提供使用者名稱,使用者密碼及連線字串(tnsnames.ora中設定),
建立與監聽器的連線。
B. 客戶端一旦與監聽器建立了連線,則在客戶端生成使用者程式。同時監聽器會判斷客戶端
請求的DB服務名是否為當前這個監聽器管理的服務名(service_names), 如果不是或不存在,
報錯且中斷,如果是,則監聽器會在該伺服器名所在的DB伺服器上建立伺服器程式。
C. 監聽器在建立伺服器程式以後,會將使用者程式和伺服器程式建立連線,之後監聽器退出與
客戶端的連線(這就是為什麼程式與DB建立連線後,即使關閉監聽器,程式仍然連線著DB的原因)。
D. 伺服器程式根據使用者程式提供的使用者名稱及密碼到資料字典裡判斷是否匹配。
E. 如果不匹配,報錯,如果匹配,則分配PGA, 並生成SESSION .

 


11.2  配置監聽器

監聽配置檔案位於$ORACLE_HOME/network/admin/listener.ora,可以手工編輯,也可以透過
圖形介面netca設定,1521 是監聽器的預設埠。

典型的listener.ora 檔案內容:

SID_LIST_LISTENER =   (註冊到監聽器的service name所在區域)
  (SID_LIST =
    (SID_DESC =       (對外部過程呼叫的服務名)
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/product/oracle)
      (PROGRAM = extproc)
    )
  )

LISTENER =     (監聽名稱)
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = franklindb)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))   (對外部過程呼叫的監聽資訊)
    )
  )

 

-- 備註 --  
     預設安裝時,會安裝一個PL/SQL外部程式(ExtProc)條目在listener.ora中,
是oracle為呼叫外部程式預設配置的監聽,它的名字通常是ExtProc或PLSExtProc,
但一般不會使用它。可以直接從listener.ora中將這項移除,因為對ExtProc已經有多
種攻擊手段了,在不使用外部程式時,oracle也是建議刪除的。
  PLSExtProc是pl/sql external procdure的意思,就是在pl/sql中呼叫外部語句,
如c、java寫的過程。現在,Oracle已經全面支援JAVA了,這東西也就過時了,之所以
繼續保留是考慮到相容以前老版本的資料庫。
  有時可能會在多個資料庫例項之間複製listener.ora,檢查複製來的檔案中是否
含有不需要的服務,確保只留下的確需要的服務專案,減少監聽器受攻擊的面。

 

手工新增監聽器 --

同一臺server上可以存在多個監聽器,只不過每個監聽器必須在不同埠上進行監聽,
這些監聽器透過同一個listener.ora檔案進行配置,比如新增一個my_listener監聽:

MY_LISTENER =     (監聽名稱)
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = franklindb)(PORT = 1526))
    )
  )

 

服務名稱 --

監聽器接收來自客戶端的連線請求時,會判斷客戶端tnsnames.ora中設定請求的服務
名是否為該監聽器管理的服務名,可是我們在listener.ora中沒有發現服務名稱的配置,
這是為什麼呢 ?

這裡我們先來了解服務名,可以把服務理解為一組相似任務的邏輯組合,比如一個企業
中的銷售,採購,財務,人事等4個部門,那麼可以劃分4個服務名:sales,pur,fin,hr,
每個功能不同的部門連線到不同的服務名,這樣可以對資料庫活動分組,更好進行跟蹤
和調優。

那麼服務是如何體現在監聽器裡的呢 ? Oracle是透過將服務註冊到監聽器裡來實現的。
有下面兩種註冊方式:
A. 動態註冊 - 透過DB例項中的PMON將當前例項裡的服務名(引數service_names)註冊到
同一個伺服器上的、預設的、並且是1521埠上監聽的監聽器,服務名由初始化引數
service_names 決定,該引數預設為資料庫名,可以動態更改,也可以指定多個值,也
就是多個服務名,每個服務名之間透過逗號隔開。

SQL> alter system set service_names='ora10g,sales,pur,fin,hr' ;

修改後我們需要等一段時間,PMON程式就會將這些服務名都註冊到預設的監聽器中(預設
表示監聽名稱為LISTENER, 埠為1521),  當然,我們也可以不等PMON程式自動註冊服務
名,而是執行下面的命令,理解將這些服務名註冊到監聽器中:

SQL> alter system register ;

備註: 一般我們在dbca建立資料庫之前需要netca建立相關網路服務檔案,然後dbca才會
動態註冊,需要注意順序 。

 

動態註冊到非預設監聽 --

如果需要將服務名動態註冊到非預設監聽,比如剛才建立的my_listener上,我們需要設定
例項初始化引數 local_listener . 該引數說明了要動態註冊的監聽器的資訊。

SQL> alter system set local_listener=
     '(ADDRESS_list=(ADDRESS = (PROTOCOL = TCP)(HOST = franklindb)(PORT = 1526)))' ;

這裡應該也可以將這個host,ip等描述寫入DB SERVER的tnsnames.ora中,設定別名來取代 ,比如  SQL> alter system set local_listener='tnsnames.ora中的別名' ; 

詳細介紹動態註冊的文章:

http://space.itpub.net/35489/viewspace-622765

 

 

 

靜態註冊 --

相對與動態註冊而言的,資料庫服務名資訊手工寫入listener.ora 檔案中。靜態註冊服務名
由SID_LIST_ 這部分來指定,例如:


SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/product/oracle)
      (PROGRAM = extproc)
    )
    (SID_DESC =       (新增這段SID_DESC,即可為預設監聽靜態註冊一個服務名)
      (GLOBAL_DBNAME = static_srv)  (global_dbname表示對外公佈的服務名)
      (ORACLE_HOME = /u01/product/oracle)
      (SID_NAME = ora10g)
    )
  )

備註: GLOBAL_DB_NAME 表示對外公佈的服務名,也就是使用者連線資料庫時所使用
的名稱,它可以任意取名 。SID_NAME 表示服務名對應的資料庫例項名。我們可以
加入多個SID_DESC,從而為DB定義多個服務名 。

 

監聽器的管理 --

$lsnrctl
LSNRCTL > help
LSNRCTL > start
LSNRCTL > start  my_listener
LSNRCTL > stop
LSNRCTL > status


假設資料庫例項名為teststby , 靜態註冊設定如下:

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/product/oracle)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = teststby)
      (ORACLE_HOME = /u01/product/oracle)
      (GLOBAL_DBNAME = test11g2)
    )
  )

檢視監聽狀態:

LSNRCTL > status

Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "test11g2" has 1 instance(s).
  Instance "teststby", status UNKNOWN, has 1 handler(s) for this service...
Service "teststby" has 1 instance(s).
  Instance "teststby", status READY, has 1 handler(s) for this service...
Service "teststbyXDB" has 1 instance(s).
  Instance "teststby", status READY, has 1 handler(s) for this service...

其中因為初始化引數中設定了 dispatchers='(PROTOCOL=TCP) (SERVICE=teststbyXDB)'
所以teststbyXDB狀態也表現為READY, dispatchers 設定是用於共享伺服器的。

其中teststby 是READY 狀態,它就是初始化引數service_names中設定的服務名,而
Service "test11g2" 的status狀態為UNKNOWN.  這是因為teststby 服務是在初始化
引數service_names中定義的(前面我們知道,可以定義多個服務名,逗號隔開),是
由PMON程式動態註冊到監聽器,因此PMON程式所在的資料庫一定處於開啟狀態,所以
服務名對應的例項準備好(READY)接受使用者連線請求。   但是test11g2 服務是透過
編輯listener.ora檔案靜態註冊的服務名,監聽器並不確定這個服務名對應的例項
是否有開啟,所以例項對應的status為UNKNOWN . 

備註: 動態註冊的服務,在例項開啟後,對應的監聽自動開啟,例項關閉後對應
的監聽自動關閉 。 

SQL> show parameter service 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------
service_names                        string      teststby

 

關閉 teststby 例項後,READY對應的監聽被自動關閉:

Service "PLSExtProc" has 1 instance(s).
  Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "test11g2" has 1 instance(s).
  Instance "teststby", status UNKNOWN, has 1 handler(s) for this service...

 

 

11.3  配置客戶端

兩種方式 :  簡單連線及本地命名 

sqlnet.ora 中設定ezconnect 表示簡單連線,檔案內容:
NAMES.DIRECTORY_PATH=(TNSNAMES,EZCONNECT) 

簡單連線方式: SQL> connect  

簡單連線不支援負載均衡,故障轉移(Failover)等高階特性 。


本地命名 - tnsnames.ora 位於客戶端,例子: 
TESTSTBY =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dbtest)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = test11g2)
    )
  )

配置客戶端的tnsnames.ora檔案後,我們一般使用tnsping 來測試網路連線。

$ tnsping  TESTSTBY (別名) , 能通,說明透過連線字串能連線到指定的監聽
器上,但是該工具不會驗證字串包含的服務名是否為監聽器所管理的服務名,它
只是驗證網路連線是否正常 。

 


11.4  配置共享連線

Oracle連線中有兩種連線方式:  專用連線和共享連線 。

專用連線方式下使用者程式和伺服器程式一一對應,使用者程式退出,伺服器程式
也退出,並釋放佔用的資源,伺服器程式作為使用者程式的代理程式(影子程式),
負責執行使用者程式發出的命令,並返回命令執行後得到的結果 。

共享連線方式下,使用者程式和伺服器程式存在多對多的關係,專用連線方式下,
建立連線後,使用者程式沒有命令發出時,伺服器程式處於空閒狀態,但是資源
仍然被佔用(還是連線著),且不能處理其他使用者程式發出的命令,但是在共享
連線中,只要某個伺服器程式空閒,它還可以處理其他使用者發出的命令,因此
需要的程式個數就減少了,資源的利用更加高效,佔用的PGA也相對減少了。
因此可以支援更多的使用者連線請求。


Dispatcher --

共享連線時,需要配置多個名為dispatcher的元件,它作為使用者程式和伺服器
程式之間的協調者,負責將使用者程式的請求傳遞給伺服器程式,並將伺服器程式
得到的結果返回給使用者,PMON程式會定期將每個dispatcher的地址及工作負載
註冊到監聽器,當使用者程式連線到監聽器時,監聽器會選擇一個負載最低的
dispatcher , 並把該dispatcher的地址返回給使用者程式,從而使用者程式與該
dispatcher建立起了連線。 使用者程式在session的整個生命週期中,連線的
dispatcher是不會變化的。


共享連線模式下使用者程式的連線過程如下:
A. 使用者程式連線到監聽器 ;
B. 監聽器根據各個註冊的dispatcher的負載,選擇一個負載最低的dispatcher,
並將其地址返回給使用者程式,假設監聽器選擇了dispatcher1 ;
C. 使用者程式根據監聽返回的地址,連線到該dispatcher ;
D. dispatcher接收到使用者程式發出的請求後,會將請求放入請求佇列,請求佇列
位於SGA中,請求佇列可以被所有dispatcher說共享;
E. 在伺服器程式中,最空閒的伺服器程式會從請求佇列中按照先進先出的原則,
挑選一個請求進行處理;
F. 伺服器程式將處理後的結果放入相應佇列中(Oracle會為每個dispatcher準備
一個對應的響應佇列)。
G. 響應佇列中的結果返回給對應的dispatcher.
H. Dispatcher 將結果返回給使用者程式。


PGA,UGA在兩種連線模式下的分配 --

專用連線模式下,使用者程式對應的PGA被伺服器程式獨享。
共享連線模式下,使用者的PGA需要在不同的伺服器程式之間共享,這時PGA中的UGA
(包括遊標狀態及session資訊)會被轉移到SGA中(為了共享),如果配置了large
pool, UGA在large pool中分配,如果沒有,UGA在shared pool中分配。

 


配置共享連線 --

初始化引數 dispatchers = (PROTOCOL=TCP) (dispatchers=3) , 表示啟動3個
dispatcher , 還可以透過設定max_dispatchers引數來定義最大可同時啟動的
dispatcher數量 。比如max_dispatchers=10 .

伺服器程式 -- 透過配置shared_servers 來配置伺服器程式,可以動態生成 。
一般設定較少的數值,然後設定max_shared_servers 來限制同時執行的最大的
伺服器程式 。 比如設定shared_servers=5,max_shared_servers=20,負載高
導致需要額外的伺服器程式的時候,會自動建立伺服器程式直到最多20個伺服器
程式同時執行,當負載降低的時,會自動刪除直到剩下5個伺服器程式為止。

 

能夠使用共享連線的session個數 --

shared_server_sessions 引數說明同時可以進行共享連線的session的個數 。
在伺服器段配置共享連線後,還需要在客戶端tnsnames.ora中指定共享連線方式
進行連線: 

TESTSTBY =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = dbtest)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = shared)
      (SERVICE_NAME = test11g2)
    )
  )

如果 (SERVER = DEDICATED) 表示為專用連線模式。


$ lsnrctl service 檢視相關共享連線資訊 。

 

共享連線的限制 -- 

有些操作是不能在共享連線的模式下進行的,包括開啟關閉例項,建立表空間和
資料檔案,維護表,索引等,這些動作必須在專用連線下進行。同時,共享連線
適用於純OLTP應用,對於需掃描大量資料,執行較長時間的操作也不適合(因為共享
的伺服器程式不能佔用太久,數量較少),比如備份恢復等 。 所以一般共享連
接較少使用。 

 

11.5  呼叫外部過程

在編寫PL/SQL的過程中,有時候我們發現透過c或java等外部函式來實現會容易得多,
Oracle提供了在PL/SQL中呼叫外部函式(C函式或java class)的功能,擴充套件了PL/SQL
的程式功能。

呼叫外部函式的過程 :

A. 使用者程式執行PL/SQL過程;
B. 執行過程各種,呼叫一個C++語言寫的函式:c_func, 這裡需要藉助別名庫(別名
庫是資料庫中的一個物件,用來描述一個外部函式所在的動態連結庫的路徑和名稱,
透過別名庫可以知道被呼叫的外部函式在哪個檔案裡) .
C. PL/SQL將對外部函式的呼叫請求傳送給監聽器。
D. 監聽器生成一個extproc程式,該程式專門用來處理外部函式的呼叫,每個session
都會生成一個屬於該session的extproc程式,並且在整個session生命週期裡,extproc
程式會一直存在。
E. Extproc 程式複雜將別名庫所指定的動態連線庫檔案載入到記憶體。
F. Extproc 程式執行指定的外部函式,並將結果返回給伺服器程式,進而返回給使用者程式。

監聽及伺服器端tnsnames.ora中配置extproc :

監聽器中的extproc --

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /u01/product/oracle)
      (PROGRAM = extproc)
    )
    (SID_DESC =
      (SID_NAME = teststby)
      (ORACLE_HOME = /u01/product/oracle)
      (GLOBAL_DBNAME = test11g2)
    )
  )

 

tnsnames.ora中的extproc設定 --

EXTPROC_CONNECTION_DATA =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
    )
    (CONNECT_DATA =
      (SID = PLSExtProc)  -- 必須和監聽中設定的SID一致
      (PRESENTATION = RO)
    )
  )

 

-- 備註 --  
     預設安裝時,會安裝一個PL/SQL外部程式(ExtProc)條目在listener.ora中,
是oracle為呼叫外部程式預設配置的監聽,它的名字通常是ExtProc或PLSExtProc,
但一般不會使用它。可以直接從listener.ora中將這項移除,因為對ExtProc已經有多
種攻擊手段了,在不使用外部程式時,oracle也是建議刪除的。
  PLSExtProc是pl/sql external procdure的意思,就是在pl/sql中呼叫外部語句,
如c、java寫的過程。現在,Oracle已經全面支援JAVA了,這東西也就過時了,之所以
繼續保留是考慮到相容以前老版本的資料庫。
  有時可能會在多個資料庫例項之間複製listener.ora,檢查複製來的檔案中是否
含有不需要的服務,確保只留下的確需要的服務專案,減少監聽器受攻擊的面。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-673177/,如需轉載,請註明出處,否則將追究法律責任。

相關文章