new: mysql db tuning recommendations in server diagnostics

pull/8500/head
Luciano Righetti 2022-07-19 13:36:53 +02:00
parent 44f7418b0d
commit b4fb6251ce
No known key found for this signature in database
GPG Key ID: CB91F2A37C557248
4 changed files with 142 additions and 1 deletions

View File

@ -1146,6 +1146,7 @@ class ServersController extends AppController
// get the DB diagnostics
$dbDiagnostics = $this->Server->dbSpaceUsage();
$dbSchemaDiagnostics = $this->Server->dbSchemaDiagnostic();
$dbConfiguration = $this->Server->dbConfiguration();
$redisInfo = $this->Server->redisInfo();
@ -1166,7 +1167,7 @@ class ServersController extends AppController
$securityAudit = (new SecurityAudit())->run($this->Server);
$view = compact('gpgStatus', 'sessionErrors', 'proxyStatus', 'sessionStatus', 'zmqStatus', 'moduleStatus', 'yaraStatus', 'gpgErrors', 'proxyErrors', 'zmqErrors', 'stix', 'moduleErrors', 'moduleTypes', 'dbDiagnostics', 'dbSchemaDiagnostics', 'redisInfo', 'attachmentScan', 'securityAudit');
$view = compact('gpgStatus', 'sessionErrors', 'proxyStatus', 'sessionStatus', 'zmqStatus', 'moduleStatus', 'yaraStatus', 'gpgErrors', 'proxyErrors', 'zmqErrors', 'stix', 'moduleErrors', 'moduleTypes', 'dbDiagnostics', 'dbSchemaDiagnostics', 'dbConfiguration', 'redisInfo', 'attachmentScan', 'securityAudit');
} else {
$view = [];
}
@ -1207,6 +1208,7 @@ class ServersController extends AppController
'readableFiles' => $readableFiles,
'dbDiagnostics' => $dbDiagnostics,
'dbSchemaDiagnostics' => $dbSchemaDiagnostics,
'dbConfiguration' => $dbConfiguration,
'redisInfo' => $redisInfo,
'finalSettings' => $dumpResults,
'extensions' => $extensions,
@ -2205,6 +2207,17 @@ class ServersController extends AppController
}
}
public function dbConfiguration()
{
$dbConfiguration = $this->Server->dbConfiguration();
if ($this->_isRest()) {
return $this->RestResponse->viewData($dbConfiguration, $this->response->type());
} else {
$this->set('dbConfiguration', $dbConfiguration);
$this->render('/Elements/healthElements/db_config_diagnostic');
}
}
public function cspReport()
{
if (!$this->request->is('post')) {

View File

@ -132,6 +132,59 @@ class Server extends AppModel
public $syncTestErrorCodes = array();
const MYSQL_RECOMMENDED_SETTINGS = [
'INNODB_BUFFER_POOL_SIZE' => [
'default' => '134217728',
'recommended' => '2147483648',
'explanation' => 'The InnoDB buffer pool is the memory area where caches table and index data reside. It is the most important MySQL setting, in a dedicated server it should be around 3/4 of all the available RAM. In a shared server it should be around 1/2 of the available RAM.',
],
'INNODB_DEDICATED_SERVER' => [
'default' => '0',
'recommended' => '',
'explanation' => 'Set to `1` if the database is running in a dedicated server. The database engine will examine the available memory and dynamically set `innodb_buffer_pool_size`, `innodb_log_file_size`, `innodb_log_files_in_group` and `innodb_flush_method`. It is particularly useful in cloud enviroments that can be auto-scaled.',
],
'INNODB_LOG_FILE_SIZE' => [
'default' => '100663296',
'recommended' => '629145600',
'explanation' => 'This parameter determines the fixed size for MySQLs redo logs. Tuning this value affects the crash recovery time and also overall system performance.',
],
'INNODB_LOG_FILES_IN_GROUP' => [
'default' => '2',
'recommended' => '2',
'explanation' => 'Defines the number of log files in the log group.',
],
'INNODB_CHANGE_BUFFERING' => [
'default' => 'none',
'recommended' => 'none',
'explanation' => 'Whether InnoDB performs change buffering, an optimization that delays write operations to secondary indexes so that the I/O operations can be performed sequentially, enabling it causes extremely long shutdown times for upgrades.',
],
'INNODB_IO_CAPACITY' => [
'default' => '200',
'recommended' => '1000',
'explanation' => 'Defines the number of I/O operations per second (IOPS) available to InnoDB background tasks, such as flushing pages from the buffer pool and merging data from the change buffer.',
],
'INNODB_IO_CAPACITY_MAX' => [
'default' => '2000',
'recommended' => '2000',
'explanation' => 'If flushing activity falls behind, InnoDB can flush more aggressively, at a higher rate of I/O operations per second (IOPS) than defined by the `innodb_io_capacity variable`.',
],
'INNODB_STATS_PERSISTENT' => [
'default' => 'ON',
'recommended' => 'ON',
'explanation' => 'Specifies whether InnoDB index statistics are persisted to disk. Otherwise, statistics may be recalculated frequently which can lead to variations in query execution plans.',
],
'INNODB_READ_IO_THREADS' => [
'default' => '4',
'recommended' => '16',
'explanation' => 'The number of I/O threads for read operations in InnoDB.',
],
'INNODB_WRITE_IO_THREADS' => [
'default' => '4',
'recommended' => '4',
'explanation' => 'The number of I/O threads for write operations in InnoDB.',
],
];
public function __construct($id = false, $table = null, $ds = null)
{
parent::__construct($id, $table, $ds);
@ -2717,6 +2770,35 @@ class Server extends AppModel
return $schemaDiagnostic;
}
/*
* Get RDBMS configuration values
*/
public function dbConfiguration(): array
{
if ($this->isMysql()) {
$configuration = [];
$dbVariables = $this->query("SELECT VARIABLE_NAME, VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES;");
$settings = array_keys(self::MYSQL_RECOMMENDED_SETTINGS);
foreach ($dbVariables as $dbVariable) {
if (in_array($dbVariable['GLOBAL_VARIABLES']['VARIABLE_NAME'], $settings)) {
$configuration[] = [
'name' => $dbVariable['GLOBAL_VARIABLES']['VARIABLE_NAME'],
'value' => $dbVariable['GLOBAL_VARIABLES']['VARIABLE_VALUE'],
'default' => self::MYSQL_RECOMMENDED_SETTINGS[$dbVariable['GLOBAL_VARIABLES']['VARIABLE_NAME']]['default'],
'recommended' => self::MYSQL_RECOMMENDED_SETTINGS[$dbVariable['GLOBAL_VARIABLES']['VARIABLE_NAME']]['recommended'],
'explanation' => self::MYSQL_RECOMMENDED_SETTINGS[$dbVariable['GLOBAL_VARIABLES']['VARIABLE_NAME']]['explanation'],
];
}
}
return $configuration;
} else {
return [];
}
}
/*
* Work in progress, still needs DEFAULT in the schema for it to work correctly
* Currently only works for missing_column and column_different

View File

@ -0,0 +1,40 @@
<div>
<?= $this->element('/genericElements/IndexTable/index_table', array(
'data' => array(
'data' => $dbConfiguration,
'skip_pagination' => 1,
'fields' => array(
array(
'name' => __('Setting'),
'data_path' => 'name'
),
array(
'name' => __('Default'),
'class' => 'align-left',
'header_class' => 'align-left',
'data_path' => 'default'
),
array(
'name' => __('Current'),
'class' => 'align-left',
'header_class' => 'align-left',
'data_path' => 'value',
),
array(
'name' => __('Recommended'),
'class' => 'align-left',
'header_class' => 'align-left',
'data_path' => 'recommended'
),
array(
'name' => __('Explanation'),
'header_class' => 'align-left',
'data_path' => 'explanation'
),
),
'title' => __('SQL database configuration'),
'description' => __('Best practices for configuring RDBMS parameters for performance.'),
)
));
?>
</div>

View File

@ -281,6 +281,12 @@
)); ?>
</div>
<?php if (!empty($dbConfiguration)): ?>
<?= $this->element('/healthElements/db_config_diagnostic', array(
'dbConfiguration' => $dbConfiguration
)); ?>
<?php endif; ?>
<h3><?= __("Redis info") ?></h3>
<div class="diagnostics-box">
<b><?= __('PHP extension version') ?>:</b> <?= $redisInfo['extensionVersion'] ?: ('<span class="red bold">' . __('Not installed.') . '</span>') ?><br>