Oracle建立連接的過程
如果我們想登陸數據庫並在數據庫中真正做事情,就必須先建立連接,首先我會介紹如何建立連接,再介紹建立連接的兩種方式的原理,以及建立連接的過程中在客戶端和服務端都做了些什么。
如何連接到數據庫
客戶端和服務端主要是通過TCP/IP協議建立連接的。對於服務端而言,服務端在連接過程中主要關心的是怎么處理請求的問題,Oracle服務器端一定會在固定的地址上啟動一個監聽器用於專門處理連接請求的進程或者是線程。
對於客戶端而言我們需要知道服務端的IP地址,監聽器的端口以及服務名,並率先發起請求。
如果在$ORACLE_HOME/network/admin目錄下的配置文件tnsnames.ora中配置了數據庫的TNS連接字符串如下:
MUPHY =
(DESCREPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = www.muphy.me)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = muphy)
)
)
那么我們就可以按照下面的語法連接到數據庫:
$ sqlplus eoda/foo@muphy
如果我們知道數據庫主機是127.0.0.1,端口是1521,服務名是muphy,那么可以直接在終端中輸入按照下面的語法連接到數據庫:
$ sqlplus eoda/foo@127.0.0.1:1521@muphy
這種簡單的方式連接到數據庫在某些情況非常有用,比如說連接問題的排錯,或者手頭沒有可以使用的tnsnames.ora,或者其他解析方式時。
專用服務器連接
當我們登陸數據庫是,Oracle監聽器進程總會通過fork()或者exec()系統調用創建一個新進程(windows系統為線程),這個新的進程通常是專用服務器配置,繼承了監聽器建立的連接,因為這個服務器進程會在會話生存期中專門為此會話訪問,會話與專用服務器之間存在一對一的關系,如下圖所示:
按照定義,專用服務器不是實例的一部分,客戶端會與這個專用服務器直接通信,包括接收和處理客戶端發來的SQL,如果必要的話,還會為客戶端讀取數據文件,在緩存中查找需要的數據,運行PL/SQL代碼等操作。
共享服務器連接
Oracle的另外一種連接方式是共享服務器,如果采用這種連接方式,數據庫監視器就不會對每個用戶連接創建新的線程或者進程。
在共享服務器中,Oracle使用一個“共享進程”池為多個用戶提供服務,實際上就是一種連接池機制。利用共享服務器,我們不必為10000個數據庫創建10000個進程,而只需要創建很少的進程,這些進程所有會話共享,大大降低了服務器創建和維護進程的開銷,能夠處理更多的連接請求。
共享服務器與專用服務器之間有一個重大的區別:共享服務器不會與客戶端直接通信,因為共享服務器進程是共享的,還需要另外一種機制才能與服務器通信,這種機制就是使用了一個或者一組調度程序的進程,監視器會一直在主機的某一設置好的端口上運行,而調度程序會在服務器上隨意指派的端口上接收連接請求。
通過進程監控器進程PMON,監視器進程知道實例中運行了哪些調度程序以及調度程序的信息,監視器接收到客戶端的共享服務器連接請求后,他會從調度程序中選擇一個調度程序進程,並把這個進程的連接信息返回給客戶端,其中說明了如何連接到這個調度程序,監視器返回調度程序的連接信息后與客戶端斷開連接,監視器的工作到此結束。
客戶端通過監視器返回的連接信息與調度程序通信,調度程序的進程將客戶端的請求放入SGA中的請求隊列,第一個空閑的共享服務器進程會處理這個請求,請求處理完后,共享服務器會把相應放在原調度程序的相應隊列中,調度程序進程一直在監視這個隊列,當它發現相應隊列中有處理結果時,就把結果傳給客戶端。
共享服務器請求處理流程如下:
用一個圖來總結客戶端與Oracle建立連接的兩種方式之間的交互方式: