is*() methods now return boolean values;
[phpmyadmin.git] / server_status.php
blob3bbf2e033a1a3cf443f1d207b65203fafadd4a27
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * displays status variables with descriptions and some hints an optmizing
5 * + reset status variables
7 * @version $Id$
8 * @package phpMyAdmin
9 */
11 /**
12 * no need for variables importing
13 * @ignore
15 if (! defined('PMA_NO_VARIABLES_IMPORT')) {
16 define('PMA_NO_VARIABLES_IMPORT', true);
18 require_once './libraries/common.inc.php';
20 /**
21 * Does the common work
23 require './libraries/server_common.inc.php';
26 /**
27 * Displays the links
29 require './libraries/server_links.inc.php';
32 /**
33 * Displays the sub-page heading
35 echo '<div id="serverstatus">' . "\n";
36 echo '<h2>' . "\n"
37 . ($GLOBALS['cfg']['MainPageIconic']
38 ? '<img class="icon" src="' . $GLOBALS['pmaThemeImage'] .
39 's_status.png" width="16" height="16" alt="" />'
40 : '')
41 . $strServerStatus . "\n"
42 . '</h2>' . "\n";
45 /**
46 * flush status variables if requested
48 if (isset($_REQUEST['flush'])) {
49 $_flush_commands = array(
50 'STATUS',
51 'TABLES',
52 'QUERY CACHE',
55 if (in_array($_REQUEST['flush'], $_flush_commands)) {
56 PMA_DBI_query('FLUSH ' . $_REQUEST['flush'] . ';');
58 unset($_flush_commands);
62 /**
63 * get status from server
65 $server_status = PMA_DBI_fetch_result('SHOW GLOBAL STATUS', 0, 1);
68 /**
69 * for some calculations we require also some server settings
71 $server_variables = PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES', 0, 1);
74 /**
75 * starttime calculation
77 $start_time = PMA_DBI_fetch_value(
78 'SELECT UNIX_TIMESTAMP() - ' . $server_status['Uptime']);
81 /**
82 * cleanup some deprecated values
84 $deprecated = array(
85 'Com_prepare_sql' => 'Com_stmt_prepare',
86 'Com_execute_sql' => 'Com_stmt_execute',
87 'Com_dealloc_sql' => 'Com_stmt_close',
90 foreach ($deprecated as $old => $new) {
91 if (isset($server_status[$old])
92 && isset($server_status[$new])) {
93 unset($server_status[$old]);
96 unset($deprecated);
99 /**
100 * calculate some values
102 // Key_buffer_fraction
103 if (isset($server_status['Key_blocks_unused'])
104 && isset($server_variables['key_cache_block_size'])
105 && isset($server_variables['key_buffer_size'])) {
106 $server_status['Key_buffer_fraction_%'] =
108 - $server_status['Key_blocks_unused']
109 * $server_variables['key_cache_block_size']
110 / $server_variables['key_buffer_size']
111 * 100;
112 } elseif (
113 isset($server_status['Key_blocks_used'])
114 && isset($server_variables['key_buffer_size'])) {
115 $server_status['Key_buffer_fraction_%'] =
116 $server_status['Key_blocks_used']
117 * 1024
118 / $server_variables['key_buffer_size'];
121 // Ratio for key read/write
122 if (isset($server_status['Key_writes'])
123 && isset($server_status['Key_write_requests'])
124 && $server_status['Key_write_requests'] > 0)
125 $server_status['Key_write_ratio_%'] = 100 * $server_status['Key_writes'] / $server_status['Key_write_requests'];
127 if (isset($server_status['Key_reads'])
128 && isset($server_status['Key_read_requests'])
129 && $server_status['Key_read_requests'] > 0)
130 $server_status['Key_read_ratio_%'] = 100 * $server_status['Key_reads'] / $server_status['Key_read_requests'];
132 // Threads_cache_hitrate
133 if (isset($server_status['Threads_created'])
134 && isset($server_status['Connections'])
135 && $server_status['Connections'] > 0) {
136 $server_status['Threads_cache_hitrate_%'] =
138 - $server_status['Threads_created']
139 / $server_status['Connections']
140 * 100;
145 * define some alerts
147 // name => max value before alert
148 $alerts = array(
149 // lower is better
150 // variable => max value
151 'Aborted_clients' => 0,
152 'Aborted_connects' => 0,
154 'Binlog_cache_disk_use' => 0,
156 'Created_tmp_disk_tables' => 0,
158 'Handler_read_rnd' => 0,
159 'Handler_read_rnd_next' => 0,
161 'Innodb_buffer_pool_pages_dirty' => 0,
162 'Innodb_buffer_pool_reads' => 0,
163 'Innodb_buffer_pool_wait_free' => 0,
164 'Innodb_log_waits' => 0,
165 'Innodb_row_lock_time_avg' => 10, // ms
166 'Innodb_row_lock_time_max' => 50, // ms
167 'Innodb_row_lock_waits' => 0,
169 'Slow_queries' => 0,
170 'Delayed_errors' => 0,
171 'Select_full_join' => 0,
172 'Select_range_check' => 0,
173 'Sort_merge_passes' => 0,
174 'Opened_tables' => 0,
175 'Table_locks_waited' => 0,
176 'Qcache_lowmem_prunes' => 0,
177 'Slow_launch_threads' => 0,
179 // depends on Key_read_requests
180 // normaly lower then 1:0.01
181 'Key_reads' => (0.01 * $server_status['Key_read_requests']),
182 // depends on Key_write_requests
183 // normaly nearly 1:1
184 'Key_writes' => (0.9 * $server_status['Key_write_requests']),
186 'Key_buffer_fraction' => 0.5,
188 // alert if more than 95% of thread cache is in use
189 'Threads_cached' => 0.95 * $server_variables['thread_cache_size']
191 // higher is better
192 // variable => min value
193 //'Handler read key' => '> ',
198 * split variables in sections
200 $allocations = array(
201 // variable name => section
203 'Com_' => 'com',
204 'Innodb_' => 'innodb',
205 'Ndb_' => 'ndb',
206 'Ssl_' => 'ssl',
207 'Handler_' => 'handler',
208 'Qcache_' => 'qcache',
209 'Threads_' => 'threads',
210 'Slow_launch_threads' => 'threads',
212 'Binlog_cache_' => 'binlog_cache',
213 'Created_tmp_' => 'created_tmp',
214 'Key_' => 'key',
216 'Delayed_' => 'delayed',
217 'Not_flushed_delayed_rows' => 'delayed',
219 'Flush_commands' => 'query',
220 'Last_query_cost' => 'query',
221 'Slow_queries' => 'query',
223 'Select_' => 'select',
224 'Sort_' => 'sort',
226 'Open_tables' => 'table',
227 'Opened_tables' => 'table',
228 'Table_locks_' => 'table',
230 'Rpl_status' => 'repl',
231 'Slave_' => 'repl',
233 'Tc_' => 'tc',
236 $sections = array(
237 // section => section name (description)
238 'com' => array('title' => ''),
239 'query' => array('title' => $strSQLQuery),
240 'innodb' => array('title' => 'InnoDB'),
241 'ndb' => array('title' => 'NDB'),
242 'ssl' => array('title' => 'SSL'),
243 'handler' => array('title' => $strHandler),
244 'qcache' => array('title' => $strQueryCache),
245 'threads' => array('title' => $strThreads),
246 'binlog_cache' => array('title' => $strBinaryLog),
247 'created_tmp' => array('title' => $strTempData),
248 'delayed' => array('title' => $strServerStatusDelayedInserts),
249 'key' => array('title' => $strKeyCache),
250 'select' => array('title' => $strJoins),
251 'repl' => array('title' => $strReplication),
252 'sort' => array('title' => $strSorting),
253 'table' => array('title' => $strNumTables),
254 'tc' => array('title' => $strTransactionCoordinator),
259 * define some needfull links/commands
261 // variable or section name => (name => url)
262 $links = array();
264 $links['table'][$strFlushTables]
265 = $PMA_PHP_SELF . '?flush=TABLES&amp;' . PMA_generate_common_url();
266 $links['table'][$strShowOpenTables]
267 = 'sql.php?sql_query=' . urlencode('SHOW OPEN TABLES') .
268 '&amp;goto=server_status.php&amp;' . PMA_generate_common_url();
270 $links['repl'][$strShowSlaveHosts]
271 = 'sql.php?sql_query=' . urlencode('SHOW SLAVE HOSTS') .
272 '&amp;goto=server_status.php&amp;' . PMA_generate_common_url();
273 $links['repl'][$strShowSlaveStatus]
274 = 'sql.php?sql_query=' . urlencode('SHOW SLAVE STATUS') .
275 '&amp;goto=server_status.php&amp;' . PMA_generate_common_url();
276 $links['repl']['doc'] = 'replication';
278 $links['qcache'][$strFlushQueryCache]
279 = $PMA_PHP_SELF . '?flush=' . urlencode('QUERY CACHE') . '&amp;' .
280 PMA_generate_common_url();
281 $links['qcache']['doc'] = 'query_cache';
283 $links['threads'][$strMySQLShowProcess]
284 = 'server_processlist.php?' . PMA_generate_common_url();
285 $links['threads']['doc'] = 'mysql_threads';
287 $links['key']['doc'] = 'myisam_key_cache';
289 $links['binlog_cache']['doc'] = 'binary_log';
291 $links['Slow_queries']['doc'] = 'slow_query_log';
293 $links['innodb'][$strServerTabVariables]
294 = 'server_engines.php?engine=InnoDB&amp;' . PMA_generate_common_url();
295 $links['innodb'][$strInnodbStat]
296 = 'server_engines.php?engine=InnoDB&amp;page=Status&amp;' .
297 PMA_generate_common_url();
298 $links['innodb']['doc'] = 'innodb';
301 // sort status vars into arrays
302 foreach ($server_status as $name => $value) {
303 if (isset($allocations[$name])) {
304 $sections[$allocations[$name]]['vars'][$name] = $value;
305 unset($server_status[$name]);
306 } else {
307 foreach ($allocations as $filter => $section) {
308 if (preg_match('/^' . $filter . '/', $name)
309 && isset($server_status[$name])) {
310 unset($server_status[$name]);
311 $sections[$section]['vars'][$name] = $value;
316 unset($name, $value, $filter, $section, $allocations);
318 // rest
319 $sections['all']['vars'] =& $server_status;
321 $hour_factor = 3600 / $server_status['Uptime'];
324 * start output
327 <div id="statuslinks">
328 <a href="<?php echo
329 $PMA_PHP_SELF . '?' . PMA_generate_common_url(); ?>"
330 ><?php echo $strRefresh; ?></a>
331 <a href="<?php echo
332 $PMA_PHP_SELF . '?flush=STATUS&amp;' . PMA_generate_common_url(); ?>"
333 ><?php echo $strShowStatusReset; ?></a>
334 <?php echo PMA_showMySQLDocu('server_status_variables','server_status_variables'); ?>
335 </div>
338 <?php
339 echo sprintf($strServerStatusUptime,
340 PMA_timespanFormat($server_status['Uptime']),
341 PMA_localisedDate($start_time)) . "\n";
343 </p>
345 <div id="sectionlinks">
346 <?php
347 foreach ($sections as $section_name => $section) {
348 if (! empty($section['vars']) && ! empty($section['title'])) {
349 echo '<a href="' . $PMA_PHP_SELF . '?' .
350 PMA_generate_common_url() . '#' . $section_name . '">' .
351 $section['title'] . '</a>' . "\n";
355 </div>
357 <h3><?php echo $strServerTrafficNotes; ?></h3>
359 <table id="serverstatustraffic" class="data">
360 <thead>
361 <tr>
362 <th colspan="2"><?php echo $strTraffic . '&nbsp;' . PMA_showHint($strStatisticsOverrun); ?></th>
363 <th>&oslash; <?php echo $strPerHour; ?></th>
364 </tr>
365 </thead>
366 <tbody>
367 <tr class="odd">
368 <th class="name"><?php echo $strReceived; ?></th>
369 <td class="value"><?php echo
370 implode(' ',
371 PMA_formatByteDown($server_status['Bytes_received'], 4)); ?></td>
372 <td class="value"><?php echo
373 implode(' ',
374 PMA_formatByteDown(
375 $server_status['Bytes_received'] * $hour_factor, 4)); ?></td>
376 </tr>
377 <tr class="even">
378 <th class="name"><?php echo $strSent; ?></th>
379 <td class="value"><?php echo
380 implode(' ',
381 PMA_formatByteDown($server_status['Bytes_sent'], 4)); ?></td>
382 <td class="value"><?php echo
383 implode(' ',
384 PMA_formatByteDown(
385 $server_status['Bytes_sent'] * $hour_factor, 4)); ?></td>
386 </tr>
387 <tr class="odd">
388 <th class="name"><?php echo $strTotalUC; ?></th>
389 <td class="value"><?php echo
390 implode(' ',
391 PMA_formatByteDown(
392 $server_status['Bytes_received'] + $server_status['Bytes_sent'], 4)
393 ); ?></td>
394 <td class="value"><?php echo
395 implode(' ',
396 PMA_formatByteDown(
397 ($server_status['Bytes_received'] + $server_status['Bytes_sent'])
398 * $hour_factor, 4)
399 ); ?></td>
400 </tr>
401 </tbody>
402 </table>
404 <table id="serverstatusconnections" class="data">
405 <thead>
406 <tr>
407 <th colspan="2"><?php echo $strConnections; ?></th>
408 <th>&oslash; <?php echo $strPerHour; ?></th>
409 <th>%</th>
410 </tr>
411 </thead>
412 <tbody>
413 <tr class="odd">
414 <th class="name"><?php echo $strMaxConnects; ?></th>
415 <td class="value"><?php echo
416 PMA_formatNumber($server_status['Max_used_connections'], 0); ?> </td>
417 <td class="value">--- </td>
418 <td class="value">--- </td>
419 </tr>
420 <tr class="even">
421 <th class="name"><?php echo $strFailedAttempts; ?></th>
422 <td class="value"><?php echo
423 PMA_formatNumber($server_status['Aborted_connects'], 4, 0); ?></td>
424 <td class="value"><?php echo
425 PMA_formatNumber($server_status['Aborted_connects'] * $hour_factor,
426 4, 2); ?></td>
427 <td class="value"><?php echo
428 $server_status['Connections'] > 0
429 ? PMA_formatNumber(
430 $server_status['Aborted_connects'] * 100 / $server_status['Connections'],
431 0, 2) . '%'
432 : '--- '; ?></td>
433 </tr>
434 <tr class="odd">
435 <th class="name"><?php echo $strAbortedClients; ?></th>
436 <td class="value"><?php echo
437 PMA_formatNumber($server_status['Aborted_clients'], 4, 0); ?></td>
438 <td class="value"><?php echo
439 PMA_formatNumber($server_status['Aborted_clients'] * $hour_factor,
440 4, 2); ?></td>
441 <td class="value"><?php echo
442 $server_status['Connections'] > 0
443 ? PMA_formatNumber(
444 $server_status['Aborted_clients'] * 100 / $server_status['Connections'],
445 0, 2) . '%'
446 : '--- '; ?></td>
447 </tr>
448 <tr class="even">
449 <th class="name"><?php echo $strTotalUC; ?></th>
450 <td class="value"><?php echo
451 PMA_formatNumber($server_status['Connections'], 4, 0); ?></td>
452 <td class="value"><?php echo
453 PMA_formatNumber($server_status['Connections'] * $hour_factor,
454 4, 2); ?></td>
455 <td class="value"><?php echo
456 PMA_formatNumber(100, 0, 2); ?>%</td>
457 </tr>
458 </tbody>
459 </table>
461 <hr class="clearfloat" />
463 <h3><?php echo
464 sprintf($strQueryStatistics,
465 PMA_formatNumber($server_status['Questions'], 0)); ?></h3>
467 <table id="serverstatusqueriessummary" class="data">
468 <thead>
469 <tr>
470 <th><?php echo $strTotalUC; ?></th>
471 <th>&oslash; <?php echo $strPerHour; ?></th>
472 <th>&oslash; <?php echo $strPerMinute; ?></th>
473 <th>&oslash; <?php echo $strPerSecond; ?></th>
474 </tr>
475 </thead>
476 <tbody>
477 <tr class="odd">
478 <td class="value"><?php echo
479 PMA_formatNumber($server_status['Questions'], 4, 0); ?></td>
480 <td class="value"><?php echo
481 PMA_formatNumber($server_status['Questions'] * $hour_factor,
482 3, 2); ?></td>
483 <td class="value"><?php echo
484 PMA_formatNumber(
485 $server_status['Questions'] * 60 / $server_status['Uptime'],
486 3, 2); ?></td>
487 <td class="value"><?php echo
488 PMA_formatNumber(
489 $server_status['Questions'] / $server_status['Uptime'],
490 3, 2); ?></td>
491 </tr>
492 </tbody>
493 </table>
495 <div id="serverstatusqueriesdetails">
496 <?php
497 // number of tables to split values into
498 $tables = 2;
499 $rows_per_table = (int) ceil(count($sections['com']['vars']) / $tables);
500 $current_table = 0;
501 $odd_row = true;
502 $countRows = 0;
503 $perc_factor = 100 / ($server_status['Questions'] - $server_status['Connections']);
504 foreach ($sections['com']['vars'] as $name => $value) {
505 $current_table++;
506 if ($countRows === 0 || $countRows === $rows_per_table) {
507 $odd_row = true;
508 if ($countRows === $rows_per_table) {
509 echo ' </tbody>' . "\n";
510 echo ' </table>' . "\n";
513 <table id="serverstatusqueriesdetails<?php echo $current_table; ?>" class="data">
514 <col class="namecol" />
515 <col class="valuecol" span="3" />
516 <thead>
517 <tr><th colspan="2"><?php echo $strQueryType; ?></th>
518 <th>&oslash; <?php echo $strPerHour; ?></th>
519 <th>%</th>
520 </tr>
521 </thead>
522 <tbody>
523 <?php
524 } else {
525 $odd_row = !$odd_row;
527 $countRows++;
529 // For the percentage column, use Questions - Connections, because
530 // the number of connections is not an item of the Query types
531 // but is included in Questions. Then the total of the percentages is 100.
532 $name = str_replace('Com_', '', $name);
533 $name = str_replace('_', ' ', $name);
535 <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>">
536 <th class="name"><?php echo htmlspecialchars($name); ?></th>
537 <td class="value"><?php echo PMA_formatNumber($value, 4, 0); ?></td>
538 <td class="value"><?php echo
539 PMA_formatNumber($value * $hour_factor, 4, 2); ?></td>
540 <td class="value"><?php echo
541 PMA_formatNumber($value * $perc_factor, 0, 2); ?>%</td>
542 </tr>
543 <?php
546 </tbody>
547 </table>
548 </div>
550 <div id="serverstatussection">
551 <?php
552 //Unset used variables
553 unset(
554 $tables, $rows_per_table, $current_table, $countRows, $perc_factor,
555 $hour_factor, $sections['com'],
556 $server_status['Aborted_clients'], $server_status['Aborted_connects'],
557 $server_status['Max_used_connections'], $server_status['Bytes_received'],
558 $server_status['Bytes_sent'], $server_status['Connections'],
559 $server_status['Questions'], $server_status['Uptime']
562 foreach ($sections as $section_name => $section) {
563 if (! empty($section['vars'])) {
565 <table class="data" id="serverstatussection<?php echo $section_name; ?>">
566 <caption class="tblHeaders">
567 <a class="top"
568 href="<?php echo $PMA_PHP_SELF . '?' .
569 PMA_generate_common_url() . '#serverstatus'; ?>"
570 name="<?php echo $section_name; ?>"><?php echo $strPos1; ?>
571 <?php echo
572 ($GLOBALS['cfg']['MainPageIconic']
573 ? '<img src="' . $GLOBALS['pmaThemeImage'] .
574 's_asc.png" width="11" height="9" align="middle" alt="" />'
575 : ''); ?>
576 </a>
577 <?php
578 if (! empty($section['title'])) {
579 echo $section['title'];
582 </caption>
583 <col class="namecol" />
584 <col class="valuecol" />
585 <col class="descrcol" />
586 <thead>
587 <tr>
588 <th><?php echo $strVar; ?></th>
589 <th><?php echo $strValue; ?></th>
590 <th><?php echo $strDescription; ?></th>
591 </tr>
592 </thead>
593 <?php
594 if (! empty($links[$section_name])) {
596 <tfoot>
597 <tr class="tblFooters">
598 <th colspan="3" class="tblFooters">
599 <?php
600 foreach ($links[$section_name] as $link_name => $link_url) {
601 if ('doc' == $link_name) {
602 echo PMA_showMySQLDocu($link_url, $link_url);
603 } else {
604 echo '<a href="' . $link_url . '">' . $link_name . '</a>' . "\n";
607 unset($link_url, $link_name);
609 </th>
610 </tr>
611 </tfoot>
612 <?php
615 <tbody>
616 <?php
617 $odd_row = false;
618 foreach ($section['vars'] as $name => $value) {
619 $odd_row = !$odd_row;
621 <tr class="<?php echo $odd_row ? 'odd' : 'even'; ?>">
622 <th class="name"><?php echo htmlspecialchars($name); ?></th>
623 <td class="value"><?php
624 if (isset($alerts[$name])) {
625 if ($value > $alerts[$name]) {
626 echo '<span class="attention">';
627 } else {
628 echo '<span class="allfine">';
631 if ('%' === substr($name, -1, 1)) {
632 echo PMA_formatNumber($value, 0, 2) . ' %';
633 } elseif (is_numeric($value) && $value == (int) $value) {
634 echo PMA_formatNumber($value, 4, 0);
635 } elseif (is_numeric($value)) {
636 echo PMA_formatNumber($value, 4, 2);
637 } else {
638 echo htmlspecialchars($value);
640 if (isset($alerts[$name])) {
641 echo '</span>';
643 ?></td>
644 <td class="descr">
645 <?php
646 if (isset($GLOBALS['strShowStatus' . $name . 'Descr'])) {
647 echo $GLOBALS['strShowStatus' . $name . 'Descr'];
650 if (isset($links[$name])) {
651 foreach ($links[$name] as $link_name => $link_url) {
652 if ('doc' == $link_name) {
653 echo PMA_showMySQLDocu($link_url, $link_url);
654 } else {
655 echo ' <a href="' . $link_url . '">' . $link_name . '</a>' .
656 "\n";
659 unset($link_url, $link_name);
662 </td>
663 </tr>
664 <?php
666 unset($name, $value);
668 </tbody>
669 </table>
670 <?php
673 unset($section_name, $section, $sections, $server_status, $odd_row, $alerts);
675 </div>
676 </div>
677 <?php
681 * Sends the footer
683 require_once './libraries/footer.inc.php';