]> granicus.if.org Git - php/commitdiff
Add new INI for rollbacking connections put back into the pconn pool
authorAndrey Hristov <andrey@php.net>
Wed, 29 Jan 2014 13:27:43 +0000 (15:27 +0200)
committerAndrey Hristov <andrey@php.net>
Wed, 29 Jan 2014 13:27:43 +0000 (15:27 +0200)
as well a function get the the statistics in easier way than ob_start()
and parsing phpinfo().

NEWS
ext/mysqli/mysqli.c
ext/mysqli/mysqli_api.c
ext/mysqli/mysqli_fe.c
ext/mysqli/mysqli_fe.h
ext/mysqli/mysqli_nonapi.c
ext/mysqli/php_mysqli_structs.h
ext/mysqli/tests/mysqli_pconn_max_links.phpt

diff --git a/NEWS b/NEWS
index 3b41c6a0550661d13b224355aa28d88b2a37e832..4b43de8ebf7dfb9c2d27ae405b56d8e7c27ca9ea 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,10 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2014, PHP 5.6.0 Alpha 2
+- mysqli
+  . Added new function mysqli_get_links_stats() as well as new INI variable
+    mysqli.rollback_on_cached_plink of type bool (Andrey)
+
 
 23 Jan 2014, PHP 5.6.0 Alpha 1
 - CLI server:
index 929f776a4389c2f9a818de8cc8eb2e18bb69bbc3..2a5a8c61ff675f7bfd4a7cbf41e122a46edeeb2e 100644 (file)
@@ -558,6 +558,7 @@ PHP_INI_BEGIN()
        STD_PHP_INI_ENTRY_EX("mysqli.max_links",                        "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_links,                      zend_mysqli_globals,            mysqli_globals, display_link_numbers)
        STD_PHP_INI_ENTRY_EX("mysqli.max_persistent",           "-1",   PHP_INI_SYSTEM,         OnUpdateLong,           max_persistent,         zend_mysqli_globals,            mysqli_globals, display_link_numbers)
        STD_PHP_INI_BOOLEAN("mysqli.allow_persistent",          "1",    PHP_INI_SYSTEM,         OnUpdateLong,           allow_persistent,       zend_mysqli_globals,            mysqli_globals)
+       STD_PHP_INI_BOOLEAN("mysqli.rollback_on_cached_plink",  "0",PHP_INI_SYSTEM,             OnUpdateBool,           rollback_on_cached_plink,       zend_mysqli_globals,            mysqli_globals)
        STD_PHP_INI_ENTRY("mysqli.default_host",                        NULL,   PHP_INI_ALL,            OnUpdateString,         default_host,           zend_mysqli_globals,            mysqli_globals)
        STD_PHP_INI_ENTRY("mysqli.default_user",                        NULL,   PHP_INI_ALL,            OnUpdateString,         default_user,           zend_mysqli_globals,            mysqli_globals)
        STD_PHP_INI_ENTRY("mysqli.default_pw",                          NULL,   PHP_INI_ALL,            OnUpdateString,         default_pw,                     zend_mysqli_globals,            mysqli_globals)
@@ -597,6 +598,7 @@ static PHP_GINIT_FUNCTION(mysqli)
 #else
        mysqli_globals->embedded = 0;
 #endif
+       mysqli_globals->rollback_on_cached_plink = FALSE;
 }
 /* }}} */
 
index 902840159586d94f158210b01d0f9751ce2c128c..d6f274b5699207bd18cc6af91a5dce2861a3abf7 100644 (file)
@@ -599,10 +599,20 @@ void php_mysqli_close(MY_MYSQL * mysql, int close_type, int resource_status TSRM
 #if defined(MYSQLI_USE_MYSQLND)
                                mysqlnd_end_psession(mysql->mysql);
 #endif
-                               zend_ptr_stack_push(&plist->free_links, mysql->mysql);
 
+                               if (MyG(rollback_on_cached_plink) &&
+#if !defined(MYSQLI_USE_MYSQLND)
+                                       mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, TRANS_COR_NO_OPT, NULL))
+#else
+                                       FAIL == mysqlnd_rollback(mysql->mysql, TRANS_COR_NO_OPT, NULL))
+#endif
+                               {
+                                       mysqli_close(mysql->mysql, close_type);                 
+                               } else {
+                                       zend_ptr_stack_push(&plist->free_links, mysql->mysql);
+                                       MyG(num_inactive_persistent)++;
+                               }
                                MyG(num_active_persistent)--;
