2010-09-08 33 views
15

Tôi có một vòng lặp foreach mà dĩa bên trong nó. Sau khi dĩa quá trình, nó truy cập cơ sở dữ liệu. Tôi nhận được một lỗi:pcntl_fork và kết nối MySQL đã biến mất

SQLSTATE[HY000]: General error: 2006 MySQL server has gone away 

Có điều là, tôi đang kết nối với cơ sở dữ liệu sau Tôi đã chia hai.

Câu hỏi của tôi: Tại sao điều này lại xảy ra?

Nếu điều này xảy ra, tôi có thực sự truy cập cơ sở dữ liệu trước khi tắt không? Liệu đứa trẻ có kế thừa các kết nối DB không?

(lưu ý: Tôi có thể đăng mã, nhưng nó khá lớn vì tất cả đều nằm trong lớp học, điều này có thể gây ra sự nhầm lẫn khi tôi truy cập DB. Một điều bạn nên biết là tôi đang sử dụng ZF .)

+0

Tôi chưa từng chơi Zend Framework nhưng tôi tự hỏi liệu nó có giữ một số loại nội bộ kết nối cơ sở dữ liệu hay không. Hoặc có lẽ nó đang làm các kết nối liên tục? Ngoài ra, trẻ em không nên kế thừa các kết nối db hoặc bất cứ thứ gì khác vì chúng là các tiến trình php khác nhau. – Fanis

+0

Ack, tôi đã sửa. Câu trả lời trên của tôi dựa trên trực giác nhưng không dựa trên kinh nghiệm cá nhân vì điều này chưa được yêu cầu. Đọc thêm vào nó tôi thấy trẻ em chia hai làm thừa kế kết nối db của cha mẹ của họ, và nó là một vấn đề đã biết: http://www.php.net/manual/en/function.pcntl-fork.php#70721 – Fanis

+0

@Fanis - Can bạn biến nhận xét cuối cùng của mình thành câu trả lời để tôi có thể nhấp vào kiểm tra màu xanh lục lớn? Cảm ơn bạn đã đào bới thông tin này. Tôi sẽ không ngã ba, thay vào đó tôi sẽ thực hiện một quy trình mới sẽ có kết nối db riêng của nó. Sau đó nó sẽ nĩa, để không buộc quá trình gọi điện thoại, và sau đó làm nó hoạt động ở trẻ em, đăng nhập nó vào một nhật ký mà một tiến trình khởi động khác sẽ đến và kiểm tra xem nó đã được hoàn thành hay chưa. Hmmmm ... Nó chỉ có thể làm việc lần này thôi! Cảm ơn! –

Trả lời

13

(comment -> câu trả lời theo yêu cầu của tấm áp phích của)

Đọc thêm vào nó tôi thấy con chia hai làm kế thừa kết nối db của cha mẹ, và nó là một vấn đề được biết: http://php.net/manual/en/function.pcntl-fork.php#70721

+0

Tôi chỉ nghĩ rằng tôi sẽ làm rõ: Lý do tại sao tôi nhận được lỗi mặc dù đứa trẻ thừa hưởng kết nối db là tôi đang forking một loạt các quy trình mới mà tất cả đều cần một kết nối db. –

2

Trừ nó là không phải là sự cố . Đó là cách pcntl_fork được thiết kế. Bất kỳ phần mở rộng nào (như các tài liệu nêu rõ) rằng việc duy trì các bộ mô tả tập tin riêng của nó sau đó sẽ có các bộ mô tả bị hỏng bởi vì tất cả các con đều có cùng một bộ mô tả tập tin.

0

Bạn có thể tránh kết nối đóng cửa khi chia hai quá trình xuất cảnh, nếu bạn giết quá trình chia hai với SIGKILL.

<?php 
$dbh = new PDO('pgsql:host=localhost', $username, $password); 
$pid = pcntl_fork(); 
if($pid == 0){ 
     register_shutdown_function(function(){ 
       posix_kill(getmypid(), SIGKILL); 
     }); 
     exit; 
} 
sleep(1); 
$statement = $dbh->query('select 1'); 
var_dump($statement); 

Lý do của hành vi này là khi PHP gửi đến máy chủ cơ sở dữ liệu "Chấm dứt kết nối" lệnh. Nhưng socket sẽ được đóng bởi hệ thống chỉ khi tất cả các liên kết đến socket được đóng lại. Sử dụng SIGKILL giúp chúng ta tránh việc gửi lệnh "Terminate connection" đến máy chủ cơ sở dữ liệu.

Các vấn đề liên quan