ConnectionRefusedError主因是MySQL服务未启动或未监听TCP地址;需用127.0.0.1而非localhost测试连通,显式指定port,配置用户远程权限,并await创建连接池。

为什么直接用 aiomysql.create_pool() 容易报错 ConnectionRefusedError
多数人卡在这一步:刚写完 aiomysql.create_pool() 就抛 ConnectionRefusedError: [Errno 111] Connection refused,不是代码写错了,而是 MySQL 服务根本没开或没监听正确地址。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 先用命令行确认 MySQL 可达:
mysql -h 127.0.0.1 -P 3306 -u root -p(注意别用localhost,它在某些系统下会走 socket 而非 TCP,而aiomysql只走 TCP) -
host参数必须填 IP(如"127.0.0.1"),不能填"localhost";port显式指定,别依赖默认值 - 确保 MySQL 用户有远程访问权限(哪怕本地测试):
CREATE USER 'test'@'%' IDENTIFIED BY 'pass'; GRANT ALL ON testdb.* TO 'test'@'%'; FLUSH PRIVILEGES; - 连接池初始化必须
await,不能直接赋值——它返回的是协程对象,不是池实例
aiomysql.Pool 的 minsize 和 maxsize 怎么设才不拖慢响应又不爆连接
设太小(比如 minsize=1, maxsize=1)会导致并发请求排队;设太大(如 maxsize=100)可能压垮 MySQL 或触发 Too many connections 错误。关键看你的 QPS 和单次查询耗时。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- Web 服务场景(如 FastAPI):起步用
minsize=5, maxsize=20;观察SHOW STATUS LIKE 'Threads_connected';峰值,再微调 - 短平快查询(maxsize ≈ 并发请求数 × 1.5(留缓冲)
- 长耗时查询(如含 JOIN 或 GROUP BY):降低
maxsize,配合超时控制(connect_timeout=5),避免连接被长时间占着 - 务必设
pool_recycle=3600(1 小时),防止 MySQL 的wait_timeout主动断连导致后续查询抛OperationalError: (2013, "Lost connection")
用 pool.acquire() + conn.cursor() 写 CRUD 时,漏掉 await cursor.execute() 会怎样
常见错误是把 cursor.execute("INSERT ...", (x,)) 当同步操作直接写,结果插入无声无息、数据没进库,也不报错——因为没 await,协程根本没执行。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 所有数据库 I/O 操作都必须
await:await cursor.execute()、await cursor.fetchall()、await conn.commit() - 增删改后记得
await conn.commit();如果用autocommit=True初始化池,则不用手动 commit,但要注意事务隔离性丢失 - 用上下文管理器更安全:
async with pool.acquire() as conn: async with conn.cursor() as cursor: await cursor.execute("SELECT * FROM users WHERE id = %s", (1,)) result = await cursor.fetchone()自动释放连接和游标,不用手动close() - 查单条用
fetchone(),查多条用fetchall(),别混用;fetchone()返回tuple或None,别直接当字典用
MySQL 报 Packet sequence number wrong 或 Lost connection 的真实原因
这类错误表面是网络问题,实际 90% 是连接池复用了一个已被 MySQL 主动关闭的连接。MySQL 默认 wait_timeout=28800(8 小时),但开发环境常设成 60 秒,而连接池里的空闲连接没及时检测失效。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 初始化池时加
ping=True(推荐):aiomysql.create_pool(..., ping=True),每次从池取连接前自动发 PING 包检测存活 - 或设
pool_recycle=30(秒),强制连接用满 30 秒就换新,适合开发环境 - 生产环境禁用
ping=True(轻微性能损耗),改用pool_recycle+ 监控Threads_connected+ 设置 MySQL 的interactive_timeout和wait_timeout一致且略大于pool_recycle - 别在连接上做长时间阻塞操作(如调外部 API),会卡住整个连接,引发连锁超时
连接池不是“设了就完事”的黑盒,它的健康度直接受 MySQL 配置、网络稳定性、应用查询模式三者共同影响。尤其 ping 和 pool_recycle 的组合策略,不同环境必须差异化配置,抄参数很容易翻车。


















