我将带有随机数据的行插入到mysql数据库中。插入一些行后,greenlet挂起连接。统计打印greenlet一直在运行
任何数量的工作者(包括一个)都会发生这种情况,包括mysql-connector和mysqldb驱动程序。 sqlite工作正常。
This没有效果(据我所知,它已在新gevent中修复)
def patch():
from gevent import monkey
monkey.patch_all()
# fix https://bugs.launchpad.net/myconnpy/+bug/712037
from mysql.connector.connection import MySQLConnection
MySQLConnection.get_characterset_info = MySQLConnection.get_charset
patch()
from sqlalchemy import MetaData, Table, Column, Integer, String, create_engine
from gevent import spawn, sleep
from random import randrange
from time import time
class Stats(object):
def __init__(self):
self.inserts, self.faults = 0, 0
def run(self):
while True:
sleep(1)
print "%d %d %d" % (time(), self.inserts, self.faults)
self.inserts, self.faults = 0, 0
class Victim(object):
metadata = MetaData()
Entry = Table(
'entry', metadata,
Column('id', Integer, primary_key=True),
Column('junk', String(128), unique=True)
)
def __init__(self, cs, stats):
self.e = create_engine(cs)
self.metadata.drop_all(self.e)
self.metadata.create_all(self.e)
self.stats = stats
def add(self, junk, i):
print i, 'connecting'
c = self.e.connect()
print i, 'connected'
t = c.begin()
try:
q = self.Entry.insert().values(junk=junk)
c.execute(q)
t.commit()
self.stats.inserts += 1
except Exception as e:
print i, 'EXCEPTION: ', e
t.rollback()
self.stats.faults += 1
print i, 'done'
def flood(victim, i):
a, z, l = ord('a'), ord('z')+1, 100
while True:
victim.add(''.join(chr(randrange(a, z)) for _ in xrange(l)), i)
sleep(0)
def main(n_threads, cs):
stats = Stats()
victim = Victim(cs, stats)
threads = [ spawn(flood, victim, i) for i in xrange(n_threads) ]
threads.append(spawn(stats.run))
[t.join() for t in threads]
#main(2, 'mysql://root:root@localhost/junk')
main(1, 'mysql+mysqlconnector://root:root@localhost/junk')
发生了什么事?
重新测试,错误在没有gevent的情况下仍然存在,可能是服务器配置
答案 0 :(得分:1)
我只是忘了释放使用过的连接,所以连接从未登记回池。 ...
def add(self, junk, i):
print i, 'connecting'
c = self.e.connect()
...
try:
...
except Exception as e:
...
finally:
c.close() # <-- this returns conenction into pool
print i, 'done'