PDOException: SQLSTATE[08004] [1040] 连接太多

Posted

技术标签:

【中文标题】PDOException: SQLSTATE[08004] [1040] 连接太多【英文标题】:PDOException: SQLSTATE[08004] [1040] Too many connections 【发布时间】:2018-12-22 22:36:51 【问题描述】:

我的数据库有问题;我在过去半年一直在运行一个网站,从现在开始它一直运行良好,因为它在访问它时一直输出错误:

数据库连接失败:PDOException: SQLSTATE[08004] [1040] Too dbconfig.php:14 中的许多连接

我对此进行了很长时间的研究,但找不到可能导致此问题的单一解决方案,因为半年后出现此问题的方式很奇怪。

我的连接代码是这样的:

class Database 
    private $host = "localhost";
    private $db_name = "[...]";
    private $username = "[...]";
    private $password = "[...]";

    public $conn;

    public function dbConnection() 
        $this->conn = null; 

        try 
            $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   
         catch(PDOException $exception) 
            exit('Database failed to connect: ' . $exception);
        

        return $this->conn;
    

可能是什么问题?我也在将此代码用于其他网站,所以我希望这些网站不会很快出现同样的错误。

【问题讨论】:

因此,您的网站越来越繁忙,用户越来越多,因此,您现在看到了这条消息。根据您的 mysql 配置,任何时候可以在您的数据库上打开多少个连接都有一定的限制。要检查此限制,请运行此 sql:SHOW VARIABLES LIKE 'max_connections' 检查您的数据库是否允许您将其设置得更高。您是在 PHP 中保持连接还是在脚本执行时关闭它们?在不再需要它们时关闭它们可能是值得的。另外,单个用户在单个会话中消耗了多少个数据库连接? @WebCode.ie 您好,该网站似乎又可以正常工作了(现在?)。该网站每个会话消耗 1 个连接,并且在不活动后保持连接一小时,然后将其关闭。我认为这与我的连接代码有关,我不确定我的主机是否允许我设置最大连接数,我将与他们核实。 (还是很奇怪,因为我的网站不是很受欢迎) 我已经执行了SHOW VARIABLES LIKE 'max_connections',它设置为500 好吧,一种解决方法是根据需要打开和关闭数据库连接。警惕搜索引擎和其他机器人消耗您的连接以获取他们需要的数据。 答案实际上取决于您在实际代码中调用 Database 类的方式、时间和地点! 【参考方案1】:

您似乎在此代码中不必要地破坏了连接。如果已经建立连接,您应该重新使用它。此外,如果您有任何打开的语句或结果,这实际上不会关闭连接,而是会打开另一个连接。这可能是你的问题。同样,这实际上取决于您如何在实际脚本中使用此类。在同一个脚本中重复调用它可能会导致您的问题。

因此,如果它已经建立连接,则不要重用它。如果没有其他原因,实际上连接到数据库是一个相对较慢的过程。这通常称为单例模式。

class Database 
    private $host = "localhost";
    private $db_name = "[...]";
    private $username = "[...]";
    private $password = "[...]";

    public $conn = null;

    public function dbConnection() 
        if ( $this->conn !== null ) 
            // already have an open connection so lets reuse it
            return $this->conn;
        

        try 
            $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   
         catch(PDOException $exception) 
            exit('Database failed to connect: ' . $exception);
        

        return $this->conn;
    

【讨论】:

以上是关于PDOException: SQLSTATE[08004] [1040] 连接太多的主要内容,如果未能解决你的问题,请参考以下文章

PDOException: SQLSTATE[08004] [1040] 连接太多

带有消息“SQLSTATE [42000]”的未捕获异常“PDOException”:语法错误或访问冲突:

致命错误:未捕获的 PDOException:SQLSTATE[42000]:? [复制]

PDOException:SQLSTATE [HY093] [重复]

PDOException (1044) SQLSTATE[HY000] [1044] 用户''@'localhost'拒绝访问数据库'forge'

未捕获的 PDOException:SQLSTATE[42000]:语法错误或访问冲突