MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Automatiser la vérification de la configuration de la base de données

De nombreux administrateurs système négligent généralement l'importance du réglage continu de la configuration de la base de données. Les options de configuration sont souvent configurées ou ajustées une seule fois, pendant la phase d'installation, et laissées de côté jusqu'à ce que des événements indésirables se produisent sur le service de base de données. Ce n'est qu'alors que l'on accordera plus d'attention à revoir les options de configuration et à ajuster les limites, les seuils, les tampons, les caches, etc., dans l'envie de restaurer à nouveau le service de base de données.

Notre objectif dans cet article de blog est d'automatiser le processus de vérification et de validation de la configuration de la base de données. Il s'agit d'un processus important car les options de configuration changent constamment d'une version majeure à l'autre. Un fichier de configuration inchangé pourrait potentiellement contenir des options obsolètes qui ne sont plus prises en charge par la nouvelle version du serveur, ce qui entraîne généralement des problèmes majeurs sur le serveur mis à niveau.

Outils de gestion de configuration

Puppet, Ansible, Chef et SaltStack sont les plus couramment utilisés par DevOps pour la gestion et l'automatisation de la configuration. La gestion de la configuration permet aux utilisateurs de documenter l'environnement, d'améliorer l'efficacité, la gérabilité et la reproductibilité, et fait partie intégrante de l'intégration et du déploiement continus. La plupart des outils de gestion de configuration fournissent un catalogue de modules et de référentiels auxquels d'autres peuvent contribuer, simplifiant la courbe d'apprentissage pour que l'utilisateur de la communauté s'adapte à la technologie.

Bien que les outils de gestion de la configuration soient principalement utilisés pour automatiser le déploiement et l'installation, nous pouvons également effectuer des vérifications de la configuration et l'application dans une approche push-out centralisée. Chacun de ces outils a sa propre façon de modéliser un fichier de configuration. Quant à Puppet, le fichier modèle généralement suffixé par ".erb" et à l'intérieur, nous pouvons définir les options de configuration avec des valeurs pré-formulées.

L'exemple suivant montre un modèle de fichier pour la configuration MySQL :

[mysqld]
thread_concurrency = <%= processorcount.to_i * 2 %>
# Replication
log-bin            = /var/lib/mysql/mysql-bin.log
log-bin-index      = /var/lib/mysql/mysql-bin.index
binlog_format      = mixed
server-id         = <%= @mysql_server_id or 1 %>

# InnoDB
innodb_buffer_pool_size = <%= (memorysizeinbytes.to_i / 2 / 1024 / 1024).to_i -%>M
innodb_log_file_size    = <%= ((memorysizeinbytes.to_i / 2 / 1024 / 1024) * 0.25).to_i -%>M

Comme indiqué ci-dessus, la valeur de configuration peut être une valeur fixe ou calculée dynamiquement. Par conséquent, le résultat final peut être différent selon les spécifications matérielles de l'hôte cible avec d'autres variables prédéfinies. Dans le fichier de définition de Puppet, nous pouvons pousser notre modèle de configuration comme ceci :

# Apply our custom template
file { '/etc/mysql/conf.d/my-custom-config.cnf':
  ensure  => file,
  content => template('mysql/my-custom-config.cnf.erb')
}

Outre la création de modèles, nous pouvons également pousser les valeurs de configuration directement à partir du fichier de définition. Voici un exemple de définition de Puppet pour la configuration de MariaDB 10.5 à l'aide du module Puppet MySQL :

# MariaDB configuration
class {'::mysql::server':
  package_name     => 'mariadb-server',
  service_name     => 'mariadb',
  root_password    => 't5[sb^D[+rt8bBYu',
  manage_config_file => true,
  override_options => {
    mysqld => {
      'bind_address' => '127.0.0.1',
      'max_connections' => '500',
      'log_error' => '/var/log/mysql/mariadb.log',
      'pid_file'  => '/var/run/mysqld/mysqld.pid',
    },
    mysqld_safe => {
      'log_error' => '/var/log/mysql/mariadb.log',
    },
  }
}

