Read-Write Pools

Last updated

This page explains when each of the two MySQLPool pools is used and what happens when one side is not configured.

Two Pools

init() creates up to two mysql2/promise pools (src/MySQLPool.ts:74-91):

Pool Created when Typical target
Read pool readPool The read config has a non-empty database A read replica
Write pool writePool The write config has a non-empty database The primary

Both pools use waitForConnections: true: when every connection is busy, requests queue instead of failing immediately.

Which Pool Each Method Uses

Method Pool
get() Second argument to table(), default "read"
insert(), update(), upsert() Always the write pool
read() Always the read pool
write() Always the write pool
query(sql, params, target) target; when omitted, the target from the most recent table() call
import MySQLPool from "@pardnchiu/mysql-pool";

// Read from the replica
const list = await MySQLPool.table("orders").where("user_id", 1).get();

// Read from the primary right after a write to avoid replication lag
const fresh = await MySQLPool.table("orders", "write").where("user_id", 1).get();

table(name, "write") only affects get() and later query() calls without a target; write methods use the write pool anyway.

Only One Side Configured

Setup Result
Read side only With a config object, the write side falls back to config.read; with environment variables, no write pool is created and write methods throw write connection is not available.
Write side only No read pool; table("x").get() throws read connection is not available., so use table("x", "write").get()
Neither side No pools are created and init() still resolves

read() and write() check the pool before calling query() and throw Read pool connection is not available. / Write pool connection is not available. (src/MySQLPool.ts:395-404).

Single Database

When you do not need read-write splitting, use the config key so both pools share one config:

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

This still creates two independent pools, each with its own connectionLimit, so the total connection cap against that database is the sum of both.

中文