讀寫連線池

最後更新

本頁說明 MySQLPool 的兩個連線池分別在何時被使用,以及某一側未設定時會發生什麼事。

兩個連線池

init() 最多建立兩個 mysql2/promise 連線池(src/MySQLPool.ts:74-91):

連線池 建立條件 典型用途
讀取池 readPool 讀取端設定的 database 非空 指向唯讀副本(replica)
寫入池 writePool 寫入端設定的 database 非空 指向主庫(primary)

兩個連線池都以 waitForConnections: true 建立:連線用完時請求會排隊等待,而不是立即失敗。

每個方法走哪個連線池

方法 連線池
get() table() 第二個參數,預設 "read"
insert()、update()、upsert() 固定寫入池
read() 固定讀取池
write() 固定寫入池
query(sql, params, target) target;省略時沿用最近一次 table() 設定的目標
import MySQLPool from "@pardnchiu/mysql-pool";

// 從副本讀
const list = await MySQLPool.table("orders").where("user_id", 1).get();

// 剛寫入就要讀到最新資料時,改從主庫讀,避開複寫延遲
const fresh = await MySQLPool.table("orders", "write").where("user_id", 1).get();

table(name, "write") 只影響 get() 與之後未指定 target 的 query();寫入方法本來就走寫入池。

只設定一側

設定狀況 結果
只設讀取端 寫入端設定會沿用 config.read(傳設定物件時);以環境變數初始化時寫入池不建立,寫入方法拋出 write connection is not available.
只設寫入端 讀取池不建立;table("x").get() 拋出 read connection is not available.,必須改寫成 table("x", "write").get()
兩側皆未設定 兩個連線池都不建立,init() 仍會成功回傳

read() 與 write() 在呼叫前另外檢查連線池,錯誤訊息為 Read pool connection is not available./Write pool connection is not available.(src/MySQLPool.ts:395-404)。

單一資料庫

不需要讀寫分離時,用 config 鍵讓兩個連線池共用同一組設定:

await MySQLPool.init({
  config: { host: "127.0.0.1", user: "app", password: "secret", database: "app" },
});

此時仍會建立兩個獨立的連線池,各自套用 connectionLimit,連到同一個資料庫的總連線數上限為兩者相加。

相關頁面

EN