-                               MyG(num_inactive_persistent)++;
                        }
                }
                mysql->persistent = FALSE;
index 61e8e5c81ebce3a8d9b8a2ae4722c091f5e03c6a..3d31b8183ca96ddd62f33fb32a97ed8c49bde49a 100644 (file)
@@ -373,6 +373,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_refresh, 0, 0, 1)
        ZEND_ARG_INFO(0, options)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_no_options, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 
 /* {{{ mysqli_functions[]
  *
@@ -425,6 +428,7 @@ const zend_function_entry mysqli_functions[] = {
 #endif
        PHP_FE(mysqli_get_client_info,                                          arginfo_mysqli_only_link)
        PHP_FE(mysqli_get_client_version,                                       arginfo_mysqli_only_link)
+       PHP_FE(mysqli_get_links_stats,                                          arginfo_mysqli_no_options)
        PHP_FE(mysqli_get_host_info,                                            arginfo_mysqli_only_link)
        PHP_FE(mysqli_get_proto_info,                                           arginfo_mysqli_only_link)
        PHP_FE(mysqli_get_server_info,                                          arginfo_mysqli_only_link)
index d5ae8a6ff9bf71b8feadf1ec7e4ef63507782a2e..9a9f851248ba7e4652dda63d21f3e11fb41918aa 100644 (file)
@@ -60,6 +60,7 @@ PHP_FUNCTION(mysqli_get_charset);
 PHP_FUNCTION(mysqli_get_client_info);
 PHP_FUNCTION(mysqli_get_client_version);
 PHP_FUNCTION(mysqli_get_host_info);
+PHP_FUNCTION(mysqli_get_links_stats);
 PHP_FUNCTION(mysqli_get_proto_info);
 PHP_FUNCTION(mysqli_get_server_info);
 PHP_FUNCTION(mysqli_get_server_version);
index db0352baeb0323243cccb2d4d0b7049bf63a9dee..312f2806cecf583482017ef1076f2a4fc6ab8ee5 100644 (file)
@@ -1207,6 +1207,23 @@ PHP_FUNCTION(mysqli_release_savepoint)
 /* }}} */
 
 
