Bug #80412 [Com]: PHP-FPM : PDO / Broken Pipe when DBMS ends the connection
| From: | heavy-traffic-website at yopmail dot com | Date: | Thu, 26 Nov 2020 22:22:19 +0000 |
| Subject: | Bug #80412 [Com]: PHP-FPM : PDO / Broken Pipe when DBMS ends the connection | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-230654@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=80412&edit=1
ID: 80412
Comment by: heavy-traffic-website at yopmail dot com
Reported by: heavy-traffic-website at yopmail dot com
Summary: PHP-FPM : PDO / Broken Pipe when DBMS ends the
connection
Status: Closed
Type: Bug
Package: PDO Core
Operating System: Debian 11
PHP Version: 7.4.12
Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
I saw it and approve, thank you !
Previous Comments:
------------------------------------------------------------------------
[2020-11-26 11:55:50] nikic@php.net
I've put up https://github.com/php/php-src/pull/6458 to
suppress the broken pipe error more thoroughly.
------------------------------------------------------------------------
[2020-11-26 10:59:23] heavy-traffic-website at yopmail dot com
Ok, so, i now understand, seeing lot of PHP INTERNAL errors, but PDO still works.
nikic@php.net ; I supposed you have right.
Then, this was just surprising me, i thought PDO was not working fine but i seems it is. I will
suppress this error from the logs, and go on like that...
Thank you for support.
------------------------------------------------------------------------
[2020-11-26 10:52:45] heavy-traffic-website at yopmail dot com
Actual result:
--------------
string(26) "<BEFORE new PDO(), loop 1>"
string(34) "------------[ ERROR ]-------------"
string(79) "-- errstr: PDO::__construct(): send of 5 bytes failed with errno=32 Broken
pipe"
string(34) "----------------------------------"
string(25) "<AFTER new PDO(), loop 1>"
object(PDO)#2 (0) {
}
int(1)
string(26) "<BEFORE new PDO(), loop 2>"
string(25) "<AFTER new PDO(), loop 2>"
object(PDO)#3 (0) {
}
int(1)
string(26) "<BEFORE new PDO(), loop 3>"
string(25) "<AFTER new PDO(), loop 3>"
object(PDO)#2 (0) {
}
int(1)
string(26) "<BEFORE new PDO(), loop 4>"
string(25) "<AFTER new PDO(), loop 4>"
object(PDO)#3 (0) {
}
int(1)
string(26) "<BEFORE new PDO(), loop 5>"
string(25) "<AFTER new PDO(), loop 5>"
object(PDO)#2 (0) {
}
int(1)
string(26) "<BEFORE new PDO(), loop 6>"
string(25) "<AFTER new PDO(), loop 6>"
object(PDO)#3 (0) {
}
int(1)
------------------------------------------------------------------------
[2020-11-25 20:01:27] heavy-traffic-website at yopmail dot com
Description:
------------
Related to this very old bug reported 10 years ago
=> https://bugs.php.net/bug.php?id=53287
(johannes@php.net) was wrong - the bug still exists and no one fixed it.
--> Please consider the bug onto the PHP side, not the DBMS side.
PHP (php7.4-fpm) have threads with broken persistent connections cached with PDO and this should try
to reconnect a new one connection rather than calling the error handler in the case where the pipe
is already broken, during opening a nwe connection using persistence. Maybe there is a leak, why
don't you free a broken pipe and try to reuse it ?
Also, the PDO::_construct() return a PDO objet (without throwing an Exception), but PHP rises an
E_NOTICE :
string(68) "PDO::__construct(): send of 5 bytes failed with errno=32 Broken pipe"
That seems to deal with a E_CORE_WARNING ; generated by the core of PHP.
Currently, there is NO SOLUTION UNLESS FORGET PERSITANCE, it sucks !
Test script:
---------------
ini_set("error_reporting", (string) E_ALL);
ini_set("display_errors", "On");
ini_set("display_startup_errors", "On");
ini_set("track_errors", "On");
function my_error($errno, $errstr, $errfile, $errline)
{
var_dump("------------[ ERROR ]-------------");
var_dump("-- errstr: " . $errstr);
var_dump("----------------------------------");
}
set_error_handler("my_error");
abstract class Database
{
private static ?PDO $_db = null;
final public static function test() : ?PDO
{
for ($i = 1 ; $i <=6 ; ++$i)
{
var_dump("<BEFORE new PDO(), loop $i>");
try {
self::$_db = new PDO("mysql:host=127.0.0.1;dbname=XXX",
"XXX", "XXX", [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
}
catch (PDOException $e) {
var_dump("----------[ EXCEPTION ]-----------");
var_dump("-- excstr: " . $e->getMessage());
var_dump("----------------------------------");
}
var_dump("<AFTER new PDO(), loop $i>")
var_dump(self::$_db);
var_dump("<PING select, loop $i>");
var_dump(self::$_db->query("SELECT 1")->rowCount());
}
return self::$_db;
}
}
Database::test();
Expected result:
----------------
string(26) "<BEFORE new PDO(), loop 1>"
string(25) "<AFTER new PDO(), loop 1>"
object(PDO)#2 (0) {
}
string(21) "<PING select, loop 1>"
int(1)
string(26) "<BEFORE new PDO(), loop 2>"
string(25) "<AFTER new PDO(), loop 2>"
object(PDO)#4 (0) {
}
string(21) "<PING select, loop 2>"
int(1)
string(26) "<BEFORE new PDO(), loop 3>"
string(25) "<AFTER new PDO(), loop 3>"
object(PDO)#3 (0) {
}
string(21) "<PING select, loop 3>"
int(1)
string(26) "<BEFORE new PDO(), loop 4>"
string(25) "<AFTER new PDO(), loop 4>"
object(PDO)#2 (0) {
}
string(21) "<PING select, loop 4>"
int(1)
string(26) "<BEFORE new PDO(), loop 5>"
string(25) "<AFTER new PDO(), loop 5>"
object(PDO)#4 (0) {
}
string(21) "<PING select, loop 5>"
int(1)
string(26) "<BEFORE new PDO(), loop 6>"
string(25) "<AFTER new PDO(), loop 6>"
object(PDO)#3 (0) {
}
string(21) "<PING select, loop 6>"
int(1)
Actual result:
--------------
< I AM DOING SOME TESTS NOW >
< Please wait for an update >
------------------------------------------------------------------------
[2020-11-25 15:22:18] heavy-traffic-website at yopmail dot com
Some precisons :
ini_set("error_reporting", (string) E_ALL);
ini_set("display_errors", "On");
ini_set("display_startup_errors", "On");
ini_set("track_errors", "On");
set_exception_handler("my_exception");
set_error_handler("my_error");
[ERROR HANDLER]
errno: int(8)
errstr: string(68) "PDO::__construct(): send of 5 bytes failed with errno=32 Broken pipe"
errfile: string(31) "/var/www/XXX/Database.class.php"
errline: int(28)
line 27 --> $db = new PDO("mysql:host=127.0.0.1;dbname=XXX", "XXX",
"XXX",
line 28 --> PDO::ATTR_PERSISTENT => true,
line 29 --> PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=80412
--
Edit this bug report at https://bugs.php.net/bug.php?id=80412&edit=1