検索
ホームページデータベースmysql チュートリアルMySQL 過去を振り返り、新しいことを学ぶ -- Innodb ストレージ エンジンのロック

最近、ロックの問題にたくさん遭遇したので、それらを解決した後、ロックに関する本を注意深く読みました。それらは次のように構成されています:

1
、ロックの種類

Innodb ストレージ エンジンは、次の 2 の標準行レベル ロックを実装しています:

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

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

トランザクションが行 r の共有ロックを取得すると、読み取りによって行 が変更されないため、別のトランザクションもすぐに行 r の共有ロックを取得できます。 この場合、rのデータはロック対応です。ただし、トランザクションが行 r の排他ロックを取得したい場合は、トランザクションが行 r を解放するまで待つ必要があります。この場合、ロックは互換性がありません。次の表に示すように、この 2 つは互換性がありません:

排他ロックと共有ロックの互換性

競合

競合

S 共有ロック

競合

互換性があります

2、ロック拡張

Innodb ストレージ エンジンは、行レベルでのロックとテーブル レベルでのロックを同時に許可する多粒度ロックをサポートしています。時間が存在する。さまざまな粒度でのロック操作をサポートするために、InnoDB ストレージ エンジンは、インテンション ロックという追加のロック方法をサポートしています。インテンション ロックは、主にトランザクション内の次の行に要求されるロックの種類を明らかにするために設計されたテーブル レベルのロックです。また、2 つのタイプに分けられます:

? 意図された共有ロック (IS Lock)、トランザクションはテーブル内の特定の行の共有ロックを取得したいと考えています。

? 意図的な排他ロック (IX Lock)、トランザクションはテーブル内の特定の行に対して排他ロックを取得しようとしています。

InnoDB は行レベルのロックをサポートしているため、インテンション ロックはテーブル全体 scan 以外のリクエストを実際にはブロックしません。共有ロック、排他ロック、意図共有ロック、意図排他ロックはすべて相互に互換性があります/相互に排他的な関係は、互換性マトリックスで表すことができます(yは互換性を意味し、n は互換性がないことを意味します)、以下に示すように:

競合

IS

意図共有ロック

Clash

S

シェアロック

互換性

競合

互換性

IX 意図排他ロック

紛争

紛争

互換性あり

互換性あり

インテント共有ロック

競合

互換性あり

互換性あり

対応

それらの間の関係はすべて互換性があります。つまり、それらはすべて単に「意図的」であり、まだ YY ステージで実際には何もしていないので、互換性があります。 残りは XIX S これら 4 つの関係セットは、関係から派生します。

簡単に言うと、の関係なぜ?なぜなら、トランザクションは IX ロックを取得した後、X ロックを取得する権利を有するからです。 XIXが互換性がある場合、両方のトランザクションがを取得する状況が発生します。相互排他は矛盾するため、XIXは相互排他のみ可能です。残りの 3 セットの関係は類似しており、同じ方法で導出できます。 3、ロックシーンをシミュレートします

InnoDB Pluginを導入する前は、SHOW FULL PROCESSLISSHOW ENGINE INNODB STATUSを介して現在のデータベースリクエストを表示し、トランザクション内のロック状況を判断することしかできませんでした。新しいバージョンの InnoDB プラグイン では、3 テーブル、INNODB_LOCKSINNODB_TRXinformation_schema に追加されましたライブラリINNODB_LOCK_WAITS。これらの 3 テーブルを使用すると、現在のトランザクションをより簡単に監視し、考えられるロックの問題を分析できます。データベースが正常に実行されている場合、これらの 3 テーブルはレコードがなく空になります。

3.1

、オープントランザクションt1t2、シミュレートロック

オープン

2セッション ウィンドウを開いて 2 トランザクション を開きますt1t2

最初のウィンドウでトランザクションを開きます

t1次のようにロック操作を実行しますt1トランザクションウィンドウインターフェース:

