Merge pull request #19786 from MauricioFauth/Innodb_getPageBufferpool-refactor
Refactor the Engines\Innodb::getPageBufferpool() method
This commit is contained in:
commit
e5acf85ecf
@ -6030,24 +6030,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Encoding.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "\*" between mixed and 100 results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 2
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "\*" between mixed and mixed results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 1
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '#^Binary operation "/" between \(float\|int\) and mixed results in an error\.$#'
|
||||
identifier: binaryOp.invalid
|
||||
count: 2
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '''
|
||||
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Dbal\\DatabaseInterface\:
|
||||
@ -6057,18 +6039,6 @@ parameters:
|
||||
count: 5
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison via "\=\=" is not allowed\.$#'
|
||||
identifier: equal.notAllowed
|
||||
count: 2
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|numeric\-string, mixed given\.$#'
|
||||
identifier: argument.type
|
||||
count: 11
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#'
|
||||
identifier: foreach.nonIterable
|
||||
|
||||
@ -4096,29 +4096,6 @@
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
</DeprecatedMethod>
|
||||
<MixedArgument>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_data']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_dirty']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_flushed']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_free']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_latched']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_misc']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_total']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_total'] * $status['Innodb_page_size']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_read_requests']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_reads']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_reads'] * 100
|
||||
/ $status['Innodb_buffer_pool_read_requests']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_wait_free']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_wait_free'] * 100
|
||||
/ $status['Innodb_buffer_pool_write_requests']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_write_requests']]]></code>
|
||||
</MixedArgument>
|
||||
<MixedOperand>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_pages_total']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_reads']]]></code>
|
||||
<code><![CDATA[$status['Innodb_buffer_pool_wait_free']]]></code>
|
||||
</MixedOperand>
|
||||
</file>
|
||||
<file src="src/Engines/Pbxt.php">
|
||||
<PossiblyUnusedMethod>
|
||||
|
||||
72
resources/templates/server/engines/_innodb_buffer_pool.twig
Normal file
72
resources/templates/server/engines/_innodb_buffer_pool.twig
Normal file
@ -0,0 +1,72 @@
|
||||
<table class="table table-striped table-hover w-auto float-start caption-top">
|
||||
<caption>{{ t('Buffer pool usage') }}</caption>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Free pages') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.pagesFree, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Dirty pages') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.pagesDirty, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Pages containing data') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.pagesData, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Pages to be flushed') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.pagesFlushed, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Busy pages') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.pagesMisc, 0) }}</td>
|
||||
</tr>
|
||||
{% if buffer_pool.pagesLatched != null %}
|
||||
<tr>
|
||||
<th scope="row">{{ t('Latched pages') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.pagesLatched, 0) }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
{{ t('Total:') }} {{ t('%s pages')|format(format_number(buffer_pool.pagesTotal, 0)) }} / {{ format_byte_down(buffer_pool.pagesTotal * buffer_pool.innodbPageSize)|join(' ') }}
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<table class="table table-striped table-hover w-auto ms-4 float-start caption-top">
|
||||
<caption>{{ t('Buffer pool activity') }}</caption>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Read requests') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.readRequests, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Write requests') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.writeRequests, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Read misses') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.reads, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Write waits') }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(buffer_pool.waitFree, 0) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Read misses in %') }}</th>
|
||||
<td class="font-monospace text-end">
|
||||
{{- buffer_pool.readRequests != 0 ? format_number(buffer_pool.reads * 100 / buffer_pool.readRequests, 3, 2) ~ '%' : '---' -}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">{{ t('Write waits in %') }}</th>
|
||||
<td class="font-monospace text-end">
|
||||
{{- buffer_pool.writeRequests != 0 ? format_number(buffer_pool.waitFree * 100 / buffer_pool.writeRequests, 3, 2) ~ '%' : '---' -}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -1,19 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* The InnoDB storage engine
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Engines;
|
||||
|
||||
use PhpMyAdmin\Dbal\DatabaseInterface;
|
||||
use PhpMyAdmin\Engines\Innodb\BufferPool;
|
||||
use PhpMyAdmin\StorageEngine;
|
||||
use PhpMyAdmin\Util;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
use function __;
|
||||
use function htmlspecialchars;
|
||||
use function implode;
|
||||
|
||||
/**
|
||||
* The InnoDB storage engine
|
||||
@ -110,141 +107,11 @@ class Innodb extends StorageEngine
|
||||
*
|
||||
* @return string html table with stats
|
||||
*/
|
||||
public function getPageBufferpool(): string
|
||||
public function getPageBufferPool(): string
|
||||
{
|
||||
// The following query is only possible because we know
|
||||
// that we are on MySQL 5 here (checked above)!
|
||||
// side note: I love MySQL 5 for this. :-)
|
||||
$sql = 'SHOW STATUS'
|
||||
. ' WHERE Variable_name LIKE \'Innodb\\_buffer\\_pool\\_%\''
|
||||
. ' OR Variable_name = \'Innodb_page_size\';';
|
||||
$status = DatabaseInterface::getInstance()->fetchResult($sql, 0, 1);
|
||||
|
||||
/** @var string[] $bytes */
|
||||
$bytes = Util::formatByteDown($status['Innodb_buffer_pool_pages_total'] * $status['Innodb_page_size']);
|
||||
|
||||
$output = '<table class="table table-striped table-hover w-auto float-start caption-top">' . "\n"
|
||||
. ' <caption>' . "\n"
|
||||
. ' ' . __('Buffer Pool Usage') . "\n"
|
||||
. ' </caption>' . "\n"
|
||||
. ' <tfoot>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th colspan="2">' . "\n"
|
||||
. ' ' . __('Total:') . ' '
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_total'], 0)
|
||||
. ' ' . __('pages')
|
||||
. ' / '
|
||||
. implode(' ', $bytes) . "\n"
|
||||
. ' </th>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' </tfoot>' . "\n"
|
||||
. ' <tbody>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Free pages') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_free'], 0)
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Dirty pages') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_dirty'], 0)
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Pages containing data') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_data'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Pages to be flushed') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_flushed'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Busy pages') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_misc'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>';
|
||||
|
||||
// not present at least since MySQL 5.1.40
|
||||
if (isset($status['Innodb_buffer_pool_pages_latched'])) {
|
||||
$output .= ' <tr>'
|
||||
. ' <th scope="row">' . __('Latched pages') . '</th>'
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_pages_latched'], 0)
|
||||
. '</td>'
|
||||
. ' </tr>';
|
||||
}
|
||||
|
||||
$output .= ' </tbody>' . "\n"
|
||||
. '</table>' . "\n\n"
|
||||
. '<table class="table table-striped table-hover w-auto ms-4 float-start caption-top">' . "\n"
|
||||
. ' <caption>' . "\n"
|
||||
. ' ' . __('Buffer Pool Activity') . "\n"
|
||||
. ' </caption>' . "\n"
|
||||
. ' <tbody>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Read requests') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_read_requests'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Write requests') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_write_requests'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Read misses') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_reads'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Write waits') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. Util::formatNumber($status['Innodb_buffer_pool_wait_free'], 0) . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Read misses in %') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. ($status['Innodb_buffer_pool_read_requests'] == 0
|
||||
? '---'
|
||||
: htmlspecialchars(
|
||||
Util::formatNumber(
|
||||
$status['Innodb_buffer_pool_reads'] * 100
|
||||
/ $status['Innodb_buffer_pool_read_requests'],
|
||||
3,
|
||||
2,
|
||||
),
|
||||
) . ' %') . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' <tr>' . "\n"
|
||||
. ' <th scope="row">' . __('Write waits in %') . '</th>' . "\n"
|
||||
. ' <td class="font-monospace text-end">'
|
||||
. ($status['Innodb_buffer_pool_write_requests'] == 0
|
||||
? '---'
|
||||
: htmlspecialchars(
|
||||
Util::formatNumber(
|
||||
$status['Innodb_buffer_pool_wait_free'] * 100
|
||||
/ $status['Innodb_buffer_pool_write_requests'],
|
||||
3,
|
||||
2,
|
||||
),
|
||||
) . ' %') . "\n"
|
||||
. '</td>' . "\n"
|
||||
. ' </tr>' . "\n"
|
||||
. ' </tbody>' . "\n"
|
||||
. '</table>' . "\n";
|
||||
|
||||
return $output;
|
||||
return (new Template())->render('server/engines/_innodb_buffer_pool', [
|
||||
'buffer_pool' => $this->getBufferPoolStatus(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,4 +180,14 @@ class Innodb extends StorageEngine
|
||||
|
||||
return $dbi->fetchValue("SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';", 1) === 'ON';
|
||||
}
|
||||
|
||||
private function getBufferPoolStatus(): BufferPool
|
||||
{
|
||||
$result = DatabaseInterface::getInstance()->tryQuery(
|
||||
"SHOW STATUS WHERE Variable_name LIKE 'Innodb\\_buffer\\_pool\\_%' OR Variable_name = 'Innodb_page_size';",
|
||||
cacheAffectedRows: false,
|
||||
);
|
||||
|
||||
return BufferPool::fromResult($result !== false ? $result->fetchAllKeyPair() : []);
|
||||
}
|
||||
}
|
||||
|
||||
69
src/Engines/Innodb/BufferPool.php
Normal file
69
src/Engines/Innodb/BufferPool.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Engines\Innodb;
|
||||
|
||||
use function is_numeric;
|
||||
|
||||
/**
|
||||
* @see https://dev.mysql.com/doc/refman/en/innodb-buffer-pool.html
|
||||
* @see https://mariadb.com/docs/server/server-usage/storage-engines/innodb/innodb-buffer-pool
|
||||
*/
|
||||
final readonly class BufferPool
|
||||
{
|
||||
/**
|
||||
* @param numeric-string $innodbPageSize Innodb_page_size
|
||||
* @param numeric-string $pagesData Innodb_buffer_pool_pages_data
|
||||
* @param numeric-string $pagesDirty Innodb_buffer_pool_pages_dirty
|
||||
* @param numeric-string $pagesFlushed Innodb_buffer_pool_pages_flushed
|
||||
* @param numeric-string $pagesFree Innodb_buffer_pool_pages_free
|
||||
* @param numeric-string $pagesMisc Innodb_buffer_pool_pages_misc
|
||||
* @param numeric-string $pagesTotal Innodb_buffer_pool_pages_total
|
||||
* @param numeric-string $readRequests Innodb_buffer_pool_read_requests
|
||||
* @param numeric-string $reads Innodb_buffer_pool_reads
|
||||
* @param numeric-string $waitFree Innodb_buffer_pool_wait_free
|
||||
* @param numeric-string $writeRequests Innodb_buffer_pool_write_requests
|
||||
* @param numeric-string|null $pagesLatched Innodb_buffer_pool_pages_latched
|
||||
*/
|
||||
public function __construct(
|
||||
public string $innodbPageSize,
|
||||
public string $pagesData,
|
||||
public string $pagesDirty,
|
||||
public string $pagesFlushed,
|
||||
public string $pagesFree,
|
||||
public string $pagesMisc,
|
||||
public string $pagesTotal,
|
||||
public string $readRequests,
|
||||
public string $reads,
|
||||
public string $waitFree,
|
||||
public string $writeRequests,
|
||||
public string|null $pagesLatched,
|
||||
) {
|
||||
}
|
||||
|
||||
/** @param array<string|null> $result */
|
||||
public static function fromResult(array $result): self
|
||||
{
|
||||
return new self(
|
||||
self::getNumeric($result['Innodb_page_size'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_data'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_dirty'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_flushed'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_free'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_misc'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_total'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_read_requests'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_reads'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_wait_free'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_write_requests'] ?? null) ?? '0',
|
||||
self::getNumeric($result['Innodb_buffer_pool_pages_latched'] ?? null),
|
||||
);
|
||||
}
|
||||
|
||||
/** @return numeric-string|null */
|
||||
private static function getNumeric(string|null $value): string|null
|
||||
{
|
||||
return is_numeric($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
116
tests/unit/Engines/Innodb/BufferPoolTest.php
Normal file
116
tests/unit/Engines/Innodb/BufferPoolTest.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Engines\Innodb;
|
||||
|
||||
use PhpMyAdmin\Engines\Innodb\BufferPool;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(BufferPool::class)]
|
||||
final class BufferPoolTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param array<string|null> $result
|
||||
* @param numeric-string $innodbPageSize
|
||||
* @param numeric-string $pagesData
|
||||
* @param numeric-string $pagesDirty
|
||||
* @param numeric-string $pagesFlushed
|
||||
* @param numeric-string $pagesFree
|
||||
* @param numeric-string $pagesMisc
|
||||
* @param numeric-string $pagesTotal
|
||||
* @param numeric-string $readRequests
|
||||
* @param numeric-string $reads
|
||||
* @param numeric-string $waitFree
|
||||
* @param numeric-string $writeRequests
|
||||
* @param numeric-string|null $pagesLatched
|
||||
*/
|
||||
#[DataProvider('resultProvider')]
|
||||
public function testCreateFromResult(
|
||||
array $result,
|
||||
string $innodbPageSize,
|
||||
string $pagesData,
|
||||
string $pagesDirty,
|
||||
string $pagesFlushed,
|
||||
string $pagesFree,
|
||||
string $pagesMisc,
|
||||
string $pagesTotal,
|
||||
string $readRequests,
|
||||
string $reads,
|
||||
string $waitFree,
|
||||
string $writeRequests,
|
||||
string|null $pagesLatched,
|
||||
): void {
|
||||
$bufferPool = BufferPool::fromResult($result);
|
||||
self::assertSame($innodbPageSize, $bufferPool->innodbPageSize);
|
||||
self::assertSame($pagesData, $bufferPool->pagesData);
|
||||
self::assertSame($pagesDirty, $bufferPool->pagesDirty);
|
||||
self::assertSame($pagesFlushed, $bufferPool->pagesFlushed);
|
||||
self::assertSame($pagesFree, $bufferPool->pagesFree);
|
||||
self::assertSame($pagesMisc, $bufferPool->pagesMisc);
|
||||
self::assertSame($pagesTotal, $bufferPool->pagesTotal);
|
||||
self::assertSame($readRequests, $bufferPool->readRequests);
|
||||
self::assertSame($reads, $bufferPool->reads);
|
||||
self::assertSame($waitFree, $bufferPool->waitFree);
|
||||
self::assertSame($writeRequests, $bufferPool->writeRequests);
|
||||
self::assertSame($pagesLatched, $bufferPool->pagesLatched);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<array-key, array{
|
||||
* array<string|null>,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string,
|
||||
* numeric-string|null
|
||||
* }>
|
||||
*/
|
||||
public static function resultProvider(): iterable
|
||||
{
|
||||
yield [[], '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', null];
|
||||
|
||||
$result = [
|
||||
'Innodb_page_size' => '1',
|
||||
'Innodb_buffer_pool_pages_data' => '2',
|
||||
'Innodb_buffer_pool_pages_dirty' => '3',
|
||||
'Innodb_buffer_pool_pages_flushed' => '4',
|
||||
'Innodb_buffer_pool_pages_free' => '5',
|
||||
'Innodb_buffer_pool_pages_misc' => '6',
|
||||
'Innodb_buffer_pool_pages_total' => '7',
|
||||
'Innodb_buffer_pool_read_requests' => '8',
|
||||
'Innodb_buffer_pool_reads' => '9',
|
||||
'Innodb_buffer_pool_wait_free' => '10',
|
||||
'Innodb_buffer_pool_write_requests' => '11',
|
||||
'Innodb_buffer_pool_pages_latched' => '12',
|
||||
];
|
||||
|
||||
yield [$result, '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
|
||||
|
||||
$result = [
|
||||
'Innodb_page_size' => null,
|
||||
'Innodb_buffer_pool_pages_data' => null,
|
||||
'Innodb_buffer_pool_pages_dirty' => null,
|
||||
'Innodb_buffer_pool_pages_flushed' => null,
|
||||
'Innodb_buffer_pool_pages_free' => null,
|
||||
'Innodb_buffer_pool_pages_misc' => null,
|
||||
'Innodb_buffer_pool_pages_total' => null,
|
||||
'Innodb_buffer_pool_read_requests' => null,
|
||||
'Innodb_buffer_pool_reads' => null,
|
||||
'Innodb_buffer_pool_wait_free' => null,
|
||||
'Innodb_buffer_pool_write_requests' => null,
|
||||
'Innodb_buffer_pool_pages_latched' => null,
|
||||
];
|
||||
|
||||
yield [$result, '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', null];
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ use PhpMyAdmin\Dbal\DatabaseInterface;
|
||||
use PhpMyAdmin\Engines\Innodb;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
use function __;
|
||||
|
||||
@ -126,86 +127,183 @@ class InnodbTest extends AbstractTestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for getPageBufferpool
|
||||
* @param list<array{string, string}> $variables
|
||||
* @param list<array{string, string}> $usageTableRows
|
||||
* @param list<array{string, string}> $activityTableRows
|
||||
*/
|
||||
public function testGetPageBufferpool(): void
|
||||
{
|
||||
self::assertSame(
|
||||
'<table class="table table-striped table-hover w-auto float-start caption-top">' . "\n" .
|
||||
' <caption>' . "\n" .
|
||||
' Buffer Pool Usage' . "\n" .
|
||||
' </caption>' . "\n" .
|
||||
' <tfoot>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th colspan="2">' . "\n" .
|
||||
' Total: 4,096 pages / 65,536 KiB' . "\n" .
|
||||
' </th>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' </tfoot>' . "\n" .
|
||||
' <tbody>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Free pages</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Dirty pages</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Pages containing data</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Pages to be flushed</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Busy pages</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr> </tbody>' . "\n" .
|
||||
#[DataProvider('pageBufferPoolProvider')]
|
||||
public function testGetPageBufferPool(
|
||||
array $variables,
|
||||
string $totalPages,
|
||||
string $totalBytes,
|
||||
array $usageTableRows,
|
||||
array $activityTableRows,
|
||||
): void {
|
||||
$dbiDummy = $this->createDbiDummy();
|
||||
$dbiDummy->addResult(
|
||||
"SHOW STATUS WHERE Variable_name LIKE 'Innodb\\_buffer\\_pool\\_%' OR Variable_name = 'Innodb_page_size';",
|
||||
$variables,
|
||||
);
|
||||
DatabaseInterface::$instance = $this->createDatabaseInterface($dbiDummy);
|
||||
|
||||
$pageBufferPool = (new Innodb('innodb'))->getPageBufferPool();
|
||||
$dbiDummy->assertAllQueriesConsumed();
|
||||
|
||||
$expected = '<table class="table table-striped table-hover w-auto float-start caption-top">' . "\n" .
|
||||
' <caption>Buffer pool usage</caption>' . "\n" .
|
||||
' <tbody>' . "\n";
|
||||
|
||||
foreach ($usageTableRows as $tableRow) {
|
||||
$expected .= ' <tr>' . "\n" .
|
||||
' <th scope="row">' . $tableRow[0] . '</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">' . $tableRow[1] . '</td>' . "\n" .
|
||||
' </tr>' . "\n";
|
||||
}
|
||||
|
||||
$expected .= ' </tbody>' . "\n" .
|
||||
' <tfoot>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th colspan="2">' . "\n" .
|
||||
' Total: ' . $totalPages . ' pages / ' . $totalBytes . "\n" .
|
||||
' </th>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' </tfoot>' . "\n" .
|
||||
'</table>' . "\n\n" .
|
||||
'<table class="table table-striped table-hover w-auto ms-4 float-start caption-top">' . "\n" .
|
||||
' <caption>' . "\n" .
|
||||
' Buffer Pool Activity' . "\n" .
|
||||
' </caption>' . "\n" .
|
||||
' <tbody>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Read requests</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">64' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Write requests</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">64' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Read misses</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">32' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Write waits</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Read misses in %</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">50 %' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Write waits in %</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">0 %' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' </tbody>' . "\n" .
|
||||
'</table>' . "\n",
|
||||
$this->object->getPageBufferpool(),
|
||||
);
|
||||
' <caption>Buffer pool activity</caption>' . "\n" .
|
||||
' <tbody>' . "\n";
|
||||
|
||||
foreach ($activityTableRows as $tableRow) {
|
||||
$expected .= ' <tr>' . "\n" .
|
||||
' <th scope="row">' . $tableRow[0] . '</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">' . $tableRow[1] . '</td>' . "\n" .
|
||||
' </tr>' . "\n";
|
||||
}
|
||||
|
||||
$expected .= ' </tbody>' . "\n" . '</table>' . "\n";
|
||||
|
||||
self::assertSame($expected, $pageBufferPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<array-key, array{
|
||||
* list<array{string, string}>,
|
||||
* string,
|
||||
* string,
|
||||
* list<array{string, string}>,
|
||||
* list<array{string, string}>
|
||||
* }>
|
||||
*/
|
||||
public static function pageBufferPoolProvider(): iterable
|
||||
{
|
||||
yield [
|
||||
[
|
||||
['Innodb_buffer_pool_pages_data', '0'],
|
||||
['Innodb_buffer_pool_pages_dirty', '0'],
|
||||
['Innodb_buffer_pool_pages_flushed', '0'],
|
||||
['Innodb_buffer_pool_pages_free', '0'],
|
||||
['Innodb_buffer_pool_pages_misc', '0'],
|
||||
['Innodb_buffer_pool_pages_total', '4096'],
|
||||
['Innodb_buffer_pool_read_ahead_rnd', '0'],
|
||||
['Innodb_buffer_pool_read_ahead', '0'],
|
||||
['Innodb_buffer_pool_read_ahead_evicted', '0'],
|
||||
['Innodb_buffer_pool_read_requests', '64'],
|
||||
['Innodb_buffer_pool_reads', '32'],
|
||||
['Innodb_buffer_pool_wait_free', '0'],
|
||||
['Innodb_buffer_pool_write_requests', '64'],
|
||||
['Innodb_page_size', '16384'],
|
||||
],
|
||||
'4,096',
|
||||
'65,536 KiB',
|
||||
[
|
||||
['Free pages', '0'],
|
||||
['Dirty pages', '0'],
|
||||
['Pages containing data', '0'],
|
||||
['Pages to be flushed', '0'],
|
||||
['Busy pages', '0'],
|
||||
],
|
||||
[
|
||||
['Read requests', '64'],
|
||||
['Write requests', '64'],
|
||||
['Read misses', '32'],
|
||||
['Write waits', '0'],
|
||||
['Read misses in %', '50%'],
|
||||
['Write waits in %', '0%'],
|
||||
],
|
||||
];
|
||||
|
||||
yield [
|
||||
[
|
||||
['Innodb_buffer_pool_pages_data', '0'],
|
||||
['Innodb_buffer_pool_pages_dirty', '0'],
|
||||
['Innodb_buffer_pool_pages_flushed', '0'],
|
||||
['Innodb_buffer_pool_pages_free', '0'],
|
||||
['Innodb_buffer_pool_pages_latched', '0'],
|
||||
['Innodb_buffer_pool_pages_misc', '0'],
|
||||
['Innodb_buffer_pool_pages_total', '4096'],
|
||||
['Innodb_buffer_pool_read_ahead_rnd', '0'],
|
||||
['Innodb_buffer_pool_read_ahead', '0'],
|
||||
['Innodb_buffer_pool_read_ahead_evicted', '0'],
|
||||
['Innodb_buffer_pool_read_requests', '0'],
|
||||
['Innodb_buffer_pool_reads', '32'],
|
||||
['Innodb_buffer_pool_wait_free', '0'],
|
||||
['Innodb_buffer_pool_write_requests', '0'],
|
||||
['Innodb_page_size', '16384'],
|
||||
],
|
||||
'4,096',
|
||||
'65,536 KiB',
|
||||
[
|
||||
['Free pages', '0'],
|
||||
['Dirty pages', '0'],
|
||||
['Pages containing data', '0'],
|
||||
['Pages to be flushed', '0'],
|
||||
['Busy pages', '0'],
|
||||
['Latched pages', '0'],
|
||||
],
|
||||
[
|
||||
['Read requests', '0'],
|
||||
['Write requests', '0'],
|
||||
['Read misses', '32'],
|
||||
['Write waits', '0'],
|
||||
['Read misses in %', '---'],
|
||||
['Write waits in %', '---'],
|
||||
],
|
||||
];
|
||||
|
||||
yield [
|
||||
[
|
||||
['Innodb_buffer_pool_pages_data', '1000'],
|
||||
['Innodb_buffer_pool_pages_dirty', '2000'],
|
||||
['Innodb_buffer_pool_pages_flushed', '3000'],
|
||||
['Innodb_buffer_pool_pages_free', '4000'],
|
||||
['Innodb_buffer_pool_pages_misc', '5000'],
|
||||
['Innodb_buffer_pool_reads', '6000'],
|
||||
['Innodb_buffer_pool_read_requests', '7000'],
|
||||
['Innodb_buffer_pool_wait_free', '8000'],
|
||||
['Innodb_buffer_pool_write_requests', '9000'],
|
||||
['Innodb_buffer_pool_pages_latched', '10000'],
|
||||
['Innodb_page_size', '11000'],
|
||||
['Innodb_buffer_pool_pages_total', '12000'],
|
||||
],
|
||||
'12,000',
|
||||
'129 k KiB',
|
||||
[
|
||||
['Free pages', '4,000'],
|
||||
['Dirty pages', '2,000'],
|
||||
['Pages containing data', '1,000'],
|
||||
['Pages to be flushed', '3,000'],
|
||||
['Busy pages', '5,000'],
|
||||
['Latched pages', '10,000'],
|
||||
],
|
||||
[
|
||||
['Read requests', '7,000'],
|
||||
['Write requests', '9,000'],
|
||||
['Read misses', '6,000'],
|
||||
['Write waits', '8,000'],
|
||||
['Read misses in %', '85.71%'],
|
||||
['Write waits in %', '88.89%'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -400,27 +400,6 @@ class DbiDummy implements DbiExtension
|
||||
['Pbxt', 'NO', 'Pbxt storage engine'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'query' => 'SHOW STATUS WHERE Variable_name'
|
||||
. ' LIKE \'Innodb\\_buffer\\_pool\\_%\''
|
||||
. ' OR Variable_name = \'Innodb_page_size\';',
|
||||
'result' => [
|
||||
['Innodb_buffer_pool_pages_data', 0],
|
||||
['Innodb_buffer_pool_pages_dirty', 0],
|
||||
['Innodb_buffer_pool_pages_flushed', 0],
|
||||
['Innodb_buffer_pool_pages_free', 0],
|
||||
['Innodb_buffer_pool_pages_misc', 0],
|
||||
['Innodb_buffer_pool_pages_total', 4096],
|
||||
['Innodb_buffer_pool_read_ahead_rnd', 0],
|
||||
['Innodb_buffer_pool_read_ahead', 0],
|
||||
['Innodb_buffer_pool_read_ahead_evicted', 0],
|
||||
['Innodb_buffer_pool_read_requests', 64],
|
||||
['Innodb_buffer_pool_reads', 32],
|
||||
['Innodb_buffer_pool_wait_free', 0],
|
||||
['Innodb_buffer_pool_write_requests', 64],
|
||||
['Innodb_page_size', 16384],
|
||||
],
|
||||
],
|
||||
['query' => 'SHOW ENGINE INNODB STATUS;', 'result' => false],
|
||||
['query' => 'SELECT @@innodb_version;', 'result' => [['1.1.8']]],
|
||||
['query' => 'SELECT @@disabled_storage_engines', 'result' => [['']]],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user