Skip to content

18.2 数据库连接失败

问题描述

在 PHP 开发中,数据库连接失败是一个常见的问题。当尝试连接到数据库时,可能会遇到各种错误,如连接超时、认证失败、服务器不可达等。

常见原因

1. 连接参数错误

连接参数错误是最常见的原因,包括主机名、端口、用户名、密码或数据库名不正确。

示例

php
<?php
// 错误的连接参数
$conn = mysqli_connect('localhost', 'wrong_user', 'wrong_password', 'wrong_database');

if (!$conn) {
    die('连接失败: ' . mysqli_connect_error());
}
?>

2. 数据库服务器未运行

如果数据库服务器未运行,连接会失败。

3. 网络问题

网络问题,如防火墙阻止、网络中断等,会导致连接失败。

4. 权限问题

数据库用户可能没有足够的权限连接到数据库。

5. 连接数限制

如果数据库服务器达到最大连接数限制,新的连接会被拒绝。

排查方法

1. 检查连接参数

仔细检查连接参数,确保主机名、端口、用户名、密码和数据库名正确。

2. 测试数据库服务器

使用命令行工具测试数据库服务器是否可访问:

bash
# MySQL
mysql -h localhost -u username -p

# PostgreSQL
psql -h localhost -U username -d database

3. 检查网络连接

使用 ping 命令测试网络连接:

bash
ping localhost

4. 检查数据库用户权限

检查数据库用户是否有足够的权限:

sql
-- MySQL
SHOW GRANTS FOR 'username'@'localhost';

-- PostgreSQL
\du

5. 检查连接数限制

检查数据库服务器的连接数限制:

sql
-- MySQL
SHOW VARIABLES LIKE 'max_connections';

-- PostgreSQL
SHOW max_connections;

解决方案

1. 修复连接参数

确保连接参数正确:

php
<?php
// 正确的连接参数
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "myDB";

// 创建连接
$conn = mysqli_connect($servername, $username, $password, $dbname);

// 检查连接
if (!$conn) {
    die('连接失败: ' . mysqli_connect_error());
}
echo '连接成功';
?>

2. 启动数据库服务器

确保数据库服务器正在运行:

bash
# MySQL (Ubuntu/Debian)
sudo service mysql start

# MySQL (CentOS/RHEL)
sudo systemctl start mysqld

# PostgreSQL (Ubuntu/Debian)
sudo service postgresql start

# PostgreSQL (CentOS/RHEL)
sudo systemctl start postgresql

3. 解决网络问题

检查防火墙设置,确保数据库端口(MySQL 默认 3306,PostgreSQL 默认 5432)已开放:

bash
# Ubuntu/Debian
sudo ufw allow 3306/tcp

# CentOS/RHEL
sudo firewall-cmd --add-port=3306/tcp --permanent
sudo firewall-cmd --reload

4. 授予数据库用户权限

为数据库用户授予足够的权限:

sql
-- MySQL
GRANT ALL PRIVILEGES ON myDB.* TO 'username'@'localhost' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

-- PostgreSQL
GRANT ALL PRIVILEGES ON DATABASE myDB TO username;

5. 增加连接数限制

增加数据库服务器的连接数限制:

MySQL:修改 my.cnf 文件

ini
[mysqld]
max_connections = 100

PostgreSQL:修改 postgresql.conf 文件

ini
max_connections = 100

6. 使用 PDO 连接

使用 PDO(PHP Data Objects)连接数据库,提供更好的错误处理:

php
<?php
try {
    $pdo = new PDO('mysql:host=localhost;dbname=myDB', 'username', 'password');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo '连接成功';
} catch (PDOException $e) {
    die('连接失败: ' . $e->getMessage());
}
?>

7. 实现连接池

对于高并发应用,实现连接池可以减少连接开销:

php
<?php
class DatabasePool {
    private static $connections = [];
    
    public static function getConnection() {
        $key = 'default';
        if (!isset(self::$connections[$key])) {
            self::$connections[$key] = mysqli_connect('localhost', 'username', 'password', 'myDB');
        }
        return self::$connections[$key];
    }
    
    public static function closeAll() {
        foreach (self::$connections as $connection) {
            mysqli_close($connection);
        }
    }
}

// 使用连接池
$conn = DatabasePool::getConnection();
?>

实战演练

场景:MySQL 连接失败

问题:尝试连接 MySQL 数据库时失败,错误信息为 Access denied for user 'root'@'localhost' (using password: YES)

排查步骤

  1. 检查用户名和密码:确保用户名和密码正确。
  2. 检查用户权限:确保用户有连接权限。
  3. 检查数据库是否存在:确保数据库已创建。

解决方案

  1. 重置 root 密码

    bash
    # 停止 MySQL 服务
    sudo service mysql stop
    
    # 以安全模式启动 MySQL
    sudo mysqld_safe --skip-grant-tables &
    
    # 登录 MySQL
    mysql -u root
    
    # 重置密码
    USE mysql;
    UPDATE user SET authentication_string=PASSWORD('new_password') WHERE User='root';
    FLUSH PRIVILEGES;
    EXIT;
    
    # 重启 MySQL 服务
    sudo service mysql restart
  2. 创建数据库

    sql
    CREATE DATABASE myDB;
  3. 授予权限

    sql
    GRANT ALL PRIVILEGES ON myDB.* TO 'root'@'localhost' IDENTIFIED BY 'new_password';
    FLUSH PRIVILEGES;

场景:PostgreSQL 连接失败

问题:尝试连接 PostgreSQL 数据库时失败,错误信息为 could not connect to server: Connection refused

排查步骤

  1. 检查 PostgreSQL 服务:确保服务正在运行。
  2. 检查连接参数:确保主机名、端口、用户名和数据库名正确。
  3. 检查网络连接:确保网络连接正常。

解决方案

  1. 启动 PostgreSQL 服务

    bash
    sudo service postgresql start
  2. 创建用户和数据库

    bash
    # 切换到 postgres 用户
    sudo -u postgres psql
    
    # 创建用户
    CREATE USER username WITH PASSWORD 'password';
    
    # 创建数据库
    CREATE DATABASE myDB OWNER username;
  3. 修改 pg_hba.conf 文件

    txt
    # 允许本地连接
    local   all             all                                     md5
    
    # 允许 IPv4 连接
    host    all             all             127.0.0.1/32            md5
  4. 重启 PostgreSQL 服务

    bash
    sudo service postgresql restart

总结

数据库连接失败是 PHP 开发中常见的问题,通常由连接参数错误、数据库服务器未运行、网络问题、权限问题或连接数限制导致。通过检查连接参数、测试数据库服务器、检查网络连接、检查数据库用户权限和连接数限制,可以有效地排查和解决这些问题。

在开发过程中,应该注意以下几点:

  • 使用正确的连接参数
  • 确保数据库服务器正在运行
  • 确保网络连接正常
  • 为数据库用户授予足够的权限
  • 合理设置连接数限制
  • 使用 PDO 提供更好的错误处理
  • 实现连接池减少连接开销

通过这些措施,可以减少数据库连接失败的发生,提高应用程序的稳定性和可靠性。

© 2026 编程马·菜鸟教程 版权所有