2012-09-25 71 views
0

我認爲這是代碼的問題,但代碼很簡單,我不知道它可能是什麼。PDO/MySQL/PHP/OS X:MySQL服務器在後續查詢中消失了嗎?

我驗證了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 
+0

查看你的'log-error =/var/log/mysql/mysqld.err'你是否運行InnoDB引擎? – CappY

+0

如果您省略closeCursor()調用會發生什麼? – ethrbunny

+0

ethrbunny - 同樣的事情,我把它放在那裏,因爲有人在另一個問題上提出了它。 CappY - 該日誌文件不存在。我正在使用InnoDB,是 – ashgromnies

回答

4

我想通了。

我正在使用pcntl_fork來開發一個多進程守護進程。父進程負責運行一個循環來查詢數據庫,並根據它所看到的數據派生子進行額外的工作。

孩子們不需要數據庫連接,但是他們仍然被給予一個,因爲使用pcntl_fork。我只是在使用exit()來完成他們的工作後才終止子進程,這導致了'友好的'PHP清理關閉了它認爲孩子擁有的活動MySQL連接。

控制權將返回給父母,他們會發現他們的數據庫連接突然不再有效,因爲他們試圖在數據庫中查找更多數據以發送給孩子。

對我來說,修正是使用posix_kill(getmypid(), 9);殺死孩子而不是exit();

+1

這對我們很有幫助,解決了一個非常煩人的問題!謝謝! :-) –

相關問題