【问题标题】:When Im swtiching from mysql to mysqli driver I get too many connections error. Why?当我从 mysql 切换到 mysqli 驱动程序时,出现了太多连接错误。为什么?
【发布时间】:2014-07-09 06:36:37
【问题描述】:

为什么我收到太多连接错误:

消息:mysqli_connect(): (08004/1040): 连接太多

切换时

$db['default']['dbdriver'] = 'mysql';

$db['default']['dbdriver'] = 'mysqli';

在codeIgniter的db配置文件中? ?

这说明mysqli驱动没有正确关闭所有连接?

更新:

切换数据库驱动时出现的连接过多似乎不是正确的原因(如答案所示)

我查看了我的客户网络托管公司,他们已将 max_user_connections 设置为 40(不,并不令人印象深刻 - 但我基本上只是想使用 group_concat 列出具有值的用户)。

$this->db->select('u.id AS user_id, u.first_name, 
u.housenr, u.address, u.phone, u.garage_nr, u.parking_nr, 
u.standing_correction, u.email, u.note, GROUP_CONCAT(wc.consumption) AS consumption, 
GROUP_CONCAT(wc.id) AS consumption_id, GROUP_CONCAT(wc.consumption_date) AS 
consumption_date, GROUP_CONCAT(wc.working_meetings) AS working_meetings, 
GROUP_CONCAT(wc.nrof_garage) AS nrof_garage, GROUP_CONCAT(wc.nrof_parking) AS nrof_parking, GROUP_CONCAT(wc.correction) AS correction, , 
GROUP_CONCAT(wc.correction_refers) AS correction_refers')->from('water_consumption wc');
$this->db->join('user u', 'u.id = wc.user_id');        
$this->db->join('role r', 'u.role_id = r.id');
$this->db->where('r.name', 'member'); //Only users with members-role        
$this->db->group_by('u.id'); 
$this->db->order_by('LENGTH(housenr), housenr, first_name'); //Natural sorting
$this->db->order_by('consumption_date', 'desc');

$q = $this->db->get();
if ($q->num_rows() > 0) {            
    $res = $q->result('Water_consumption');
    //more code...

这确实很奇怪,但是使用时似乎每个返回的对象都使用一个连接

$res = $q->result('Water_consumption');

这是我的假设,因为大约创建了 40 个对象并且 max_user_connections 设置为 40。

但是在使用时

$res = $q->result();

它似乎没有使用那么多连接并且显示了模板(虽然不正确,因为它为每个耗水对象调用了函数)。

这适用于我的本地 wamp 没有任何问题,返回所有对象(大约 60 个)大约需要 2-3 秒。

【问题讨论】:

标签: codeigniter mysqli


【解决方案1】:

基本上 MySQL 不关心应用程序是否正确关闭连接。它有一个系统变量wait_timeout,任何在指定秒数内没有发生任何事情的连接将被自动关闭。 (不过,默认值似乎是28800 seconds,这应该远远超过任何 Web 应用程序的需要。您可能想要测试降低该值。)

也许您不小心将persistent connections 用于MySQLi by specifying the hostname with a preceding p:You can also trigger Codeigniter to use persistent connections by specifying an option.也许你这样做没有考虑后果?
使用持久连接可以更快地超出您的限制。我会推荐链接问题的已接受答案中的建议:默认情况下不要使用持久连接。

您是否简要估计过您的应用程序使用的连接数? (一次最多可以发生多少个 php 进程或 Web 服务器进程 + cronjobs。)也许你的 max_connections 限制一直太低,但这并没有出现在错误消息中。 (无论出于何种原因......)

【讨论】:

  • 我仔细阅读了您的答案并测试了不同的东西。当 water_consumptions 表中有大约 40 行时,我现在使用没有持久连接的 mysqli 连接。看到我更新的问题。
  • 当我删除 water_consumptions 表中的一些行时,它按预期工作。
  • 您使用的是哪个版本的 PHP?您是否使用 CodeIgniter 的开发分支测试过您的代码?也许数据库驱动程序中存在另一个错误...如果此错误仍然存​​在,您应该在 CodeIgniter 上打开一个错误报告。也许你是对的。 The MySQL extension reused connections 多次调用mysql_connect 时。而没有留下任何通知,MySQLi extension does the same toomysqli_connect 似乎每次都打开一个新连接。
  • 如果 connect 被多次调用,可以通过在 connect 方法中添加调试输出来轻松检查。也许你应该试试。
  • 我已经验证了使用 $this->db->result('object'); 时会多次调用 connect但是当使用 $this->db->result();无论是使用 mysql 驱动还是使用 mysqli 驱动,结果都是一样的。我也尝试过 PDO 和完全相同的问题。在本地,我使用的是 PHP 版本 5.4.12,在生产服务器上它是 PHP 版本 5.5.7-1+sury.org~precise+1
【解决方案2】:

有时最明显的答案正盯着你...

我说过

$res = $q->result('Water_consumption');

每次都会建立连接。

但是在使用时

$res = $q->result();

没有。

事实证明,每个Water_consumption 都是从另一个类扩展而来的,该类建立一个连接以处理登录内容。那个班级正在建立联系,所以

$res = $q->result('Water_consumption');

包含两个对象将建立两个连接。

但同样的事情也会发生在这里..

$x = new Water_consumption;
$x = new Water_consumption;

这也会创建两个连接。

【讨论】:

  • @GhostGambler - 谢谢!但现在我看到了它从哪里开始。它在核心 CI_Controller 中。 ($this->load->initialize();) 每次创建新对象时都完成连接是否“正常”行为?
  • 想通了。显然数据库是在自动加载文件中自动加载的,这导致这是真的。
  • 基本上你在这里帮助自己;)
猜你喜欢
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 2013-03-26
  • 1970-01-01
相关资源
最近更新 更多