ホームページ  >  記事  >  データベース  >  MySQL ロック メカニズムの再考

MySQL ロック メカニズムの再考

coldplay.xixi
coldplay.xixi転載
2021-04-06 10:07:502036ブラウズ

MySQL ロック メカニズムの再考

記事ディレクトリ

  • ロック
    • ロックの分類
    • 共有ロック (読み取りロック、読み取りと書き込みは相互に排他的、読み取りと読み取りは相互に影響しません)
    • 排他ロック (書き込みロック、排他ロック)
    • 共有ロックと排他ロックの違い
  • テーブル ロック
    • ##インテンション ロック: インテンション共有ロックとインテンション排他ロック
      • なぜ必要なのかインテンション ロックを追加するには
    • 単一テーブル ロック
    • グローバル テーブル ロック
  • 行ロック
  • 行ロックテーブル ロックにアップグレードされます (行 ロックは実際にインデックスをロックします。インデックスを使用せずにテーブル全体がスキャンされる場合、テーブル全体がロックされます)
  • 特定の行レコードが変更または削除されると、トランザクションが送信されない場合、行は常にロックされます。ロック ロック
  • レコード ロック
  • ギャップ ロック
    • ギャップ ロックの役割: ファントムの防止reading
    • innodb 自動 ギャップロック使用条件
    • ギャップロックでロックされる領域
    • #ネクストキーロック【キーロック】
    #レコード ロック、ギャップ ロックと一時ロックの違い
  • 関連する無料学習の推奨事項:

mysql ビデオ チュートリアル Lock

Lock は、コンピュータが複数のスレッドを調整して同じ共有リソースにアクセスするためのメカニズムであり、主に同時実行セキュリティの問題を解決するために使用されます。複数のスレッドが同じ共有リソースにアクセスする。


MySQL ロック メカニズムの再考ロックの分類

(1) パフォーマンスの観点から、楽観的ロックと悲観的ロックに分けられます MySQL が採用しているのは、バージョン番号管理、(2)ではJVM CAS

を使用 データベース操作の種類はリードロック(共有ロック)、ライトロック(排他ロック)に分かれます。 【リードロック、ライトロックは共に悲観ロック】

読み取りロック (共有ロック): 同じ行レコードに対して複数の読み取り操作を同時に実行できますが、トランザクションは実行できません

    書き込みロック (排他ロック) ): 排他的ロックを取得するトランザクションは、データの読み取りとデータの変更の両方ができます。書き込みロックを取得するトランザクションが完了するまで、他のトランザクションによる書き込みロックまたは読み取りロックの取得がブロックされます。
  • (3) 粒度レベルから、テーブル ロックと行ロックに分けられます

注:

(1) 読み取りロック、書き込みロック ロックはすべて行レベルのロックです。つまり、トランザクション 1 は製品 A の書き込みロックを取得し、トランザクション 2 は製品 B の書き込みロックを取得し、相互にブロックしません。 (2) SQL ステートメントで行ロックが使用されている場合、SQL がインデックスを使用せずにテーブル全体のスキャンを使用する場合、行レベルのロックはテーブル ロックになります。

(3) ロックはコミットまたはロールバックが実行されたときにのみ解放され、すべてのロックが同時に解放されます。
(4) Innodb エンジンが通常の変更および削除 SQL ステートメントを実行すると、変更および削除された行に行ロックが追加されます。


共有ロック (読み取りロック、読み取りと書き込みの相互排他、読み取りと読み取りは相互に影響しません)

トランザクション A は、共有ロックを使用して特定の (トランザクション B がこれらのレコードを読み取ることができる場合、共有ロックの追加を続行できますが、これらのレコードを変更することはできません (トランザクション C がこれらのデータを変更または削除すると、ロック待機がタイムアウトになるかトランザクションが終了するまでブロック状態になります) A コミット)