L'exemple ci-dessus montre que nous avons utilisé manage_config_file => true avec override_options pour structurer nos lignes de configuration qui seront ensuite poussées par Puppet. Toute modification du fichier manifeste ne reflétera que le contenu du fichier de configuration MySQL cible. Ce module ne chargera pas la configuration dans l'exécution ni ne redémarrera le service MySQL après avoir poussé les modifications dans le fichier de configuration. Il est de la responsabilité de l'administrateur système de redémarrer le service pour activer les modifications.

Pour Puppet et Chef, vérifiez la sortie du journal de l'agent pour voir si les options de configuration sont corrigées. Pour Ansible, regardez simplement la sortie de débogage pour voir si les félicitations sont mises à jour avec succès. L'utilisation d'outils de gestion de configuration peut vous aider à automatiser les vérifications de configuration et à appliquer une approche de configuration centralisée.

interpréteur MySQL

Une vérification d'intégrité est importante avant d'effectuer toute mise à niveau. MySQL Shell a une fonctionnalité très intéressante qui est destinée à exécuter une série de tests pour vérifier si votre installation existante peut être mise à niveau en toute sécurité vers MySQL 8.0, appelée Upgrade Checker Utility. Vous pouvez gagner énormément de temps lors de la préparation d'une mise à niveau. Une mise à niveau majeure, en particulier vers MySQL 8.0, introduit et déconseille de nombreuses options de configuration et présente donc un risque important d'incompatibilité après la mise à niveau.

Cet outil est spécialement conçu pour MySQL (serveur Percona inclus), en particulier lorsque vous souhaitez effectuer une mise à niveau majeure de MySQL 5.7 vers MySQL 8.0. Pour invoquer cet utilitaire, connectez-vous à MySQL Shell et, en tant qu'utilisateur root, spécifiez les informations d'identification, la version cible et le fichier de configuration :

$ mysqlsh
mysql> util.checkForServerUpgrade('[email protected]:3306', {"password":"p4ssw0rd", "targetVersion":"8.0.11", "configPath":"/etc/my.cnf"})

Au bas du rapport, vous obtiendrez le résumé clé :

Errors:   7
Warnings: 36
Notices:  0

7 errors were found. Please correct these issues before upgrading to avoid compatibility issues.

Concentrez-vous d'abord sur la correction de toutes les erreurs, car cela causera des problèmes majeurs après la mise à niveau si aucune action n'est entreprise. Examinez le rapport généré et recherchez tous les problèmes liés à la formulation "Erreur :", par exemple :

15) Removed system variables

  Error: Following system variables that were detected as being used will be
    removed. Please update your system to not rely on them before the upgrade.
  More information: https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html#optvars-removed

  log_builtin_as_identified_by_password - is set and will be removed
  show_compatibility_56 - is set and will be removed

Une fois toutes les erreurs corrigées, essayez de réduire les avertissements autant que possible. Les avertissements n'affecteront généralement pas la fiabilité du serveur MySQL, mais peuvent potentiellement dégrader les performances ou modifier le comportement par rapport à ce qu'ils avaient l'habitude de faire. Par exemple, jetez un œil aux avertissements suivants :

