MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Automatyzacja sprawdzania konfiguracji bazy danych

Wielu administratorów systemów często pomija znaczenie ciągłego dostrajania konfiguracji bazy danych. Opcje konfiguracyjne są często konfigurowane lub dostosowywane raz, podczas etapu instalacji, i pomijane do czasu wystąpienia niepożądanych zdarzeń w usłudze bazy danych. Tylko wtedy można by zwrócić większą uwagę na ponowne sprawdzenie opcji konfiguracyjnych i dostrojenie limitów, progów, buforów, pamięci podręcznych itp., w celu ponownego przywrócenia usługi bazy danych.

W tym poście na blogu koncentrujemy się na automatyzacji procesu sprawdzania i walidacji konfiguracji bazy danych. Jest to ważny proces, ponieważ opcje konfiguracji zawsze zmieniają się w głównych wersjach. Niezmieniony plik konfiguracyjny może potencjalnie zawierać przestarzałe opcje, które nie są już obsługiwane przez nowszą wersję serwera, co często powoduje poważne problemy w zaktualizowanym serwerze.

Narzędzia do zarządzania konfiguracją

Puppet, Ansible, Chef i SaltStack są najczęściej używane przez DevOps do zarządzania konfiguracją i automatyzacji. Zarządzanie konfiguracją pozwala użytkownikom dokumentować środowisko, poprawiać wydajność, łatwość zarządzania i odtwarzalność oraz stanowi integralną część ciągłej integracji i wdrażania. Większość narzędzi do zarządzania konfiguracją zapewnia katalog modułów i repozytoriów, które inni mogą wnieść, ułatwiając użytkownikowi społeczności naukę dostosowania się do technologii.

Chociaż narzędzia do zarządzania konfiguracją są używane głównie do automatyzacji wdrażania i instalacji, możemy również przeprowadzać sprawdzanie konfiguracji i egzekwowanie w ramach scentralizowanego podejścia wypychania. Każde z tych narzędzi ma swój własny sposób tworzenia szablonu pliku konfiguracyjnego. Jeśli chodzi o Puppet, to w pliku szablonu powszechnie dodawany jest przyrostek „.erb”, a wewnątrz niego możemy zdefiniować opcje konfiguracyjne wraz z wstępnie sformułowanymi wartościami.

Poniższy przykład pokazuje plik szablonu do konfiguracji 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

Jak pokazano powyżej, wartość konfiguracji może być wartością stałą lub obliczaną dynamicznie. Dlatego wynik końcowy może się różnić w zależności od specyfikacji sprzętowej hosta docelowego z innymi predefiniowanymi zmiennymi. W pliku definicji Puppet możemy wepchnąć nasz szablon konfiguracji w następujący sposób:

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

Oprócz tworzenia szablonów, możemy również przesłać wartości konfiguracyjne bezpośrednio z pliku definicji. Poniżej znajduje się przykład definicji Puppet dla konfiguracji MariaDB 10.5 przy użyciu modułu 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',
    },
  }
}

Powyższy przykład pokazuje, że użyliśmy manage_config_file => true z override_options do ustrukturyzowania naszych linii konfiguracyjnych, które później zostaną wypchnięte przez Puppet. Wszelkie modyfikacje pliku manifestu będą odzwierciedlać tylko zawartość docelowego pliku konfiguracyjnego MySQL. Ten moduł nie załaduje konfiguracji do środowiska wykonawczego ani nie zrestartuje usługi MySQL po wepchnięciu zmian do pliku konfiguracyjnego. Ponowne uruchomienie usługi w celu aktywowania zmian jest obowiązkiem administratora SysAdmina.

W przypadku Puppet i Chef sprawdź dane wyjściowe dziennika agenta, aby sprawdzić, czy opcje konfiguracji zostały poprawione. W przypadku Ansible po prostu spójrz na wyniki debugowania, aby sprawdzić, czy gratulacje zostały pomyślnie zaktualizowane. Korzystanie z narzędzi do zarządzania konfiguracją może pomóc zautomatyzować sprawdzanie konfiguracji i wymusić scentralizowane podejście do konfiguracji.

Powłoka MySQL

Przed wykonaniem jakiejkolwiek aktualizacji ważne jest sprawdzenie poprawności. MySQL Shell ma bardzo fajną funkcję, która ma na celu przeprowadzenie serii testów w celu sprawdzenia, czy istniejącą instalację można bezpiecznie zaktualizować do MySQL 8.0, o nazwie Upgrade Checker Utility. Możesz zaoszczędzić mnóstwo czasu, przygotowując się do aktualizacji. Poważna aktualizacja, zwłaszcza do MySQL 8.0, wprowadza i odrzuca wiele opcji konfiguracyjnych, a zatem wiąże się z dużym ryzykiem niezgodności po aktualizacji.

