[復刻版]はMySQLの文字セットが原因一貫性のないパフォーマンスに、あなたが信じることを敢えて25%減少しましたか?MySQLの文字セットが25%減少したため、一貫性のないパフォーマンスに、あなたは信じることを敢えて?

MySQLの文字セットが25%減少したため、一貫性のないパフォーマンスに、あなたは信じることを敢えて?

 
HTTPS:// www.cnblogs.com/dba-john/p/12497686.html 

実際にクライアントとサーバー側の文字の文字セットとの間の関係を理解するための支障となっていない... 

もっと考慮すべきことは、実際にフォーマットをエンコードされています。

 

話はこれです:

私は、MySQLの性能試験のためにあった、100%、80%、私たち、16%SYS、3%のWA、次のを発見したiops2000のiostatディスク、avgqu-SZ 3つ以下、70%までのutil%、参照するには、そのCPU使用率の近くを見つけましたディスクへのIOボトルネックがトップではなく、CPUに。SYS一部の使用ビット高いです。

私が印象的な2の前に立って、トップビューPERF使用することを決定して、それがmy_ismbchar_utf8mb4とmy_charpos_mbです。

my_charpos_mbは一時的に不明で、my_ismbchar_utf8mb4名前は明らかに文字セットに関連して、示唆しています。

 

 

経験はこれが正常でないことを私に伝えます!一般的に言って、CPUの消費量は、ああ最も関連性の高いデータ・ページ・オペレーションの魚でなければなりません。

私はすぐに開いているMySQLの内部文書の検索、貴重な情報を見つけることができませんでした。

 

ああ、あなたはこの話を主婦知りたいですか?申し訳ありませんが、私は唯一の圧力試験は、国際慣行に従い、私は環境とバージョン情報を入れます言いました:

コードをコピー
ハードウェア:8コア16ギガバイト、200ギガバイトSSD、テンセントクラウド仮想マシンの
オペレーティングシステムのバージョン:CentOSのリリース6.9(最終)
MySQLバージョン:5.7.28ログMySQLコミュニティサーバ( GPL)、 インストールバイナリ
MySQLのパラメータを:innodb_buffer_pool_size = 10752M 
          innodb_flush_log_at_trx_commit = 1 
          = 1 sync_binlog。
          キャラクタ・サーバー-SET = utf8mb4 
SysBenchバージョン:1.0.19 
SysBenchパラメータ:sysbench /usr/share/sysbench/oltp_read_write.lua --tables = 3 --table-サイズ= 1000000 --mysqlパスワード= ** * --mysqlユーザー=ルート--mysql-ソケット=は/ usr / local / mysql5.7.28 /にmysql.sock --threads = 128 --time = 1800実行
コードをコピー

サーバーのキャラクタ・セットは、dbの次の文字セットとテーブルをチェックし、utf8mb4です。

 

 

 

 

 

 えーえー、すべてがとても正常なようだ......

サーバー、DBは、文字のテーブルは今だけ最大の疑惑をsysbench、同じです!

しかし、これらのsysbenchはすでにそれを設定するには、セッションのMySQLの文字セットに接続されているか確認しますか?

私sysbenchコマンドは、明示的に文字セットを指定していません。ショーにはcharacter_set_client情報をPROCESSLISTない、INFORMATION_SCHEMA mysqlの図書館と図書館情報character_set_clientなかったし。

sysbench --help文字セットに関連するオプションおよびパラメータがありません。https://github.com/akopytov/sysbench/blob/master/src/drivers/mysql/drv_mysql.c   SysBenchソースコードや文字は、関連する設定を行います。

LATIN1で、セットの不整合が発生した文字があるはずsysbench MySQLの接続キャラクタセットがデフォルトで設定される必要があり、そうです。

 

しかし、技術的な問題のために、私は推測ああに依存することはできません!私は下に取得する必要があり、それが下に着くチェック......

 

 

出典:

CPUは右、my_ismbchar_utf8mb4機能で食べますか?最初に、そのソースコードが見つかりました:

定義された文字列/ののctype-utf8.c:

