MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Prüfung der Datenbankkonfiguration automatisieren

Viele Systemadministratoren übersehen häufig die Bedeutung der laufenden Feinabstimmung der Datenbankkonfiguration. Konfigurationsoptionen werden häufig während der Installationsphase einmal konfiguriert oder optimiert und dann ausgelassen, bis einige unerwünschte Ereignisse für den Datenbankdienst auftreten. Nur dann würde man mehr Aufmerksamkeit darauf verwenden, die Konfigurationsoptionen erneut zu besuchen und die Grenzen, Schwellenwerte, Puffer, Caches usw. zu optimieren, in dem Drang, den Datenbankdienst wieder wiederherzustellen.

Unser Fokus in diesem Blogpost liegt auf der Automatisierung der Datenbankkonfigurationsprüfung und des Validierungsprozesses. Dies ist ein wichtiger Prozess, da sich die Konfigurationsoptionen in den Hauptversionen ständig ändern. Eine unveränderte Konfigurationsdatei könnte möglicherweise veraltete Optionen enthalten, die von der neueren Serverversion nicht mehr unterstützt werden, was häufig zu einigen größeren Problemen auf dem aktualisierten Server führt.

Konfigurationsverwaltungstools

Puppet, Ansible, Chef und SaltStack werden am häufigsten von DevOps für das Konfigurationsmanagement und die Automatisierung verwendet. Das Konfigurationsmanagement ermöglicht es Benutzern, die Umgebung zu dokumentieren, die Effizienz, Verwaltbarkeit und Reproduzierbarkeit zu verbessern und ist ein integraler Bestandteil der kontinuierlichen Integration und Bereitstellung. Die meisten Konfigurationsmanagement-Tools bieten einen Katalog von Modulen und Repositories, zu denen andere beitragen können, wodurch die Lernkurve für Community-Benutzer vereinfacht wird, um sich an die Technologie anzupassen.

Obwohl Konfigurationsmanagement-Tools hauptsächlich zur Automatisierung von Bereitstellung und Installation verwendet werden, können wir Konfigurationsprüfungen und -durchsetzung auch in einem zentralisierten Push-out-Ansatz durchführen. Jedes dieser Tools hat seine eigene Art, eine Konfigurationsdatei zu erstellen. Wie bei Puppet, der Vorlagendatei mit der Endung „.erb“, können wir die Konfigurationsoptionen zusammen mit vorformulierten Werten definieren.

Das folgende Beispiel zeigt eine Vorlagendatei für die MySQL-Konfiguration:

[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

Wie oben gezeigt, kann der Konfigurationswert ein fester Wert sein oder dynamisch berechnet werden. Daher kann das Endergebnis je nach Hardwarespezifikation des Zielhosts mit anderen vordefinierten Variablen unterschiedlich sein. In der Puppet-Definitionsdatei können wir unsere Konfigurationsvorlage wie folgt pushen:

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

Anders als Templating können wir die Konfigurationswerte auch direkt aus der Definitionsdatei pushen. Das Folgende ist ein Beispiel einer Puppet-Definition für die MariaDB 10.5-Konfiguration mit dem Puppet-MySQL-Modul:

# 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',
    },
  }
}

Das obige Beispiel zeigt, dass wir manage_config_file => true mit override_options verwendet haben, um unsere Konfigurationszeilen zu strukturieren, die später von Puppet ausgegeben werden. Jede Änderung an der Manifestdatei spiegelt nur den Inhalt der Ziel-MySQL-Konfigurationsdatei wider. Dieses Modul lädt weder die Konfiguration in die Laufzeit noch startet es den MySQL-Dienst neu, nachdem es die Änderungen in die Konfigurationsdatei gepusht hat. Es liegt in der Verantwortung des SysAdmin, den Dienst neu zu starten, um die Änderungen zu aktivieren.

Überprüfen Sie für Puppet und Chef die Ausgabe des Agentenprotokolls, um festzustellen, ob die Konfigurationsoptionen korrigiert wurden. Sehen Sie sich für Ansible einfach die Debugging-Ausgabe an, um zu sehen, ob die Glückwünsche erfolgreich aktualisiert wurden. Die Verwendung von Konfigurationsverwaltungstools kann Ihnen dabei helfen, Konfigurationsprüfungen zu automatisieren und einen zentralisierten Konfigurationsansatz durchzusetzen.

MySQL-Shell

