Sql-Server

數據庫連接與原始 TCP 連接

  • December 28, 2018

我有一些關於數據庫客戶端和數據庫如何互動的基本問題

  1. 數據庫是否支持在來自客戶端的單個數據庫連接上同時進行多個事務?如果不是,為什麼不呢?(因為多路復用將節省每個連接的資源成本,當需要同時執行數千個同時查詢時,連接池是爭用的來源,多路復用肯定可以避免)
  2. 數據庫客戶端級別的連接與物理原始 TCP 連接之間的關係是什麼。是多對一嗎$$ multuplexing $$(或)一對一?如果不復用為什麼不呢?
  3. 如果多路復用,數據庫伺服器是否從其末端(或)多個邏輯連接維護單個邏輯連接

PS:我知道其中一些細節會因數據庫而異,但想知道一般流行的實現,如 Postgres、Mysql、Oracle、SQL server 和 DB2 是如何實現這些的

數據庫是否支持在來自客戶端的單個數據庫連接上同時進行多個事務?

對於 SQL Server,沒有。

如果不是,為什麼不呢?(因為多路復用將節省每個連接的資源成本)

這將使必須在多個客戶端平台上實現的網路協議嚴重複雜化,從而可能產生錯誤和性能問題。

並且由多個連接引起的資源成本很小,並且通過連接池在很大程度上減輕了,其中一組長期連接在客戶端程序中的所有執行緒之間共享。

甲骨文

一個鮮為人知的事實是,在 Oracle 中,同一個 TCP 連接中可以有 0 個、1 個甚至更多的會話。

這在. _Chapter 5 - Oracle Processes

https://books.google.com/books?id=NG4RpD8aLEIC&pg=PA170

連接與會話

許多人驚訝地發現連接不是會話的同義詞。在大多數人的眼中,它們是相同的,但事實是它們不必如此。一個連接上可能建立了零個、一個或多個會話。 **每個會話都是獨立的,即使它們都共享與數據庫的相同物理連接。一個會話中的送出不會影響該連接上的任何其他會話。事實上,使用該連接的每個會話都可以使用不同的使用者身份!**在 Oracle 中,連接只是客戶端程序和數據庫實例之間的物理電路——最常見的是網路連接。該連接可能是到一個專用的伺服器程序或到一個調度程序。如前所述,一個連接可能有零個或多個會話,這意味著一個連接可能存在而沒有相應的會話。

展示:

登錄數據庫:

[oracle@o71 ~]$ sqlplus bp/bp@\'localhost:1521/min18\'

SQL*Plus: Release 18.0.0.0.0 - Production on Thu Dec 27 21:20:03 2018
Version 18.4.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Last Successful login time: Thu Dec 27 2018 21:07:47 +01:00

Connected to:
Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0

SQL>

在另一個會話中,從其他地方開始,查詢 BP 的會話:

SQL> select sid, process, port, paddr from v$session where username = 'BP';

      SID PROCESS                        PORT PADDR
---------- ------------------------ ---------- ----------------
      395 31251                         35298 0000000066E75338

現在在原始會話中啟用自動跟踪:

SQL> set autotrace on

並從另一個會話再次檢查會話:

SQL> select sid, process, port, paddr from v$session where username = 'BP';

      SID PROCESS                        PORT PADDR
---------- ------------------------ ---------- ----------------
      395 31251                         35298 0000000066E75338
      399 31251                         35298 0000000066E75338

SQL> !sudo netstat -tanlp | grep 35298
tcp        0      0 127.0.0.1:35298         127.0.0.1:1521          ESTABLISHED 31251/sqlplus
tcp        0      0 127.0.0.1:1521          127.0.0.1:35298         ESTABLISHED 31253/oracleMIN18

我們有 2 個會話,使用相同的客戶端和伺服器程序以及相同的 TCP 連接(這通常是令人驚訝的部分)。現在如果我們disconnect,但讓 sqlplus 在第一個會話中執行:

SQL> disconnect
Disconnected from Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0
SQL>

並從另一個會話再次檢查數據庫:

SQL> select sid, process, port, paddr from v$session where username = 'BP';

no rows selected

SQL> select spid from v$process where addr = '0000000066E75338';

SPID
------------------------
31253

SQL> !sudo netstat -tanlp | grep 35298
tcp        0      0 127.0.0.1:35298         127.0.0.1:1521          ESTABLISHED 31251/sqlplus
tcp        0      0 127.0.0.1:1521          127.0.0.1:35298         ESTABLISHED 31253/oracleMIN18

SQL> select sid, process, port, paddr from v$session where paddr = '0000000066E75338';

no rows selected

我們仍然有數據庫伺服器程序,我們仍然有客戶端程序,我們仍然有它們之間的 TCP 連接,但是我們有 0 個會話與它們關聯。使用 退出 sqlplus 後exit,即程序和連接終止:

SQL> exit
[oracle@o71 ~]$

和:

SQL> select spid from v$process where addr = '0000000066E75338';

no rows selected

SQL> !sudo netstat -tanlp | grep 35298
tcp        0      0 127.0.0.1:35298         127.0.0.1:1521          TIME_WAIT   -

所以這是可能的,但除了上面的書和基於它建構的展示之外,我從未在實踐中看到過這一點。

引用自:https://dba.stackexchange.com/questions/225859