【问题标题】:Preventing too many connections in MySql when inserting tens of thousands of records防止MySql在插入几万条记录时连接过多
【发布时间】:2018-03-26 14:57:45
【问题描述】:

我在使用 MySQL 时遇到问题,在插入数万条记录时,我经常收到“数据库连接过多错误”。我正在使用 Python 和 Scrapy 来抓取网页并将信息插入 MySQL。代码如下:

import MySQLdb     

# connect to the MySQL server
self.CONN = MySQLdb.connect(host=SQL_HOST,
    user=SQL_USER,
    passwd=SQL_PASSWD,
    db=SQL_DB,
    charset='utf8', use_unicode=True)

cursor = self.CONN.cursor()

sql = "INSERT INTO myTable (id, license, address, name, city, state, zip_code, country) \
          SELECT uuid(), '" + item['license_num'] + "', '" + item['address'] + "', '" + item['name'] + "', '" + item['city']+ "', '" + item['state'] + "', '" + item['city'] + "', '" + item['state'] + "', '" + item['zip_code'] + "', '" + item['country'] FROM (SELECT 1) t \
          WHERE NOT EXISTS (SELECT name FROM myTable WHERE license='" + item['license_num'] + "');"

if cursor.execute(sql):
    results = cursor.fetchall()
    print results
    print 'ADDED BUSINESS: ' + item['name']
    print json.dumps(dict(item), indent=4, sort_keys=True)
    self.CONN.commit()
    cursor.close()

我认为可能是内存问题,但我检查了:

[root@s18573288 ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          4096       1896       2199        106          0       1370
-/+ buffers/cache:        525       3570
Swap:            0          0          0

似乎不是内存问题。我的磁盘空间只有 6% 被使用。我不想重新启动 MySQL,因为它可能会损坏我的数据。如果我让它运行,我希望它会恢复。所以我的问题是如何改进下面的sql以防止连接过多?

【问题讨论】:

  • 你在哪里循环吗?
  • 是的,每次抓取 Scrapy Item 时都会调用此代码。
  • 您是否创建了太多与 mysql 有连接的对象?关闭游标不会关闭与 mysql 的连接。理想情况下,您应该在连接到 mysql 数据库的过程中只有一个对象。如果您在 Linux 下运行该进程,您可以使用“lsof”命令来检查进程中打开的套接字或连接数。

标签: mysql sql python-2.7 scrapy


【解决方案1】:

您必须确保每次调用代码时光标都关闭。 此代码可能会有所帮助

import MySQLdb     

# connect to the MySQL server
self.CONN = MySQLdb.connect(host=SQL_HOST,
    user=SQL_USER,
    passwd=SQL_PASSWD,
    db=SQL_DB,
    charset='utf8', use_unicode=True)

cursor = self.CONN.cursor()

sql = """\
INSERT INTO myTable (id, license, address, name, city, state, zip_code, country) \
SELECT uuid(), \
'" + item['license_num'] + "', \
'" + item['address'] + "', \
'" + item['name'] + "', \
'" + item['city']+ "', \
'" + item['state'] + "', \
'" + item['city'] + "', \
'" + item['state'] + "', \
'" + item['zip_code'] + "', \
'" + item['country'] \
FROM (SELECT 1) t WHERE NOT EXISTS (SELECT name FROM myTable WHERE license='" + item['license_num'] + "');
"""

try:
    cursor.execute(sql):
    results = cursor.fetchall()
    print results
    print 'ADDED BUSINESS: ' + item['name']
    print json.dumps(dict(item), indent=4, sort_keys=True)
    self.CONN.commit()
except Exception as e:
    print str(e)
finally:
    cursor.close()

【讨论】:

  • 好的,所以当我按照你的建议实施它时,我会得到“命令不同步;你现在不能运行这个命令”(2014)异常
  • 我应该为每个插入打开一个新连接吗?
【解决方案2】:

尝试在脚本结束时关闭 MySQL 连接

finally:
    cursor.close() 
    self.CONN.close()  # close connection

【讨论】:

    猜你喜欢
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-22
    • 2015-09-25
    • 1970-01-01
    相关资源
    最近更新 更多