mysql> set autocommit =0;
Query OK, 0 rows affected (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
  开始执行锁定操作
mysql> select * from test.t1 where a<5 for update;
+---+----+----+
| a | b  | c  |
+---+----+----+
| 1 | c2 | c2 |
| 2 | a  |    |
| 3 | r5 | r3 |
| 4 | r4 | r5 |
+---+----+----+
4 rows in set (0.00 sec)


mysql>

这个时候,事务t1已经锁定了表t1的所有a的数据行,然后去第二个窗口开启第二个事务t2,如下,会看到update语句一直在等待事务t1释放锁资源,过了几秒后,会有报错信息,如下t2事务窗口界面:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
 
mysql> update test.t1 set b=&#39;t2&#39; where a=1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql>


 

3.2,通过3个系统表来查看锁信息

l  1INNODB_TRX

先看下表的重要字段以及记录的信息

a)         trx_idinnodb存储引擎内部事务唯一的事务id

b) trx_state: 現在のトランザクションのステータス。

c) trx_started: トランザクションが開始された時刻。

d) trx_requested_lock_id: トランザクション id のステータスが LOCK WAIT の場合、この値は占有されているロック リソース現在のトランザクションidtrx_stateLOCK WAITでない場合、この値はnullです。 e) trx_wait_started

: トランザクションの開始を待機している時間。 f) trx_weight

: トランザクションの重みは、トランザクションによって変更およびロックされた行の数を反映します。 innodbのストレージエンジンでは、デッドロックが発生してロールバックが必要な場合、innodbストレージエンジンはロールバックの値が最も小さいトランザクションを選択します。

g)         trx_mysql_thread_id:正在运行的mysql中的线程idshow full processlist显示的记录中的thread_id

h)         trx_query:事务运行的sql语句,在实际中发现,有时会显示为null值,当为null的时候,就是t2事务中等待锁超时直接报错(ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction)后,trx_query就显示为null

……

因为前面模拟了事务锁场景,开启了t1t2事务,现在去查看这个表信息,会有2条记录如下:

mysql> select * from INNODB_TRX\G
*************************** 1. row ***************************
                    trx_id: 3015646
                 trx_state: LOCK WAIT
               trx_started: 2014-10-07 18:29:39
     trx_requested_lock_id: 3015646:797:3:2
          trx_wait_started: 2014-10-07 18:29:39
                trx_weight: 2
       trx_mysql_thread_id: 18
                 trx_query: update test.t1 set b=&#39;t2&#39; where a=1
       trx_operation_state: starting index read
         trx_tables_in_use: 1
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 376
           trx_rows_locked: 1
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: READ COMMITTED
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 10000
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 2. row ***************************
                    trx_id: 3015645
                 trx_state: RUNNING
               trx_started: 2014-10-07 18:29:15
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 2
       trx_mysql_thread_id: 17
                 trx_query: NULL
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 0
          trx_lock_structs: 2
     trx_lock_memory_bytes: 376
           trx_rows_locked: 4
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: READ COMMITTED
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 10000
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
2 rows in set (0.00 sec)
 
mysql>


これは、トランザクションt2が実行中であるtrx_query: update test.t1 set b='t2' where a=1sqlステートメント、など、現在実行中のトランザクションの一部のみを記録します。 t1が先に実行されるので trx_state: RUNNING 最初に適用されたリソースは常に実行中、t2は後から実行されるので trx_state: LOCK WAIT in Wait t1が完了した後にリソースが解放されるようにします。 ただし、ロックの一部の詳細を慎重に判断することはできません。INNODB_LOCKS テーブル データを再度確認する必要があります。

l

2INNODB_LOCKSテーブルa)

lock_id

: ロックされたidとロックされたスペースID、番号、ページ数、数量B) Lock_trx_id

: ロックトランザクション

IDc) lock_mode

: ロックモード。

d)         lock_type:锁的类型,表锁还是行锁

e)         lock_table:要加锁的表。

f)          lock_index:锁的索引。

g)         lock_spaceinnodb存储引擎表空间的id号码

h)         lock_page:被锁住的页的数量,如果是表锁,则为null值。

i)           lock_rec:被锁住的行的数量,如果表锁,则为null值。

j)           lock_data:被锁住的行的主键值,如果表锁,则为null值。

mysql> select * from INNODB_LOCKS\G
*************************** 1. row ***************************
    lock_id: 3015646:797:3:2
lock_trx_id: 3015646
  lock_mode: X
  lock_type: RECORD
 lock_table: `test`.`t1`
 lock_index: PRIMARY
 lock_space: 797
  lock_page: 3
   lock_rec: 2
  lock_data: 1
*************************** 2. row ***************************
    lock_id: 3015645:797:3:2
