Patch mysql_pconnect-should-reconnect-in-all-error-cases.patch for MySQL related Bug #71699
Patch version 2016-03-02 08:30 UTC
Return to Bug #71699 |
Download this patch
Patch Revisions:
Developer: pch@ordbogen.com
From bd2b4007ecb231a458720c0274430cf22c415ed9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Peter=20N=C3=B8rlund?= <pch@ordbogen.com>
Date: Wed, 2 Mar 2016 09:11:51 +0100
Subject: [PATCH] mysql_pconnect should reconnect in all error cases
If mysql_ping fails, and the error code was not 2006 (CR_SERVER_GONE_ERROR),
mysql_pconnect would still reuse the connecting, causing subsequent queries to
fail.
If for instance, a PHP script ran out of memory while fetching from a MySQL
result, the reused MySQL connecting would be in an invalid state, causing
queries (and ping) to fail with 2014 (CR_COMMANDS_OUT_OF_SYNC).
Just bypassing the check for error code 2006 would cause a crash, since PHP
would attempt to use the mysql handle directly, so we close the handle and
create a new one.
---
ext/mysql/php_mysql.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c
index 2d3ba60..c168a5a 100644
--- a/ext/mysql/php_mysql.c
+++ b/ext/mysql/php_mysql.c
@@ -932,20 +932,21 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
mysqlnd_end_psession(mysql->conn);
#endif
if (mysql_ping(mysql->conn)) {
- if (mysql_errno(mysql->conn) == 2006) {
+ mysql_close(mysql->conn);
#ifndef MYSQL_USE_MYSQLND
- if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
+ mysql->conn = mysql_init(NULL);
+ if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
#else
- if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
-#endif
- {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
- zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
- efree(hashed_details);
- MYSQL_DO_CONNECT_RETURN_FALSE();
- }
- mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
+ mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
+ if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
+#endif
+ {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
+ zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
+ efree(hashed_details);
+ MYSQL_DO_CONNECT_RETURN_FALSE();
}
+ mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
} else {
#ifdef MYSQL_USE_MYSQLND
mysqlnd_restart_psession(mysql->conn);
--
1.9.1
|