SQLSTATE [HY000] [2002]资源暂时不可用 - mysql - innodb和pdo

时间:2014-09-27 04:19:11

标签: php mysql sql pdo

在我的错误日志中获得大量结果,如下所示。数据库中的所有表都是innodb,就这些表的任何交互而言,所有表都是带有预处理语句的pdo。

正如我所说,所有错误几乎与下面列出的错误完全相同,但会发生在几个不同的页面上。无论页面如何,错误行总是指向我开始一个新语句的点...例如$stmt = $db->prepare("........语句本身完全正常,没有错误所以我有点困惑的是什么导致此

不同页面的此类错误:

  

[25-Sep-2014 10:19:09 America / Chicago]无法连接数据库:   SQLSTATE [HY000] [2002]资源暂时不可用[2014年9月25日   10:19:09 America / Chicago] PHP致命错误:调用成员函数   在/home/test/public_html/add_log.php上的非对象上准备()   第28行

示例将错误点指向 - 在本例中为$stmt = $db->prepare("行。它总是指向开始一个新的预备声明的行。

$stmt = $db->prepare("
    SELECT 
        accounts.account_id,
        computers.computer_id,
        computers.status,
        users.user_id
    FROM accounts
    LEFT JOIN computers
        ON computers.account_id = accounts.account_id AND computers.computer_uid = :computer_uid
    LEFT JOIN users
        ON users.computer_id = computers.computer_id AND users.username = :username
    WHERE accounts.account_key = :account_key
");

//bindings
$binding = array(
    'account_key' => $_POST['account_key'],
    'computer_uid' => $_POST['computer_uid'],
    'username' => $_POST['username']
);
$stmt->execute($binding);   
//result (can only be one or none)
$result = $stmt->fetch(PDO::FETCH_ASSOC);

连接脚本:

<?php

if(!defined('INCLUDE_CHECK')) die('You are not allowed to execute this file directly');

// db config
$db_host        = 'localhost';
$db_database    = '*******';
$db_user        = '*******';
$db_pass        = '*******';

//db connection
try {
    $db = new PDO("mysql:host=$db_host;dbname=$db_database;charset=utf8", $db_user, $db_pass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true));
}
catch(PDOException $e) {
    error_log("Failed to connect to database: ".$e->getMessage());
}

?>

我想到的事情:

  • 这个特殊的脚本运行很多...有时可以在一秒钟内多次调用它。

  • 在这个网站上,我为所有准备好的语句使用相同的格式... $ stmt = ... $ result或$ results = ...但是,我没有关闭光标不需要,因为驱动程序是MySQL,它是自动完成的。

  • 我在连接设置中将PDO :: ATTR_PERSISTENT设置为true - 这会对此错误产生影响吗?

这里发生了什么错误?任何人吗?

编辑 - 更多信息:

  • 我已将localhost更改为明确的127.0.0.1
  • 我已将持久连接关闭/ false

由于执行上述操作,错误已更改为SQLSTATE[HY000] [2002] Connection timed out。这实际上是个人/家庭连接到我的问题吗?或者我的server / db实际上是个问题?

编辑2:

我使用$_SERVER['DOCUMENT_ROOT']是否可能导致问题?由于此文件已被点击&#39;通常它也需要连接脚本,就像下面的行一样。我需要在每个页面上按如下所示连接脚本:

  

需要$ _SERVER [&#39; DOCUMENT_ROOT&#39;]。&#39; /custom/functions/connect.php' ;;

5 个答案:

答案 0 :(得分:7)

我将在这个主题上指出@MrGomez topic,这主要是对你所说的错误的简明但描述性。这不是PDO相关的问题,而是MySQL特定的。

获取资源的原因&#34;资源暂时不可用&#34;

  1. 耗尽MySQL可用内存
  2. 在当前用户
  3. 下耗尽MySQL文件描述符
  4. 遇到活锁或死锁
  5. 上游代理资源不足
  6. 耗尽可用于分配的PID
  7. 但是,您的日志应该有更多内容让您知道发生了什么。就像确定任何文件是否有锁定一样。

答案 1 :(得分:3)

实际上并没有指向那条线。

日志中的错误

  

[25-Sep-2014 10:19:09 America / Chicago]无法连接数据库:SQLSTATE [HY000] [2002]资源暂时不可用

看起来好像是由catch语句写的:

try {
    $db = new PDO("mysql:host=$db_host;dbname=$db_database;charset=utf8", $db_user, $db_pass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true));
}
catch(PDOException $e) {
    error_log("Failed to connect to database: ".$e->getMessage()); // ERROR HERE
}

注意:未在catch语句中设置$db

然后您的脚本继续执行,直到它到达$db->prepare行。当$db为空时,它会输出另一个错误,这次是文件行。

除此之外 - 请参阅revo的答案,了解为什么您可能会收到“资源暂时不可用”错误。

答案 2 :(得分:2)

增加max_connections中的my.cnf

max_connections                 = 1000

检查可用于mysql的文件描述符:

ulimit -n

如果它的值默认值为1024,则更改为65535或更高

ulimit -n 65535

重启mysqld

答案 3 :(得分:0)

只是一个想法 - 您是否能够将数据库连接存储在内存中,这样您就不必继续重新创建新连接?另外,就你的 DIR 而言,魔法常数很棒(我今天才完全意识到)。希望有所帮助。

答案 4 :(得分:0)

通常意味着您需要指定TCP / IP:

"mysql:host=127.0.0.1" or 
"mysql:host=localhost;port=3306"

在你的情况下:

$db_host        = 'localhost';
$db_port        = '3306';

可能是这样的:

try {
    $db = new PDO("mysql:host=$db_host;port=$db_port;dbname=$db_database;charset=utf8", $db_user, $db_pass, array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true));
}
catch(PDOException $e) {
    error_log("Failed to connect to database: ".$e->getMessage()); // ERROR HERE
}