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

Automatiser tjek af databasekonfiguration

Mange systemadministratorer overser almindeligvis vigtigheden af ​​løbende justering af databasekonfiguration. Konfigurationsmuligheder bliver ofte konfigureret eller justeret én gang i installationsfasen og udeladt, indtil der opstår uønskede hændelser i databasetjenesten. Først da ville man være mere opmærksom på at genbesøge konfigurationsmulighederne og justere grænserne, tærsklerne, bufferne, caches osv. i trangen til at gendanne databasetjenesten igen.

Vores fokus i dette blogindlæg er at automatisere tjek og validering af databasekonfigurationen. Dette er en vigtig proces, fordi konfigurationsmulighederne altid ændrer sig på tværs af større versioner. En uændret konfigurationsfil kan potentielt have forældede indstillinger, der ikke længere understøttes af den nyere serverversion, hvilket ofte forårsager nogle store problemer med den opgraderede server.

Konfigurationsstyringsværktøjer

Puppet, Ansible, Chef og SaltStack bruges oftest af DevOps til konfigurationsstyring og automatisering. Konfigurationsstyring giver brugerne mulighed for at dokumentere miljøet, forbedre effektiviteten, håndterbarheden og reproducerbarheden og en integreret del af kontinuerlig integration og implementering. De fleste af konfigurationsstyringsværktøjerne giver et katalog over moduler og arkiver, som andre kan bidrage med, hvilket forenkler indlæringskurven for fællesskabsbrugeren til at tilpasse sig teknologien.

Selvom konfigurationsstyringsværktøjer for det meste bruges til at automatisere implementering og installation, kan vi også udføre konfigurationstjek og håndhævelse i en centraliseret push-out tilgang. Hvert af disse værktøjer har sin egen måde at skabe en konfigurationsfil på. Med hensyn til Puppet, skabelonfilen almindeligvis suffikset med ".erb", og inde i den, kan vi definere konfigurationsmulighederne sammen med præ-formulerede værdier.

Det følgende eksempel viser en skabelonfil til 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

Som vist ovenfor kan konfigurationsværdien være en fast værdi eller dynamisk beregnet. Derfor kan slutresultatet være anderledes i henhold til målværtens hardwarespecifikation med andre foruddefinerede variabler. I Puppet-definitionsfilen kan vi skubbe vores konfigurationsskabelon sådan her:

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

Udover at skabe skabeloner kan vi også skubbe konfigurationsværdierne direkte fra definitionsfilen. Følgende er et eksempel på Puppet-definition til MariaDB 10.5-konfiguration ved hjælp af 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',
    },
  }
}

Ovenstående eksempel viser, at vi brugte manage_config_file => true med override_options til at strukturere vores konfigurationslinjer, som senere vil blive skubbet ud af Puppet. Enhver ændring af manifestfilen vil kun afspejle indholdet af MySQL-målkonfigurationsfilen. Dette modul vil hverken indlæse konfigurationen i runtime eller genstarte MySQL-tjenesten efter at have skubbet ændringerne ind i konfigurationsfilen. Det er SysAdmins ansvar at genstarte tjenesten for at aktivere ændringerne.

For Puppet and Chef, tjek outputtet af agentloggen for at se, om konfigurationsmulighederne er rettet. For Ansible skal du blot se på fejlfindingsoutputtet for at se, om lykønskningen er blevet opdateret. Brug af værktøjer til konfigurationsadministration kan hjælpe dig med at automatisere konfigurationstjek og gennemtvinge en centraliseret konfigurationstilgang.

MySQL Shell

Et fornuftstjek er vigtigt, før du udfører en opgradering. MySQL Shell har en meget cool funktion, der er beregnet til at køre en række tests for at verificere, om din eksisterende installation er sikker at opgradere til MySQL 8.0, kaldet Upgrade Checker Utility. Du kan spare enormt meget tid, når du forbereder dig på en opgradering. En større opgradering, især til MySQL 8.0, introducerer og fraskriver mange konfigurationsmuligheder og har derfor en stor risiko for inkompatibilitet efter opgraderingen.

