MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Automatizza il controllo della configurazione del database

Molti amministratori di sistema trascurano comunemente l'importanza dell'ottimizzazione continua della configurazione del database. Le opzioni di configurazione vengono spesso configurate o ottimizzate una volta, durante la fase di installazione, e vengono omesse fino a quando non si verificano eventi indesiderati nel servizio database. Solo allora, si potrebbe prestare maggiore attenzione per rivisitare le opzioni di configurazione e ottimizzare i limiti, le soglie, i buffer, le cache, ecc., nell'urgenza di ripristinare nuovamente il servizio di database.

Il nostro obiettivo in questo post del blog è automatizzare il controllo della configurazione del database e il processo di convalida. Questo è un processo importante perché le opzioni di configurazione cambiano continuamente nelle versioni principali. Un file di configurazione invariato potrebbe potenzialmente avere opzioni obsolete che non sono più supportate dalla versione più recente del server, il che in genere causa alcuni problemi importanti al server aggiornato.

Strumenti di gestione della configurazione

Puppet, Ansible, Chef e SaltStack sono più comunemente usati da DevOps per la gestione della configurazione e l'automazione. La gestione della configurazione consente agli utenti di documentare l'ambiente, migliorare l'efficienza, la gestibilità e la riproducibilità ed è parte integrante dell'integrazione e della distribuzione continue. La maggior parte degli strumenti di gestione della configurazione fornisce un catalogo di moduli e repository a cui altri possono contribuire, semplificando la curva di apprendimento dell'utente della comunità per adattarsi alla tecnologia.

Sebbene gli strumenti di gestione della configurazione siano utilizzati principalmente per automatizzare la distribuzione e l'installazione, possiamo anche eseguire controlli e imposizione della configurazione in un approccio push-out centralizzato. Ciascuno di questi strumenti ha il proprio modo di modellare un file di configurazione. Come per Puppet, il file template comunemente suffisso ".erb" e al suo interno possiamo definire le opzioni di configurazione insieme a valori pre-formulati.

L'esempio seguente mostra un file modello per la configurazione di 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

Come mostrato sopra, il valore di configurazione può essere un valore fisso o calcolato dinamicamente. Pertanto, il risultato finale può essere diverso in base alle specifiche hardware dell'host di destinazione con altre variabili predefinite. Nel file di definizione del pupazzo, possiamo eseguire il push del nostro modello di configurazione in questo modo:

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

Oltre alla creazione di modelli, possiamo anche inviare i valori di configurazione direttamente dal file di definizione. Quello che segue è un esempio di definizione Puppet per la configurazione di MariaDB 10.5 utilizzando il modulo 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'esempio sopra mostra che abbiamo usato manage_config_file => true con override_options per strutturare le nostre linee di configurazione che in seguito verranno eliminate da Puppet. Qualsiasi modifica al file manifest rifletterà solo il contenuto del file di configurazione MySQL di destinazione. Questo modulo non caricherà la configurazione in runtime né riavvierà il servizio MySQL dopo aver inserito le modifiche nel file di configurazione. È responsabilità dell'amministratore di sistema riavviare il servizio per attivare le modifiche.

Per Puppet e Chef, controlla l'output del registro dell'agente per vedere se le opzioni di configurazione sono corrette. Per Ansible, guarda semplicemente l'output del debug per vedere se i complimenti sono stati aggiornati correttamente. L'utilizzo degli strumenti di gestione della configurazione può aiutarti ad automatizzare i controlli di configurazione e ad applicare un approccio di configurazione centralizzato.

Shell MySQL

Un controllo di integrità è importante prima di eseguire qualsiasi aggiornamento. MySQL Shell ha una caratteristica molto interessante che ha lo scopo di eseguire una serie di test per verificare se l'installazione esistente è sicura per l'aggiornamento a MySQL 8.0, chiamata Upgrade Checker Utility. Puoi risparmiare un'enorme quantità di tempo quando ti prepari per un aggiornamento. Un importante aggiornamento, in particolare a MySQL 8.0, introduce e depreca molte opzioni di configurazione e quindi presenta un grosso rischio di incompatibilità dopo l'aggiornamento.

Questo strumento è progettato specificamente per MySQL (incluso Percona Server), soprattutto quando si desidera eseguire un aggiornamento importante da MySQL 5.7 a MySQL 8.0. Per invocare questa utility, connettiti con MySQL Shell e, come utente root, specifica le credenziali, la versione di destinazione e il file di configurazione:

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

In fondo al rapporto, otterrai il riepilogo chiave:

Errors:   7
Warnings: 36
Notices:  0

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

Concentrati prima sulla correzione di tutti gli errori, perché ciò causerà gravi problemi dopo l'aggiornamento se non viene eseguita alcuna azione. Dai un'occhiata al rapporto generato e trova tutti i problemi con la dicitura "Errore:" in linea, ad esempio:

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

Una volta che tutti gli errori sono stati corretti, prova a ridurre gli avvisi il più possibile. Gli avvisi per lo più non influiranno sull'affidabilità del server MySQL, ma possono potenzialmente degradare le prestazioni o modificare il comportamento rispetto a prima. Ad esempio, dai un'occhiata ai seguenti avvisi:

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 fornisce una panoramica critica di cosa aspettarsi e ci evita un'enorme sorpresa dopo l'aggiornamento.

Consulenti ClusterControl

ClusterControl ha una serie di mini-programmi interni chiamati Advisors, in cui si scrive un piccolo programma che vive ed esegue all'interno della struttura degli oggetti ClusterControl. Puoi pensarla come una funzione pianificata che esegue uno script creato in Developer Studio e produce un risultato contenente stato, consigli e giustificazione. Ciò consente agli utenti di estendere facilmente la funzionalità di ClusterControl creando advisor personalizzati che possono essere eseguiti su richiesta o in base a una pianificazione.

Lo screenshot seguente mostra un esempio di InnoDB Advisor chiamato innodb_log_file_size check, dopo essere stato attivato e programmato all'interno di ClusterControl:

Il risultato sopra può essere trovato in ClusterControl -> Performance -> Advisors. Per ogni Advisor, mostra lo stato dell'advisor, l'istanza del database, la giustificazione e il consiglio. Ci sono anche informazioni sulla pianificazione e l'ultima ora di esecuzione. L'advisor può anche essere eseguito su richiesta facendo clic sul pulsante "Compila ed esegui" in Developer Studio.

Gli advisor di cui sopra contengono il codice seguente, scritto utilizzando ClusterControl Domain-Specific Language (DSL) che è abbastanza simile a 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 fornisce un ambiente di sviluppo integrato (IDE) pronto all'uso chiamato Developer Studio (accessibile in Gestisci -> Developer Studio) per scrivere, compilare, salvare, eseguire il debug e pianificare l'Advisor:

Con Developer Studio e Advisors, gli utenti non hanno limiti nell'estendere le funzionalità di monitoraggio e gestione di ClusterControl. È letteralmente lo strumento perfetto per automatizzare il controllo della configurazione per tutti i software di database open source come MySQL, MariaDB, PostgreSQL e MongoDB, nonché per i sistemi di bilanciamento del carico come HAProxy, ProxySQL, MaxScale e PgBouncer. Puoi anche scrivere un Advisor per utilizzare l'utility MySQL Shell Upgrade Checker, come mostrato nel capitolo precedente.

Pensieri finali

Il controllo e l'ottimizzazione della configurazione sono parti importanti della routine DBA e SysAdmin per garantire che i sistemi critici come database e proxy inversi siano sempre pertinenti e ottimali man mano che i carichi di lavoro crescono.