简体   繁体   English

mysql连接错误太多。

[英]mysql too many connection error.

I have a .txt file with a list of 60,000 English words. 我有一个.txt文件,列出了60,000个英语单词。 I wanted to insert those to my database, so I simply just did as show here. 我想将这些插入到我的数据库中,所以我只是按照这里的显示进行操作。

$file = new SplFileObject('list.txt');

foreach ($file as $line => $word) {
    $p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test');
    $p->query("INSERT INTO words (english) VALUES('$word') ");
}

Now, after I run this script, I get the following error: 现在,运行此脚本后,出现以下错误:

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [1040] Too many connections' in /var/www/skillz/test/curl/index.php:17 Stack trace: #0 /var/www/test/index.php(17): PDO->__construct('mysql:host=loca...', 'root', 'test') #1 {main} thrown in /var/www/test/index.php on line 4

That line 4 is where the new PDO('mysql:') is located. line 4new PDO('mysql:')所在的位置。 So, I tried to search this error, and found this answer that seemed a solution . 因此,我尝试搜索此错误,并找到了似乎可以解决的答案 And I edited mysql accordingly, as 我相应地编辑了mysql

$ vi /etc/my.cnf
  max_connections=250

But I still get the same error, I have MySql 5.5.38 running PHP-FPM, NGINX in CentOS 6.5 但是我仍然遇到相同的错误,我在CentOS 6.5中运行MySql 5.5.38运行PHP-FPM,NGINX

Don't open a new Connection for every word. 不要为每个单词打开一个新的连接。 You only need one connection open for the lifetime of your inserts. 在插入的整个生命周期内,只需要打开一个连接即可。 I'm not sure about the true lifetime of a PDO object, I know they're cleaned up when they're not used, but garbage collection might not do that for a couple of minutes, and for 60,000 words, you're going to hit your limit of connections to the database faster than it can clean them up. 我不确定PDO对象的真实寿命,我知道它们在不使用时会被清理掉,但是垃圾回收可能在几分钟之内无法完成,而对于60,000个单词,您将达到您与数据库的连接限制的速度快于清理连接的速度。

$file = new SplFileObject('list.txt');
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test');

foreach ($file as $line => $word) {

    $p->query("INSERT INTO words (english) VALUES('$word') ");
}

You should declare the SQL connection outside the foreach. 您应该在foreach之外声明SQL连接。 Because it will make 60.000 connections. 因为它将建立60.000个连接。

$file = new SplFileObject('list.txt');
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test');

foreach ($file as $line => $word) {

    $p->query("INSERT INTO words (english) VALUES('$word') ");
}

You only need to declare the SQL connection once and you can use it anytime as you want. 您只需要声明一次SQL连接,就可以随时使用它。 If you put it in foreach it will make a SQL connection every word, that's why you got that message. 如果将它放在foreach中,它将使每个单词都建立一个SQL连接,这就是为什么收到该消息的原因。

Solution 1 Use batch insert statement : 解决方案1:使用批处理插入语句:

INSERT INTO words (col1, col2) VALUES ('val1', 'val2'), ('val3', 'val4'), ...('val3n', 'val4n');

This fails if you also want to check if some rows failed or not. 如果您还想检查某些行是否失败,则失败。 So, below is another solution. 因此,下面是另一种解决方案。

Solution 2 解决方案2

Create a persistent database connection. 创建一个持久数据库连接。 This will use the same connection in all iterations of the loop. 这将在循环的所有迭代中使用相同的连接。

$file = new SplFileObject('list.txt');
$p = new PDO('mysql:host=localhost; dbname=test_dictionary', 'root', 'test', array(
    PDO::ATTR_PERSISTENT => true)); //Persistent Database Connection
foreach ($file as $line => $word) {
    $p->query("INSERT INTO words (english) VALUES('$word') ");
}
$p = null; //Destroy Connection

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM