ホームページ  >  記事  >  データベース  >  MySQL の update ステートメントがどのように実行されるかを分析してみましょう。

MySQL の update ステートメントがどのように実行されるかを分析してみましょう。

WBOY
WBOY転載
2022-03-31 12:08:162732ブラウズ

この記事では、mysql に関する関連知識を提供します。主に、更新ステートメントの実行方法に関する関連問題を紹介します。更新更新操作を実行すると、テーブルに関連するクエリ キャッシュが無効になります。 , したがって、このステートメントはテーブル上のすべてのキャッシュされた結果をクリアします。一緒に見てみましょう。皆さんのお役に立てれば幸いです。

MySQL の update ステートメントがどのように実行されるかを分析してみましょう。

推奨学習: mysql チュートリアル

事前準備

まずテーブルを作成し、次に 3 つの部分を挿入しますデータの数:

CREATE TABLE T(
	ID int(11) NOT NULL AUTO_INCREMENT,
	c int(11) NOT NULL,
	PRIMARY KEY (ID)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试表';INSERT INTO T(c) VALUES (1), (2), (3);

その後、更新操作を実行します:

update T set c=c+1 where ID=2;

更新操作について説明する前に、MySQL での SQL ステートメントの実行プロセスを見てみましょう~

SQL ステートメント 実行プロセス

MySQL の update ステートメントがどのように実行されるかを分析してみましょう。

図に示すように、MySQL データベースは主に サービス層ストレージの 2 つのレベルに分かれています。エンジン層 サービス層: サーバー層には、MySQL のコア機能のほとんどを含む、コネクタ、クエリ キャッシュ、アナライザー、オプティマイザー、エグゼキュータが含まれます。ストアド プロシージャを含む、すべてのクロスストレージ エンジン機能もこの層に実装されています。トリガー、ビューなど。ストレージ エンジン レイヤー: ストレージ エンジン レイヤーには、MyISAM、InnoDB、Memory などの一般的な MySQL ストレージ エンジンが含まれます。最も一般的に使用されるのは、MySQL のデフォルトのストレージ エンジンでもある InnoDB です。

サーバー層のコンポーネントの概要

  • コネクタ: MySQL クライアントのログインが必要であり、コネクタが必要です。ユーザーを MySQL データベースに接続します (「mysql -u ユーザー名 -p パスワード」)。MySQL にログインします。TCP ハンドシェイクの完了後、コネクタは入力されたユーザー名とパスワードに基づいてログイン ID を検証します。

  • クエリ キャッシュ: 実行リクエストを受信した後、MySQL はまずクエリ キャッシュを検索して、この SQL ステートメントが実行されたかどうか、およびステートメントが実行されたかどうかを確認します。そして結果はキーと値のペアの形式でメモリに配置されます。キーはクエリ ステートメントであり、値はクエリの結果です。この SQL 文がキーから見つかると、SQL の実行結果が直接返されます。キャッシュに存在しない場合は、後続の実行フェーズが続行されます。実行が完了すると、実行結果はクエリ キャッシュに配置されます。利点は効率が高いことです。ただし、MySQL で特定のテーブルが更新されると、すべてのクエリ キャッシュが無効になり、頻繁に更新されるデータベースの場合、クエリ キャッシュのヒット率が非常に低くなるため、クエリ キャッシュの使用は推奨されません。注: MySQL バージョン 8.0 では、クエリ キャッシュ機能が削除され、クエリ キャッシュ機能はありません。

  • Analyzer: は字句解析と文法に分かれています。分析

    • ## 字句解析: まず、MySQL は SQL ステートメントに従って解析します。アナライザーは最初に字句解析を行います。作成した SQL は複数の文字列とスペースで構成されます。 SQL ステートメントの場合、MySQL はその中の文字列が何であるか、そしてそれが何を表しているかを識別する必要があります。
    • 文法解析: 次に、文法解析を実行します。構文解析は、字句解析の結果に基づいて、入力された SQL ステートメントが MySQL の構文を文法規則に基づいて満たしているかどうかを判断します。 SQL ステートメントが間違っている場合は、次のプロンプトが表示されます。 SQL サンタックスにエラーがあります

  • ## オプティマイザー:

    After アナライザー After分析では、SQL は正当ですが、実行前にオプティマイザによって処理される必要があります。オプティマイザは、どのインデックスを使用するか、どの接続を使用するかを決定します。オプティマイザの役割は、最も重要なことを決定することです。効率的な実行計画。

  • Executor:

    実行フェーズでは、MySQL はまずステートメントを実行する権限があるかどうかを判断します。権限がない場合は、次のエラーを返します。権限がありません。権限がある場合は、テーブルを開いて実行を続行します。テーブルが開かれると、実行プログラムはターゲット エンジン定義に従ってエンジンが提供するインターフェイスを使用します。インデックス付きテーブルの場合、実行ロジックは同様です。

  • SQL ステートメントの実行プロセスを理解した後、上記の
update T set c=c 1 where ID=2;

がどのように実行されるかを詳しく分析してみましょう。 Update ステートメントの分析

update T set c=c+1 where ID=2;

update update

操作を実行すると、このテーブルに関連するクエリ キャッシュが無効になるため、このステートメントはキャッシュされた結果をすべて表示します。テーブル T はクリアされます。次に、アナライザーは構文分析と字句分析を実行します。これが更新ステートメントであることがわかった後、オプティマイザーは使用するインデックスを決定し、次に実行プログラムが特定の実行を担当します。最初に行を見つけてから更新します。 。

通常の考え方によれば、このレコードを検索し、その値を変更して保存します。データの変更を伴うため、ログが必要になります。更新操作には 2 つの重要なログ モジュールが含まれます。 redo ログ (やり直しログ) bin ログ (アーカイブ ログ) 。 MySQL のこれら 2 つのログも学習する必要があります。

redo ログ

  • MySQL では、すべての更新操作をディスクに書き込む必要がある場合、ディスクも対応するレコードを見つける必要があります。更新され、プロセス全体の IO コストと検索コストが非常に高くなります。
    MySQL は WAL (先書きログ) テクノロジを使用しています。WAL の正式名は Write-Ahead Logging です。重要な点は、最初にログを書き込み、次にログに書き込むことです。ディスク
  • 具体的には、レコードを更新する必要がある場合、InnoDB エンジンはまずレコードを REDO ログに書き込み、メモリを更新します。この時点で更新は完了します。同時に、InnoDB エンジンは適切なタイミングで操作レコードをディスクに更新します。この更新は多くの場合、システムが比較的アイドル状態のときに行われます。
  • InnoDB の REDO ログはサイズが固定されており、たとえば 4 つのファイルのセットとして構成され、各ファイルのサイズが 1GB の場合、合計 4GB の操作を記録できます。最初から書き始めて最後まで書き、その後最初に戻ってループで書きます。

上記の REDO ログの概要を聞いた後、友人は次のように尋ねるかもしれません: REDO ログはどこに保存されますか? , データベース情報はディスクに保存され、REDO ログもディスクに保存されます。最初に REDO ログに書き込んでからデータベースに書き込む必要があるのはなぜですか? , REDO ログがデータでいっぱいの場合はどうすればよいですか? ###等。次にこれらの質問に答えてみましょう。

REDO ログはどこに保存されますか?

InnoDB エンジンは、最初にレコードを REDO ログに書き込みます。REDO ログがどこにあっても、ディスク上にもあります。これもディスクに書き込むプロセスですが、異なる点は次のとおりです。更新プロセスはディスク上のランダム IO であり、時間がかかります。 REDO ログの書き込みは、ディスク上のシーケンシャル IO です。効率的にしましょう。

redo ログ 容量は固定されていますが、足りなくなりますか?

まず第一に、REDO ログは

リサイクルされているため、領域が足りなくなる心配はありません。たとえば、REDO ログは 4 つのファイルのセットとして構成され、各ファイルは 1G です。これを記述するプロセスは次のとおりです:
MySQL の update ステートメントがどのように実行されるかを分析してみましょう。

簡単な要約:

REDO ログは Innodb ストレージ エンジンの独自のメカニズムであり、使用できます。 異常なリカバリ クラッシュセーフ に対処するために、redo を使用すると、mysql が異常に再起動したときに、コミットされていないトランザクションがロールバックされ、送信されたトランザクションがデータベースに安全にドロップされることが保証されます。

crash-safe:

REDO ログを使用すると、InnoDB はデータベースが異常に再起動した場合でも、以前に送信されたレコードが失われないことを保証できます。この機能は crash-safe と呼ばれます。

binlog (アーカイブ ログ)

REDO ログは、innoDB エンジンに固有のログです。 Binlog は、mysql サーバー層のログです。

実際、MySQL には当初 InnoDB ストレージ エンジンがなく、5.5 より前の MyISAM であったため、bin ログ ログは REDO ログよりも早く出現しました。ただし、MyISAM にはクラッシュセーフ機能がなく、binlog ログはアーカイブにのみ使用できます。 InnoDB は、他社によってプラグインの形で MySQL に導入されましたが、binlog のみに依存するとクラッシュ セーフ機能がないため、InnoDB は別のログ システム、つまり REDO ログを使用してクラッシュ セーフ機能を実現します。

redo logbin log的总结

  • redo log是为了保证innoDB引擎的crash-safe能力,也就是说在mysql异常宕机重启的时候,之前提交的事务可以保证不丢失;(因为成功提交的事务肯定是写入了redo log,可以从redo log恢复)
  • bin log是归档日志,将每个更新操作都追加到日志中。这样当需要将日志恢复到某个时间点的时候,就可以根据全量备份+bin log重放实现。 如果没有开启binlog,那么数据只能恢复到全量备份的时间点,而不能恢复到任意时间点。如果连全量备份也没做,mysql宕机,磁盘也坏了,那就很尴尬了。。

redo logbin log的区别:

  • redo log 是 InnoDB 引擎特有的;bin log 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  • redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;bin log 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  • redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

InnoDB引擎部分在执行这个简单的update语句的时候的内部流程

update T set c=c+1 where ID=2;

MySQL の update ステートメントがどのように実行されるかを分析してみましょう。

手动用begin开启事务,然后执行update语句,再然后执行commit语句,那上面的update更新流程之前 哪些是update语句执行之后做的,哪些是commit语句执行之后做的?

事实上,redo log在内存中有一个redo log buffer,binlog 也有一个binlog cache.所以在手动开启的事务中,你执行sql语句,其实是写到redo log bufferbinlog cache中去的(肯定不可能是直接写磁盘日志,一个是性能差一个是回滚的时候不可能去回滚磁盘日志吧),然后当你执行commit的时候,首先要将redo log的提交状态游prepare改为commit状态,然后就要把binlog cache刷新到binlog日志(可能也只是flush到操作系统的page cache,这个就看你的mysql配置),redo log buffer刷新到redo log 日志(刷新时机也是可以配置的)。 如果你回滚的话,就只用把binlog cacheredo log buffer中的数据清除就行了。

在update过程中,mysql突然宕机,会发生什么情况?

  • 如果redolog写入了,处于prepare状态,binlog还没写入,那么宕机重启后,redolog中的这个事务就直接回滚了。

  • 如果redolog写入了,binlog也写入了,但redolog还没有更新为commit状态,那么宕机重启以后,mysql会去检查对应事务在binlog中是否完整。如果是,就提交事务;如果不是,就回滚事务。 (redolog处于prepare状态,binlog完整启动时就提交事务,为啥要这么设计? 主要是因为binlog写入了,那么就会被从库或者用这个binlog恢复出来的库使用,为了数据一致性就采用了这个策略)
    redo log和binlog是通过xid这个字段关联起来的。

推荐学习:mysql教程

以上がMySQL の update ステートメントがどのように実行されるかを分析してみましょう。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。