1.3 KiB
1.3 KiB
DB Connection Pool Singleton Hotfix (2026-04-30)
背景
/daily_sales 出現 PostgreSQL FATAL: sorry, too many clients already。根因不是單一查詢過重,而是多個 route 會在 request 內直接呼叫 DatabaseManager(),舊實作每次初始化都 create_engine(),導致同一個 worker process 內反覆建立新的 SQLAlchemy connection pool。
修正
database/manager.py 的 DatabaseManager 以 (DATABASE_TYPE, effective_db_path) 作為 key 快取 engine 與 Session factory。後續直接 DatabaseManager() 會共用同一組連線池,不再持續放大 PostgreSQL client 數。
第二輪硬化:
- 將「查快取 + 建立 engine」放在同一把 lock 內,避免併發第一波 request 同時建立多個 pool。
- PostgreSQL pool 從
pool_size=5, max_overflow=10收斂為pool_size=2, max_overflow=3,降低 gunicorn 多 worker 下的總連線上限。
維運提醒
- 若再次遇到
too many clients already,先檢查是否有新模組繞過database.manager.get_db_manager()或直接create_engine()。 - 熱修後需重啟
momo-pro-system,讓舊 process 釋放既有連線池。 - 不需要重啟或重建
momo-db。 - 用容器內 Flask test client 塞入
logged_in=Truesession,可直接 smoke/daily_sales真實查詢路徑;未登入 curl 只會測到 301/登入頁。