Eine Plausibilitätsprüfung ist wichtig, bevor Sie ein Upgrade durchführen. MySQL Shell hat eine sehr coole Funktion, die eine Reihe von Tests ausführen soll, um zu überprüfen, ob Ihre vorhandene Installation sicher auf MySQL 8.0 aktualisiert werden kann, das sogenannte Upgrade Checker Utility. Bei der Vorbereitung auf ein Upgrade können Sie enorm viel Zeit sparen. Ein größeres Upgrade, insbesondere auf MySQL 8.0, führt viele Konfigurationsoptionen ein und verwirft sie und birgt daher ein großes Risiko für Inkompatibilität nach dem Upgrade.

Dieses Tool wurde speziell für MySQL entwickelt (einschließlich Percona Server), insbesondere wenn Sie ein größeres Upgrade von MySQL 5.7 auf MySQL 8.0 durchführen möchten. Um dieses Dienstprogramm aufzurufen, verbinden Sie sich mit MySQL Shell und geben Sie als Root-Benutzer die Anmeldeinformationen, die Zielversion und die Konfigurationsdatei an:

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

Am Ende des Berichts erhalten Sie die Schlüsselzusammenfassung:

Errors:   7
Warnings: 36
Notices:  0

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

Konzentrieren Sie sich zuerst darauf, alle Fehler zu beheben, da dies nach dem Upgrade zu großen Problemen führen wird, wenn keine Maßnahmen ergriffen werden. Sehen Sie sich den generierten Bericht noch einmal an und finden Sie alle Probleme mit dem Wortlaut „Error:“ inline, zum Beispiel:

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

Sobald alle Fehler behoben sind, versuchen Sie, die Warnungen so weit wie möglich zu reduzieren. Die Warnungen wirken sich meistens nicht auf die Zuverlässigkeit des MySQL-Servers aus, können aber möglicherweise die Leistung beeinträchtigen oder das Verhalten gegenüber früher ändern. Sehen Sie sich zum Beispiel die folgenden Warnungen an:

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 bietet einen kritischen Überblick darüber, was zu erwarten ist, und bewahrt uns vor einer großen Überraschung nach dem Upgrade.

ClusterControl-Berater

ClusterControl hat eine Reihe von internen Miniprogrammen namens Advisors, in denen Sie ein kleines Programm schreiben, das innerhalb der Struktur der ClusterControl-Objekte lebt und ausgeführt wird. Sie können es sich als eine geplante Funktion vorstellen, die ein in Developer Studio erstelltes Skript ausführt und ein Ergebnis erzeugt, das Status, Ratschläge und Begründungen enthält. Auf diese Weise können Benutzer die Funktionalität von ClusterControl einfach erweitern, indem sie benutzerdefinierte Berater erstellen, die bei Bedarf oder nach Zeitplan ausgeführt werden können.

Der folgende Screenshot zeigt ein Beispiel für InnoDB Advisors namens innodb_log_file_size check, nachdem sie innerhalb von ClusterControl aktiviert und geplant wurden:

Das obige Ergebnis finden Sie unter ClusterControl -> Performance -> Advisors. Für jeden Berater werden der Status des Beraters, die Datenbankinstanz, die Begründung und der Rat angezeigt. Es gibt auch Informationen über den Zeitplan und die letzte Ausführungszeit. Der Advisor kann auch bei Bedarf ausgeführt werden, indem Sie auf die Schaltfläche "Compile and Run" unter Developer Studio klicken.

Die obigen Ratgeber enthalten den folgenden Code, der mit ClusterControl Domain-Specific Language (DSL) geschrieben wurde, was JavaScript ziemlich ähnlich ist:

#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 bietet eine sofort einsatzbereite integrierte Entwicklungsumgebung (IDE) namens Developer Studio (zugänglich unter Verwalten -> Developer Studio), um den Advisor zu schreiben, zu kompilieren, zu speichern, zu debuggen und zu planen:

Mit Developer Studio und Advisors haben Benutzer keine Grenzen bei der Erweiterung der Überwachungs- und Verwaltungsfunktionen von ClusterControl. Es ist buchstäblich das perfekte Tool, um die Konfigurationsprüfung für all Ihre Open-Source-Datenbanksoftware wie MySQL, MariaDB, PostgreSQL und MongoDB sowie die Load Balancer wie HAProxy, ProxySQL, MaxScale und PgBouncer zu automatisieren. Sie können sogar einen Advisor schreiben, um das MySQL Shell Upgrade Checker Utility zu nutzen, wie im vorherigen Kapitel gezeigt.

Abschließende Gedanken

Konfigurationsprüfung und -optimierung sind wichtige Teile der DBA- und SysAdmin-Routine, um sicherzustellen, dass kritische Systeme wie Datenbank- und Reverse-Proxys immer relevant und optimal sind, wenn Ihre Workloads wachsen.