gpt4 book ai didi

php - PDO/MySQL/PHP/OS X : MySQL server has gone away on subsequent queries?

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:54 24 4
gpt4 key购买 nike

我认为这是某处代码的问题,但代码太简单了,我不确定它可能是什么。

我已经验证了 wait_timeout 足够高并且已经检查了这里的所有内容:http://dev.mysql.com/doc/refman/5.1/en/gone-away.html没有任何成功。

这会在一次脚本运行中执行的第二个查询中重复发生,因此我确定这是一个编码错误。

我围绕 PDO 类创建了一个非常简单的包装器来拥有一个单独的数据库句柄:

<?php

class PDOWrapper
{
protected static $instance;
protected $dbh;

function __construct()
{
if ( is_null(static::$instance) )
{
static::$instance = $this;
$this->connect_to_db();
}
}

static function instance()
{
if ( is_null(static::$instance) )
{
new static;
}

return static::$instance;
}

private function connect_to_db()
{
$db_info = array(
0 => array(
'hostname' => "Host",
'username' => "User",
'password' => "Pass",
'db' => "DB",
)
);

//Try to connect to the database
try
{
$dbh = new PDO('mysql:host=' . $db_info[0]['hostname'] . ';dbname=' . $db_info[0]['db'], $db_info[0]['username'], $db_info[0]['password'], array( PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => true ));
}
catch (PDOException $e)
{
log_message("Error connecting to DB!: " . $e->getMessage(), LOG_LEVEL_CRITICAL );
return false;
}

$this->dbh = $dbh;
}

public static function get_dbh()
{
if ( is_null(static::$instance) )
{
new static;
}

return static::$instance->dbh;
}
}

然后我像这样使用包装器:

function somefunc(){
$dbh = PDOWrapper::get_dbh();
$future_sth = $dbh->prepare("SELECT * FROM some_table");
$future_sth->execute();
$ret = $future_sth->fetchAll(PDO::FETCH_ASSOC);
print_r($ret);
$future_sth->closeCursor();
return $ret;
}

我在事件循环中重复调用这个函数。第一次调用它时,print_r 运行良好,并打印出我希望看到的行。

然而,在函数执行一次后,我得到以下信息:

Warning: Error while sending QUERY packet. PID=92871
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away'

我不知道为什么它会“消失”。我的 my.cnf 看起来没问题。等待超时时间很长,无论如何我一运行第二个查询就会立即发生这种情况。有什么想法吗?

在 MySQL 错误日志中看起来没有任何明显错误:

120925 12:48:46 mysqld_safe Starting mysqld daemon with databases from /usr/local/var/mysql
120925 12:48:46 [Warning] The syntax '--log' is deprecated and will be removed in a future release. Please use '--general-log'/'--general-log-file' instead.
120925 12:48:46 [Warning] Setting lower_case_table_names=2 because file system for /usr/local/var/mysql/ is case insensitive
120925 12:48:46 InnoDB: The InnoDB memory heap is disabled
120925 12:48:46 InnoDB: Mutexes and rw_locks use GCC atomic builtins
120925 12:48:46 InnoDB: Compressed tables use zlib 1.2.5
120925 12:48:46 InnoDB: Initializing buffer pool, size = 128.0M
120925 12:48:46 InnoDB: Completed initialization of buffer pool
120925 12:48:46 InnoDB: highest supported file format is Barracuda.
120925 12:48:46 InnoDB: Waiting for the background threads to start
120925 12:48:47 InnoDB: 1.1.8 started; log sequence number 2273680401
120925 12:48:47 [Note] Server hostname (bind-address): '0.0.0.0'; port: 3306
120925 12:48:47 [Note] - '0.0.0.0' resolves to '0.0.0.0';
120925 12:48:47 [Note] Server socket created on IP: '0.0.0.0'.
120925 12:48:47 [Note] Event Scheduler: Loaded 0 events
120925 12:48:47 [Note] /usr/local/Cellar/mysql/5.5.25a/bin/mysqld: ready for connections.
Version: '5.5.25a-log' socket: '/tmp/mysql.sock' port: 3306 Source distribution

最佳答案

我想通了。

我正在使用 pcntl_fork 开发一个多进程守护进程。父进程负责运行一个循环来查询数据库,并派生子进程根据它看到的数据执行额外的工作。

children 不需要数据库连接,但是他们仍然得到了一个,因为使用了 pcntl_fork。我只是在子进程完成工作后使用 exit() 杀死它们,这导致“友好”的 PHP 清理关闭它认为子进程拥有的事件 MySQL 连接。

控制权将返回给父级,当他们试图在数据库中查找更多数据以发送给子级时,他们会发现他们的数据库连接突然不再有效。

对我来说,解决方法是使用 posix_kill(getmypid(), 9); 来杀死 child 而不是 exit();

关于php - PDO/MySQL/PHP/OS X : MySQL server has gone away on subsequent queries?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12587068/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com