python - sqlalchemy + mysql死锁

标签 python mysql sqlalchemy

我将带有随机数据的行插入到 mysql 数据库中。插入一些行后,greenlet 在连接时挂起。统计打印greenlet保持运行

这种情况发生在任意数量的 worker (包括一个)上,包括 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,错误仍然存​​在,可能与服务器配置有关

最佳答案

我只是忘记释放使用过的连接,所以从未将连接重新 checkin 池中。 ...

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'

关于python - sqlalchemy + mysql死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5324410/

相关文章:

python - 一旦没有线程请求它,垃圾收集锁

java - 如何使用Where子句查询显示从jtextfield到jtable的搜索查询从mysql表

python - 使用 sqlalchemy/alembic 为现有数据库创建 "zero state"迁移,为现有数据库创建 "faking"零迁移

python - psycopg2 的 fast_executemany 替代方案

python - sqlalchemy:在子查询上使用过滤器的子查询加载

python - 使用 Python,查找单词列表的字谜

python - 每 x 秒执行一次 Python 而无需重新打开选项卡

python - 查找两个占位符之间的所有内容并将其替换为变量的内容

mysql - Order BY 根本不起作用

使用 WHERE IN 时 MySQL 触发器不更新多行