Dette værktøj er specielt designet til MySQL (Percona Server inkluderet), især når du ønsker at udføre en større opgradering fra MySQL 5.7 til MySQL 8.0. For at starte dette værktøj skal du oprette forbindelse til MySQL Shell og som root-bruger angive legitimationsoplysningerne, målversionen og konfigurationsfilen:

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

Nederst i rapporten får du nøgleoversigten:

Errors:   7
Warnings: 36
Notices:  0

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

Fokuser på at rette alle fejlene først, fordi dette vil forårsage store problemer efter opgraderingen, hvis der ikke foretages nogen handling. Tag et kig tilbage på den genererede rapport og find alle problemer med "Fejl:" ordlyden inline, for eksempel:

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

Når alle fejlene er rettet, så prøv at reducere advarslerne, som det er muligt. Advarslerne vil for det meste ikke påvirke pålideligheden af ​​MySQL-serveren, men kan potentielt forringe ydeevnen eller ændret adfærd, end de plejede. Tag for eksempel et kig på følgende advarsler:

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 giver et kritisk overblik over, hvad vi kan forvente og afværger os fra en kæmpe overraskelse efter opgraderingen.

ClusterControl Advisors

ClusterControl har en række interne miniprogrammer kaldet Advisors, hvor man skriver et lille program, der lever og kører inden for strukturen af ​​ClusterControl objekterne. Du kan tænke på det som en planlagt funktion, der udfører et script oprettet i Developer Studio og producerer et resultat, der indeholder status, råd og begrundelse. Dette giver brugerne mulighed for nemt at udvide funktionaliteten af ​​ClusterControl ved at oprette tilpassede rådgivere, der kan køre on-demand eller efter en tidsplan.

Følgende skærmbillede viser et eksempel på InnoDB Advisors kaldet innodb_log_file_size check, efter at være blevet aktiveret og planlagt i ClusterControl:

Ovenstående resultat kan findes under ClusterControl -> Performance -> Advisors. For hver rådgiver viser den rådgiverens status, databaseinstans, begrundelse og rådgivning. Der er også information om tidsplan og sidste udførelsestidspunkt. Rådgiveren kan også udføres on-demand ved at klikke på knappen "Kompilér og kør" under Developer Studio.

Ovenstående rådgivere, der indeholder følgende kode, skrevet ved hjælp af ClusterControl Domain-Specific Language (DSL), som er ret lig 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 leverer et out-of-the-box integreret udviklingsmiljø (IDE) kaldet Developer Studio (tilgængeligt under Administrer -> Developer Studio) til at skrive, kompilere, gemme, fejlsøge og planlægge rådgiveren:

Med Developer Studio og Advisors har brugerne ingen grænser for at udvide ClusterControls overvågnings- og administrationsfunktioner. Det er bogstaveligt talt det perfekte værktøj til at automatisere konfigurationskontrollen for al din open source-databasesoftware som MySQL, MariaDB, PostgreSQL og MongoDB, såvel som belastningsbalancererne som HAProxy, ProxySQL, MaxScale og PgBouncer. Du kan endda skrive en rådgiver for at gøre brug af MySQL Shell Upgrade Checker Utility, som vist i forrige kapitel.

Sidste tanker

Konfigurationskontrol og -justering er vigtige dele af DBA- og SysAdmin-rutinen for at sikre, at kritiske systemer som database og omvendte proxyer altid er relevante og optimale, efterhånden som dine arbejdsbelastninger vokser.


  1. Installation af Redis på Debian 9

  2. Få $elemMatch (projektion) til at returnere alle objekter, der matcher kriterier

  3. Mongo konverterer alle numeriske felter, der er gemt som streng

  4. Kan ikke starte MongoDB som en tjeneste