13) System variables with new default values

  Warning: Following system variables that are not defined in your
    configuration file will have new default values. Please review if you rely on
    their current values and if so define them before performing upgrade.
  More information:
    https://mysqlserverteam.com/new-defaults-in-mysql-8-0/

  back_log - default value will change
  character_set_server - default value will change from latin1 to utf8mb4
  collation_server - default value will change from latin1_swedish_ci to
    utf8mb4_0900_ai_ci
  event_scheduler - default value will change from OFF to ON
  explicit_defaults_for_timestamp - default value will change from OFF to ON
  innodb_autoinc_lock_mode - default value will change from 1 (consecutive) to
    2 (interleaved)
  innodb_flush_method - default value will change from NULL to fsync (Unix),
    unbuffered (Windows)
  innodb_flush_neighbors - default value will change from 1 (enable) to 0
    (disable)
  innodb_max_dirty_pages_pct - default value will change from 75 (%)  90 (%)
  innodb_max_dirty_pages_pct_lwm - default value will change from_0 (%) to 10
    (%)
  innodb_undo_log_truncate - default value will change from OFF to ON
  innodb_undo_tablespaces - default value will change from 0 to 2
  log_error_verbosity - default value will change from 3 (Notes) to 2 (Warning)
  max_allowed_packet - default value will change from 4194304 (4MB) to 67108864
    (64MB)
  max_error_count - default value will change from 64 to 1024
  optimizer_trace_max_mem_size - default value will change from 16KB to 1MB
  performance_schema_consumer_events_transactions_current - default value will
    change from OFF to ON
  performance_schema_consumer_events_transactions_history - default value will
    change from OFF to ON
  slave_rows_search_algorithms - default value will change from 'INDEX_SCAN,
    TABLE_SCAN' to 'INDEX_SCAN, HASH_SCAN'
  table_open_cache - default value will change from 2000 to 4000
  transaction_write_set_extraction - default value will change from OFF to
    XXHASH64

Upgrade Checker Utility fournit un aperçu critique de ce à quoi s'attendre et nous évite une énorme surprise après la mise à niveau.

Conseillers ClusterControl

ClusterControl a un certain nombre de mini-programmes internes appelés Advisors, où vous écrivez un petit programme qui vit et s'exécute dans la structure des objets ClusterControl. Vous pouvez le considérer comme une fonction planifiée qui exécute un script créé dans Developer Studio et produit un résultat contenant un statut, des conseils et une justification. Cela permet aux utilisateurs d'étendre facilement les fonctionnalités de ClusterControl en créant des conseillers personnalisés qui peuvent s'exécuter à la demande ou selon un calendrier.

La capture d'écran suivante montre un exemple de conseillers InnoDB appelés innodb_log_file_size check, après avoir été activés et planifiés dans ClusterControl :

Le résultat ci-dessus se trouve sous ClusterControl -> Performance -> Advisors. Pour chaque conseiller, il affiche le statut du conseiller, l'instance de la base de données, la justification et le conseil. Il y a aussi des informations sur le calendrier et la dernière heure d'exécution. Le conseiller peut également être exécuté à la demande en cliquant sur le bouton "Compiler et exécuter" sous Developer Studio.

Les conseillers ci-dessus contenant le code suivant, écrit à l'aide du langage spécifique au domaine (DSL) de ClusterControl, qui est assez similaire à JavaScript :

#include "common/mysql_helper.js"
#include "cmon/graph.h"

var DESCRIPTION="This advisor calculates the InnoDB log growth per hour and"
" compares it with the innodb_log_file_size configured on the host and"
" notifies you if the InnoDB log growth is higher than what is configured, which is important to avoid IO spikes during flushing.";
var TITLE="Innodb_log_file_size check";
var MINUTES = 20;


