# \[淺談]- How Do RDBMS Thread work ?

在設計一個多人使用DBMS (database management system)，基本上都會使用的 OS (operation system) 的多執行緒的功能，大概分為3種：

1. Process per DBMS Worker
2. Thread per DBMS Worker
3. Process Pool
4. DBMS Thread Pkg

在以下進行介紹時，有以下兩個假設（不討論在這兩個架設之外的細節）：

1. OS 本身已經支援 Thread
2. 單核CPU 下的環境

#### 1. Process per DBMS Worker

在 DBMS 中，一個 user 會對應到一個獨立的 OS Process 存取資料，這樣子就稱為Process per DBMS Worke。這樣子的作法的時空背景是在 OS Thread 技術才剛發展的年代，使得以現今的角度看，會有以下幾個問題：

1. 需要更大的記憶體
2. Context switch 需要觸發 OS 的 table, file, network 的機制，而這些thread 卻不用。

但好處就是可以使用到作業系統層級的 Process 交互機制。

<figure><img src="https://853423727-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZBn9owI5fBe0HrECdk%2Fuploads%2F6DJ2a8f05mjOZJG3BibT%2Fimage.png?alt=media&#x26;token=b0ac8b59-fd98-4789-a78f-0a9bb6a10a09" alt=""><figcaption></figcaption></figure>

#### 2. Thread per DBMS Worker

在 DBMS 中所有的 user 都只會對應到 OS 的一個 Process，而不是所有的 user 都會有對應的 Process 。在這樣的做法下有以下好處：

1. 更節省 Memory 的空間，更有利於大連線需求
2. thread switch 比 Process 來得更快 (不需要等待 OS 排成)

壞處是：

1. 有可能在操作 I/O 的時候造成 Process block

基於壞處，在這一類 DB 實作的時候，不會使用 Block (Sync) I/O ，反而會使用 None-Block (Async) I/O。

<figure><img src="https://853423727-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZBn9owI5fBe0HrECdk%2Fuploads%2FNbnrBvAvFZAwMj20HoPW%2Fimage.png?alt=media&#x26;token=db603efe-dadb-4622-a6f2-78cf6c31cdbc" alt=""><figcaption></figcaption></figure>

#### 3. Process Pool

在 BDMS 中，多個連線共用多個 Process。這種方式是把可用的 Process 整合成一個 pool，這一類的 pool 可以動態的 scaling up/down。

這類型的設計會繼承所有的 Process per DBMS Worker 的好處，但更加節省資源。

<figure><img src="https://853423727-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZBn9owI5fBe0HrECdk%2Fuploads%2FJdfELlBug7Ss4IfGgGp0%2Fimage.png?alt=media&#x26;token=c7d580fd-33fe-4fc2-ac20-570acccd4ee7" alt=""><figcaption></figcaption></figure>

#### 4. DBMS Threads Pkg

在 Database 設計初期其實還沒有 threads 的概念，直到 1990 之後 thread 才普遍的存在於各 OS 中，因此大部分的 Relation Database 都沒有使用 thread 反而是獨立發展自己的 Thread Pkg.

### Shared Data and Process Boundaries

在 DBMS 設計上都會盡可能地讓執行緒之間達到 independent，但事實上要完全做到是完全不可能的。勢必有可能會 worker 之間會存取到相同的記憶體位置。在資料庫的運作中，Client 透過 SQL 取得資料，事實上DBMS 要做到這件事情是要透過 buffer。

1. Disk I/O Buffer: 用於 Read/Write 資料的 buffer 主要分成兩類：
   1. Database I/O Request: buffer pool 所有存取 persistent data 都必須透過此去達成
   2. Log I/O Request: A Queue for log. 所有執行緒存取資料都會需要更新 logs。然而再 Transaction 中，會以 log 作為是否成功的基準。換句話說，當執行 Transaction 的時候 DBMS 在未 flushed 之前，都不會釋放資源。
2. Client communication buffers: 指的是 SQL。在 DBMS 去 Fetch 資料是透過 SQL 去抓取資料。在這部分，有時候要加速抓取的速度，有可能會使用先前已經執行過 SQL 用於達到 prefetch 的效果。&#x20;
3. Lock Table: 用於 Process 取用資源的一個保護機制，以避免 concurrency issues。

<figure><img src="https://853423727-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MZBn9owI5fBe0HrECdk%2Fuploads%2Fxd1Dwr1EQSzrcivYWna9%2Fimage.png?alt=media&#x26;token=54c560c3-29c8-48c7-ba4a-54f382784f85" alt=""><figcaption></figcaption></figure>

### Admission Control

主要用於控制 Throughput 的機制，是一個非常重要的 DB 元件。尤其在多工系統中容易突破系統的臨界值 使得整體的效能大幅下降。因此 Admission Control Policy 對於 DBMS 來說是非常重要的。

一般來說有兩層：

1. Process Dispatcher: 用於確保 client connection 低於臨界值&#x20;
2. Execution Admission Controller: 主要決定是否讓某個 query 執行或者延後。通常在 query 已經進行優化，解譯的階段才執行。

### 參考資料

\[1] Hellerstein, Joseph M., Michael Stonebraker, and James Hamilton. "Architecture of a database system." *Foundations and Trends® in Databases* 1.2 (2007): 141-259.