+/* {{{ proto bool mysqli_get_links_stats()
+   Returns information about open and cached links */
+PHP_FUNCTION(mysqli_get_links_stats)
+{
+       if (ZEND_NUM_ARGS()) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "no parameters expected");
+               return; 
+       }
+       array_init(return_value);
+       add_assoc_long_ex(return_value, "total", sizeof("total"), MyG(num_links));
+       add_assoc_long_ex(return_value, "active_plinks", sizeof("active_plinks"), MyG(num_active_persistent));
+       add_assoc_long_ex(return_value, "cached_plinks", sizeof("cached_plinks"), MyG(num_inactive_persistent));
+}
+/* }}} */
+
+
+
 /*
  * Local variables:
  * tab-width: 4
index e7c02f9c9b32b612ffd767c6fd462caf059a4d2f..cc0c8fe63fbf6570f5bd816a6b1a65e01452ae88 100644 (file)
@@ -334,6 +334,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqli)
        HashTable               *report_ht;
        unsigned long   multi_query;
        unsigned long   embedded;
+       zend_bool               rollback_on_cached_plink;
 ZEND_END_MODULE_GLOBALS(mysqli)
 
 
index e87ef00b2112f7a2f216a8ad00ccf2bffcb2afbf..99e51e7c5e90ce12add97e877054f4dd6779aa2b 100644 (file)
@@ -42,6 +42,7 @@ Persistent connections and mysqli.max_links
 --INI--
 mysqli.allow_persistent=1
 mysqli.max_persistent=2
+mysqli.rollback_on_cached_plink=1
 --FILE--
 <?php
        require_once("connect.inc");
@@ -58,10 +59,18 @@ mysqli.max_persistent=2
                        mysqli_errno($plink), mysqli_error($plink));
        }
 
+       var_dump(mysqli_get_links_stats(1));
+
+       echo "Before pconnect:";
+       var_dump(mysqli_get_links_stats());
+
        if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket))
                printf("[001] Cannot connect using the second DB user created during SKIPIF, [%d] %s\n",
                        mysqli_connect_errno(), mysqli_connect_error());
 
+       echo "After pconnect:";
+       var_dump(mysqli_get_links_stats());
+
        ob_start();
        phpinfo();
        $phpinfo = strip_tags(ob_get_contents());
@@ -110,11 +119,17 @@ mysqli.max_persistent=2
        if (isset($running_threads[$pthread_id]))
                printf("[009] Persistent connection has not been killed\n");
 
+       echo "Before second pconnect:";
+       var_dump(mysqli_get_links_stats());
+
        // this fails and we have 0 (<= $num_plinks) connections
        if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket))
                printf("[010] Can connect using the old password, [%d] %s\n",
                        mysqli_connect_errno($link), mysqli_connect_error($link));
 
+       echo "After second pconnect:";
+       var_dump(mysqli_get_links_stats());
+
        ob_start();
        phpinfo();
        $phpinfo = strip_tags(ob_get_contents());
@@ -123,7 +138,13 @@ mysqli.max_persistent=2
        if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches))
                printf("[010] Cannot get # of active persistent links from phpinfo()\n");
 
+       var_dump(mysqli_get_links_stats());
+
        $num_plinks_kill = $matches[1];
+       $sstats = mysqli_get_links_stats();
+       if ($sstats['active_plinks'] != $num_plinks_kill) {
+               printf("[010.2] Num of active plinks differ %s %s\n", $sstats['active_plinks'], $num_plinks_kill);
+       }
        if ($num_plinks_kill > $num_plinks)
                printf("[011] Expecting Active Persistent Links < %d, got %d\n", $num_plinks, $num_plinks_kill);
 
@@ -141,9 +162,11 @@ mysqli.max_persistent=2
        mysqli_free_result($res);
        var_dump($row);
 
-       if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket))
+       if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) {
                printf("[015] Can open more persistent connections than allowed, [%d] %s\n",
                        mysqli_connect_errno(), mysqli_connect_error());
+               var_dump(mysqli_get_links_stats());
+       }
 
        ob_start();
        phpinfo();
@@ -179,18 +202,71 @@ mysqli_query($link, 'DROP USER pcontest');
 mysqli_close($link);
 ?>
 --EXPECTF--
-array(2) {
-  [%u|b%"id"]=>
-  %unicode|string%(1) "1"
-  [%u|b%"label"]=>
-  %unicode|string%(1) "a"
+Warning: mysqli_get_links_stats(): no parameters expected in %s on line %d
+NULL
+Before pconnect:array(3) {
+  ["total"]=>
+  int(1)
+  ["active_plinks"]=>
+  int(0)
+  ["cached_plinks"]=>
+  int(0)
+}
+After pconnect:array(3) {
+  ["total"]=>
+  int(2)
+  ["active_plinks"]=>
+  int(1)
+  ["cached_plinks"]=>
+  int(0)
 }
 array(2) {
-  [%u|b%"id"]=>
-  %unicode|string%(1) "1"
-  [%u|b%"label"]=>
-  %unicode|string%(1) "a"
+  ["id"]=>
+  string(1) "1"
+  ["label"]=>
+  string(1) "a"
+}
+Before second pconnect:array(3) {
+  ["total"]=>
+  int(2)
+  ["active_plinks"]=>
+  int(1)
+  ["cached_plinks"]=>
+  int(0)
 }
 
-Warning: %s: Too many open persistent links (%d) in %s on line %d
+Warning: main(): MySQL server has gone away in %s on line %d
+
+Warning: main(): Error reading result set's header in %s line %d
+After second pconnect:array(3) {
+  ["total"]=>
+  int(1)
+  ["active_plinks"]=>
+  int(0)
+  ["cached_plinks"]=>
+  int(0)
+}
+array(3) {
+  ["total"]=>
+  int(1)
+  ["active_plinks"]=>
+  int(0)
+  ["cached_plinks"]=>
+  int(0)
+}
+array(2) {
+  ["id"]=>
+  string(1) "1"
+  ["label"]=>
+  string(1) "a"
+}
+[015] Can open more persistent connections than allowed, [0] 
+array(3) {
+  ["total"]=>
+  int(3)
+  ["active_plinks"]=>
+  int(2)
+  ["cached_plinks"]=>
+  int(0)
+}
 done!
\ No newline at end of file