通过套接字的mysql连接失败

时间:2012-08-30 09:57:36

标签: php drupal amazon-ec2 mysql

情况是,我们有AWS EC2中型实例,上面有Linux 它也有Drupal。除此之外,我们也有很少的文件可以访问mysql,其设置与Drupal相同 问题是 - 在某一点上,mysql拒绝连接 它发生在负载较低或较大(与此无关)时,一旦无法访问,mysqld进程仍在运行,并且不会下降。
重新启动此过程并不能解决问题。重新启动实例 - 修复问题。

当我连接到localhost时,它会给出:

Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

当mysql.sock文件到位并具有正确的权限时 重启mysqld没有帮助,但重启实例 - 解决了问题。

my.cnf看起来像那样:

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0

wait_timeout=28800

interactive_timeout = 28800

max_allowed_packet=32M

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

mysqld运行时没有任何错误,在日志中我们有:

120830  9:48:00 [Note] /usr/libexec/mysqld: Shutdown complete

120830 09:48:00 mysqld_safe mysqld from pid file /var/run/mysqld/mysqld.pid ended
120830 09:48:01 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
120830  9:48:01 [Note] Plugin 'FEDERATED' is disabled.
120830  9:48:01 InnoDB: The InnoDB memory heap is disabled
120830  9:48:01 InnoDB: Mutexes and rw_locks use GCC atomic builtins
120830  9:48:01 InnoDB: Compressed tables use zlib 1.2.3
120830  9:48:01 InnoDB: Using Linux native AIO
120830  9:48:01 InnoDB: Initializing buffer pool, size = 128.0M
120830  9:48:01 InnoDB: Completed initialization of buffer pool
120830  9:48:02 InnoDB: highest supported file format is Barracuda.
120830  9:48:02  InnoDB: Waiting for the background threads to start
120830  9:48:03 InnoDB: 1.1.8 started; log sequence number 4191070086
120830  9:48:03 [Note] Event Scheduler: Loaded 0 events
120830  9:48:03 [Note] /usr/libexec/mysqld: ready for connections.
Version: '5.5.20'  socket: '/var/lib/mysql/mysql.sock -u root'  port: 3306  MySQL Community Server (GPL)

当问题再次发生时,我再次接受日志,尝试停止httpd然后mysqld,然后运行mysqld然后运行httpd,日志与正常条件日志完全相同,并且具有相同的重启序列。

在php.ini中更改并没有保存这种情况:

mysql.allow_persistent = Off

按此顺序重新启动,没有帮助(甚至尝试了不同的命令):

service httpd stop
service mysqld stop
service mysqld start
service httpd start

我们想知道什么是问题,以及如何防止它像这样下降。

3 个答案:

答案 0 :(得分:1)

从上述症状来看,可能会发生以下情况。我希望它有所帮助。

您的PHP可能使用持久数据库连接,这些连接可能无法正常关闭。达到某个限制后,数据库将不再接受新连接(来自unix socket OR network)。

在php.ini中有与数据库持久连接相关的设置,例如:

mysql.allow_persistent = Off

mysqld重新开始工作的事实可能与两件事有关:

  1. 重新启动可能与显式service mysqld stop后跟service mysqld start不同;此外,您可以在重新启动时检查日志,看它是否遇到任何异常情况。

  2. 重启序列可以稍微改变,也可以涉及PHP设置,所以你先停止apache,然后停止mysqld;之后,你以相反的顺序开始它们。

答案 1 :(得分:1)

只是浏览一下你的配置:你的超时非常高。正如其他人猜测的那样,我认为您正在尝试使用持久连接。但这些通常不适用于标准ext/mysql(i)或ext / PDO`。

如果您不想玩new mysqlnd multiplexing plugin之类的东西(请参阅intro,请参阅FAQ,我建议您显着降低wait_timeout并观看当遇到流量高峰时,max_connections(在mysqld端)。

因此,当您的应用程序无法正确处理它们时,wait_timeout基本上可以释放连接句柄。在Web应用程序中,连接应该空闲超过10秒是没有意义的。而且你不需要很多很多孤儿连接就可以了。

其次,max_connections变量也很重要,因为仅仅将其调整为5,000就不够了 - 因为虽然这意味着MySQL将允许多个连接,但它也会分配资源(RAM)来处理这些潜在的联系 - 即使你从不需要它们

在峰值期间,您应该可以使用root帐户连接到MySQL。这是一种能够调试服务器的安全措施。我的建议是暂时启用slow-log

此外,在峰值期间,请检查进程列表:mysqladmin -u root -pPASS PROCESSLIST。如果有任何内容被切断,请与root(mysql -u root -pPASS)联系并发出SHOW FULL PROCESSLIST;

从流程列表中,调查与EXPLAIN一起显示几次的查询,以了解它的底部。如果他们不使用索引,那就是你的问题之一。

另一种选择可能是Percona server。它们有很多新增功能 - 冰山一角:xtradb(与innodb 100%兼容)和慢速查询日志,可以为您提供更精细的输出(毫秒)。当然,它也是免费的。很好地阅读MySQL的所有内容 - the mysql performance blog

LBNL - 我只是猜测,但可能只是缺乏资源。 c1.medium是一个不错的入门级实例(t1.microm1.small没有实际用途IM * H * O),但这可能还不够。这一切都取决于数据库的大小和实际流量。

随意发表评论,我可以尝试扩展我的答案。

添加 - 我只是阅读了对其他答案的评论。

您可能希望摆脱EBS支持的实例。我认为这是一个非常糟糕的主意。如果您确实需要持久性,则需要创建一个带有临时存储的常规实例,然后将一对(多于1个)EBS卷附加到它,并RAID 10 across them以增加IO / s。

另外,我还没有提到,但听起来你的服务器上也没有监控。就个人而言,我们使用Librato silverline,它为我们提供了所有实例的近实时命运。这也应该有助于缩小存储的潜在问题。

答案 2 :(得分:1)

我不是这个主题的非常有经验的用户,但是当我遇到一些套接字文件时,我将我的应用配置为使用TCP / IP。您可以在软件配置中使用127.0.0.1而不是localhost来强制TCP / IP而不是套接字文件。

您可能对Xiaofeng Teng回答another stackoverflow question

感兴趣
  

除了迈克尔的话,

     

还有另一个链接:   http://dev.mysql.com/doc/refman/5.1/en/connecting.html,它说:

     
    

在Unix上,MySQL程序专门处理主机名localhost     与其他人相比可能与您的期望不同的方式     基于网络的程序。用于连接到localhost,MySQL程序     尝试使用Unix套接字文件连接到本地服务器。     即使给出了--port或-P选项来指定端口,也会发生这种情况     号。

  
     

这不是典型的tcp / ip连接。

当然,这不会回答你的问题,但也许可以解决你的问题。