MySQL ロックの詳細な説明

Apr 29, 2020 am 11:12 AM
mysql

ロックは、現実の世界では、外の世界から身を隠したいときに使用されるツールです。コンピューターにおいて、複数のプロセスまたは郡によるリソースへの同時アクセスを調整するためのメカニズムです。データベースでは、従来のコンピューティング リソース (CPU、RAM、I/O など) をめぐる競争に加えて、データは多くのユーザーによって共有され、アクセスされるリソースでもあります。データへの同時アクセスの一貫性と有効性をどのように確保するかは、すべてのデータベースが解決しなければならない問題です。ロックの競合も、データベースへの同時アクセスのパフォーマンスに影響を与える重要な要素です。この観点から、ロックはデータベースにとって特に重要です。

1. MySQL のロック

MySQL にはロックとラッチの概念があります。データベースでは、両方とも「」と呼び出すことができます。ロック」とありますが、この2つは全く異なる意味を持ちます。

MySQL ロックの詳細な説明

#ラッチは、必要なロック時間が非常に短い必要があるため、一般にラッチ (軽量ロック) と呼ばれます。 InnoDB エンジンでは、Latch は mutex (ミューテックス) と rwlock (読み取り/書き込みロック) に分けられます。その目的は、重要なリソースを操作する同時スレッドの正確性を保証することであり、通常はデッドロック検出メカニズムはありません。

Lock のオブジェクトはトランザクションであり、テーブル、ページ、行などのデータベース内のオブジェクトをロックするために使用されます。また、一般に、ロック オブジェクトはトランザクションのコミットまたはロールバック後にのみ解放されます (トランザクション分離レベルによって解放時間は異なる場合があります)。

Latch の詳細な説明については、次を参照してください。 MySQL ラッチ競合の詳細な分析と判断に関して、この記事では主に Lock ロックに焦点を当てています。

ロックの種類

実際には、データに対する操作は読み取りと書き込みの 2 つだけです。データベースがロックを実装する場合、これも実行されます。 2 つの操作は異なるロックを使用します。InnoDB は標準の行レベルのロック、つまり共有ロック (Shared Lock) と排他ロック (Exclusive Lock) を実装します。

  • 共有ロック (読み取りロック) を使用すると、トランザクションは 1 行のデータを読み取ることができます。

  • 排他ロック (書き込みロック)。トランザクションでデータ行を削除または更新できるようにします。

##そして、それらの名前は、それぞれの別の特性も暗示しています。共有ロックは相互に互換性がありますが、ミューテックス ロックは他のロックとは互換性がありません:

MySQL ロックの詳細な説明

これらの使用法を少し考えてみると、なぜこのように設計されているかが理解できます。共有ロックは読み取り操作を表し、ミューテックス ロックは書き込み操作を表すため、データベース内でそれらを並列化できます。この方法によってのみ、スレッドの競合が発生せず、スレッドの安全性を確保できます。

ロック粒度

ロック ロックは、粒度に応じて主にテーブル ロック、ページ ロック、行ロックに分類されます。ストレージ エンジンが異なれば、ロックの粒度も異なります。

MySQL ロックの詳細な説明

テーブル ロック

テーブル レベルのロックは、MySQL ストレージ エンジンの中で最も詳細なロック メカニズムです。このロック機構の最大の特徴は、実装ロジックが非常にシンプルで、システムへの悪影響が最小限であることです。したがって、ロックの取得と解放は非常に高速です。テーブルレベルのロックはテーブル全体を一度にロックするため、私たちを悩ませているデッドロックの問題を回避できます。

もちろん、ロックの粒度が大きいことによる最大の悪影響は、ロック リソースの競合の可能性が最も高くなり、同時実行性が大幅に低下することです。

テーブル レベルのロックは、主に MyISAM、MEMORY、CSV などの一部の非トランザクション ストレージ エンジンによって使用されます。

テーブル ロックの構文は非常に単純です:

# 获取表锁
LOCK TABLES
    tbl_name [[AS] alias] lock_type
    [, tbl_name [[AS] alias] lock_type] ...
 
lock_type:
    READ [LOCAL]
  | [LOW_PRIORITY] WRITE
 
# 释放表锁
UNLOCK TABLES
ログイン後にコピー

MyISAM はクエリを実行する前にテーブルのロックとロック解除の操作を自動的に実行します。通常、ユーザーは手動でテーブルを追加したりロックを解除したりする必要はありません。 、ただし、ロックされているときにも表示する必要があります。例: 特定の時刻 t1 と t2 におけるテーブル内のデータの数を取得します。

