MySQL は、元のデータと同じデータがある場合、更新ステートメントを再度実行しますか?

MySQL は、元のデータと同じデータがある場合、更新ステートメントを再度実行しますか?

背景

この記事では主に、MySQL が更新ステートメントを実行するときに、元のデータと同一の (つまり、変更されていない) 更新ステートメントが MySQL 内で再実行されるかどうかをテストします。

テスト環境

  • MySQL 5.7.25
  • セントロス7.4

binlog_format は ROW です

パラメータ

root@localhost : (なし) 04:53:15> 'binlog_row_image' のような変数を表示します。
+------------------+-------+
| 変数名 | 値 |
+------------------+-------+
| binlog_row_image | フル |
+------------------+-------+
セット内の 1 行 (0.00 秒)

root@localhost : (なし) 04:53:49> 'binlog_format' のような変数を表示します。 
+---------------+-------+
| 変数名 | 値 |
+---------------+-------+
| binlog_format | 行 |
+---------------+-------+
セット内の 1 行 (0.00 秒)

root@localhost : test 05:15:14> 'transaction_isolation' のような変数を表示します。
+----------------------+-----------------+
| 変数名 | 値 |
+----------------------+-----------------+
| トランザクション分離 | 繰り返し読み取り |
+----------------------+-----------------+
セット内の 1 行 (0.00 秒)

テスト手順

セッション1

root@localhost: テスト 04:49:48> 開始;
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

root@localhost : test 04:49:52> select * from test where id =1;
+----+------+------+------+
| id | sid | mid | 名前 |
+----+------+------+------+
| 1 | 999 | 871 | 北西 |
+----+------+------+------+
セット内の 1 行 (0.00 秒)

root@localhost : (なし) 04:54:03> show engine innodb status\Gshow master status\G
...
---
ログ
---
ログシーケンス番号 12090390
ログが 12090390 までフラッシュされました
ページ数は 12090390 までフラッシュされました
最後のチェックポイントは12090381
保留中のログ フラッシュ 0 件、保留中の chkp 書き込み 0 件
33 ログ I/O が完了しました。0.00 ログ I/O/秒

************************** 1. 行 ****************************
  ファイル:mysql-bin.000001
  ポジション: 154
 バイナリログ_Do_DB: 
 バイナリログを無視: 
実行されたGtidセット: 
セット内の 1 行 (0.00 秒)

セッション2

root@localhost : test 04:47:45> update test set sid=55 where id =1;
クエリは正常、1 行が影響を受けました (0.01 秒)
一致した行: 1 変更された行: 1 警告: 0

root@localhost : (なし) 04:54:03> show engine innodb status\Gshow master status\G
...
---
ログ
---
ログシーケンス番号 12091486
ログが 12091486 までフラッシュされました
ページ数は 12091486 までフラッシュされました
最後のチェックポイントは12091477
保留中のログ フラッシュ 0 件、保留中の chkp 書き込み 0 件
39 ログ I/O が完了しました。0.00 ログ I/O/秒

************************** 1. 行 ****************************
  ファイル:mysql-bin.000001
  位置: 500
 バイナリログ_Do_DB: 
 バイナリログを無視: 
実行されたGtidセット: 8392d215-4928-11e9-a751-0242ac110002:1
セット内の 1 行 (0.00 秒)

セッション1

root@localhost : test 04:49:57> update test set sid=55 where id =1; 
クエリは正常、影響を受けた行は 0 行 (0.00 秒)
一致した行: 1 変更: 0 警告: 0

root@localhost : (なし) 04:54:03> show engine innodb status\Gshow master status\G
...
---
ログ
---
ログシーケンス番号 12091486
ログが 12091486 までフラッシュされました
ページ数は 12091486 までフラッシュされました
最後のチェックポイントは12091477
保留中のログ フラッシュ 0 件、保留中の chkp 書き込み 0 件
39 ログ I/O が完了しました。0.00 ログ I/O/秒

************************** 1. 行 ****************************
  ファイル:mysql-bin.000001
  位置: 500
 バイナリログ_Do_DB: 
 バイナリログを無視: 
実行されたGtidセット: 8392d215-4928-11e9-a751-0242ac110002:1
セット内の 1 行 (0.00 秒)