lock_trx_id: 3015645
  lock_mode: X
  lock_type: RECORD
 lock_table: `test`.`t1`
 lock_index: PRIMARY
 lock_space: 797
  lock_page: 3
   lock_rec: 2
  lock_data: 1
2 rows in set (0.00 sec)
 
mysql>


owren現在のロック情報を見ることができます。2。トランザクションはロックされています。同じデータを見てください

Lock_space:797Lock_Page:3Lock_rec:2トランザクションt1およびトランザクションt2同じlnodbdataブロックにアクセスしてから、lock_datafieldinformationlock_data:1を渡すと、データのロックが表示されます行はすべて主キー 1 を持つデータ レコードです。2 トランザクション t1t2 が同じリソースに適用されていることがわかります。そのため、それらはロックされ、トランザクションが待機中です。 lock_modeからも確認できます:

PS: 範囲クエリの更新を実行する場合、この lock_data の値は完全には正確ではありません。範囲更新を実行すると、lock_data は、現在のリソースがロックされている場合、同時にページがロックされているため、最初に見つかった最初の行の主キー値のみを返します id; InnoDB ストレージ エンジンのバッファ プールの容量により、INNODB_LOCKS テーブルを表示すると、この lock_data の値が表示されます。 InnoDB ストレージ エンジンはディスクからの別のルックアップを実行しないことを意味します。 INNODB_LOCK_WAITS テーブル

トランザクション量が比較的少ない場合は直感的に確認できますが、トランザクション量が非常に大きくロック待ちが頻繁に発生する場合は、

INNODB_LOCK_WAITS

テーブルを使用してさらに多くのことを行うことができます現在のロック待機状況を直感的に反映します:

INNODB_LOCK_WAITS テーブルのメインフィールドは次のとおりです:

1)         requesting_trx_id:申请锁资源的事务id

2)         requested_lock_id:申请的锁的id

3)         blocking_trx_id:阻塞的事务id

4)         blocking_lock_id:阻塞的锁的id

去看下当前锁等待信息,如下所示:

mysql> select * from INNODB_LOCK_WAITS\G
*************************** 1. row ***************************
requesting_trx_id: 3015646
requested_lock_id: 3015646:797:3:2
  blocking_trx_id: 3015645
 blocking_lock_id: 3015645:797:3:2
1 row in set (0.00 sec)
mysql>


这里我们可以看到事务t1(3015646)申请了锁资源,而事务t2(3015645)则阻塞了事务t1的申请。我们管理其他表,得到更直观的详细信息,如下所示:

mysql> SELECT it2.`trx_id` AS waiting_trx_id, it2.`trx_mysql_thread_id` AS waiting_thread,it2.`trx_query` AS waiting_query,  it1.`trx_id` AS blocking_trx_id, it1.`trx_mysql_thread_id` blocking_thread, it1.`trx_query` blocking_query FROM `information_schema`.`INNODB_LOCK_WAITS` ilw, `information_schema`.`INNODB_TRX` it1,`information_schema`.`INNODB_TRX` it2 WHERE it1.`trx_id`=ilw.`blocking_trx_id` AND it2.`trx_id`=ilw.`requesting_trx_id`;
+----------------+----------------+-------------------------------------+-----------------+-----------------+----------------+
| waiting_trx_id | waiting_thread | waiting_query                       | blocking_trx_id | blocking_thread | blocking_query |
+----------------+----------------+-------------------------------------+-----------------+-----------------+----------------+
| 3015647        |             18 | update test.t1 set b=&#39;t2&#39; where a>2 | 3015645         |              17 | NULL           |
+----------------+----------------+-------------------------------------+-----------------+-----------------+----------------+
1 row in set (0.00 sec)
 
mysql>


 

4 原理分析一貫性 非ロック行読み取り (一貫性のある非ロック読み取り

CNRと呼ばれる) は、InnoDBを参照します ストレージ エンジンが電流を読み取る行マルチバージョン管理 (マルチバージョン管理) による実行 タイムデータベースで実行されるデータ。読み取り行が deleteupdate

操作を実行している場合、読み取り操作は行ロックが解放されるまで待機しません。逆に、 InnoDB ストレージ エンジンはその行を読み取ります。以下の図に示すように、行のスナップショット データ: Xのリリースを待つ必要がないため、非ロック読み取り。アクセスされた行のロック、スナップショット データ この実装は Undo セグメントを通じて実装され、Undo はトランザクション内のデータをロールバックするために使用されるため、スナップショット自体が使用されます。さらに、履歴データを変更する必要がないため、スナップショットの読み取りにはロックをアップロードする必要がありません。

