sql >> データベース >  >> RDS >> Mysql

MySQLパフォーマンスベンチマーク:MySQL5.7とMySQL8.0

    MySQL 8.0は、OracleMySQLチームによってプッシュされた膨大な変更と修正をもたらしました。物理ファイルが変更されました。たとえば、*。frm、*。TRG、*。TRN、および*.parは存在しなくなりました。 CTE(共通テーブル式)、ウィンドウ関数、非表示インデックス、正規表現(または正規表現)など、多数の新機能が追加されました。後者は変更され、完全なUnicodeサポートを提供し、マルチバイトセーフです。データディクショナリも変更されました。現在、データベースオブジェクトに関する情報を格納するトランザクションデータディクショナリが組み込まれています。以前のバージョンとは異なり、ディクショナリデータはメタデータファイルと非トランザクションテーブルに保存されていました。 mysql_native_passwordに代わるデフォルトの認証であるcaching_sha2_passwordが新たに追加され、セキュリティが向上しました。セキュリティは強化されていますが、安全な接続またはRSAキーペアを使用したパスワード交換をサポートする暗号化されていない接続のいずれかを使用する必要があります。

    MySQL 8.0が提供するこれらの優れた機能、拡張機能、改善点のすべてを備えた私たちのチームは、特にClusterControlでのMySQL 8.0.xバージョンのサポートが進行中であることを考えると、現在のバージョンのMySQL8.0がどの程度うまく機能するかを判断することに関心がありました。これについて)。このブログ投稿では、MySQL 8.0の機能については説明しませんが、MySQL 5.7に対するパフォーマンスのベンチマークを行い、その後どのように改善されたかを確認する予定です。

    サーバーのセットアップと環境

    このベンチマークでは、次のAWSEC2環境を使用した本番環境に最小限のセットアップを使用する予定です。

    インスタンスタイプ:t2.xlargeインスタンス
    ストレージ:gp2(最小100および最大16000 IOPSのSSDストレージ)
    vCPUS:4
    メモリ:16GiB
    MySQL 5.7バージョン: MySQL Community Server(GPL)5.7.24
    MySQL 8.0バージョン:MySQL Community Server-GPL 8.0.14

    このベンチマークにも設定した注目すべき変数はいくつかあります。それは次のとおりです。

    • innodb_max_dirty_pages_pct =90##これはMySQL8.0のデフォルト値です。詳細については、こちらをご覧ください。
    • innodb_max_dirty_pages_pct_lwm =10##これはMySQL8.0のデフォルト値です
    • innodb_flush_neighbors =0
    • innodb_buffer_pool_instances =8
    • innodb_buffer_pool_size =8GiB

    両方のバージョン(MySQL5.7およびMySQL8.0)に対してここで設定されている残りの変数は、My.cnfテンプレート用にClusterControlによってすでに調整されています。

    また、ここで使用したユーザーは、caching_sha2_passwordを使用するMySQL8.0の新しい認証に準拠していません。代わりに、両方のサーバーバージョンでmysql_native_passwordが使用され、innodb_dedicated_server変数がOFF(デフォルト)になっています。これはMySQL8.0の新機能です。

    作業を楽にするために、別のホストからClusterControlを使用してMySQL 5.7コミュニティバージョンノードをセットアップし、クラスター内のノードを削除し、ClusterControlホストをシャットダウンしてMySQL 5.7ノードを休止状態にします(トラフィックの監視なし)。技術的には、MySQL5.7とMySQL8.0の両方のノードは休止状態であり、アクティブな接続はノードを通過していないため、本質的に純粋なベンチマークテストです。

    使用されるコマンドとスクリプト

    このタスクでは、sysbenchを使用して2つの環境のテストと負荷シミュレーションを行います。このテストで使用されているコマンドまたはスクリプトは次のとおりです。

    sb-prepare.sh

    #!/bin/bash
    
    host=$1
    #host192.168.10.110
    port=3306
    user='sysbench'
    password='[email protected]'
    table_size=500000
    rate=20
    ps_mode='disable'
    sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --threads=1 --max-requests=0 --time=3600 --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --tables=10 --report-interval=1 --skip-trx=on --table-size=$table_size --rate=$rate --db-ps-mode=$ps_mode prepare

    sb-run.sh

    #!/usr/bin/env bash
    
    host=$1
    port=3306
    user="sysbench"
    password="[email protected]"
    table_size=100000
    tables=10
    rate=20
    ps_mode='disable'
    threads=1
    events=0
    time=5
    trx=100
    path=$PWD
    
    counter=1
    
    echo "thread,cpu" > ${host}-cpu.csv
    
    for i in 16 32 64 128 256 512 1024 2048; 
    do 
    
        threads=$i
    
        mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
        tmpfile=$path/${host}-tmp${threads}
        touch $tmpfile
        /bin/bash cpu-checker.sh $tmpfile $host $threads &
    
        /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --events=$events --threads=$threads --time=$time --mysql-host=$host --mysql-user=$user --mysql-password=$password --mysql-port=$port --report-interval=1 --skip-trx=on --tables=$tables --table-size=$table_size --rate=$rate --delete_inserts=$trx --order_ranges=$trx --range_selects=on --range-size=$trx --simple_ranges=$trx --db-ps-mode=$ps_mode --mysql-ignore-errors=all run | tee -a $host-sysbench.log
    
        echo "${i},"`cat ${tmpfile} | sort -nr | head -1` >> ${host}-cpu.csv
        unlink ${tmpfile}
    
        mysql -h $host -e "SHOW GLOBAL STATUS" >> $host-global-status.log
    done
    
    python $path/innodb-ops-parser.py $host
    
    mysql -h $host -e "SHOW GLOBAL VARIABLES" >> $host-global-vars.log

    したがって、スクリプトはsbtestスキーマを準備し、テーブルとレコードにデータを入力するだけです。次に、/ usr / share / sysbench/oltp_read_write.luaスクリプトを使用して読み取り/書き込み負荷テストを実行します。スクリプトは、グローバルステータスとMySQL変数をダンプし、CPU使用率を収集し、スクリプトinnodb-ops-parser.pyによって処理されるInnoDB行操作を解析します。次に、スクリプトは、ベンチマーク中に収集されたダンプログに基づいて* .csvファイルを生成します。次に、ここでExcelスプレッドシートを使用して、*。csvファイルからグラフを生成しました。このgithubリポジトリのコードを確認してください。

    それでは、グラフの結果に進みましょう!

    InnoDB行操作

    基本的にここでは、選択(読み取り)、削除、挿入、および更新を行うInnoDB行操作のみを抽出しました。スレッド数が増えると、MySQL8.0はMySQL5.7を大幅に上回ります。どちらのバージョンにも特定の構成変更はありませんが、私が設定した注目すべき変数のみがあります。したがって、どちらのバージョンもほとんどデフォルト値を使用しています。

    興味深いことに、新しいバージョンでの読み取りと書き込みのパフォーマンスに関するMySQLサーバーチームの主張に関して、グラフは、特に高負荷サーバーでの大幅なパフォーマンスの向上を示しています。すべてのInnoDB行操作についてMySQL5.7とMySQL8.0の違いを想像してみてください。特にスレッドの数が増えると、大きな違いがあります。 MySQL 8.0は、ワークロードに関係なく効率的に実行できることを示しています。

    処理されたトランザクション

    上のグラフに示されているように、MySQL 8.0のパフォーマンスは、トランザクションの処理にかかる時間に大きな違いを示しています。パフォーマンスが低いほどパフォーマンスが向上します。つまり、トランザクションの処理が高速になります。処理されたトランザクション(2番目のグラフ)も、両方のトランザクション数が互いに異ならないことを示しています。つまり、どちらのバージョンもほぼ同じ数のトランザクションを実行しますが、完了する速度が異なります。 MySQL 5.7は低負荷でも多くの処理を実行できますが、特に本番環境での現実的な負荷は、特に最も忙しい時期に、より高くなると予想されます。

    上のグラフは、処理できたトランザクションを示していますが、読み取りと書き込みを分けています。ただし、実際にはグラフに外れ値がありますが、これらはグラフを歪める結果のほんの一部であるため、含めませんでした。

    MySQL 8.0は、特に読み取りを行うための大きな改善を明らかにしています。特にワークロードの高いサーバーの場合、書き込みの効率が高くなります。バージョン8.0での読み取りのMySQLパフォーマンスに影響を与えるいくつかの優れた追加サポートは、降順でインデックスを作成する機能(またはフォワードインデックススキャン)です。以前のバージョンでは、昇順または逆方向のインデックススキャンしかなく、MySQLは降順が必要な場合にファイルソートを実行する必要がありました(ファイルソートが必要な場合は、max_length_for_sort_dataの値を確認することを検討してください)。降順のインデックスにより、オプティマイザーは、最も効率的なスキャン順序で一部の列の昇順と他の列の降順が混在している場合に、複数列のインデックスを使用することもできます。詳細については、こちらをご覧ください。

    CPUリソース

    このベンチマーク中に、いくつかのハードウェアリソース、特にCPU使用率を使用することにしました。

    まず、ベンチマーク中にCPUリソースを取得する方法について説明します。 sysbenchには、データベースのベンチマークを行う際に、プロセス中に使用または使用されたハードウェアリソースの集合的な統計は含まれていません。そのため、ファイルを作成してフラグを作成し、SSH経由でターゲットホストに接続し、Linuxコマンド「top」からデータを収集し、1秒間スリープしてから再度収集することで、データを解析しました。その後、mysqldプロセスのCPU使用率の最も顕著な増加を取得してから、フラグファイルを削除します。 githubにあるコードを確認できます。

    グラフの結果についてもう一度説明します。MySQL8.0が大量のCPUを消費していることがわかります。 MySQL5.7以上。ただし、MySQL8.0で追加された新しい変数を処理する必要がある場合があります。たとえば、これらの変数はMySQL8.0サーバーに影響を与える可能性があります。

    • innodb_log_spin_cpu_abs_lwm =80
    • innodb_log_spin_cpu_pct_hwm =50
    • innodb_log_wait_for_flush_spin_hwm =400
    • innodb_parallel_read_threads =4

    変数とその値は、このベンチマークのデフォルト値のままになります。最初の3つの変数は、REDOロギング用のCPUを処理します。これは、MySQL 8.0では、InnoDBがREDOログに書き込む方法を再設計したために改善されました。変数innodb_log_spin_cpu_pct_hwmにはCPUアフィニティがあります。つまり、たとえばmysqldが4コアにのみ固定されている場合、他のCPUコアは無視されます。並列読み取りスレッドの場合、MySQL 8.0では、使用するスレッドの数を調整できる新しい変数が追加されます。

    しかし、私はその主題についてこれ以上掘り下げませんでした。 MySQL 8.0が提供する機能を利用することで、パフォーマンスを向上させる方法がいくつかあります。

    結論

    MySQL8.0にはたくさんの改善があります。ベンチマークの結果は、読み取りワークロードの管理だけでなく、MySQL5.7と比較して高い読み取り/書き込みワークロードでも目覚ましい改善があったことを示しています。

    MySQL 8.0の新機能に目を向けると、ソフトウェアだけでなく(Memcachedの大幅な改善、DevOpsの動作を改善するためのリモート管理など)最新のテクノロジーを利用しているようです。ハードウェアでも。たとえば、デフォルトの文字エンコードとしてlatin1をUTF8MB4に置き換えたとします。これは、UTF8が非US-ASCII文字で2バイトを必要とするため、より多くのディスク領域が必要になることを意味します。このベンチマークは、caching_sha2_passwordで新しい認証方法を使用することを利用していませんが、暗号化を使用するかどうかにかかわらず、パフォーマンスには影響しません。認証されると、キャッシュに保存されます。つまり、認証は1回だけ行われます。したがって、クライアントに1人のユーザーを使用している場合、問題はなく、以前のバージョンよりも安全です。

    MySQLは最新のハードウェアとソフトウェアを活用しているため、デフォルトの変数を変更します。詳細については、こちらをご覧ください。

    全体として、MySQL8.0はMySQL5.7を効率的に支配しています。


    1. エラーの取得:pgsqlをrailsで動作させようとすると、ユーザーpostgresのピア認証が失敗しました

    2. SQL Server(T-SQL)のパーティションテーブルの境界値を取得する

    3. Oracle CloudPlatformでのMySQLデータベースサービスでのOracleJDeveloperの使用、パート3

    4. SQLServerサービスブローカーの会話グループ