mysqli_pconn_max_links.phpt 9.2 KB

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