LOCK TABLE t1 read, t2 read;
select count(t1.id1) as 'sum' from t1;
select count(t2.id1) as 'sum' from t2;
UNLOCK TABLES;
ログイン後にコピー

ページ ロック

ページ レベルのロックは MySQL 独自のロック レベルであり、他のデータベース管理ソフトウェアではあまり一般的ではありません。ページ レベルのロックの特徴は、ロックの粒度が行レベルのロックとテーブル レベルのロックの間であるため、ロックを取得するために必要なリソース オーバーヘッドとロックによって提供できる同時処理能力も上記 2 つの間の範囲内にあることです。さらに、ページレベルのロックと行レベルのロックによりデッドロックが発生します。

データベースにリソース ロックを実装するプロセスでは、ロック リソースの粒度が小さくなるにつれて、同じ量のデータをロックするためにより多くのメモリが消費され、実装アルゴリズムもますます複雑になります。複雑であるほど、複雑になります。ただし、ロックされたリソースの粒度が減少するにつれて、アプリケーションのアクセス要求がロック待機に遭遇する可能性も減少し、システム全体の同時実行性も増加します。

ページレベルのロックの主な用途は、BerkeleyDB ストレージ エンジンです。

行ロック

行级锁定最大的特点就是锁定对象的粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的。由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予应用程序尽可能大的并发处理能力而提高一些需要高并发应用系统的整体性能。

虽然能够在并发处理能力上面有较大的优势,但是行级锁定也因此带来了不少弊端。由于锁定资源的颗粒度很小,所以每次获取锁和释放锁需要做的事情也更多,带来的消耗自然也就更大了。此外,行级锁定也最容易发生死锁。

使用行级锁定的主要是InnoDB存储引擎。

总结

  • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。

  • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。

  • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般。

从锁的角度来说,表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。

2、InnoDB中的锁

意向锁

上节提到InnoDB 支持多种粒度的锁,也就是行锁和表锁。为了支持多粒度锁定,InnoDB 存储引擎引入了意向锁(Intention Lock)。

那什么是意向锁呢?我们在这里可以举一个例子:如果没有意向锁,当已经有人使用行锁对表中的某一行进行修改时,如果另外一个请求要对全表进行修改,那么就需要对所有的行是否被锁定进行扫描,在这种情况下,效率是非常低的;不过,在引入意向锁之后,当有人使用行锁对表中的某一行进行修改之前,会先为表添加意向互斥锁(IX),再为行记录添加互斥锁(X),在这时如果有人尝试对全表进行修改就不需要判断表中的每一行数据是否被加锁了,只需要通过等待意向互斥锁被释放就可以了。

与上一节中提到的两种锁的种类相似的是,意向锁也分为两种:

  • 意向共享锁(IS):事务想要在获得表中某些记录的共享锁,需要在表上先加意向共享锁。

  • 意向互斥锁(IX):事务想要在获得表中某些记录的互斥锁,需要在表上先加意向互斥锁。

随着意向锁的加入,锁类型之间的兼容矩阵也变得愈加复杂:

MySQL ロックの詳細な説明

意向锁其实不会阻塞全表扫描之外的任何请求,它们的主要目的是为了表示是否有人请求锁定表中的某一行数据。

行锁的算法

InnoDB存储引擎有3种行锁的算法,其分别是:

  • Record Lock:单个行记录上的锁。

  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。

  • Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。

Record Lock总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定。

Next-Key Lock是结合了Gap Lock和Record Lock的一种锁定算法,在Next-Key Lock算法下,InnoDB对于行的查询都是采用这种锁定算法。例如有一个索引有10,11,13和20这4个值,那么该索引可能被Next-Key Locking的区间为:

MySQL ロックの詳細な説明

除了Next-Key Locking,还有Previous-Key Locking技术。同样上述的值,使用Previous-Key Locking技术,那么可锁定的区间为:

MySQL ロックの詳細な説明

但是不是所有索引都会加上Next-key Lock的,在查询的列是唯一索引(包含主键索引)的情况下,Next-key Lock会降级为Record Lock。

接下来,我们来通过一个例子解释一下。

CREATE TABLE z (
    a INT,
    b INT,
    PRIMARY KEY(a),    // a是主键索引
    KEY(b)    // b是普通索引
);
INSERT INTO z select 1, 1;
INSERT INTO z select 3, 1;
INSERT INTO z select 5, 3;
INSERT INTO z select 7, 6;
INSERT INTO z select 10, 8;
ログイン後にコピー

这时候在会话A中执行 SELECT * FROM z WHERE b = 3 FOR UPDATE ,索引锁定如下:

MySQL ロックの詳細な説明

这时候会话B执行的语句落在锁定范围内的都会进行waiting

SELECT * FROM z WHERE a = 5 LOCK IN SHARE MODE;
INSERT INTO z SELECT 4, 2;
INSERT INTO z SELECT 6, 5;
ログイン後にコピー

用户可以通过以下两种方式来显示的关闭Gap Lock:

  • 将事务的隔离级别设为 READ COMMITED。

  • 将参数innodb_locks_unsafe_for_binlog设置为1。

从上面的例子可以看出来,Gap Lock的作用是为了阻止多个事务将记录插入到同一个范围内,设计它的目的是用来解决Phontom Problem(幻读问题)。在MySQL默认的隔离级别(Repeatable Read)下,InnoDB就是使用它来解决幻读问题。

幻读是指在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次的SQL可能会返回之前不存在的行,也就是第一次执行和第二次执行期间有其他事务往里插入了新的行。

一致性非锁定读

一致性非锁定读(consistent nonlocking read)是指InnoDB存储引擎通过多版本控制(MVCC)的方式来读取当前执行时间数据库中行的数据。如果读取的这行正在执行DELETE或UPDATE操作,这时读取操作不会向XS锁一样去等待锁释放,而是会去读一个快照数据。MVCC相关的知识我已经在另外一篇文章中阐述了,这里就不做过多原理的分析了。地址:谈谈MySQL InnoDB存储引擎事务的ACID特性

MySQL ロックの詳細な説明

在事务隔离级别RC和RR下,InnoDB存储引擎使用非锁定的一致性读。然而对于快照数据的定义却不同,在RC级别下,对于快照数据,非一致性读总是读取被锁定行的最新一份快照数据。而在RR级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本。

下面我们通过一个例子来看看大家是否对MVCC理解了。

MySQL ロックの詳細な説明

可以看到,第1步和第2步是非常容易理解的,而在第3步事务B插入一条新的数据后,在第4步事务A还是查不到,也就是利用了MVCC的特性来实现。当事务B提交后,第5步的查询在RC和RR隔离级别下的输出是不同的,这个的原因在另一篇博客中也说到了,是因为他们创建ReadView的时机不同。

但是很诡异的是在第6步的时候,事务A更新了一条它看不见的记录,然后查询就能够查询出来了。这里很多人容易迷惑,不可见不代表记录不存在,它只是利用了可见性判断忽略了而已。更新成功之后,事务A顺其自然的记录了这条记录的Undo log,在随后的查询中,因为它能够看见自己的改动这一个可见性的判断,自然就能够查询出来了。这里很多名词需要去深入读一下此文:谈谈MySQL InnoDB存储引擎事务的ACID特性

一致性锁定读

前面说到,在默认隔离级别RR下,InnoDB存储引擎的SELECT操作使用一致性非锁定读。但是在某些情况下,用户需要显式地对数据库读取操作进行加锁以保证数据逻辑的一致性。InnoDB存储引擎对于SELECT语句支持两种一致性的锁定读(locking read)操作。

  • SELECT … FOR UPDATE (X锁)

  • SELECT … LOCK IN SHARE MODE (S锁)

3、锁带来的问题

通过锁定机制可以实现事务隔离性要求,使得事务可以并发的工作。锁提高了并发,但是却会带来潜在的问题。不过好在有事务隔离性的要求,不同的隔离级别解决的锁的问题也不同,这里只进行简单的介绍,不进行举例分析了。

MySQL ロックの詳細な説明

InnoDB存储引擎在RR级别就已经解决了所有问题,但是它和Serializable的区别在哪里呢?区别就在于RR级别还存在一个丢失更新问题,而SERIALIZABLE无论对于查询还是更新都会进行锁定操作。

MySQL ロックの詳細な説明

如圖所示,用戶原始金額為100,如果程式中對於轉帳和存款的判斷是先查詢再更新的話就會出現丟失更新的問題,也就是後面的更新覆蓋了前面的更新。如果想避免這種問題,只能每次更新的時候金額是基於表裡最新的數值來做。如果必須先查詢再更新,可以在更新的條件判斷金額(樂觀鎖),也可以使用隔離等級最高的SERIALIZABLE。

4、死鎖

死鎖是指兩個或兩個以上的交易在執行過程中,因爭奪鎖定資源而造成的一種互相等待的現象,這裡直接放上先前專案中遇到的一個死鎖問題以及深入的分析:由一次線上問題帶來的MySQL死鎖問題分析,這裡就不再贅述了。

推薦教學:《Mysql教學

###

