Skip to content

Commit 2232c8f

Browse files
committed
perf(db): 数据库连接池配置 + 慢查询超时(DB_POOL_SIZE, DB_QUERY_TIMEOUT)
1 parent 2f0a8d5 commit 2232c8f

3 files changed

Lines changed: 75 additions & 1 deletion

File tree

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ DB_PORT=3306
1515
DB_DATABASE=leverage
1616
DB_USERNAME=leverage
1717
DB_PASSWORD=your_password_here
18+
# 连接池大小(生产环境建议 20-50,开发环境建议 5-10)
19+
DB_POOL_SIZE=20
20+
# 全局查询超时(ms),超过此时间 TypeORM 会记录警告日志
21+
DB_QUERY_TIMEOUT=10000
1822

1923
# ---- Redis ----
2024
REDIS_HOST=localhost

docs/DEPLOYMENT.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,55 @@ server {
165165

166166
---
167167

168+
## Database Connection Pool Tuning
169+
170+
The backend uses TypeORM with a MySQL2 connection pool. Two environment variables control pool behavior:
171+
172+
| Variable | Default | Description |
173+
|----------|---------|-------------|
174+
| `DB_POOL_SIZE` | `20` | Maximum number of simultaneous DB connections |
175+
| `DB_QUERY_TIMEOUT` | `10000` | Slow query warning threshold (ms). TypeORM logs a warning when exceeded but does **not** kill the query; use DB-level `wait_timeout` for hard kills. |
176+
177+
### Recommended values by environment
178+
179+
| Environment | `DB_POOL_SIZE` | `DB_QUERY_TIMEOUT` |
180+
|-------------|---------------|-------------------|
181+
| Development | 5–10 | 10000 |
182+
| Staging | 10–20 | 10000 |
183+
| Production (OJ) | 20–50 | 10000 |
184+
185+
### How to choose `DB_POOL_SIZE`
186+
187+
- A pool that is **too small** causes connection queuing under load, increasing API latency.
188+
- A pool that is **too large** exhausts MariaDB's `max_connections` (default 151). Leave headroom for admin connections.
189+
- Rule of thumb: `DB_POOL_SIZE` × number of app replicas < `max_connections − 10`.
190+
191+
### Slow query logging
192+
193+
In non-production environments (`NODE_ENV !== 'production'`), TypeORM also logs every query. Watch the logs for `[TypeORM] query: SELECT …` lines that take longer than `DB_QUERY_TIMEOUT` — these are candidates for index optimization.
194+
195+
To suppress verbose query logs on a staging server while keeping slow-query warnings:
196+
197+
```dotenv
198+
NODE_ENV=production
199+
DB_QUERY_TIMEOUT=5000
200+
```
201+
202+
### Additional MariaDB server tuning
203+
204+
For high-concurrency OJ workloads, also tune the DB server itself:
205+
206+
```ini
207+
# /etc/mysql/mariadb.conf.d/99-oj.cnf
208+
[mysqld]
209+
max_connections = 200
210+
wait_timeout = 30
211+
interactive_timeout = 30
212+
innodb_buffer_pool_size = 1G # adjust to available RAM
213+
```
214+
215+
---
216+
168217
## Production Recommendations
169218

170219
### Run as a single process

src/database/database.module.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,29 @@ const entities = [
7777
process.env.NODE_ENV === 'production' ? ['dist/migrations/*.js'] : [],
7878
migrationsRun: process.env.NODE_ENV === 'production',
7979
migrationsTableName: 'migrations',
80-
logging: process.env.NODE_ENV === 'development',
80+
logging:
81+
process.env.NODE_ENV !== 'production'
82+
? ['error', 'warn', 'query']
83+
: ['error'],
8184
charset: 'utf8mb4',
85+
// 全局查询超时(慢查询记录警告,防止慢查询卡住连接池)
86+
maxQueryExecutionTime: parseInt(
87+
process.env.DB_QUERY_TIMEOUT || '10000',
88+
),
89+
// 连接池配置
90+
extra: {
91+
// 最大连接数(生产 20-50,开发 5-10)
92+
connectionLimit: parseInt(process.env.DB_POOL_SIZE || '20'),
93+
// 获取连接超时(ms)
94+
acquireTimeout: 30000,
95+
// 连接超时(ms)
96+
connectTimeout: 10000,
97+
// 空闲连接超时(10分钟)
98+
idleTimeoutMillis: 600000,
99+
// 心跳查询保持连接
100+
enableKeepAlive: true,
101+
keepAliveInitialDelay: 10000,
102+
},
82103
}),
83104
}),
84105
],

0 commit comments

Comments
 (0)