私の連絡先情報
郵便メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
一般に、MySQL は 2 つの層に分けることができます。
mysql -h$ip -P$port -u$user -p
接続コマンドの mysql は、サーバーとの接続を確立するために使用されるクライアント ツールです。従来の TCP ハンドシェイクが完了すると、コネクタは
この時点で、入力したユーザー名とパスワードが使用されます。
クライアントが非アクティブな状態が長時間続くと、コネクタは自動的に切断します。この時間はパラメータ wait_timeout によって制御され、デフォルト値は 8 時間です。
接続が切断された後にクライアントが再度リクエストを送信すると、エラー リマインダーが表示されます。 Lost connection to MySQL server during query
。この時点で続行したい場合は、再接続してからリクエストを実行する必要があります。
データベースでは、接続が長いとは、接続が成功した後、クライアントがリクエストを継続する場合、常に同じ接続が使用されることを意味します。短い接続とは、いくつかのクエリが実行された後に接続が切断され、次のクエリのために新しい接続が再確立されることを意味します。
接続を確立するプロセスは通常複雑なので、使用中に接続を確立するアクションを最小限に抑える、つまり長い接続を使用するようにすることをお勧めします。
ただし、長い接続をすべて使用すると、MySQL によって占有されるメモリが急速に増加することがあります。これは、これが原因です。MySQL の実行中に一時的に使用されるメモリは接続オブジェクトで管理されます。 。これらのリソースは、接続が切断されると解放されます。それで、もし長時間の接続が蓄積されると、過剰なメモリ使用量が発生する可能性があります。、現象から判断すると、MySQLが異常再起動したと思われます。
この問題を解決するにはどうすればよいでしょうか?次の 2 つのオプションを検討できます。
mysql_reset_connection
接続リソースを再初期化します。このプロセスでは再接続や権限の確認は必要ありませんが、接続は作成されたばかりの状態に復元されます。MySQL はクエリ リクエストを取得すると、まずクエリ キャッシュに移動して、このステートメントが以前に実行されたかどうかを確認します。以前に実行されたステートメントとその結果は、キーと値のペアの形式でメモリに直接キャッシュされる場合があります。 キーはクエリ ステートメントであり、値はクエリ結果です。クエリがこのキャッシュ内で直接キーを見つけることができた場合、値はクライアントに直接返されます。
ステートメントがクエリ キャッシュにない場合は、実行フェーズが続行されます。実行が完了すると、実行結果はクエリ キャッシュに保存されます。クエリがキャッシュにヒットすると、MySQL は後続の複雑な操作を実行せずに結果を直接返すことができ、非常に効率的であることがわかります。
しかし、ほとんどの場合、私はそうしますクエリ キャッシュを使用しないことをお勧めします。 、なぜ?クエリ キャッシュは多くの場合、良いことよりも害を及ぼすためです。
クエリ キャッシュは非常に頻繁に無効になり、テーブルが更新されている限り、このテーブル上のすべてのクエリ キャッシュがクリアされます。そのため、せっかく結果を保存したのに、使用する前にアップデートによって消えてしまったという可能性もあります。更新圧力が高いデータベースの場合、クエリ キャッシュのヒット率は非常に低くなります。あなたのビジネスに、長い間 1 回しか更新されない静的なテーブルがある場合を除きます。たとえば、システム構成テーブルの場合、このテーブルのクエリはクエリ キャッシュに適しています。
幸いなことに、MySQL はこの「オンデマンドで使用する」方法も提供します。 query_cache_type パラメータを DEMAND に設定すると、デフォルトの SQL ステートメントにクエリ キャッシュが使用されなくなります。クエリ キャッシュを使用することが確実なステートメントの場合は、次のステートメントのように SQL_CACHE を使用して明示的に指定できます。
select SQL_CACHE * from T where ID=10;
認識しなければならないのは、MySQL 8.0 バージョンはクエリ キャッシュ機能全体を直接削除しますつまり、この機能は 8.0 以降では利用できなくなります。
クエリ キャッシュがヒットしない場合は、ステートメントの実際の実行が開始されます。まず、MySQL はユーザーが何をしたいのかを知る必要があるため、SQL ステートメントを解析する必要があります。
「Kong Yiji」という記事をまだ覚えているかどうかはわかりませんが、ホテルの支配人は宿泊客の信用記録を記録するために特別に使用されるピンクのボードを持っています。クレジットで支払う人が少ない場合は、顧客の名前と口座をボードに書くことができます。しかし、クレジットアカウントを持っている人が多すぎると、ファンボードがそれらを追跡できない場合が常にあります。このとき、店主はクレジットアカウントを記録するための専用の台帳を持っている必要があります。
誰かが信用を返済したい、または借金を返済したい場合、店主には通常 2 つの選択肢があります。
商売が繁盛してカウンターが混雑しているとき、店主は間違いなく選択します後者 , 前者の操作が面倒すぎるためです。まず、この人の信用口座の合計記録を見つけなければなりません。考えてみると、何十ページものページがぎっしりと詰まっており、名前を見つけるには、店主が老眼鏡をかけてゆっくり探し、そろばんを取り出して計算し、最後にその結果をメモに書き戻す必要があるかもしれません。台帳。
このプロセス全体を考えるのは面倒です。逆に、最初にピンクのボードに書き出すと簡単です。考えてみてください。ピンクのボードの助けがなければ、店主は会計を記録するたびに帳簿をひっくり返さなければなりません。効率が耐えられないほど低いではありませんか。
同様に、この問題は MySQL にも存在します。すべての更新操作をディスクに書き込む必要があり、更新前にディスクで対応するレコードを見つける必要がある場合、プロセス全体の IO コストと検索コストが非常に高くなります。この問題を解決するために、MySQL の設計者は、ホテルの店主のピンクのボードに似たアイデアを使用して更新効率を向上させました。
ピンクのボードと台帳の間の連携プロセス全体は、実際には MySQL でよく言及されるものです。 WAL
テクノロジー、WAL
フルネームはWrite-Ahead Logging
、重要なポイントは最初にログを書き込み、次にディスクに書き込みます、つまり、最初にピンクのボードを書き、忙しくないときに家計簿を書きます。
具体的には、レコードを更新する必要がある場合、InnoDB エンジンはまずレコードを REDO ログ (ピンクのボード) に書き込み、メモリを更新します。この時点で更新は完了します。同時に、InnoDB エンジンは適切なタイミングで操作記録をディスクに更新します。この更新は、店主が閉店後に行うのと同じように、システムが比較的アイドル状態のときに行われることがよくあります。
今日のクレジット口座がそれほど多くない場合、店主は閉店時間まで商品を整理するのを待つことができます。しかし、ある日にたくさんのクレジット口座があり、ピンクのボードがいっぱいになった場合はどうすればよいでしょうか?このとき、店主は作業を中止し、ピンクのボード上の信用記録の一部を台帳に更新し、新しい口座を作成するためのスペースを確保するためにピンクのボードからこれらの記録を消去する必要がありました。
同様に、InnoDB の REDO ログは固定サイズです。たとえば、各ファイルのサイズが 1 GB の 4 つのファイルのセットとして構成でき、この「ピンクのボード」には合計 4 GB の操作を記録できます。以下の図のように、最初から書き始めて、最初に戻ってループして書きます。
write pos は現在のレコードの位置で、ファイル No.3 の最後まで書き込んだ後、ファイル No.0 の先頭に戻ります。 チェックポイントは消去される現在位置であり、レコードを消去する前にレコードをデータ ファイルに更新する必要があります。
書き込み pos とチェックポイントの間のスペースは、新しい操作を記録するために使用できる「ピンクのボード」の空の部分です。書き込み pos がチェックポイントに追いついた場合は、「ピンクのボード」がいっぱいで、現時点では新しい更新を実行できないことを意味します。チェックポイントを進めるには、まずいくつかのレコードを停止して消去する必要があります。
REDO ログを使用すると、InnoDB はデータベースが異常に再起動した場合でも、以前に送信されたレコードが失われないことを保証できます。この機能は、と呼ばれます。crash-safe
。
クラッシュセーフの概念を理解するために、以前の信用記録の例を考えてみましょう。信用記録がピンクのボードに記録されているか台帳に記載されていれば、店主が数日間突然営業を停止するなど、後で忘れてしまったとしても、台帳のデータから信用口座を明らかにすることができ、営業再開後のピンクボード。
前に述べたように、MySQL 全体には実際には 2 つの部分があります。1 つは主に MySQL の機能レベルで処理を行うサーバー層で、もう 1 つはストレージに関連する特定の事項を担当するエンジン層です。上で話したピンクのボード REDO ログは InnoDB エンジン固有のログです、そして サーバー層には、binlog (アーカイブ ログ) と呼ばれる独自のログもあります。。
なぜログが 2 つあるのかと疑問に思われると思います。
それは、最初の MySQL には InnoDB エンジンがなかったからです。 MySQL 独自のエンジンは MyISAM ですが、MyISAM にはクラッシュセーフ機能がなく、binlog ログはアーカイブにのみ使用できます。 InnoDB は、別の会社によってプラグインの形で MySQL に導入されました。binlog のみに依存するとクラッシュ セーフ機能がないため、InnoDB は別のログ システム、つまり REDO ログを使用してクラッシュ セーフ機能を実現します。
これら 2 つのログには、次の 3 つの違いがあります。
これら 2 つのログの概念を理解した上で、この単純な更新ステートメントを実行するときのエグゼキューターと InnoDB エンジンの内部プロセスを見てみましょう。
この update ステートメントの実行フローチャートを示します。図の明るいボックスは InnoDB 内で実行されることを示し、暗いボックスはエグゼキューターで実行されることを示します。
update文実行処理
最後の 3 つのステップが少し「循環的」であることに気づいたかもしれません。REDO ログの書き込みは準備とコミットの 2 つのステップに分かれています。これは「2 フェーズ コミット」です。
なぜ「2段階提出」が必要なのでしょうか?これは、2 つのログ間の差異を許容するためです。論理的に一貫した 。この問題を説明するには、この記事の冒頭の質問から始める必要があります。「データベースを半月以内に任意の秒の状態に復元するにはどうすればよいですか?」
前にも述べたように、binlog はすべての論理操作を記録し、「追記書き込み」の形式を採用します。 DBA が半月以内に復元できると約束した場合、バックアップ システムは確実に過去半月のすべてのバイナリ ログを保存し、データベース全体の定期的なバックアップを実行します。ここでの「定期的」とは、システムの重要性に応じて、1 日に 1 回または週に 1 回にすることができます。
指定した秒に復元する必要がある場合 (たとえば、ある日の午後 2 時)、テーブルが正午に誤って削除されたことに気づき、データを取得する必要がある場合は、次のように実行できます。
さて、データ回復プロセスについて話した後、戻ってログに「2 フェーズ コミット」が必要な理由について話しましょう。ここでは、矛盾による証明を使って説明することもできます。
REDO ログと binlog は 2 つの独立したロジックであるため、2 フェーズ コミットを使用しない場合は、REDO ログを最初に書き込んでから binlog を書き込むか、その逆の順序を採用する必要があります。これら 2 つの方法にはどのような問題があるかを見てみましょう。
引き続き、前の update ステートメントを例として使用します。 ID=2 の現在の行のフィールド c の値が 0 であると仮定し、更新ステートメントの実行中に、最初のログが書き込まれた後、2 番目のログが書き込まれる前にクラッシュが発生したとします。
この可能性は非常に低いのではないかと思われるかもしれませんが、一時ライブラリをいつでも復元する必要がある状況はありません。
実際には、いいえ、このプロセスは誤操作後にデータを回復するためだけに必要なわけではありません。容量を拡張する必要がある場合、つまり、システムの読み取り容量を増やすためにさらにバックアップ データベースを構築する必要がある場合、現在の一般的な方法は、完全バックアップを使用し、binlog を適用してこれを実現することです。この「不整合」が原因で問題が発生します。オンラインのマスター データベースとスレーブ データベース間の不一致です。
簡単に言うと、REDO ログと binlog の両方を使用してトランザクションのコミット ステータスを表すことができます。2 段階の提出では、2 つの状態の論理的一貫性が保たれます。。