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 = "newpass"') && 96 !mysqli_query($link, 'SET PASSWORD FOR pcontest = PASSWORD("newpass")'))|| 97 !mysqli_query($link, 'FLUSH PRIVILEGES')) 98 printf("[005] Cannot change PW of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 99 100 // change the password for the second DB user and kill the persistent connection 101 if ((!mysqli_query($link, 'SET PASSWORD FOR pcontest@localhost = "newpass"') && 102 !mysqli_query($link, 'SET PASSWORD FOR pcontest@localhost = PASSWORD("newpass")')) || 103 !mysqli_query($link, 'FLUSH PRIVILEGES')) 104 printf("[006] Cannot change PW of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 105 106 // persistent connections cannot be closed but only be killed 107 $pthread_id = mysqli_thread_id($plink); 108 if (!mysqli_query($link, sprintf('KILL %d', $pthread_id))) 109 printf("[007] Cannot KILL persistent connection of second DB user, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 110 // give the server a second to really kill the thread 111 sleep(1); 112 113 if (!$res = mysqli_query($link, "SHOW FULL PROCESSLIST")) 114 printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 115 116 $running_threads = array(); 117 while ($row = mysqli_fetch_assoc($res)) 118 $running_threads[$row['Id']] = $row; 119 mysqli_free_result($res); 120 121 if (isset($running_threads[$pthread_id])) 122 printf("[009] Persistent connection has not been killed\n"); 123 124 echo "Before second pconnect:"; 125 var_dump(mysqli_get_links_stats()); 126 127 // this fails and we have 0 (<= $num_plinks) connections 128 if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) 129 printf("[010] Can connect using the old password, [%d] %s\n", 130 mysqli_connect_errno($link), mysqli_connect_error($link)); 131 132 echo "After second pconnect:"; 133 var_dump(mysqli_get_links_stats()); 134 135 ob_start(); 136 phpinfo(); 137 $phpinfo = strip_tags(ob_get_contents()); 138 ob_end_clean(); 139 $phpinfo = substr($phpinfo, stripos($phpinfo, 'MysqlI Support => enabled'), 500); 140 if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) 141 printf("[010] Cannot get # of active persistent links from phpinfo()\n"); 142 143 var_dump(mysqli_get_links_stats()); 144 145 $num_plinks_kill = $matches[1]; 146 $sstats = mysqli_get_links_stats(); 147 if ($sstats['active_plinks'] != $num_plinks_kill) { 148 printf("[010.2] Num of active plinks differ %s %s\n", $sstats['active_plinks'], $num_plinks_kill); 149 } 150 if ($num_plinks_kill > $num_plinks) 151 printf("[011] Expecting Active Persistent Links < %d, got %d\n", $num_plinks, $num_plinks_kill); 152 153 if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) 154 printf("[012] Cannot connect using the new password, [%d] %s\n", 155 mysqli_connect_errno(), mysqli_connect_error()); 156 157 if (!$res = mysqli_query($plink, 'SELECT id, label FROM test WHERE id = 1')) 158 printf("[013] Cannot run query on persistent connection of second DB user, [%d] %s\n", 159 mysqli_errno($plink), mysqli_error($plink)); 160 161 if (!$row = mysqli_fetch_assoc($res)) 162 printf("[014] Cannot run fetch result, [%d] %s\n", 163 mysqli_errno($plink), mysqli_error($plink)); 164 mysqli_free_result($res); 165 var_dump($row); 166 167 if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) { 168 printf("[015] Can open more persistent connections than allowed, [%d] %s\n", 169 mysqli_connect_errno(), mysqli_connect_error()); 170 var_dump(mysqli_get_links_stats()); 171 } 172 173 ob_start(); 174 phpinfo(); 175 $phpinfo = strip_tags(ob_get_contents()); 176 ob_end_clean(); 177 $phpinfo = substr($phpinfo, stripos($phpinfo, 'MysqlI Support => enabled'), 500); 178 if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) 179 printf("[016] Cannot get # of active persistent links from phpinfo()\n"); 180 181 $num_plinks = $matches[1]; 182 if ($num_plinks > (int)ini_get('mysqli.max_persistent')) 183 printf("[017] mysqli.max_persistent=%d allows %d open connections!\n", ini_get('mysqli.max_persistent'),$num_plinks); 184 185 mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); 186 mysqli_query($link, 'DROP USER pcontest'); 187 mysqli_close($link); 188 print "done!"; 189?> 190--CLEAN-- 191<?php 192require_once("connect.inc"); 193if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) 194 printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); 195 196if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) 197 printf("[c002] Cannot drop table, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); 198 199mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); 200mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); 201mysqli_query($link, 'DROP USER pcontest@localhost'); 202mysqli_query($link, 'DROP USER pcontest'); 203 204mysqli_close($link); 205?> 206--EXPECTF-- 207Warning: mysqli_get_links_stats(): no parameters expected in %s on line %d 208NULL 209Before pconnect:array(3) { 210 ["total"]=> 211 int(1) 212 ["active_plinks"]=> 213 int(0) 214 ["cached_plinks"]=> 215 int(0) 216} 217After pconnect:array(3) { 218 ["total"]=> 219 int(2) 220 ["active_plinks"]=> 221 int(1) 222 ["cached_plinks"]=> 223 int(0) 224} 225array(2) { 226 ["id"]=> 227 string(1) "1" 228 ["label"]=> 229 string(1) "a" 230} 231Before second pconnect:array(3) { 232 ["total"]=> 233 int(2) 234 ["active_plinks"]=> 235 int(1) 236 ["cached_plinks"]=> 237 int(0) 238} 239After second pconnect:array(3) { 240 ["total"]=> 241 int(1) 242 ["active_plinks"]=> 243 int(0) 244 ["cached_plinks"]=> 245 int(0) 246} 247array(3) { 248 ["total"]=> 249 int(1) 250 ["active_plinks"]=> 251 int(0) 252 ["cached_plinks"]=> 253 int(0) 254} 255array(2) { 256 ["id"]=> 257 string(1) "1" 258 ["label"]=> 259 string(1) "a" 260} 261[015] Can open more persistent connections than allowed, [0] 262array(3) { 263 ["total"]=> 264 int(3) 265 ["active_plinks"]=> 266 int(2) 267 ["cached_plinks"]=> 268 int(0) 269} 270done! 271