非ロック読み取りは、InnoDB

ストレージ エンジンのデフォルト設定では、これがデフォルトの読み取り方法であり、読み取りはテーブルのロックを占有したり待機したりしません。 。ただし、トランザクション分離レベルが異なると読み取り方法が異なります。すべてのトランザクション分離レベルで一貫した読み取りが行われるわけではありません。同様に、両方が一貫した読み取りを使用する場合でも、スナップショット データの定義は異なります。

 

快照数据其实就是当前数据之前的历史版本,可能有多个版本。如上图所示,一个行可能不止有一个快照数据。我们称这种技术为行多版本技术。由此带来的并发控制,称之为多版本并发控制(Multi Version Concurrency ControlMVCC)。

 

Read CommittedRepeatable Read模式下,innodb存储引擎使用默认的非锁定一致读。在Read Committed隔离级别下,对于快照数据,非一致性读总是读取被锁定行的最新一份快照数据;而在Repeatable Read隔离级别下,对于快照数据,非一致性读总是读取事务开始时的行数据版本。

 

4.2CNR实例

开启2Session AB

Session  A:
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
 
mysql> select * from t1 where a=1;
+---+----+----+
| a | b  | c  |
+---+----+----+
| 1 | c2 | c2 |
+---+----+----+
1 row in set (0.00 sec)
 
mysql>


Session A中事务已经开始,读取了a=1的数据,但是还没有结束事务,这时我们再开启一个Session B,以此模拟并发的情况,然后对Session B做如下操作:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
 
mysql> update t1 set a=111 where a=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
 
mysql>


Session 中将a=1的行修改为a=111,但是事务同样没有提交,这样a=1的行其实加了一个X锁。这时如果再在Session A中读取a=1的数据,根据innodb存储引擎的特性,在Read CommittedRepeatable Read事务隔离级别下,会使用非锁定的一致性读。回到Session A,节着上次未提交的事务,执行select * from t1 where a=1;的操作,显示的数据应该都是原来的数据:

mysql> select * from t1 where a=1;
+---+----+----+
| a | b  | c  |
+---+----+----+
| 1 | c2 | c2 |
+---+----+----+
1 row in set (0.00 sec)
 
mysql>


因为当前a=1的数据被修改了1次,所以只有一个版本的数据,接着我们在Session Bcommit上次的事务。如:

mysql> commit;
Query OK, 0 rows affected (0.00 sec)
 
mysql>


 

Session B提交事务后,这时再在Session A中运行select * from t1 where a=1;sql语句,在READ-COMMITTEDREPEATABLE-READ事务隔离级别下,得到的结果就会不一样,对于READ-COMMITTED模事务隔离级别,它总是读取行的最新版本,如果行被锁定了,则读取该行的最新一个快照(fresh snapshot)。因此在这个例子中,因为Session B已经commit了事务,所以在READ-COMMITTED事务隔离级别下会得到如下结果,查询a=1就是为null记录,因为a=1的已经被commit成了a=111,但是如果查询a=111的记录则会被查到,如下所示:

mysql> show variables like &#39;tx_isolation&#39;;
+---------------+----------------+
| Variable_name | Value          |
+---------------+----------------+
| tx_isolation  | READ-COMMITTED |
+---------------+----------------+
1 row in set (0.00 sec)
 
mysql> select * from t1 where a=1;
Empty set (0.00 sec)
 
mysql> select * from t1 where a=111;
+-----+----+----+
| a   | b  | c  |
+-----+----+----+
| 111 | c2 | c2 |
+-----+----+----+
1 row in set (0.01 sec)
 
mysql>


 

但是如果在REPEATABLE-READ事务隔离级别下,总是读取事务开始时的数据,所以得到的结果截然不同,如下所示:

mysql> show variables like &#39;tx_isolation&#39;;
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)
 
mysql> select * from t1 where a=1;
+---+----+----+
| a | b  | c  |
+---+----+----+
| 1 | c0 | c2 |
+---+----+----+
1 row in set (0.00 sec)
 
mysql> select * from t1 where a=111;
Empty set (0.00 sec)
 
