情况概述

在八月份的时候,也就是这个月,博客站点服务器数据库经常出现“Error Establishing a Database Connection”的情况。

WordPress 数据库连接错误全面解析:解决“Error Establishing a Database Connection”插图

通过查看数据库错误日志发现,数据库始终在进行报错警告。数据库手动打开了,运行了一段时间后又自动关闭,很是苦恼。

WordPress 数据库连接错误全面解析:解决“Error Establishing a Database Connection”插图1

可能因素

  • A client attempts to access a database but has no privileges forit.(没有权限)
  • A client uses an incorrect password.(密码错误)
  • A connection packet does not contain the rightinformation.(连接没有包含正确信息)
  • It takes more than connect_timeout seconds to obtain a connectpacket. (获取连接信息起过connect_timeout的时长)
  • The client program did not call mysql_close() beforeexiting.(客户端没有调用mysql_close()函数)
  • The client had been sleeping more than wait_timeout orinteractive_timeout seconds without issuing any requests to theserver. (客户端的空连接时间过长,超过了wait_timeout和interactive_timeout的时间)

但是根据前期排查,可以确定密码错误方面不会出现任何问题。

与此同时,也要注意是否有人试图入侵到服务器。如果客户端成功连接,但后来不正确地断开连接或被终止,服务器将增加Aborted_clients状态变量,并将一个中止的连接消息记录到错误日志中。

问题排查

通过检查了WordPress的wp-config.php文件,发现数据库连接的所有必要信息都没有问题,通过phpmyadmin,进入到我wordpress数据库,发现权限出了问题。

WordPress 数据库连接错误全面解析:解决“Error Establishing a Database Connection”插图2

权限进行修改后,在mysql管理中发现未设置性能调整,由于服务器是低配置,所以优化方案设置为2-4G即可。

WordPress 数据库连接错误全面解析:解决“Error Establishing a Database Connection”插图3

对Aborted_clients和Aborted_connects进行检查

WordPress 数据库连接错误全面解析:解决“Error Establishing a Database Connection”插图4

发现value并没有太高,说明wordpress可以正常连接到数据库,而且也成功调用了mysql_close()对数据库进行了关闭。

造成 Aborted_connects 状态变量增加的可能原因:

client端试图访问数据库,但没有数据库的权限。

client端使用了错误的密码。

client端连接包不包含正确的信息。

获取一个连接包需要的时间超过connect_timeout秒。

造成Aborted_clients状态变量增加的可能原因:

程序退出前,客户机程序没有调用mysql_close()。

客户端睡眠时间超过了wait_timeout或interactive_timeout参数的秒数。

客户端程序在数据传输过程中突然终止。对权限进行修改后,查看一下当前状态,在表中注明了数据和问题所在。

WordPress 数据库连接错误全面解析:解决“Error Establishing a Database Connection”插图5

自此问题应该已经解决的差不多了,没有对mysql数据库进行性能调整,没有设置正确的权限(在报错日志中也有体现)。

及时解决

mysql关闭对站点业务影响是很大的,为了避免再次出现mysql意外关闭的情况,可以在“状态停止时提醒我”设置微信提醒,以在最短时间内解决问题。

附检查内容

在仍做了很多尝试无果后,可以在数据库中运行一下语句进行配置检查。

timeout

mysql> show global variables like '%timeout%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| have_statement_timeout | YES |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 60 |
| wait_timeout | 28800 |
+-----------------------------+----------+
  • interactive_timeout的黓认值为28800
  • wait_timeout 的默认值为:120
  • 若interactive_timeout的值过小可能导致异常。

timestamp

mysql> select current_timestamp() from dual;
+---------------------+
| current_timestamp() |
+---------------------+
| 2024-08-29 22:18:37 |
+---------------------+
1 row in set (0.00 sec)

如果当前时间不正确,手动校准也可,在配置文件中修改也可。

[mysqld]
max_allowed_packet=256M
default-time_zone = '+8:00'

log_warnings

mysql> select @@log_warnings;
+----------------+
| @@log_warnings |
+----------------+
|              2 |
+----------------+
1 row in set

将此值设置为1,可避免大量错误日志输出,修改此值的原因是因为,Aborted connection告警是很难避免的,error log里或多或少会有少量Aborted connection信息,这种情况是可以忽略的,但是当error log里频繁出现Aborted connection告警,这时候就应该注意了,可能会对业务产生较大的影响。

mysql> set global log_warnings=1;

Query OK, 0 rows affected

mysql> select @@log_warnings;
+----------------+
| @@log_warnings |
+----------------+
|              1 |
+----------------+
1 row in set