1--TEST-- 2Persistent connections and mysqli.max_links 3--SKIPIF-- 4<?php 5 require_once('skipif.inc'); 6 require_once('skipifemb.inc'); 7 require_once('skipifconnectfailure.inc'); 8 require_once('table.inc'); 9 10 mysqli_query($link, 'DROP USER pcontest'); 11 mysqli_query($link, 'DROP USER pcontest@localhost'); 12 13 if (!mysqli_query($link, 'CREATE USER pcontest@"%" IDENTIFIED BY "pcontest"') || 14 !mysqli_query($link, 'CREATE USER pcontest@localhost IDENTIFIED BY "pcontest"')) { 15 printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); 16 mysqli_close($link); 17 die("skip CREATE USER failed"); 18 } 19 20 // we might be able to specify the host using CURRENT_USER(), but... 21 if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || 22 !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { 23 printf("skip Cannot GRANT SELECT to second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); 24 mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); 25 mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); 26 mysqli_query($link, 'DROP USER pcontest@localhost'); 27 mysqli_query($link, 'DROP USER pcontest'); 28 mysqli_close($link); 29 die("skip GRANT failed"); 30 } 31 32 if (!($link_pcontest = @my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket))) { 33 mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); 34 mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); 35 mysqli_query($link, 'DROP USER pcontest@localhost'); 36 mysqli_query($link, 'DROP USER pcontest'); 37 mysqli_close($link); 38 die("skip CONNECT using new user failed"); 39 } 40 mysqli_close($link); 41?> 42--INI-- 43mysqli.allow_persistent=1 44mysqli.max_persistent=2 45mysqli.rollback_on_cached_plink=1 46--FILE-- 47<?php 48 require_once("connect.inc"); 49 require_once('table.inc'); 50 51 52 if (!mysqli_query($link, 'DROP USER pcontest') || 53 !mysqli_query($link, 'DROP USER pcontest@localhost') || 54 !mysqli_query($link, 'CREATE USER pcontest@"%" IDENTIFIED BY "pcontest"') || 55 !mysqli_query($link, 'CREATE USER pcontest@localhost IDENTIFIED BY "pcontest"') || 56 !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || 57 !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { 58 printf("[000] Init failed, [%d] %s\n", 59 mysqli_errno($plink), mysqli_error($plink)); 60 } 61 62 var_dump(mysqli_get_links_stats(1)); 63 64 echo "Before pconnect:"; 65 var_dump(mysqli_get_links_stats()); 66 67 if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) 68 printf("[001] Cannot connect using the second DB user created during SKIPIF, [%d] %s\n", 69 mysqli_connect_errno(), mysqli_connect_error()); 70 71 echo "After pconnect:"; 72 var_dump(mysqli_get_links_stats()); 73 74 ob_start(); 75 phpinfo(); 76 $phpinfo = strip_tags(ob_get_contents()); 77 ob_end_clean(); 78 79 $phpinfo = substr($phpinfo, strpos($phpinfo, 'MysqlI Support => enabled'), 500); 80 if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) 81 printf("[002] Cannot get # active persistent links from phpinfo()\n"); 82 $num_plinks = $matches[1]; 83 84 if (!$res = mysqli_query($plink, 'SELECT id, label FROM test WHERE id = 1')) 85 printf("[003] Cannot run query on persistent connection of second DB user, [%d] %s\n", 86 mysqli_errno($plink), mysqli_error($plink)); 87 88 if (!$row = mysqli_fetch_assoc($res)) 89 printf("[004] Cannot run fetch result, [%d] %s\n", 90 mysqli_errno($plink), mysqli_error($plink)); 91 mysqli_free_result($res); 92 var_dump($row); 93 94 // change the password for the second DB user and kill the persistent connection 95 if (!mysqli_query($link, 'SET PASSWORD FOR pcontest = PASSWORD("newpass")') || 96 !mysqli_query($link, 'FLUSH PRIVILEGES')) 97 printf("[005] Cannot change PW of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 98 99 // change the password for the second DB user and kill the persistent connection 100 if (!mysqli_query($link, 'SET PASSWORD FOR pcontest@localhost = PASSWORD("newpass")') || 101 !mysqli_query($link, 'FLUSH PRIVILEGES')) 102 printf("[006] Cannot change PW of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 103 104 // persistent connections cannot be closed but only be killed 105 $pthread_id = mysqli_thread_id($plink); 106 if (!mysqli_query($link, sprintf('KILL %d', $pthread_id))) 107 printf("[007] Cannot KILL persistent connection of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 108 // give the server a second to really kill the thread 109 sleep(1); 110 111 if (!$res = mysqli_query($link, "SHOW FULL PROCESSLIST")) 112 printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 113 114 $running_threads = array(); 115 while ($row = mysqli_fetch_assoc($res)) 116 $running_threads[$row['Id']] = $row; 117 mysqli_free_result($res); 118 119 if (isset($running_threads[$pthread_id])) 120 printf("[009] Persistent connection has not been killed\n"); 121 122 echo "Before second pconnect:"; 123 var_dump(mysqli_get_links_stats()); 124 125 // this fails and we have 0 (<= $num_plinks) connections 126 if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) 127 printf("[010] Can connect using the old password, [%d] %s\n", 128 mysqli_connect_errno($link), mysqli_connect_error($link)); 129 130 echo "After second pconnect:"; 131 var_dump(mysqli_get_links_stats()); 132 133 ob_start(); 134 phpinfo(); 135 $phpinfo = strip_tags(ob_get_contents()); 136 ob_end_clean(); 137 $phpinfo = substr($phpinfo, stripos($phpinfo, 'MysqlI Support => enabled'), 500); 138 if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) 139 printf("[010] Cannot get # of active persistent links from phpinfo()\n"); 140 141 var_dump(mysqli_get_links_stats()); 142 143 $num_plinks_kill = $matches[1]; 144 $sstats = mysqli_get_links_stats(); 145 if ($sstats['active_plinks'] != $num_plinks_kill) { 146 printf("[010.2] Num of active plinks differ %s %s\n", $sstats['active_plinks'], $num_plinks_kill); 147 } 148 if ($num_plinks_kill > $num_plinks) 149 printf("[011] Expecting Active Persistent Links < %d, got %d\n", $num_plinks, $num_plinks_kill); 150 151 if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) 152 printf("[012] Cannot connect using the new password, [%d] %s\n", 153 mysqli_connect_errno(), mysqli_connect_error()); 154 155 if (!$res = mysqli_query($plink, 'SELECT id, label FROM test WHERE id = 1')) 156 printf("[013] Cannot run query on persistent connection of second DB user, [%d] %s\n", 157 mysqli_errno($plink), mysqli_error($plink)); 158 159 if (!$row = mysqli_fetch_assoc($res)) 160 printf("[014] Cannot run fetch result, [%d] %s\n", 161 mysqli_errno($plink), mysqli_error($plink)); 162 mysqli_free_result($res); 163 var_dump($row); 164 165 if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) { 166 printf("[015] Can open more persistent connections than allowed, [%d] %s\n", 167 mysqli_connect_errno(), mysqli_connect_error()); 168 var_dump(mysqli_get_links_stats()); 169 } 170 171 ob_start(); 172 phpinfo(); 173 $phpinfo = strip_tags(ob_get_contents()); 174 ob_end_clean(); 175 $phpinfo = substr($phpinfo, stripos($phpinfo, 'MysqlI Support => enabled'), 500); 176 if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) 177 printf("[016] Cannot get # of active persistent links from phpinfo()\n"); 178 179 $num_plinks = $matches[1]; 180 if ($num_plinks > (int)ini_get('mysqli.max_persistent')) 181 printf("[017] mysqli.max_persistent=%d allows %d open connections!\n", ini_get('mysqli.max_persistent'),$num_plinks); 182 183 mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); 184 mysqli_query($link, 'DROP USER pcontest'); 185 mysqli_close($link); 186 print "done!"; 187?> 188--CLEAN-- 189<?php 190require_once("connect.inc"); 191if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 192 printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 193 194if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) 195 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 196 197mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); 198mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); 199mysqli_query($link, 'DROP USER pcontest@localhost'); 200mysqli_query($link, 'DROP USER pcontest'); 201 202mysqli_close($link); 203?> 204--EXPECTF-- 205Warning: mysqli_get_links_stats(): no parameters expected in %s on line %d 206NULL 207Before pconnect:array(3) { 208 ["total"]=> 209 int(1) 210 ["active_plinks"]=> 211 int(0) 212 ["cached_plinks"]=> 213 int(0) 214} 215After pconnect:array(3) { 216 ["total"]=> 217 int(2) 218 ["active_plinks"]=> 219 int(1) 220 ["cached_plinks"]=> 221 int(0) 222} 223array(2) { 224 ["id"]=> 225 string(1) "1" 226 ["label"]=> 227 string(1) "a" 228} 229Before second pconnect:array(3) { 230 ["total"]=> 231 int(2) 232 ["active_plinks"]=> 233 int(1) 234 ["cached_plinks"]=> 235 int(0) 236} 237 238Warning: main(): MySQL server has gone away in %s on line %d 239 240Warning: main(): Error reading result set's header in %s line %d 241After second pconnect:array(3) { 242 ["total"]=> 243 int(1) 244 ["active_plinks"]=> 245 int(0) 246 ["cached_plinks"]=> 247 int(0) 248} 249array(3) { 250 ["total"]=> 251 int(1) 252 ["active_plinks"]=> 253 int(0) 254 ["cached_plinks"]=> 255 int(0) 256} 257array(2) { 258 ["id"]=> 259 string(1) "1" 260 ["label"]=> 261 string(1) "a" 262} 263[015] Can open more persistent connections than allowed, [0] 264array(3) { 265 ["total"]=> 266 int(3) 267 ["active_plinks"]=> 268 int(2) 269 ["cached_plinks"]=> 270 int(0) 271} 272done!