mysql>


 

对于READ-COMMITTED的事务隔离级别而言,从数据库理论的角度来看,其实违反了事务ACIDI的特性,既是隔离性,整理成时序表,如下图所示。

| |

Time

Session  A

Session  B

time 1

Begin;

Select * from t1 where a=1;有记录

 

time 2

Begin;

Update t1 set a=111 where a=1;

|

t1から*を選択してくださいここで、a=1;

記録

コミット;

V 時間 6

コミット;

ACID原則のI原則分離に従う場合、セッション全体でセッションASelect * from t1 where a=1;がクエリされる必要があります。データは一定のままですが、現時点では セッション A は時間 5 で終了していません。クエリ結果は変更されており、時間 1 および時間 3 と矛盾しており、ACID の分離を満たしていません。 FOR UPDATE && SELECT LOCK IN SHARE MODE


デフォルト この場合、

innodb

ストレージエンジンの

select

操作は一貫した非ロック読み取りを使用しますが、場合によっては読み取り操作が使用されます。ロックする必要があります。

Innodbストレージ エンジンは、読み取り行レコードの select ステートメント ;

2

タイプの追加ロック操作をサポートします。 1つ追加します

?  SELECT ... LOCK IN SHARE MODE 对于读取的行记录添加一个S共享锁。其它事务可以向被锁定的行加S锁,但是不允许添加X锁,否则会被阻塞。

对于一致性 非锁定读,即使读取的行数已经被SELECT ... FOR UPDATE了,但是也是可以进行读取的。

         PS… FOR UPDATE以及LOCK IN SHARE MODE必须在一个事务中,如果事务commit了,锁也就释放了,所以在使用的时候务必加上begin;start transaction或者set autocommit=0;

 

例子如下:

会话A:开启事务,执行LOCK IN SHARE MODE;锁定

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
 
mysql> SELECT * FROM t1 WHERE a=1 LOCK IN SHARE MODE;
+---+----+----+
| a | b  | c  |
+---+----+----+
| 1 | c0 | c2 |
+---+----+----+
1 row in set (0.00 sec)
 
mysql>


 

同时在另外一个窗口开启会话B,执行dml操作

mysql> begin;
Query OK, 0 rows affected (0.00 sec)
 
mysql> update t1 set a=111 where a=1;


这里会卡住,没有信息。

 

再开启一个会话C,查询INNODB_LOCKSINNODB_TRXINNODB_LOCK_WAITS表,就会看到锁的详细信息:

mysql> select * from INNODB_LOCKS;
+-----------------+-------------+-----------+-----------+-------------+------------+------------+-----------+----------+-----------+
| lock_id         | lock_trx_id | lock_mode | lock_type | lock_table  | lock_index | lock_space | lock_page | lock_rec | lock_data |
+-----------------+-------------+-----------+-----------+-------------+------------+------------+-----------+----------+-----------+
| 3015708:797:3:2 | 3015708     | X         | RECORD    | `test`.`t1` | PRIMARY    |        797 |         3 |        2 | 1         |
| 3015706:797:3:2 | 3015706     | S         | RECORD    | `test`.`t1` | PRIMARY    |        797 |         3 |        2 | 1         |
+-----------------+-------------+-----------+-----------+-------------+------------+------------+-----------+----------+-----------+
2 rows in set (0.00 sec)
 
mysql>
mysql> select * from INNODB_LOCK_WAITS;
+-------------------+-------------------+-----------------+------------------+
| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id |
+-------------------+-------------------+-----------------+------------------+
| 3015708           | 3015708:797:3:2   | 3015706         | 3015706:797:3:2  |
+-------------------+-------------------+-----------------+------------------+
1 row in set (0.00 sec)
 
mysql>
mysql> SELECT it2.`trx_id` AS waiting_trx_id, it2.`trx_state` AS waiting_trx_status,it2.`trx_mysql_thread_id` AS waiting_thread,it2.`trx_query` AS waiting_query,
    -> it1.`trx_id` AS blocking_trx_id, it1.`trx_mysql_thread_id` blocking_thread, it1.`trx_query` blocking_query
    -> FROM `information_schema`.`INNODB_LOCK_WAITS` ilw, `information_schema`.`INNODB_TRX` it1,`information_schema`.`INNODB_TRX` it2
    -> WHERE it1.`trx_id`=ilw.`blocking_trx_id` AND it2.`trx_id`=ilw.`requesting_trx_id`;
