fastapi + aiomysql 连接池在 10 次调用后卡住
fastapi + aiomysql connection pool stuck after 10 calls
为什么aiomysql连接池在调用N次后卡住了? (N是maxsize
个连接数,试过默认N=10和N=3)
我认为获取的连接会在 async with
退出时自动关闭。
这是要重现的最小脚本:
from fastapi import FastAPI
import aiomysql
import secret
app = FastAPI()
@app.on_event("startup")
async def _startup():
app.state.pool = await aiomysql.create_pool(host=secret.DB_URL, port=3306, user=secret.DB_USERNAME, password=secret.DB_PASSWORD, db=secret.DB_DATABASE)
print("startup done")
async def _get_query_with_pool(pool):
async with await pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute("SELECT 1")
return await cur.fetchall()
@app.get("/v1/get_data")
async def _get_data():
return await _get_query_with_pool(app.state.pool)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
原来罪魁祸首是 pool.acquire()
之前的额外等待
async def _get_query_with_pool(pool):
async with await pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute("SELECT 1")
return await cur.fetchall()
去掉pool.acquire()前的多余等待,所以:
async def _get_query_with_pool(pool):
async with pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute("SELECT 1")
return await cur.fetchall()
现在连接成功了
2021 年第四季度更新:
事实证明连接池不值得。连接池可能导致 mysql8 alter table 永远锁定。只需打开和关闭数据库连接。
为什么aiomysql连接池在调用N次后卡住了? (N是maxsize
个连接数,试过默认N=10和N=3)
我认为获取的连接会在 async with
退出时自动关闭。
这是要重现的最小脚本:
from fastapi import FastAPI
import aiomysql
import secret
app = FastAPI()
@app.on_event("startup")
async def _startup():
app.state.pool = await aiomysql.create_pool(host=secret.DB_URL, port=3306, user=secret.DB_USERNAME, password=secret.DB_PASSWORD, db=secret.DB_DATABASE)
print("startup done")
async def _get_query_with_pool(pool):
async with await pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute("SELECT 1")
return await cur.fetchall()
@app.get("/v1/get_data")
async def _get_data():
return await _get_query_with_pool(app.state.pool)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
原来罪魁祸首是 pool.acquire()
之前的额外等待async def _get_query_with_pool(pool):
async with await pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute("SELECT 1")
return await cur.fetchall()
去掉pool.acquire()前的多余等待,所以:
async def _get_query_with_pool(pool):
async with pool.acquire() as conn:
async with conn.cursor(aiomysql.DictCursor) as cur:
await cur.execute("SELECT 1")
return await cur.fetchall()
现在连接成功了
2021 年第四季度更新:
事实证明连接池不值得。连接池可能导致 mysql8 alter table 永远锁定。只需打开和关闭数据库连接。