To narzędzie zostało zaprojektowane specjalnie dla MySQL (w tym Percona Server), zwłaszcza jeśli chcesz przeprowadzić dużą aktualizację z MySQL 5.7 do MySQL 8.0. Aby wywołać to narzędzie, połącz się z powłoką MySQL i jako użytkownik root określ poświadczenia, wersję docelową i plik konfiguracyjny:

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

Na dole raportu znajdziesz kluczowe podsumowanie:

Errors:   7
Warnings: 36
Notices:  0

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

Skup się najpierw na naprawieniu wszystkich błędów, ponieważ spowoduje to poważne problemy po aktualizacji, jeśli nie zostaną podjęte żadne działania. Spójrz wstecz na wygenerowany raport i znajdź wszystkie problemy z wbudowanym sformułowaniem „Błąd:”, na przykład:

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

Gdy wszystkie błędy zostaną naprawione, spróbuj zredukować ostrzeżenia w miarę możliwości. Ostrzeżenia w większości nie wpłyną na niezawodność serwera MySQL, ale mogą potencjalnie obniżyć wydajność lub zmienić zachowanie niż kiedyś. Spójrz na przykład na następujące ostrzeżenia:

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

Narzędzie do sprawdzania aktualizacji zapewnia krytyczny przegląd tego, czego można się spodziewać i zapobiega ogromnej niespodziance po aktualizacji.

Doradcy ClusterControl

ClusterControl ma kilka wewnętrznych miniprogramów o nazwie Advisors, w których piszesz mały program, który działa i działa w strukturze obiektów ClusterControl. Możesz myśleć o tym jako o zaplanowanej funkcji, która wykonuje skrypt utworzony w Developer Studio i generuje wynik zawierający status, poradę i uzasadnienie. Pozwala to użytkownikom na łatwe rozszerzenie funkcjonalności ClusterControl poprzez tworzenie niestandardowych doradców, którzy mogą działać na żądanie lub zgodnie z harmonogramem.

Poniższy zrzut ekranu przedstawia przykład doradców InnoDB o nazwie innodb_log_file_size check, po aktywacji i zaplanowaniu w ClusterControl:

Powyższy wynik można znaleźć w ClusterControl -> Wydajność -> Doradcy. Dla każdego Doradcy pokazuje status doradcy, instancję bazy danych, uzasadnienie i poradę. Znajdują się tam również informacje o harmonogramie i ostatnim czasie realizacji. Doradcę można również uruchomić na żądanie, klikając przycisk „Skompiluj i uruchom” w Developer Studio.

Powyżsi doradcy zawierają następujący kod, napisany przy użyciu języka ClusterControl Domain-Specific Language (DSL), który jest bardzo podobny do 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 zapewnia gotowe do użycia zintegrowane środowisko programistyczne (IDE) o nazwie Developer Studio (dostępne w Zarządzaj -> Developer Studio) do pisania, kompilowania, zapisywania, debugowania i planowania Doradcy:

Dzięki Developer Studio i Advisors użytkownicy nie mają ograniczeń w rozszerzaniu funkcji monitorowania i zarządzania ClusterControl. Jest to dosłownie doskonałe narzędzie do automatyzacji sprawdzania konfiguracji dla całego oprogramowania bazodanowego typu open source, takiego jak MySQL, MariaDB, PostgreSQL i MongoDB, a także systemów równoważenia obciążenia, takich jak HAProxy, ProxySQL, MaxScale i PgBouncer. Możesz nawet napisać Doradcę, aby skorzystać z narzędzia MySQL Shell Upgrade Checker, jak pokazano w poprzednim rozdziale.

Ostateczne myśli

Sprawdzanie i dostrajanie konfiguracji są ważnymi częściami procedury DBA i SysAdmin, aby zapewnić, że krytyczne systemy, takie jak bazy danych i zwrotne serwery proxy, są zawsze odpowiednie i optymalne w miarę wzrostu obciążenia.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jaka jest różnica między Spring Data MongoDB a Hibernate OGM dla MongoDB?

  2. Jak używać $elemMatch do projekcji agregatu?

  3. Jak usunąć jeden „dokument” według „identyfikatora” za pomocą oficjalnego sterownika C# dla MongoDB?

  4. MongoDB $toString

  5. Używasz JSON z MongoDB?