+----------------+--------------------+----------------+-------------------------------+-----------------+-----------------+----------------+
| waiting_trx_id | waiting_trx_status | waiting_thread | waiting_query                 | blocking_trx_id | blocking_thread | blocking_query |
+----------------+--------------------+----------------+-------------------------------+-----------------+-----------------+----------------+
| 3015708        | LOCK WAIT          |             18 | update t1 set a=111 where a=1 | 3015706         |              21 | NULL           |
+----------------+--------------------+----------------+-------------------------------+-----------------+-----------------+----------------+
1 row in set (0.00 sec)
 
mysql>


会话A开启的事务1(事务id3015706)执行了SELECT * FROM t1 WHERE a=1 LOCK IN SHARE MODE;

ステートメントは a=1 の行に S ロックを追加したため、トランザクション 2 がセッション B (トランザクション id: 2 3015708 ) が実行されました update t1 set a=111 where a=1;sql ステートメントは トランザクション 1 がブロックされているため、トランザクション 2 のステータス値は次のようになります待っていたLOCK WAIT。トランザクションがタイムアウトを待機するまで、エラーは次のように報告されます: mysql> update t1 set a=111 where a=1;ERROR 1205 (HY000): ロック待機タイムアウトを超過しました

mysql>

この時点で、セッション

B

のトランザクション

2

が終了します

update t1 set a=111 where a=1;'s dml リクエスト操作。 6

、自己成長およびロック

自增长在数据库中是非常常见的一种属性,在Innodb的存储引擎的内存结构中,对每个含有自增长值的表都有一个自增长计数器(auto-increment counter)。当对有自增长字段的表进行insert时候,这个计数器会被初始化,执行如下的sql语句来得到计数器的值。

SELECT MAX(auto_inc_col) FROM tablename FOR UPDATE;

插入操作会依据这个自增长的计数器值+1赋予自增长列,这个实现方式称为AUTO-INC Locking,这种锁其实是一种特殊的表锁机制,为了提高插入的性能,锁不是在一个事务完成后才释放,而是在完成对自增长值插入的sql语句后立即释放。

 

mysql 5.1.22版本开始,提供了一些轻量级互斥的自增长实现机制,这种机制大大提高自增长值插入的性能。还提供了一个参数innodb_autoinc_lock_mode,默认值为1.

 

自增长的分类:

mysqlinnodb表中,自增长列必须是索引,而且必须为索引的第一列,如果是第二个列会报错如下所示:

mysql> CREATE TABLE t(a INT AUTO_INCREMENT ,b VARCHAR(10),KEY (b,a));
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
mysql>
mysql> CREATE TABLE t(a INT AUTO_INCREMENT ,b VARCHAR(10),PRIMARY KEY (a),KEY (b,a));
Query OK, 0 rows affected (0.01 sec)
 
mysql>


而在myisam表中,则没有这样的限制,如下所示:

mysql>  CREATE TABLE t_myisam(a INT AUTO_INCREMENT ,b VARCHAR(10),KEY (b,a))engine=myisam;
Query OK, 0 rows affected (0.01 sec)


 

mysql>

 

7MySQL外键和锁

innodb存储引擎中,对于一个外键列,如果没有显式的针对这个列添加索引Innodb存储引擎会自动的对其添加一个索引,这样可以避免表锁,这点比oracle做的较好一些,oracle需要自己手动添加外键锁。

 以上就是MySQL 温故而知新--Innodb存储引擎中的锁的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
MySQLのライセンスは、他のデータベースシステムと比較してどうですか?MySQLのライセンスは、他のデータベースシステムと比較してどうですか?Apr 25, 2025 am 12:26 AM

MySQLはGPLライセンスを使用します。 1)GPLライセンスにより、MySQLの無料使用、変更、分布が可能になりますが、変更された分布はGPLに準拠する必要があります。 2)商業ライセンスは、公的な変更を回避でき、機密性を必要とする商用アプリケーションに適しています。

MyisamよりもInnodbを選びますか?MyisamよりもInnodbを選びますか?Apr 25, 2025 am 12:22 AM