以上がMySQL ロックの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MySQL:世界で最も人気のあるデータベースの紹介 MySQL:世界で最も人気のあるデータベースの紹介 Apr 12, 2025 am 12:18 AM

MySQLはオープンソースのリレーショナルデータベース管理システムであり、主にデータを迅速かつ確実に保存および取得するために使用されます。その実用的な原則には、クライアントリクエスト、クエリ解像度、クエリの実行、返品結果が含まれます。使用法の例には、テーブルの作成、データの挿入とクエリ、および参加操作などの高度な機能が含まれます。一般的なエラーには、SQL構文、データ型、およびアクセス許可、および最適化の提案には、インデックスの使用、最適化されたクエリ、およびテーブルの分割が含まれます。

phpmyadminを開く方法 phpmyadminを開く方法 Apr 10, 2025 pm 10:51 PM

次の手順でphpmyadminを開くことができます。1。ウェブサイトコントロールパネルにログインします。 2。phpmyadminアイコンを見つけてクリックします。 3。MySQL資格情報を入力します。 4.「ログイン」をクリックします。

なぜMySQLを使用するのですか?利点と利点 なぜMySQLを使用するのですか?利点と利点 Apr 12, 2025 am 12:17 AM

MySQLは、そのパフォーマンス、信頼性、使いやすさ、コミュニティサポートに選択されています。 1.MYSQLは、複数のデータ型と高度なクエリ操作をサポートし、効率的なデータストレージおよび検索機能を提供します。 2.クライアントサーバーアーキテクチャと複数のストレージエンジンを採用して、トランザクションとクエリの最適化をサポートします。 3.使いやすく、さまざまなオペレーティングシステムとプログラミング言語をサポートしています。 4.強力なコミュニティサポートを提供し、豊富なリソースとソリューションを提供します。

MySQLの場所:データベースとプログラミング MySQLの場所:データベースとプログラミング Apr 13, 2025 am 12:18 AM

データベースとプログラミングにおけるMySQLの位置は非常に重要です。これは、さまざまなアプリケーションシナリオで広く使用されているオープンソースのリレーショナルデータベース管理システムです。 1)MySQLは、効率的なデータストレージ、組織、および検索機能を提供し、Web、モバイル、およびエンタープライズレベルのシステムをサポートします。 2)クライアントサーバーアーキテクチャを使用し、複数のストレージエンジンとインデックスの最適化をサポートします。 3)基本的な使用には、テーブルの作成とデータの挿入が含まれ、高度な使用法にはマルチテーブル結合と複雑なクエリが含まれます。 4)SQL構文エラーやパフォーマンスの問題などのよくある質問は、説明コマンドとスロークエリログを介してデバッグできます。 5)パフォーマンス最適化方法には、インデックスの合理的な使用、最適化されたクエリ、およびキャッシュの使用が含まれます。ベストプラクティスには、トランザクションと準備された星の使用が含まれます

Apacheのデータベースに接続する方法 Apacheのデータベースに接続する方法 Apr 13, 2025 pm 01:03 PM

Apacheはデータベースに接続するには、次の手順が必要です。データベースドライバーをインストールします。 web.xmlファイルを構成して、接続プールを作成します。 JDBCデータソースを作成し、接続設定を指定します。 JDBC APIを使用して、接続の取得、ステートメントの作成、バインディングパラメーター、クエリまたは更新の実行、結果の処理など、Javaコードのデータベースにアクセスします。

DockerによるMySQLを開始する方法 DockerによるMySQLを開始する方法 Apr 15, 2025 pm 12:09 PM

DockerでMySQLを起動するプロセスは、次の手順で構成されています。MySQLイメージをプルしてコンテナを作成および起動し、ルートユーザーパスワードを設定し、ポート検証接続をマップしてデータベースを作成し、ユーザーはすべての権限をデータベースに付与します。

MySQLの役割:Webアプリケーションのデータベース MySQLの役割:Webアプリケーションのデータベース Apr 17, 2025 am 12:23 AM

WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。

MySQLをCentos7にインストールする方法 MySQLをCentos7にインストールする方法 Apr 14, 2025 pm 08:30 PM

MySQLをエレガントにインストールするための鍵は、公式のMySQLリポジトリを追加することです。特定の手順は次のとおりです。MYSQLの公式GPGキーをダウンロードして、フィッシング攻撃を防ぎます。 mysqlリポジトリファイルを追加:rpm -uvh https://dev.mysql.com/get/mysql80-community-rease-el7-3.noarch.rpm update yumリポジトリキャッシュ:yumアップデートインストールmysql:yumインストールmysql-server startup mysql sportin

See all articles