root@localhost : test 04:52:05> select * from test where id =1;
+----+------+------+------+
| id | sid | mid | 名前 |
+----+------+------+------+
| 1 | 999 | 871 | 北西 |
+----+------+------+------+
セット内の 1 行 (0.00 秒)

root@localhost: テスト 04:52:42> コミット;
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

root@localhost : test 04:52:52> select * from test where id =1;
+----+------+------+------+
| id | sid | mid | 名前 |
+----+------+------+------+
| 1 | 55 | 871 | 北西 |
+----+------+------+------+
セット内の 1 行 (0.00 秒)

要約する

binlog_format=rowおよびbinlog_row_image=FULLの場合、MySQL は binlog 内のすべてのフィールドを記録する必要があるため、データを読み取るときにすべてのデータが読み取られ、重複データの更新は実行されません。つまり、MySQLはInnoDBエンジンが提供する「(1,55)への変更」インターフェースを呼び出しますが、エンジンは値が元の値と同じであることを発見し、それを更新せず、直接返します。

binlog_formatはステートメントです

パラメータ

root@localhost : (なし) 04:53:15> 'binlog_row_image' のような変数を表示します。
+------------------+-------+
| 変数名 | 値 |
+------------------+-------+
| binlog_row_image | フル |
+------------------+-------+
セット内の 1 行 (0.00 秒)

root@localhost : (なし) 05:16:08> 'binlog_format' のような変数を表示します。
+---------------+-----------+
| 変数名 | 値 |
+---------------+-----------+
| binlog_format | ステートメント |
+---------------+-----------+
セット内の 1 行 (0.00 秒)

root@localhost : test 05:15:14> 'transaction_isolation' のような変数を表示します。
+----------------------+-----------------+
| 変数名 | 値 |
+----------------------+-----------------+
| トランザクション分離 | 繰り返し読み取り |
+----------------------+-----------------+
セット内の 1 行 (0.00 秒)

テスト手順

セッション1

root@localhost: テスト 05:16:42> 開始;
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

root@localhost : test 05:16:44> select * from test where id =1;
+----+------+------+------+
| id | sid | mid | 名前 |
+----+------+------+------+
| 1 | 111 | 871 | 北西 |
+----+------+------+------+
セット内の 1 行 (0.00 秒)

root@localhost : (なし) 05:16:51> show engine innodb status\Gshow master status\G
...
---
ログ
---
ログシーケンス番号 12092582
ログが 12092582 までフラッシュされました
ページ数は 12092582 までフラッシュされました
最後のチェックポイントは 12092573 です
保留中のログ フラッシュ 0 件、保留中の chkp 書き込み 0 件
45 ログ I/O が完了しました。0.00 ログ I/O/秒

************************** 1. 行 ****************************
    ファイル:mysql-bin.000001
   ポジション: 154
  バイナリログ_Do_DB: 
 バイナリログを無視: 
実行されたGtidセット: 
セット内の 1 行 (0.00 秒)

セッション2

root@localhost : test 05:18:30> update test set sid=999 where id =1;
クエリは正常、1 行が影響を受けました (0.00 秒)
一致した行: 1 変更された行: 1 警告: 0

root@localhost : (なし) 05:18:47> show engine innodb status\Gshow master status\G
...
---
ログ
---
ログシーケンス番号 12093678
ログが 12093678 までフラッシュされました
ページ数は 12093678 までフラッシュされました
最後のチェックポイントは 12093669 です
保留中のログ フラッシュ 0 件、保留中の chkp 書き込み 0 件
51 ログ I/O が完了しました。0.14 ログ I/O/秒

************************** 1. 行 ****************************
    ファイル:mysql-bin.000001
   位置: 438
  バイナリログ_Do_DB: 
 バイナリログを無視: 
実行されたGtidセット: 8392d215-4928-11e9-a751-0242ac110002:1
セット内の 1 行 (0.00 秒)

セッション1

root@localhost : test 05:16:47> update test set sid=999 where id =1;
クエリは正常、影響を受けた行は 0 行 (0.00 秒)
一致した行: 1 変更: 0 警告: 0

root@localhost : (なし) 05:20:03> show engine innodb status\Gshow master status\G
...
---
ログ
---
ログシーケンス番号 12094504
ログが 12094504 までフラッシュされました
ページ数は 12094504 までフラッシュされました
最後のチェックポイントは 12094495 です
保留中のログ フラッシュ 0 件、保留中の chkp 書き込み 0 件
56 ログ I/O が完了しました。0.00 ログ I/O/秒

************************** 1. 行 ****************************
    ファイル:mysql-bin.000001
   位置: 438
  バイナリログ_Do_DB: 
 バイナリログを無視: 
実行されたGtidセット: 8392d215-4928-11e9-a751-0242ac110002:1
セット内の 1 行 (0.00 秒)

root@localhost : test 05:19:33> select * from test where id =1;  
+----+------+------+------+
| id | sid | mid | 名前 |
+----+------+------+------+
| 1 | 999 | 871 | 北西 |
+----+------+------+------+
セット内の 1 行 (0.00 秒)

root@localhost: テスト 05:20:44> コミット;
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

root@localhost : test 05:20:57> select * from test where id =1;
+----+------+------+------+
| id | sid | mid | 名前 |
+----+------+------+------+
| 1 | 999 | 871 | 北西 |
+----+------+------+------+
セット内の 1 行 (0.00 秒)

要約する

binlog_format=statement かつ binlog_row_image=FULL の場合、InnoDB は更新ステートメント、つまり「この値を (1,999) に変更する」という操作を慎重に実行し、ロックする必要があるものはロックし、更新する必要があるものは更新します。

さて、今回の記事は以上です。この記事の内容が皆さんの勉強や仕事に少しでも参考になれば幸いです。123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • PHP で MySQL SQL ステートメントのクエリ時間を取得する方法
  • MySQL では SQL ステートメントはどのように実行されますか?

<<:  Vue が Web オンラインチャット機能を実現

>>:  Linux システムで PATH 環境変数を設定する方法 (3 つの方法)

推薦する

MySQL 結合テーブルクエリの基本操作 左結合のよくある落とし穴

概要中小規模のプロジェクトでは、特にレポートを作成するときに、結合テーブル クエリが非常に一般的な操...

MySQL の完全なデータベース バックアップからデータベースとテーブルを復元する方法

公式の MySQL ダンプ ツールで、特定のデータベースのみを復元するにはどうすればよいですか?完全...

CSSの優先度を理解する2つの方法

方法1: 値を追加する公式の説明を見るには MDN にアクセスしてください。優先度はどのように計算さ...

CSSで半透明の背景色を実現する2つの方法について簡単に説明します。

ページをレイアウトする際、ユーザーに異なる視覚効果を与えるために、div の背景色を半透明の状態に設...

Windows 10 での MySQL 5.7.19 インストール チュートリアル MySQL のルート パスワードを忘れた場合の変更方法

MySQL 5.7.19のインストールを例に挙げると、まずダウンロードしますもちろん、最初に行うこと...

React における同期および非同期 setState の問題のコード分析

React は Facebook の社内プロジェクトとして始まりました。 React の出現は革命的...

json.stringify() と json.parse() の違いと使い方

1. JSON.stringify() と JSON.parse() の違い私たちは皆、JSON.s...

Dockerコンテナ内でホストDocker操作を呼び出して実行する

まず、この投稿は Docker 初心者向けです。もちろん、ベテランであれば記事中の分割線以降の操作方...

既存のDockerコンテナの内容を変更する方法

1. Docker psはコンテナをリストします 2. Docker cpはコンテナにファイルをコピ...

Xshell にショートカット コマンドを追加する方法

便利なターミナル エミュレーターである Xshell は、開発者がホスト サーバーをリモート管理する...

WeChatアプレット開発の章:落とし穴の記録

最近、会社初のミニプログラムの開発に参加しました。開発経験は基本的にWebViewをベースとしたハイ...

docker-machineの使い方の詳しい説明

Docker-machineはDockerが公式に提供しているDocker管理ツールです。これは d...

Linux jdk のインストールと環境変数の設定チュートリアル (jdk-8u144-linux-x64.tar.gz)

最初にsudo suコマンドを使用して root アカウントに切り替えることをお勧めします。そうしな...