Myisamの代わりにInnoDBを選択する場合の状況には、次のものが含まれます。1)トランザクションサポート、2)高い並行性環境、3)高いデータの一貫性。逆に、Myisamを選択する際の状況には、1)主に操作を読む、2)トランザクションサポートは必要ありません。 INNODBは、eコマースプラットフォームなどの高いデータの一貫性とトランザクション処理を必要とするアプリケーションに適していますが、Myisamはブログシステムなどの読み取り集約型およびトランザクションのないアプリケーションに適しています。

MySQLの外国キーの目的を説明してください。MySQLの外国キーの目的を説明してください。Apr 25, 2025 am 12:17 AM

MySQLでは、外部キーの機能は、テーブル間の関係を確立し、データの一貫性と整合性を確保することです。外部キーは、参照整合性チェックとカスケード操作を通じてデータの有効性を維持します。パフォーマンスの最適化に注意し、それらを使用するときに一般的なエラーを避けてください。

MySQLのインデックスのさまざまなタイプは何ですか?MySQLのインデックスのさまざまなタイプは何ですか?Apr 25, 2025 am 12:12 AM

MySQLには、B-Treeインデックス、ハッシュインデックス、フルテキストインデックス、空間インデックスの4つのメインインデックスタイプがあります。 1.B-Treeインデックスは、範囲クエリ、ソート、グループ化に適しており、従業員テーブルの名前列の作成に適しています。 2。HASHインデックスは、同等のクエリに適しており、メモリストレージエンジンのHASH_TABLEテーブルのID列の作成に適しています。 3。フルテキストインデックスは、記事テーブルのコンテンツ列の作成に適したテキスト検索に使用されます。 4.空間インデックスは、地理空間クエリに使用され、場所テーブルのGEOM列での作成に適しています。

MySQLでインデックスをどのように作成しますか?MySQLでインデックスをどのように作成しますか?Apr 25, 2025 am 12:06 AM

tocreateanindexinmysql、usethecreateindexstatement.1)forasinglecolumn、 "createdexidx_lastnameonemployees(lastname);" 2)foracompositeindexを使用して、 "createindexidx_nameonemployees(lastname、firstname);" 3); "3)、" 3)を使用します

MySQLはSQLiteとどのように違いますか?MySQLはSQLiteとどのように違いますか?Apr 24, 2025 am 12:12 AM

MySQLとSQLiteの主な違いは、設計コンセプトと使用法のシナリオです。1。MySQLは、大規模なアプリケーションとエンタープライズレベルのソリューションに適しており、高性能と高い並行性をサポートしています。 2。SQLiteは、モバイルアプリケーションとデスクトップソフトウェアに適しており、軽量で埋め込みやすいです。

MySQLのインデックスとは何ですか?また、パフォーマンスをどのように改善しますか?MySQLのインデックスとは何ですか?また、パフォーマンスをどのように改善しますか?Apr 24, 2025 am 12:09 AM

MySQLのインデックスは、データの取得をスピードアップするために使用されるデータベーステーブル内の1つ以上の列の順序付けられた構造です。 1)インデックスは、スキャンされたデータの量を減らすことにより、クエリ速度を改善します。 2)B-Tree Indexは、バランスの取れたツリー構造を使用します。これは、範囲クエリとソートに適しています。 3)CreateIndexステートメントを使用して、createIndexidx_customer_idonorders(customer_id)などのインデックスを作成します。 4)Composite Indexesは、createIndexIDX_CUSTOMER_ORDERONORDERS(Customer_Id、Order_date)などのマルチコラムクエリを最適化できます。 5)説明を使用してクエリ計画を分析し、回避します

データの一貫性を確保するために、MySQLでトランザクションを使用する方法を説明します。データの一貫性を確保するために、MySQLでトランザクションを使用する方法を説明します。Apr 24, 2025 am 12:09 AM

MySQLでトランザクションを使用すると、データの一貫性が保証されます。 1)StartTransactionを介してトランザクションを開始し、SQL操作を実行して、コミットまたはロールバックで送信します。 2)SavePointを使用してSave Pointを設定して、部分的なロールバックを許可します。 3)パフォーマンスの最適化の提案には、トランザクション時間の短縮、大規模なクエリの回避、分離レベルの使用が合理的に含まれます。

See all articles

ホット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 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

SublimeText3 Mac版

SublimeText3 Mac版

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

メモ帳++7.3.1

メモ帳++7.3.1

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

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター