TimeoutError: QueuePool limit of size 10 overflow 10 reached, connection timed out, timeout 30
AttributeError: 'NoneType' object has no attribute 'read'
OperationalError: (OperationalError) (2013, "Lost connection to MySQL server during query (error(9, 'File descriptor was closed in another greenlet'))")
ObjectDeletedError: Instance '<BookMetaInfo at 0x10d847790>' has been deleted, or its row is otherwise not present.
有没有遇到类似异常的同学,介绍一下解决经验。
我是在持续运行 1 个小时之后才会频繁报错。为了方便用的是 Flask-SQLAlchemy 。看官方手册上讲 使用 session 连接池之后不必每次手动 session.close()
但我加了之后,却将频繁异常的时间从 20 分钟延长到1 小时。但还是没有真正解决问题。Google、StackOverFlow 上寻找答案未果,来来来求教。
注:代码太多,没法放上来。
1
aru 2015-01-07 13:23:28 +08:00 via iPhone
1. 提升sql的效率,避免慢查询
2. pool size 提高到50 |
2
aru 2015-01-07 13:25:22 +08:00 via iPhone
配置下mysql slow log,将超过1秒的sql 语句纪录下来,然后想办法优化sql语句
|
3
tanywei 2015-01-07 14:10:18 +08:00
my.cnf的连接超时也要改啊。
|
4
Feiox OP @aru 并不是慢查询导致的。因为跑测试时都是最多跑到几万的数据量。我真正疑问的是,明明官方手册上说使用连接池之后可以不用 session.close(),那为什么加了之后,却将频繁异常的时间从 20 分钟延长到1 小时。
|
5
keakon 2015-01-07 15:48:10 +08:00
session.close() 只是 rollback 并放回连接池,不会真正关闭。
我感觉你是在多个 greenlet 里同时使用了一个 session。 |
6
kkzxak47 2015-01-07 17:02:39 +08:00
'File descriptor was closed in another greenlet'
这个应该是关键错误吧 |
7
Feiox OP |
8
keakon 2015-01-08 00:40:42 +08:00
还有一个错你没放在代码里…
连接池超了,你设的同时可用的连接数是 10 个。因为你没有主动关闭,所以不会被放回连接池,直到 session 被垃圾回收。 你在每个 greenlet 和线程里都要新建一个 session,否则事务是错的。 最后,其实在 greenlet 里用 SQLAlchemy 是被阻塞的,没有并发。 |
10
Feiox OP @sbmzhcn 解决了,使用以下两点: 1. 将连接池加大,自己估算平均量 * 1.5 即可。在调用 SQLAlchemy 的类中加入 __del__ 方法,在该方法中调用 session.close () 即可。
|
11
sbmzhcn 2015-08-28 17:29:18 +08:00
Lost connection to MySQL server during query ([Errno 9] File descriptor was closed in another greenlet
我觉得别人说的 greenlet 不是协和安全的,当其中一个 session 关闭时,其它还在用,结果就出这错了,不知道大家怎么认为的,现在想知道怎么解决。 |
13
sbmzhcn 2015-08-28 17:31:24 +08:00
能把你的代码贴出来看看吗,我只要是并行写数据,就会出错。
Lost connection to MySQL server during query ([Errno 9] File descriptor was closed in another greenlet @Feiox |
15
Feiox OP @myyou 我用的是 Flask-SQLAlchemy ,直接在配置文件中修改 SQLALCHEMY_POOL_SIZE 就可以了,详见 https://pythonhosted.org/Flask-SQLAlchemy/config.html#configuration-keys
我是在类中使用的,添加 __del__ 方法,使得该对象销毁的时候自动调用 session.close () 具体代码找不到了,大概是 def __del__(self ): db.session.close () # 或者 db.session.remove () @sbmzhcn 我当时解决的并不是并行写的问题,是连接池溢出问题。对于并行写我没有研究过,当时用的方法是使用 Queue 到一个线程中统一写入。 |
16
dingyaguang117 2015-10-15 23:40:45 +08:00
@Feiox LZ 现在的并发多少 SQLALCHEMY_POOL_SIZE 设置的多少呢
|