sql >> Databasteknik >  >> NoSQL >> MongoDB

Automatisera databaskonfigurationskontroll

Många systemadministratörer förbiser ofta vikten av kontinuerlig justering av databaskonfiguration. Konfigurationsalternativ konfigureras eller justeras ofta en gång, under installationsstadiet, och utelämnas tills några oönskade händelser inträffar i databastjänsten. Först då skulle man lägga mer uppmärksamhet på att återbesöka konfigurationsalternativen och finjustera gränserna, tröskelvärdena, buffertarna, cacheminnen, etc, i lusten att återställa databastjänsten igen.

Vårt fokus i det här blogginlägget är att automatisera databaskonfigurationskontrollen och valideringsprocessen. Detta är en viktig process eftersom konfigurationsalternativen alltid ändras mellan större versioner. En oförändrad konfigurationsfil kan eventuellt ha föråldrade alternativ som inte längre stöds av den nyare serverversionen, vilket vanligtvis orsakar några större problem med den uppgraderade servern.

Konfigurationshanteringsverktyg

Puppet, Ansible, Chef och SaltStack används oftast av DevOps för konfigurationshantering och automatisering. Konfigurationshantering tillåter användare att dokumentera miljön, förbättra effektiviteten, hanterbarheten och reproducerbarheten och en integrerad del av kontinuerlig integration och driftsättning. De flesta av konfigurationshanteringsverktygen tillhandahåller en katalog med moduler och förråd som andra kan bidra med, vilket förenklar inlärningskurvan för community-användaren att anpassa sig till tekniken.

Även om verktyg för konfigurationshantering oftast används för att automatisera driftsättning och installation, kan vi också utföra konfigurationskontroller och upprätthålla i en centraliserad push-out-metod. Vart och ett av dessa verktyg har sitt eget sätt att malla en konfigurationsfil. När det gäller Puppet, mallfilen brukar suffixas med ".erb" och inuti den kan vi definiera konfigurationsalternativen tillsammans med förformulerade värden.

Följande exempel visar en mallfil för 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 visas ovan kan konfigurationsvärdet vara ett fast värde eller dynamiskt beräknat. Därför kan slutresultatet vara annorlunda enligt målvärdens hårdvaruspecifikation med andra fördefinierade variabler. I Puppet-definitionsfilen kan vi pusha vår konfigurationsmall så här:

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

Förutom att malla kan vi också skicka konfigurationsvärdena direkt från definitionsfilen. Följande är ett exempel på Puppet-definition för MariaDB 10.5-konfiguration med 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',
    },
  }
}

Exemplet ovan visar att vi använde manage_config_file => true med override_options för att strukturera våra konfigurationslinjer som senare kommer att skjutas ut av Puppet. Alla ändringar av manifestfilen kommer endast att återspegla innehållet i målkonfigurationsfilen för MySQL. Denna modul kommer varken att ladda konfigurationen till runtime eller starta om MySQL-tjänsten efter att ha tryckt in ändringarna i konfigurationsfilen. Det är SysAdmins ansvar att starta om tjänsten för att aktivera ändringarna.

För Puppet and Chef, kontrollera utdata från agentloggen för att se om konfigurationsalternativen är korrigerade. För Ansible, titta helt enkelt på felsökningsutgången för att se om gratulationerna har uppdaterats. Att använda verktyg för konfigurationshantering kan hjälpa dig att automatisera konfigurationskontroller och genomdriva en centraliserad konfigurationsmetod.

MySQL-skal

En förnuftskontroll är viktig innan du utför någon uppgradering. MySQL Shell har en väldigt cool funktion som är avsedd att köra en serie tester för att verifiera om din befintliga installation är säker att uppgradera till MySQL 8.0, kallad Upgrade Checker Utility. Du kan spara enormt mycket tid när du förbereder dig för en uppgradering. En stor uppgradering, speciellt till MySQL 8.0, introducerar och förkastar många konfigurationsalternativ och har därför en stor risk för inkompatibilitet efter uppgraderingen.

Detta verktyg är specifikt designat för MySQL (Percona Server ingår), speciellt när du vill utföra en större uppgradering från MySQL 5.7 till MySQL 8.0. För att anropa det här verktyget, anslut till MySQL Shell, och som root-användare, ange autentiseringsuppgifterna, målversionen och konfigurationsfilen:

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

Längst ner i rapporten får du nyckelsammanfattningen:

Errors:   7
Warnings: 36
Notices:  0

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

Fokusera på att åtgärda alla fel först, eftersom detta kommer att orsaka stora problem efter uppgraderingen om ingen åtgärd vidtas. Ta en titt tillbaka på den genererade rapporten och hitta alla problem med "Error:"-ordet inline, till exempel:

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 alla fel är åtgärdade, försök att minska varningarna så mycket som möjligt. Varningarna kommer oftast inte att påverka MySQL-serverns tillförlitlighet, men kan potentiellt försämra prestandan eller ändrat beteende än vad de brukade göra. Ta till exempel en titt på följande varningar:

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 ger en kritisk överblick över vad vi kan förvänta oss och förhindrar oss från en stor överraskning efter uppgraderingen.

ClusterControl Advisors

ClusterControl har ett antal interna miniprogram som heter Advisors, där man skriver ett litet program som lever och körs inom strukturen för ClusterControl-objekten. Du kan se det som en schemalagd funktion som kör ett skript skapat i Developer Studio och producerar ett resultat som innehåller status, råd och motivering. Detta gör att användare enkelt kan utöka funktionaliteten hos ClusterControl genom att skapa anpassade rådgivare som kan köras på begäran eller enligt ett schema.

Följande skärmdump visar ett exempel på InnoDB Advisors som kallas innodb_log_file_size check, efter att ha aktiverats och schemalagts i ClusterControl:

Ovanstående resultat kan hittas under ClusterControl -> Prestanda -> Rådgivare. För varje rådgivare visar den rådgivarens status, databasinstans, motivering och råd. Där finns även information om schemat och senaste genomförandetid. Rådgivaren kan också köras på begäran genom att klicka på knappen "Kompilera och kör" under Developer Studio.

Ovanstående rådgivare innehåller följande kod, skriven med ClusterControl Domain-Specific Language (DSL) som är ganska lik 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 tillhandahåller en färdig integrerad utvecklingsmiljö (IDE) som heter Developer Studio (tillgänglig under Manage -> Developer Studio) för att skriva, kompilera, spara, felsöka och schemalägga Advisor:

Med Developer Studio och Advisors har användarna ingen gräns för att utöka ClusterControls övervaknings- och hanteringsfunktioner. Det är bokstavligen det perfekta verktyget för att automatisera konfigurationskontrollen för all din databasprogramvara med öppen källkod som MySQL, MariaDB, PostgreSQL och MongoDB, såväl som belastningsbalanserare som HAProxy, ProxySQL, MaxScale och PgBouncer. Du kan till och med skriva till en rådgivare för att använda MySQL Shell Upgrade Checker Utility, som visas i föregående kapitel.

Sluta tankar

Konfigurationskontroll och justering är viktiga delar av DBA- och SysAdmin-rutinen för att säkerställa att kritiska system som databas och omvända proxyservrar alltid är relevanta och optimala när dina arbetsbelastningar växer.


  1. Redis-anslutning till 127.0.0.1:6379 misslyckades - anslut ECONNREFUSED

  2. Microsoft.Extensions.Caching.Redis väljer en annan databas än db0

  3. Ger Mongoose tillgång till tidigare värde på egendom i pre('save')?

  4. mongodb frågar både med AND och OR