共有ロックの使用方法と共有ロックの解放方法

    # 加锁SELECT ... LOCK IN SHARE MODE# 释放锁commit;rollback;
  • 関数
      SELECT ... LOCK IN SHARE MODE が追加されます。読み取られたレコードの複数の行に共有ロックが設定されている場合 (共有ロック)、他のトランザクションはこれらの行をクエリすることしかできませんが、これらのレコードを変更することはできません。複数のトランザクションが同じ行レコードに共有ロックを追加できるため、共有ロックを取得するトランザクションが必ずしも行データを変更できるとは限りません

    • 使用シナリオ:
    • 他のトランザクションによる結果セットの更新を防止しながら、結果セットの最新バージョンを読み取ります。

      例: 製品在庫に対する同時操作

    • 排他的ロック (書き込みロック) 、排他ロック)

    select ... for update は、読み取り行レコードに排他ロックを追加し、排他ロックを取得したトランザクションのみが行レコードを変更できるようにし、他のトランザクションが行レコードを変更できないようにします。通常と同じように行 update ステートメントは実行時に行ロックを追加します。

    排他ロックの使用方法

      # 加排他锁select ... for update //排他锁 # 释放锁commit;rollback;
    • 共有ロックと排他ロックの違い

      (1) トランザクションごとに 1 回排他ロックを取得すると、他のトランザクションは排他ロックを取得できなくなります。 複数のトランザクションで、同じデータ行に共有ロックを追加できます。

      (2) 他のトランザクションもその行に共有ロックまたは排他ロックを追加する可能性があるため、指定された行に共有ロックを追加するトランザクションは、必ずしもその行のデータを変更するとは限りません。排他ロックを追加するトランザクション指定された行に追加すると、排他ロックを使用して行データを変更できます。


      #テーブル ロック

      テーブル レベルのロックは、主に、次のような一部の非トランザクション ストレージ エンジンで使用されます。 MyISAM、MEMORY、CSV など。 テーブル ロックは通常、データ移行中に使用されます。

      インテンション ロック: インテンション共有ロックとインテンション排他ロック

      共有ロックを行に追加するための前提条件は、行のデータが配置されているテーブルが最初にロックを解除することです。インテンション共有ロックを取得します。 行に排他ロックを追加するための前提条件は、行のデータが配置されているテーブルが最初に目的の排他ロックを取得することです。

      注: インテンション共有ロックとインテンション排他ロックはテーブル ロックであり、手動で作成することはできません。



      インテンションロックを追加する必要がある理由

      意向锁是为了告知mysql该表已经存在数据被加锁,而不需要逐行扫描是否加锁,提搞加锁的效率。

      单个表锁定

      lock tables saas.goods read,saas.account write;  // 给saas库中的goods表加读锁,account表加写锁unlock tables;   //解锁

      全局表锁定

      FLUSH TABLES WITH READ LOCK;   // 所有库所有表都被锁定只读unlock tables;         //解锁

      注意: 在客户端和数据库断开连接时,都会隐式的执行unlock tables。如果要让表锁定生效就必须一直保持连接。

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

      行锁

      • 行锁是锁一行或者多行记录
      • MySQL的行锁是基于索引,行锁是加在索引上,而不是加在行记录上的。
        MySQL ロック メカニズムの再考
        如上图所示,数据库中有1个主键索引和1个普通索引,图中的sql语句是基于普通索引查询,命中4条记录,此时一把行锁就锁定两条记录,而其他事务修改这两条记录中的任意一条,都会一直阻塞【获取锁的事务没有执行commit之前】,下图就是上图没有执行commit语句时的情况。
        MySQL ロック メカニズムの再考

      行锁升级为表锁(行锁实际是给索引加锁,如果没用索引而全表扫描,则会给全表加锁)

      MySQL ロック メカニズムの再考
      上图中where条件中,虽然template_name建立普通索引,但使用or关键字,导致template_name的索引失效,从而进行了全表扫描,锁定了整张表。

      修改、删除某一行记录,且未提交事务时,该行会一直被行锁锁定

      MySQL ロック メカニズムの再考
      窗口1中删除某一行,但没有提交。窗口2中更新该行会一直处于阻塞中。
      MySQL ロック メカニズムの再考

      记录锁

      • 行锁:行锁是命中索引,一把锁锁的是一张表的一条记录或多条记录
      • 记录锁:记录锁是在行锁的衍生锁,记录锁锁的是表中的某一条记录,记录锁出现的条件必须是:精确命中索引,且索引是唯一索引(比如主键id、唯一索引列)。

      间隙锁(Gap Locks)

      经典参考文章

      间隙锁的作用:防止幻读

      间隙锁的目的是为了防止幻读,其主要通过两个方面实现这个目的:
      (1)防止止间隙内有新数据被插入
      (2)防止范围内已存在的数据被更新

      innodb自动使用间隙锁的条件

      (1)数据隔离级别必须为可重复读
      (2)检索条件必须使用索引(没有使用索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加)

      间隙锁锁定的区域

      根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B)。下图中,where number=5的话,那么间隙锁的区间范围为[4,11];
      MySQL ロック メカニズムの再考

      session 1:start  transaction ;触发间隙锁的方式1:select  * from news where number=4 for update ;触发间隙锁的方式2:update news set number=3 where number=4; session 2:start  transaction ;insert into news value(2,4);#(阻塞)insert into news value(2,2);#(阻塞)insert into news value(4,4);#(阻塞)insert into news value(4,5);#(阻塞)insert into news value(7,5);#(执行成功)insert into news value(9,5);#(执行成功)insert into news value(11,5);#(执行成功)

      next-key锁【临键锁】

      next-key锁其实包含了记录锁和间隙锁,即锁定一个范围,并且锁定记录本身。InnoDB默认加锁方式是next-key 锁。

      select * from news where number=4 for update ;

      MySQL ロック メカニズムの再考

      next-key锁锁定的范围为间隙锁+记录锁,即区间(2,4),(4,5)加间隙锁,同时number=4的记录加记录锁,即next-key锁的锁定的范围为(2,4],(4,5]。

      记录锁、间隙锁、临间锁的区别

      MySQL ロック メカニズムの再考

      update news  set number=0 where id>15

      sql默认加的是next-key锁。根据上图,next-key锁的区间为(-∞,1],(1,5],(5,9],(9,11],(11,+∞),上面id>15,实际上next-key锁是加在[11,+∞)这个范围内,而不是(15,+∞)这个范围内。注意:需要使用锁的字段必须加索引,因为锁是加在索引上的,没有索引则加的表锁。

      相关免费学习推荐:mysql数据库(视频)

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

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