function main()
{
    var hosts     = cluster::mySqlNodes();
    var advisorMap = {};
    for (idx = 0; idx < hosts.size(); ++idx)
    {
        host        = hosts[idx];
        map         = host.toMap();
        connected     = map["connected"];
        var advice = new CmonAdvice();
        print("   ");
        print(host);
        print("==========================");
        if (!connected)
        {
            print("Not connected");
            continue;
        }
        if (checkPrecond(host))
        {
            var configured_logfile_sz = host.sqlSystemVariable("innodb_log_file_size");
            var configured_logfile_grps = host.sqlSystemVariable("innodb_log_files_in_group");
            if (configured_logfile_sz.isError() || configured_logfile_grps.isError())
            {
                justification = "";
                msg = "Not enough data to calculate";
                advice.setTitle(TITLE);
                advice.setJustification("");
                advice.setAdvice(msg);
                advice.setHost(host);
                advice.setSeverity(Ok);
                advisorMap[idx]= advice;
                continue;
            }
            var endTime   = CmonDateTime::currentDateTime();
            var startTime = endTime - MINUTES * 60 /*seconds*/;
            var stats     = host.sqlStats(startTime, endTime);
            var array     = stats.toArray("created,interval,INNODB_LSN_CURRENT");

            if(array[2,0] === #N/A  || array[2,0] == "")
            {
                /* Not all vendors have INNODB_LSN_CURRENT*/
                advice.setTitle(TITLE);
                advice.setJustification("INNODB_LSN_CURRENT does not exists in"
                                        " this MySQL release.");
                advice.setAdvice("Nothing to do.");
                advice.setHost(host);
                advice.setSeverity(Ok);
                advisorMap[idx]= advice;
                continue;
            }
            var firstLSN = array[2,0].toULongLong();
            var latestLSN = array[2,array.columns()-1].toULongLong();
            var intervalSecs = endTime.toULongLong() - startTime.toULongLong();
            var logGrowthPerHourMB = ceiling((latestLSN - firstLSN) * 3600 / 1024/1024 / intervalSecs / configured_logfile_grps);
            var logConfiguredMB =  configured_logfile_sz/1024/1024;
            if (logGrowthPerHourMB > logConfiguredMB)
            {
                justification = "Innodb is producing " + logGrowthPerHourMB + "MB/hour, and it greater than"
                " the configured innodb log file size " + logConfiguredMB + "MB."
                " You should set innodb_log_file_size to a value greater than " +
                    logGrowthPerHourMB + "MB. To change"
                " it you must stop the MySQL Server and remove the existing ib_logfileX,"
                " and start the server again. Check the MySQL reference manual for max/min values. "
                "https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_log_file_size";
                msg = "You are recommended to increase the innodb_log_file_size to avoid i/o spikes"
                " during flushing.";
                advice.setSeverity(Warning);
            }
            else
            {
                justification = "Innodb_log_file_size is set to " + logConfiguredMB +
                    "MB and is greater than the log produced per hour: " +
                    logGrowthPerHourMB + "MB.";
                msg = "Innodb_log_file_size is sized sufficiently.";
                advice.setSeverity(Ok);
            }
        }
        else
        {
            justification = "Server uptime and load is too low.";
            msg = "Not enough data to calculate";
            advice.setSeverity(0);
        }
        advice.setHost(host);
        advice.setTitle(TITLE);
        advice.setJustification(justification);
        advice.setAdvice(msg);
        advisorMap[idx]= advice;
        print(advice.toString("%E"));
    }
    return advisorMap;
}

ClusterControl fournit un environnement de développement intégré (IDE) prêt à l'emploi appelé Developer Studio (accessible sous Gérer -> Developer Studio) pour écrire, compiler, enregistrer, déboguer et planifier l'Advisor :

Avec Developer Studio et Advisors, les utilisateurs n'ont aucune limite dans l'extension des fonctionnalités de surveillance et de gestion de ClusterControl. C'est littéralement l'outil parfait pour automatiser la vérification de la configuration de tous vos logiciels de base de données open source comme MySQL, MariaDB, PostgreSQL et MongoDB, ainsi que les équilibreurs de charge comme HAProxy, ProxySQL, MaxScale et PgBouncer. Vous pouvez même écrire un conseiller pour utiliser l'utilitaire MySQL Shell Upgrade Checker, comme indiqué dans le chapitre précédent.

Réflexions finales

La vérification et le réglage de la configuration sont des éléments importants de la routine DBA et SysAdmin pour garantir que les systèmes critiques tels que la base de données et les proxys inverses sont toujours pertinents et optimaux à mesure que vos charges de travail augmentent.