sql >> データベース >  >> NoSQL >> MongoDB

データベース構成チェックの自動化

    多くのシステム管理者は、一般的に、継続的なデータベース構成の調整の重要性を見落としています。多くの場合、構成オプションは、インストール段階で一度構成または調整され、データベースサービスで不要なイベントが発生するまで省略されます。そうして初めて、データベースサービスを再度復元したいという衝動に駆られて、構成オプションに再度アクセスし、制限、しきい値、バッファ、キャッシュなどを調整することに注意を向けることになります。

    このブログ投稿では、データベース構成のチェックと検証プロセスを自動化することに重点を置いています。構成オプションはメジャーバージョン間で常に変更されるため、これは重要なプロセスです。変更されていない構成ファイルには、新しいサーバーバージョンではサポートされなくなった非推奨のオプションが含まれている可能性があります。これにより、アップグレードされたサーバーにいくつかの大きな問題が発生することがよくあります。

    構成管理ツール

    Puppet、Ansible、Chef、SaltStackは、構成管理と自動化のためにDevOpsで最も一般的に使用されています。構成管理により、ユーザーは環境を文書化し、効率、管理性、再現性を向上させ、継続的インテグレーションと展開の不可欠な部分を実現できます。ほとんどの構成管理ツールは、他のユーザーが貢献できるモジュールとリポジトリのカタログを提供し、コミュニティユーザーがテクノロジーに適応するための学習曲線を簡素化します。

    構成管理ツールは主に展開とインストールを自動化するために使用されますが、一元化されたプッシュアウトアプローチで構成のチェックと実施を実行することもできます。これらの各ツールには、構成ファイルをテンプレート化する独自の方法があります。 Puppetは、一般的に「.erb」という接尾辞が付いたテンプレートファイルであり、その中には、事前に作成された値とともに構成オプションを定義できます。

    次の例は、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

    上記のように、構成値は固定値にすることも、動的に計算することもできます。したがって、最終結果は、他の事前定義された変数を使用したターゲットホストのハードウェア仕様に応じて異なる場合があります。 Puppet定義ファイルでは、次のように構成テンプレートをプッシュできます。

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

    テンプレート化以外に、定義ファイルから直接構成値をプッシュすることもできます。以下は、PuppetMySQLモジュールを使用したMariaDB10.5構成のPuppet定義の例です。

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

    上記の例は、manage_config_file => trueをoverride_optionsとともに使用して、後でPuppetによってプッシュされる構成行を構造化したことを示しています。マニフェストファイルへの変更は、ターゲットのMySQL構成ファイルの内容のみを反映します。このモジュールは、構成をランタイムにロードせず、変更を構成ファイルにプッシュした後にMySQLサービスを再起動しません。変更をアクティブ化するためにサービスを再起動するのは、SysAdminの責任です。

    PuppetとChefの場合、エージェントログの出力をチェックして、構成オプションが修正されているかどうかを確認します。 Ansibleの場合は、デバッグ出力を見て、おめでとうございますが正常に更新されているかどうかを確認してください。構成管理ツールを使用すると、構成チェックを自動化し、一元化された構成アプローチを実施するのに役立ちます。

    MySQLシェル

    アップグレードを実行する前に、健全性チェックが重要です。 MySQL Shellには、アップグレードチェッカーユーティリティと呼ばれる、既存のインストールがMySQL8.0に安全にアップグレードできるかどうかを確認するための一連のテストを実行することを目的とした非常に優れた機能があります。アップグレードの準備をするときに、時間を大幅に節約できます。特にMySQL8.0へのメジャーアップグレードでは、多くの構成オプションが導入および非推奨になるため、アップグレード後に非互換性が発生する大きなリスクがあります。

    このツールは、特にMySQL5.7からMySQL8.0へのメジャーアップグレードを実行する場合に、MySQL(Percona Serverを含む)用に特別に設計されています。このユーティリティを呼び出すには、MySQL Shellに接続し、rootユーザーとして、資格情報、ターゲットバージョン、および構成ファイルを指定します。

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

    レポートの下部に、主要な要約が表示されます:

    Errors:   7
    Warnings: 36
    Notices:  0
    
    7 errors were found. Please correct these issues before upgrading to avoid compatibility issues.

    最初にすべてのエラーを修正することに焦点を当てます。これは、何もしなければ、アップグレード後に大きな問題を引き起こすためです。生成されたレポートを振り返り、「Error:」という文言がインラインで含まれているすべての問題を見つけます。例:

    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

    すべてのエラーが修正されたら、可能な限り警告を減らしてみてください。警告はほとんどMySQLサーバーの信頼性に影響を与えませんが、パフォーマンスを低下させたり、以前よりも動作を変更したりする可能性があります。たとえば、次の警告を見てください。

    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

    アップグレードチェッカーユーティリティは、何を期待するかについての重要な概要を提供し、アップグレード後の大きな驚きから私たちを回避します。

    ClusterControlアドバイザ

    ClusterControlには、Advisorsと呼ばれる多数の内部ミニプログラムがあり、ClusterControlオブジェクトの構造内で動作および実行される小さなプログラムを記述します。これは、Developer Studioで作成されたスクリプトを実行し、ステータス、アドバイス、および正当化を含む結果を生成するスケジュールされた関数と考えることができます。これにより、ユーザーは、オンデマンドまたはスケジュールに従って実行できるカスタムアドバイザーを作成することにより、ClusterControlの機能を簡単に拡張できます。

    次のスクリーンショットは、ClusterControl内でアクティブ化およびスケジュールされた後の、innodb_log_file_sizeチェックと呼ばれるInnoDBアドバイザの例を示しています。

    上記の結果は、ClusterControl->Performance->Advisorsにあります。すべてのアドバイザについて、アドバイザのステータス、データベースインスタンス、正当化、およびアドバイスが表示されます。スケジュールと最終実行時間に関する情報もあります。アドバイザは、DeveloperStudioの下の[コンパイルして実行]ボタンをクリックしてオンデマンドで実行することもできます。

    JavaScriptに非常によく似たClusterControlドメイン固有言語(DSL)を使用して記述された、次のコードを含む上記のアドバイザー:

    #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は、Advisorの作成、コンパイル、保存、デバッグ、およびスケジュールを行うためのDeveloper Studio([管理]-> [Developer Studio]からアクセス可能)と呼ばれる、すぐに使用できる統合開発環境(IDE)を提供します。

    Developer StudioとAdvisorsを使用すると、ユーザーはClusterControlの監視および管理機能を拡張することに制限がありません。これは、MySQL、MariaDB、PostgreSQL、MongoDBなどのすべてのオープンソースデータベースソフトウェア、およびHAProxy、ProxySQL、MaxScale、PgBouncerなどのロードバランサーの構成チェックを自動化するための文字通り完璧なツールです。前の章で示したように、MySQL ShellUpgradeCheckerユーティリティを使用するAdvisorを作成することもできます。

    最終的な考え

    構成のチェックと調整は、DBAとSysAdminルーチンの重要な部分であり、データベースやリバースプロキシなどの重要なシステムが、ワークロードの増大に応じて常に適切で最適であることを保証します。


    1. 整数を挿入しようとすると、MongoDBはfloatを挿入します

    2. リアルタイムで追加されるRedisからオブジェクトをポップするにはどうすればよいですか?

    3. $projectステージで$in演算子を使用して配列をフィルタリングします

    4. セロリ労働者のゴシップ、混ざり合い、心拍を無効にするとどうなりますか?