python使用多线程的时候,mysql报了[ERROR] (1040, ‘Too many connections’)错误,意思是连接数太多,记录下解决办法:
SHOW VARIABLES LIKE '%max_connections%';
Variable_name | Value |
---|---|
centered max_connections | centered 100 |
SHOW STATUS LIKE 'Threads%';
Variable_name | Value | 说明 |
---|---|---|
Threads_cached | 58 | |
Threads_connected | 57 | 当前打开的连接数,含休眠的连接数 |
Threads_created | 3676 | |
Threads_running | 4 | 当前运行的连接数 |
当Threads_connected 超过max_connections 就会报错
SET GLOBAL max_connections=1000; #重启Mysql后失效
修改mysql配置文件my.cnf,在[mysqld]段中添加或修改max_connections值:
max_connections=1000 #重启Mysql服务生效
查看当前连接数详情,可以发现有很多连接处于休眠状态,虽然没在运行,但依然会占用Mysql连接数
SELECT * FROM information_schema.processlist;#查看当前连接
show global variables like 'wait_timeout';#
Variable_name | Value | 说明 |
---|---|---|
wait_timeout | 28800 | mysql在关闭一个非交互的连接之前要等待的秒数,默认是28800s |
set global WAIT_TIMEOUT=3600;
修改这个数值,表示mysql在关闭一个非交互连接之前要等待的秒数,至此可以让mysql自动关闭那些没用的连接,但要注意的是,正在使用的连接到了时间也会被关闭,因此要根据业务情况,谨慎使用。
#连接池对象
__pool = {}
def __init__(self, conf=None):
#数据库构造函数,从连接池中取出连接,并生成操作游标
self.conn = DB.__getConn(conf)
self.cursor = self.conn.cursor()
def __del__(self):
self.cursor.close()
self.conn.close()
@staticmethod
def __getConn(conf=None):
"""
@summary: 静态方法,从连接池中取出连接
@return MySQLdb.connection
"""
if not(conf):
conf = config.DB
key = "%s-%s" % (conf['host'], conf["dbname"])
if DB.__pool.has_key(key)==False or not(DB.__pool[key]):
DB.__pool[key] = PooledDB(creator=MySQLdb, mincached=1, maxcached=100,
host=conf['host'], port=conf['port'], user=conf['user'], passwd=conf['password'],
db=conf['dbname'], use_unicode=False, charset='utf8', cursorclass=DictCursor, setsession=['SET AUTOCOMMIT = 1'])
DB.__pool[key].connection()
return DB.__pool[key].connection()
class ThreadWorker(threading.Thread):
def __init__(self,lock=None,q=None,tableConf=None,threadName=""):
super(ThreadWorker, self).__init__()
self.__testDB1 = dbmanager.DB(conf=config.TESTDB1)
self.__testDB2 = dbmanager.DB(conf=config.TESTDB2)
self.__testDB3 = dbmanager.DB(conf=config.TESTDB3)
self.lock = lock
self.queue = q
self.tableConf = tableConf
self.threadName = threadName
def run(self):
syncConf = {
"test1":self.__testDB1,
"test2":self.__testDB2,
"test3":self.__testDB3,
}
targetDB = syncConf.get(self.tableConf.get("targetDb"))
#检查入库是否正确
dbCheck = check_target_db(targetDB)
if not dbCheck:
return
try:
ConsumerClass(targetDB=targetDB,lock=self.lock,q=self.queue,tableConf=self.tableConf,threadName=self.threadName).entrance()
except Exception as e:
log.logger.exception(e)