Innodb.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. /**
  3. * The InnoDB storage engine
  4. */
  5. declare(strict_types=1);
  6. namespace PhpMyAdmin\Engines;
  7. use PhpMyAdmin\StorageEngine;
  8. use PhpMyAdmin\Util;
  9. use function htmlspecialchars;
  10. use function implode;
  11. /**
  12. * The InnoDB storage engine
  13. */
  14. class Innodb extends StorageEngine
  15. {
  16. /**
  17. * Returns array with variable names related to InnoDB storage engine
  18. *
  19. * @return array variable names
  20. */
  21. public function getVariables()
  22. {
  23. return [
  24. 'innodb_data_home_dir' => [
  25. 'title' => __('Data home directory'),
  26. 'desc' => __(
  27. 'The common part of the directory path for all InnoDB data '
  28. . 'files.'
  29. ),
  30. ],
  31. 'innodb_data_file_path' => [
  32. 'title' => __('Data files'),
  33. ],
  34. 'innodb_autoextend_increment' => [
  35. 'title' => __('Autoextend increment'),
  36. 'desc' => __(
  37. 'The increment size for extending the size of an autoextending '
  38. . 'tablespace when it becomes full.'
  39. ),
  40. 'type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC,
  41. ],
  42. 'innodb_buffer_pool_size' => [
  43. 'title' => __('Buffer pool size'),
  44. 'desc' => __(
  45. 'The size of the memory buffer InnoDB uses to cache data and '
  46. . 'indexes of its tables.'
  47. ),
  48. 'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
  49. ],
  50. 'innodb_additional_mem_pool_size' => [
  51. 'title' => 'innodb_additional_mem_pool_size',
  52. 'type' => PMA_ENGINE_DETAILS_TYPE_SIZE,
  53. ],
  54. 'innodb_buffer_pool_awe_mem_mb' => ['type' => PMA_ENGINE_DETAILS_TYPE_SIZE],
  55. 'innodb_checksums' => [],
  56. 'innodb_commit_concurrency' => [],
  57. 'innodb_concurrency_tickets' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  58. 'innodb_doublewrite' => [],
  59. 'innodb_fast_shutdown' => [],
  60. 'innodb_file_io_threads' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  61. 'innodb_file_per_table' => [],
  62. 'innodb_flush_log_at_trx_commit' => [],
  63. 'innodb_flush_method' => [],
  64. 'innodb_force_recovery' => [],
  65. 'innodb_lock_wait_timeout' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  66. 'innodb_locks_unsafe_for_binlog' => [],
  67. 'innodb_log_arch_dir' => [],
  68. 'innodb_log_archive' => [],
  69. 'innodb_log_buffer_size' => ['type' => PMA_ENGINE_DETAILS_TYPE_SIZE],
  70. 'innodb_log_file_size' => ['type' => PMA_ENGINE_DETAILS_TYPE_SIZE],
  71. 'innodb_log_files_in_group' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  72. 'innodb_log_group_home_dir' => [],
  73. 'innodb_max_dirty_pages_pct' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  74. 'innodb_max_purge_lag' => [],
  75. 'innodb_mirrored_log_groups' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  76. 'innodb_open_files' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  77. 'innodb_support_xa' => [],
  78. 'innodb_sync_spin_loops' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  79. 'innodb_table_locks' => ['type' => PMA_ENGINE_DETAILS_TYPE_BOOLEAN],
  80. 'innodb_thread_concurrency' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  81. 'innodb_thread_sleep_delay' => ['type' => PMA_ENGINE_DETAILS_TYPE_NUMERIC],
  82. ];
  83. }
  84. /**
  85. * Returns the pattern to be used in the query for SQL variables
  86. * related to InnoDb storage engine
  87. *
  88. * @return string SQL query LIKE pattern
  89. */
  90. public function getVariablesLikePattern()
  91. {
  92. return 'innodb\\_%';
  93. }
  94. /**
  95. * Get information pages
  96. *
  97. * @return array detail pages
  98. */
  99. public function getInfoPages()
  100. {
  101. if ($this->support < PMA_ENGINE_SUPPORT_YES) {
  102. return [];
  103. }
  104. $pages = [];
  105. $pages['Bufferpool'] = __('Buffer Pool');
  106. $pages['Status'] = __('InnoDB Status');
  107. return $pages;
  108. }
  109. /**
  110. * returns html tables with stats over inno db buffer pool
  111. *
  112. * @return string html table with stats
  113. */
  114. public function getPageBufferpool()
  115. {
  116. global $dbi;
  117. // The following query is only possible because we know
  118. // that we are on MySQL 5 here (checked above)!
  119. // side note: I love MySQL 5 for this. :-)
  120. $sql = 'SHOW STATUS'
  121. . ' WHERE Variable_name LIKE \'Innodb\\_buffer\\_pool\\_%\''
  122. . ' OR Variable_name = \'Innodb_page_size\';';
  123. $status = $dbi->fetchResult($sql, 0, 1);
  124. $output = '<table class="table table-light table-striped table-hover w-auto float-left">' . "\n"
  125. . ' <caption>' . "\n"
  126. . ' ' . __('Buffer Pool Usage') . "\n"
  127. . ' </caption>' . "\n"
  128. . ' <tfoot class="thead-light">' . "\n"
  129. . ' <tr>' . "\n"
  130. . ' <th colspan="2">' . "\n"
  131. . ' ' . __('Total:') . ' '
  132. . Util::formatNumber(
  133. $status['Innodb_buffer_pool_pages_total'],
  134. 0
  135. )
  136. . '&nbsp;' . __('pages')
  137. . ' / '
  138. . implode(
  139. '&nbsp;',
  140. Util::formatByteDown(
  141. $status['Innodb_buffer_pool_pages_total']
  142. * $status['Innodb_page_size']
  143. )
  144. ) . "\n"
  145. . ' </th>' . "\n"
  146. . ' </tr>' . "\n"
  147. . ' </tfoot>' . "\n"
  148. . ' <tbody>' . "\n"
  149. . ' <tr>' . "\n"
  150. . ' <th scope="row">' . __('Free pages') . '</th>' . "\n"
  151. . ' <td class="text-monospace text-right">'
  152. . Util::formatNumber(
  153. $status['Innodb_buffer_pool_pages_free'],
  154. 0
  155. )
  156. . '</td>' . "\n"
  157. . ' </tr>' . "\n"
  158. . ' <tr>' . "\n"
  159. . ' <th scope="row">' . __('Dirty pages') . '</th>' . "\n"
  160. . ' <td class="text-monospace text-right">'
  161. . Util::formatNumber(
  162. $status['Innodb_buffer_pool_pages_dirty'],
  163. 0
  164. )
  165. . '</td>' . "\n"
  166. . ' </tr>' . "\n"
  167. . ' <tr>' . "\n"
  168. . ' <th scope="row">' . __('Pages containing data') . '</th>' . "\n"
  169. . ' <td class="text-monospace text-right">'
  170. . Util::formatNumber(
  171. $status['Innodb_buffer_pool_pages_data'],
  172. 0
  173. ) . "\n"
  174. . '</td>' . "\n"
  175. . ' </tr>' . "\n"
  176. . ' <tr>' . "\n"
  177. . ' <th scope="row">' . __('Pages to be flushed') . '</th>' . "\n"
  178. . ' <td class="text-monospace text-right">'
  179. . Util::formatNumber(
  180. $status['Innodb_buffer_pool_pages_flushed'],
  181. 0
  182. ) . "\n"
  183. . '</td>' . "\n"
  184. . ' </tr>' . "\n"
  185. . ' <tr>' . "\n"
  186. . ' <th scope="row">' . __('Busy pages') . '</th>' . "\n"
  187. . ' <td class="text-monospace text-right">'
  188. . Util::formatNumber(
  189. $status['Innodb_buffer_pool_pages_misc'],
  190. 0
  191. ) . "\n"
  192. . '</td>' . "\n"
  193. . ' </tr>';
  194. // not present at least since MySQL 5.1.40
  195. if (isset($status['Innodb_buffer_pool_pages_latched'])) {
  196. $output .= ' <tr>'
  197. . ' <th scope="row">' . __('Latched pages') . '</th>'
  198. . ' <td class="text-monospace text-right">'
  199. . Util::formatNumber(
  200. $status['Innodb_buffer_pool_pages_latched'],
  201. 0
  202. )
  203. . '</td>'
  204. . ' </tr>';
  205. }
  206. $output .= ' </tbody>' . "\n"
  207. . '</table>' . "\n\n"
  208. . '<table class="table table-light table-striped table-hover w-auto ml-4 float-left">' . "\n"
  209. . ' <caption>' . "\n"
  210. . ' ' . __('Buffer Pool Activity') . "\n"
  211. . ' </caption>' . "\n"
  212. . ' <tbody>' . "\n"
  213. . ' <tr>' . "\n"
  214. . ' <th scope="row">' . __('Read requests') . '</th>' . "\n"
  215. . ' <td class="text-monospace text-right">'
  216. . Util::formatNumber(
  217. $status['Innodb_buffer_pool_read_requests'],
  218. 0
  219. ) . "\n"
  220. . '</td>' . "\n"
  221. . ' </tr>' . "\n"
  222. . ' <tr>' . "\n"
  223. . ' <th scope="row">' . __('Write requests') . '</th>' . "\n"
  224. . ' <td class="text-monospace text-right">'
  225. . Util::formatNumber(
  226. $status['Innodb_buffer_pool_write_requests'],
  227. 0
  228. ) . "\n"
  229. . '</td>' . "\n"
  230. . ' </tr>' . "\n"
  231. . ' <tr>' . "\n"
  232. . ' <th scope="row">' . __('Read misses') . '</th>' . "\n"
  233. . ' <td class="text-monospace text-right">'
  234. . Util::formatNumber(
  235. $status['Innodb_buffer_pool_reads'],
  236. 0
  237. ) . "\n"
  238. . '</td>' . "\n"
  239. . ' </tr>' . "\n"
  240. . ' <tr>' . "\n"
  241. . ' <th scope="row">' . __('Write waits') . '</th>' . "\n"
  242. . ' <td class="text-monospace text-right">'
  243. . Util::formatNumber(
  244. $status['Innodb_buffer_pool_wait_free'],
  245. 0
  246. ) . "\n"
  247. . '</td>' . "\n"
  248. . ' </tr>' . "\n"
  249. . ' <tr>' . "\n"
  250. . ' <th scope="row">' . __('Read misses in %') . '</th>' . "\n"
  251. . ' <td class="text-monospace text-right">'
  252. . ($status['Innodb_buffer_pool_read_requests'] == 0
  253. ? '---'
  254. : htmlspecialchars(
  255. Util::formatNumber(
  256. $status['Innodb_buffer_pool_reads'] * 100
  257. / $status['Innodb_buffer_pool_read_requests'],
  258. 3,
  259. 2
  260. )
  261. ) . ' %') . "\n"
  262. . '</td>' . "\n"
  263. . ' </tr>' . "\n"
  264. . ' <tr>' . "\n"
  265. . ' <th scope="row">' . __('Write waits in %') . '</th>' . "\n"
  266. . ' <td class="text-monospace text-right">'
  267. . ($status['Innodb_buffer_pool_write_requests'] == 0
  268. ? '---'
  269. : htmlspecialchars(
  270. Util::formatNumber(
  271. $status['Innodb_buffer_pool_wait_free'] * 100
  272. / $status['Innodb_buffer_pool_write_requests'],
  273. 3,
  274. 2
  275. )
  276. ) . ' %') . "\n"
  277. . '</td>' . "\n"
  278. . ' </tr>' . "\n"
  279. . ' </tbody>' . "\n"
  280. . '</table>' . "\n";
  281. return $output;
  282. }
  283. /**
  284. * returns InnoDB status
  285. *
  286. * @return string result of SHOW ENGINE INNODB STATUS inside pre tags
  287. */
  288. public function getPageStatus()
  289. {
  290. global $dbi;
  291. return '<pre id="pre_innodb_status">' . "\n"
  292. . htmlspecialchars((string) $dbi->fetchValue(
  293. 'SHOW ENGINE INNODB STATUS;',
  294. 0,
  295. 'Status'
  296. )) . "\n" . '</pre>' . "\n";
  297. }
  298. /**
  299. * returns string with filename for the MySQL helppage
  300. * about this storage engine
  301. *
  302. * @return string mysql helppage filename
  303. */
  304. public function getMysqlHelpPage()
  305. {
  306. return 'innodb-storage-engine';
  307. }
  308. /**
  309. * Gets the InnoDB plugin version number
  310. *
  311. * @return string the version number, or empty if not running as a plugin
  312. */
  313. public function getInnodbPluginVersion()
  314. {
  315. global $dbi;
  316. return $dbi->fetchValue('SELECT @@innodb_version;');
  317. }
  318. /**
  319. * Gets the InnoDB file format
  320. *
  321. * (do not confuse this with phpMyAdmin's storage engine plugins!)
  322. *
  323. * @return string the InnoDB file format
  324. */
  325. public function getInnodbFileFormat()
  326. {
  327. global $dbi;
  328. return $dbi->fetchValue(
  329. "SHOW GLOBAL VARIABLES LIKE 'innodb_file_format';",
  330. 0,
  331. 1
  332. );
  333. }
  334. /**
  335. * Verifies if this server supports the innodb_file_per_table feature
  336. *
  337. * (do not confuse this with phpMyAdmin's storage engine plugins!)
  338. *
  339. * @return bool whether this feature is supported or not
  340. */
  341. public function supportsFilePerTable()
  342. {
  343. global $dbi;
  344. return $dbi->fetchValue(
  345. "SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';",
  346. 0,
  347. 1
  348. ) === 'ON';
  349. }
  350. }