コードをコピー
静的UINT 
my_ismbchar_utf8mb4(CHARSET_INFO * CS、CONSTチャーCONST * B、CONSTのchar * E)
{ 
  int型RES = my_valid_mbcharlen_utf8mb4(CS、(CONST UCHAR *)B、(CONST UCHAR *)E); 
  (RES> 1)を返しますか?RES:0; 
}
コードをコピー

これは、複雑なロジック、ちょうどコールmy_valid_mbcharlen_utf8mb4、戻り値の解像度の裁判官、1>であれば、返品resを、そうでない場合は0を持っていません。

OK、その後私は、my_valid_mbcharlen_utf8mb4でそれを見て

コードをコピー
静的int型
my_valid_mbcharlen_utf8mb4(CHARSET_INFO * CSの__attribute __ CONST((未使用))、
                           CONST UCHAR * S、CONST UCHAR * E)
{ 
  UCHAR C。

  (S> = E)であれば
    、戻りMY_CS_TOOSMALL。

  C = S [0]。
  (C <0xF0が)場合は
    リターンmy_valid_mbcharlen_utf8mb3(S、E)。

  (C <0xf5)場合は
  { 
    / *私たちは、4つの文字を必要とする(E S + 4)の場合> * / 
      リターンMY_CS_TOOSMALL4。

    / * 
省略若干行...... 
    * / 

    IF(!(IS_CONTINUATION_BYTE(S [1])&& 
          IS_CONTINUATION_BYTE(S [2])&& 
          IS_CONTINUATION_BYTE(S [3])&& 
          (C> = 0xf1 || S [1]> = 0x90を)&& 
          (C <= 0xf3 || S [1] <

    4を返します。
  } 

  戻りMY_CS_ILSEQ。
}
コードをコピー

この関数は、入力文字を比較するために、判決はutf8mb3またはutf8mb4です。utf8mb3?以前に聞いたああ!サウンドほとんどの検索、のように多くの元期間がある興味深い歴史  ☜

しかし、この関数のコードでただ見て、それが実際にCPUの7%以上を食べるようになると信じてするつもりはありません。私は信じていません!

さて、記録PERFであることを最初に見てみましょう:

コードをコピー
最初のステップ#1のmysqldプロセスpidを参照するには
PS -ef | grepをmysqldの
#ステップ2、CPUクロックイベントに関連mysqldプロセスを、ファイル保存perf.dataデフォルトでコールスタックを記録し たレコードPERF -e CPU- -g -p 14345時計
#ステップ3、perf.dataは、解決するにはPERFスクリプトツールを用いて行う スクリプト-i perf.data&> perf.unfold PERF
#ステップ4、美しいのセットをダウンロードし、強力なオールインワンのツール: gitのhttps://github.com/brendangregg/FlameGraph.gitクローン

#ステップ5:シンボルが折り畳まperf.unfold ./FlameGraph/stackcollapse-perf.pl&perf.unfold> perf.folded
#ステップ6、 A炎図 ./FlameGraph/flamegraph.pl perf.folded> perf.svg
コードをコピー

この効果は7.47パーセントに達し、my_ismbchar_utf8mb4確かに最高の割合、↓を見ることができています

 

 

 

コールスタックをトレースするには、それはGET_TEXT SQL \ sql_lex.cc()関数で見つけることができ、文字セットをチェックするために、マクロuse_mbとmy_ismbcharを呼び出します。

これら二つは同じマクロコールismbchar()である - 検出指定した文字列がマルチバイト・シーケンスであるかどうか。メガバイトでutf8mb4、フルネームはマルチバイトであります

コードをコピー
静的チャー* GET_TEXT(Lex_input_stream *リップ、INT pre_skip、INT post_skip)
{ 
  UCHAR C、月。
  UINT found_escape = 0。
  constのCHARSET_INFO * CS = lip-> m_thd->文字セット(); 

  lip-> tok_bitmap = 0; 
  9月= lip-> yyGetLast(); //文字列はこれに終わらなければならない
  一方(lip-> EOF()!)
  { 
    C = lip-> yyGet(); 
    lip-> tok_bitmap | = C; 
    { 
      INT L。
      IF(use_mb(CS)&& 
          (L = my_ismbchar(CS、
                           lip-> get_ptr()-1、
                           lip-> get_end_of_query()))){ 
        lip-> skip_binary(L-1)。
        継続する; 
      } 
    }
    (C == '\\' &&もし
        !(lip-> m_thd-> variables.sql_mode&MODE_NO_BACKSLASH_ESCAPES))
    {//エスケープ文字
      found_escape = 1; 
      もし(lip-> EOF())
    の戻り0; 
      lip-> yySkip(); 
    } 
//省略若干行... 
  } 
  戻り0。クエリの//予期せぬ終了
}
コードをコピー

 

 

 ソリューション:

これは、チェースは、ビット霧であってもよいし、ヘクタール申し訳ありませんが、私の限られた能力、それはより多くの人気のいくつかを説明することはできませんと言います。

要するに、実際に文字セットは、それがmy_ismbchar_utf8mb4が起こるのだろう(MySQLのキーワードを除く)各文字のためのユーザー入力の解析時に、文字セットをチェックするために数回行われるべきMySQLの結果として、矛盾していることを証明しましたCPUリソースなどAの話をたくさん食べます。

非常に単純な問題を解決するには、次のKeepのcharacter_set_server &&データベースのキャラクタ&&テーブルのキャラクタ&&クライアントのキャラクタが一貫した!

私はちょうどので、自分自身だけピットに、理由sysbench文字セットの無視します。

sysbenchはsysbenchもmysqlのドライバのソースコードを変更することができます(私はそれを測定するために統一latin1のキャラクタ・セットにMySQLを置くことを文字セットに関連するオプションやパラメータを提供していないので、文字セットをサポートしていますが、私はCが得意ではありませんよ... ...)

 

 

締結:

QPSだけ73797に押された可能性が文字セットを調整する前に、統一された文字セットの後、QPSは98272に達しました。98272分の73797 * 100%= 75.09パーセント

 

TPSで見てみましょうは、文字セットを調整する前に、TPSは3689まで、統一された文字セットの後、QPSは3689に達している可能性があります。= 75.08パーセント73 4913分の797 * 100%

 

 

 どのような痛みの洞察力......

話はこれです:

私は、MySQLの性能試験のためにあった、100%、80%、私たち、16%SYS、3%のWA、次のを発見したiops2000のiostatディスク、avgqu-SZ 3つ以下、70%までのutil%、参照するには、そのCPU使用率の近くを見つけましたディスクへのIOボトルネックがトップではなく、CPUに。SYS一部の使用ビット高いです。

私が印象的な2の前に立って、トップビューPERF使用することを決定して、それがmy_ismbchar_utf8mb4とmy_charpos_mbです。

my_charpos_mbは一時的に不明で、my_ismbchar_utf8mb4名前は明らかに文字セットに関連して、示唆しています。

 

 

経験はこれが正常でないことを私に伝えます!一般的に言って、CPUの消費量は、ああ最も関連性の高いデータ・ページ・オペレーションの魚でなければなりません。

私はすぐに開いているMySQLの内部文書の検索、貴重な情報を見つけることができませんでした。

 

ああ、あなたはこの話を主婦知りたいですか?申し訳ありませんが、私は唯一の圧力試験は、国際慣行に従い、私は環境とバージョン情報を入れます言いました:

コードをコピー
ハードウェア:8コア16ギガバイト、200ギガバイトSSD、テンセントクラウド仮想マシンの
オペレーティングシステムのバージョン:CentOSのリリース6.9(最終)
MySQLバージョン:5.7.28ログMySQLコミュニティサーバ( GPL)、 インストールバイナリ
MySQLのパラメータを:innodb_buffer_pool_size = 10752M 
          innodb_flush_log_at_trx_commit = 1 
          = 1 sync_binlog。
          キャラクタ・サーバー-SET = utf8mb4 
SysBenchバージョン:1.0.19 
SysBenchパラメータ:sysbench /usr/share/sysbench/oltp_read_write.lua --tables = 3 --table-サイズ= 1000000 --mysqlパスワード= ** * --mysqlユーザー=ルート--mysql-ソケット=は/ usr / local / mysql5.7.28 /にmysql.sock --threads = 128 --time = 1800実行
コードをコピー

サーバーのキャラクタ・セットは、dbの次の文字セットとテーブルをチェックし、utf8mb4です。

 

 

 

 

 

 えーえー、すべてがとても正常なようだ......

サーバー、DBは、文字のテーブルは今だけ最大の疑惑をsysbench、同じです!

しかし、これらのsysbenchはすでにそれを設定するには、セッションのMySQLの文字セットに接続されているか確認しますか?

私sysbenchコマンドは、明示的に文字セットを指定していません。ショーにはcharacter_set_client情報をPROCESSLISTない、INFORMATION_SCHEMA mysqlの図書館と図書館情報character_set_clientなかったし。

sysbench --help文字セットに関連するオプションおよびパラメータがありません。https://github.com/akopytov/sysbench/blob/master/src/drivers/mysql/drv_mysql.c   SysBenchソースコードや文字は、関連する設定を行います。

LATIN1で、セットの不整合が発生した文字があるはずsysbench MySQLの接続キャラクタセットがデフォルトで設定される必要があり、そうです。

 

しかし、技術的な問題のために、私は推測ああに依存することはできません!私は下に取得する必要があり、それが下に着くチェック......

 

 

出典:

CPUは右、my_ismbchar_utf8mb4機能で食べますか?最初に、そのソースコードが見つかりました:

定義された文字列/ののctype-utf8.c:

コードをコピー
静的UINT 
my_ismbchar_utf8mb4(CHARSET_INFO * CS、CONSTチャーCONST * B、CONSTのchar * E)
{ 
  int型RES = my_valid_mbcharlen_utf8mb4(CS、(CONST UCHAR *)B、(CONST UCHAR *)E); 
  (RES> 1)を返しますか?RES:0; 
}
コードをコピー

これは、複雑なロジック、ちょうどコールmy_valid_mbcharlen_utf8mb4、戻り値の解像度の裁判官、1>であれば、返品resを、そうでない場合は0を持っていません。

OK、その後私は、my_valid_mbcharlen_utf8mb4でそれを見て

コードをコピー
静的int型
my_valid_mbcharlen_utf8mb4(CHARSET_INFO * CSの__attribute __ CONST((未使用))、
                           CONST UCHAR * S、CONST UCHAR * E)
{ 
  UCHAR C。

  (S> = E)であれば
    、戻りMY_CS_TOOSMALL。

  C = S [0]。
  (C <0xF0が)場合は
    リターンmy_valid_mbcharlen_utf8mb3(S、E)。

  (C <0xf5)場合は
  { 
    / *私たちは、4つの文字を必要とする(E S + 4)の場合> * / 
      リターンMY_CS_TOOSMALL4。

    / * 
省略若干行...... 
    * / 

    IF(!(IS_CONTINUATION_BYTE(S [1])&& 
          IS_CONTINUATION_BYTE(S [2])&& 
          IS_CONTINUATION_BYTE(S [3])&&
          (C> = 0xf1 || S [1]> = 0x90を)&& 
          (C <= 0xf3 || S [1] <
 
    リターン4。
  } 

  戻りMY_CS_ILSEQ。
}
コードをコピー

この関数は、入力文字を比較するために、判決はutf8mb3またはutf8mb4です。utf8mb3?以前に聞いたああ!サウンドほとんどの検索、のように多くの元期間がある興味深い歴史  ☜

しかし、この関数のコードでただ見て、それが実際にCPUの7%以上を食べるようになると信じてするつもりはありません。私は信じていません!

さて、記録PERFであることを最初に見てみましょう:

コードをコピー
最初のステップ#1のmysqldプロセスpidを参照するには
PS -ef | grepをmysqldの
#ステップ2、CPUクロックイベントに関連mysqldプロセスを、ファイル保存perf.dataデフォルトでコールスタックを記録し たレコードPERF -e CPU- -g -p 14345時計
#ステップ3、perf.dataは、解決するにはPERFスクリプトツールを用いて行う スクリプト-i perf.data&> perf.unfold PERF
#ステップ4、美しいのセットをダウンロードし、強力なオールインワンのツール: gitのhttps://github.com/brendangregg/FlameGraph.gitクローン

#ステップ5:シンボルが折り畳まperf.unfold ./FlameGraph/stackcollapse-perf.pl&perf.unfold> perf.folded
#ステップ6、 A炎図 ./FlameGraph/flamegraph.pl perf.folded> perf.svg
コードをコピー

この効果は7.47パーセントに達し、my_ismbchar_utf8mb4確かに最高の割合、↓を見ることができています

 

 

 

コールスタックをトレースするには、それはGET_TEXT SQL \ sql_lex.cc()関数で見つけることができ、文字セットをチェックするために、マクロuse_mbとmy_ismbcharを呼び出します。

これら二つは同じマクロコールismbchar()である - 検出指定した文字列がマルチバイト・シーケンスであるかどうか。メガバイトでutf8mb4、フルネームはマルチバイトであります

コードをコピー
静的チャー* GET_TEXT(Lex_input_stream *リップ、INT pre_skip、INT post_skip)
{ 
  UCHAR C、月。
  UINT found_escape = 0。
  constのCHARSET_INFO * CS = lip-> m_thd->文字セット(); 

  lip-> tok_bitmap = 0; 
  9月= lip-> yyGetLast(); //文字列はこれに終わらなければならない
  一方(lip-> EOF()!)
  { 
    C = lip-> yyGet(); 
    lip-> tok_bitmap | = C; 
    { 
      INT L。
      IF(use_mb(CS)&& 
          (L = my_ismbchar(CS、
                           lip-> get_ptr()-1、
                           lip-> get_end_of_query()))){ 
        lip-> skip_binary(L-1)。
        継続する; 
      } 
    }
    (C == '\\' &&もし
        !(lip-> m_thd-> variables.sql_mode&MODE_NO_BACKSLASH_ESCAPES))
    {//エスケープ文字
      found_escape = 1; 
      もし(lip-> EOF())
    の戻り0; 
      lip-> yySkip(); 
    } 
//省略若干行... 
  } 
  戻り0。クエリの//予期せぬ終了
}
コードをコピー

 

 

 ソリューション:

これは、チェースは、ビット霧であってもよいし、ヘクタール申し訳ありませんが、私の限られた能力、それはより多くの人気のいくつかを説明することはできませんと言います。

要するに、実際に文字セットは、それがmy_ismbchar_utf8mb4が起こるのだろう(MySQLのキーワードを除く)各文字のためのユーザー入力の解析時に、文字セットをチェックするために数回行われるべきMySQLの結果として、矛盾していることを証明しましたCPUリソースなどAの話をたくさん食べます。

非常に単純な問題を解決するには、次のKeepのcharacter_set_server &&データベースのキャラクタ&&テーブルのキャラクタ&&クライアントのキャラクタが一貫した!

私はちょうどので、自分自身だけピットに、理由sysbench文字セットの無視します。

sysbenchはsysbenchもmysqlのドライバのソースコードを変更することができます(私はそれを測定するために統一latin1のキャラクタ・セットにMySQLを置くことを文字セットに関連するオプションやパラメータを提供していないので、文字セットをサポートしていますが、私はCが得意ではありませんよ... ...)

 

 

締結:

QPSだけ73797に押された可能性が文字セットを調整する前に、統一された文字セットの後、QPSは98272に達しました。98272分の73797 * 100%= 75.09パーセント

 

TPSで見てみましょうは、文字セットを調整する前に、TPSは3689まで、統一された文字セットの後、QPSは3689に達している可能性があります。= 75.08パーセント73 4913分の797 * 100%

 

 

 どのような痛みの洞察力......

おすすめ

転載: www.cnblogs.com/jinanxiaolaohu/p/12497919.html