意向锁就是InnoDB使用的表级锁澳门永利娱乐总站,会将手机号插入到user表里登记用户

在类型中不时会有那种须要,用户通过第三方系统登录时如若没有注册,则自动给用户注册,注册过的用户自动登录。有时候图省事只怕就从来INSERT INTO user ON DUPLICAET KEY UPDATE...一句
SQL
化解了,功效都平日,难点就是只要用户表中有auto_increment字段,则会招致auto_increment字段暴发空洞难点,一段时间后会发现用户ID会平时出现不屡次三番的情景,即便mysql的自增ID可以很大,一般系统是够用的,但是对于性障碍患者那么些是无法接受的。作者测试的mysql版本为5.5.58,使用的是Innodb引擎,隔离级别为Repeatable
Read。

1.Locking

1 场景

当用户从第三方登录时,假定用的是手机号做唯一标识,平日在我们自个儿的系统中会建3个用户表,如下:

 CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mobile` varchar(11) DEFAULT NULL,
  `last_login_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

当用户从第三方登录时,大家校验通过后,会将手机号插入到user表里登记用户。尽管用户已经存在,则更新最后登录时间,为了省事,常常像上面这么做,作用上看起来是没错的,难点尽管运行一段时间后会发现user表的id字段居然是不总是的,而且常常三个id之间空洞还很大,比如上二个id是4,下二个变成了21。如下边例子中,再插入一条新记录时,id会变成3,也等于说id=2那一个值被荒废了。

mysql> INSERT INTO user(mobile, last_login_time) VALUES('15012345678',
 NOW()) ON DUPLICATE KEY UPDATE last_login_time = NOW();
Query OK, 1 row affected (0.00 sec)

mysql> show create table user;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                               |
+----------------------------------------------------------------------+
| user  | CREATE TABLE `user` (
......
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 |

mysql> INSERT INTO user(mobile, last_login_time) VALUES('15012345678', 
NOW()) ON DUPLICATE KEY UPDATE last_login_time = NOW();
Query OK, 2 rows affected (0.00 sec)

mysql> show create table user;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                               |
+-------+---------------------------------------------------------------------
| user  | CREATE TABLE `user` (
......
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 |

1.1加锁方式:共享锁与独占锁

InnoDB完毕了两类行级锁, shared(S)locks 和exclusive(X)locks

  • 共享锁用于工作读取
  • 独占锁用于工作更新或许去除
  • S锁与S锁不顶牛,与X锁争执;X锁与S锁冲突,与X锁争辩

2 分析

在MySQL官方文档已经关系过这一个题材了实际上,当表t1中列a已经有3个值为1的处境下,常常状态实施上面那两条语句效果是相同的,唯独注意了,即使表t1是InnoDB引擎而且有一列为auto_increment的情景下,影响是不平等的,会暴发日前提到的auto_increment空洞难点。MyISAM引擎的表不受此影响,不会生出空洞难题。

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE t1 SET c=c+1 WHERE a=1;

越发确切的说,暴发空洞难点还跟innodb_autoinc_lock_mode本条MySQL配置相关。该配置在MySQL5.1引入,是为着进步auto_increment字段的产出质量引入的,暗中同意值为1。该值可以配备为0(traditional lock mode),1(consecutive lock mode),2(interleaved lock mode),除了0基本不爆发空洞外,配置其他值都以唯恐有auto_increment空洞的,不难总计如下,更详尽的可以参考
innodb-auto-increment-handling

  • 1)假若工作回滚了,则不管是0,1,2都会招致事情中行使过的auto_increment的值浪费。

  • 2)若是设置为0,是traditional lock mode,则任意插入语句都会加
    AUTO-INC 锁,基本不会时有暴发空洞,除了1中的rollback景况外。

  • 3)即便设置为1依然2的时候,simple inserts言辞(simple
    inserts指的是那种可以优先确定插入行数的话语,比如INSE奥迪Q3T/REPLACE INTO
    等插入单行或然多行的语句,语句中不包涵嵌套子查询)不会有空洞。不过对于bulk inserts(bulk
    inserts指的是事先不可以确定插入行数的话语,比如INSE猎豹CS6T/REPLACE INTO …
    SELECT FROM…, LOAD DATA等)和mixed-mode inserts(指的是simple
    inserts类型中约略行指定了auto_increment列的值多少尚未点名,比如:INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d')INSERT ... ON DUPLICATE KEY UPDATE那种话语)会优先分配auto_increment值,导致有的浪费。
    特别是设置为2的时候,在执行任意插入语句都不会加 AUTO-INC
    锁,从而在言语执行进度中都想必暴发空洞。

1.2加锁粒度:意向锁

InnoDB协理多粒度锁,约等于行锁与表锁的存活。意向锁就是InnoDB使用的表级锁,表明了工作之后对于这几个表所必要行级锁的花色(S|X)。因而意向锁也分为Intention
shared(IS)和Intention exclusive(IX)。

For
example,SELECT ... LOCK IN SHARE MODE
sets an IS lock and
SELECT ... FOR UPDATE
sets an IX lock.

反过来说,在收获S|X锁此前,需要取得相应的IS(或IX)|IX锁。
而这个锁的相容表如下:

X IX S IS
X Conflict Conflict Conflict Conflict
IX Conflict Compatible Conflict Compatible
S Conflict Conflict Compatible Compatible
IS Conflict Compatible Compatible Compatible

3 一种错误示范

那为了裁减第二节中的auto_increment空洞难点,一种形式就是INSE君越T前先判断下用户是不是存在,不存在才实施插入语句,否则用户每一次登录都会促成auto_increment值被浪费。方案如下:

with transaction:
    user = SELECT * FROM user WHERE mobile = '15012345678' FOR UPDATE;
    if not user:
       INSERT INTO user(mobile, last_login_time) VALUES('15012345678', NOW()) 
    UPDATE user SET last_login_time = NOW();

以此代码乍看是绝非难点了,mobile是unique
key,那样的FOR UPDATE似乎木有难点,那是一个排他锁,1个session对那条记下加了排他锁,其余session不能对那条记下加锁和改动(不可以LOCK IN SHARE MODE 以及 UPDATE
等,要专注下SELECT FOR UPDATE只在业务中照旧autocommit关闭的气象下才会加锁)。但是,这只在笔录存在的景观下才是对记录加X锁,没有Gap锁。而一旦这一个记录不设有,则对第1个不满足条件的记录加Gap锁,保障没有满意条件的笔录插入。

如果mobile=15012345678那条记下不存在,并发的五个session都得以进来SELECT ... FOR UPDATE,因为都以加的Gap锁(X
locks gap before
rec),Gap锁之间是合作的。此时,其中私行1个session再实践
INSERT INTO user(mobile, last_login_time) VALUES('15012345678', NOW())语句会因为加insert intention lock(注:插入意向锁是一种奇特的Gap锁,不是MySQL的表级意向锁IS,IX等)超时而执行破产。其实此时的Gap锁不只是锁住了
15012345678 那条记下,即便表中有其他的笔录,会将大概插入 15012345678
的间距都锁住,MySQL加锁详细分析可以见参考资料5。

1.3加锁类型

4 解决方案

为此,若是要优化auto_increment的荒废难题,又要避免上一节提到的死锁难题,依旧有个别事情要做的。可行的二种办法如下:

  • 只怕就是干脆一点,在查询用户是不是留存时一向用GET_LOCK(mobile),通过字符串锁而不是FOR UPDATE来防止上一节提到的难题。
  • 依旧就是先不加FOR UPDATE查询三遍用户表,如若用户不设有,然后再INSERT IGNORE INTO user ...。多一回询问,后边的逻辑不变。
  • 当然,percona的那篇作品avoiding-auto-increment-holes-on-innodb-with-insert-ignore还有个很tricky的主意来幸免auto_increment的肤浅难点,有趣味的可以参见。

MySQL Innodb如若出现了一部分加锁难点,可以经过上边那个指令来扶持分析。

show engine innodb status;
select * from information_schema.innodb_locks;
select * from information_schema.innodb_lock_waits;
select * from information_schema.innodb_trx;

Record Lock

Record
lock是在目录项上的锁,例如上边的SQL会将享有c1=10的行全体锁住,无法insert、update、delete

SELECT c1 FROM t WHERE c1 = 10 FOR UPDATE;

对此尚未索引的表,InnoDB也会创制贰个掩蔽的聚簇索引。

READ COMMITTED只有Record Lock没有Gap Lock和Next-key Lock,所以locking
read(即LOCK IN SHARE MODEFOR UPDATE)、UPDATE和DELETE用的都以Record
Lock
REPEATABLE READ则有Record Lock、Gap Lock和Next-key Lock

InnoDB使用行级锁时,是当它寻找或扫描1个表的目录,在它遭受的卓殊索引记录上助长共享或独占锁,所以InnoDB的行级锁实际上就是索引记录锁(Record
Lock)。

https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html\#innodb-record-locks
https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html\#isolevel\_read-committed

5 参考资料

Gap Lock

Gap
Lock是将索引记录之间的限量加锁的锁,索引值在那段范围内的笔录不只怕insert,如下SQL将锁住10<=c1<=20

SELECT c1 FROM t WHERE c1 BETWEEN 10 and 20 FOR UPDATE;

Gap
Lock可以是一段索引值、单个索引值只怕空,这是在质量和并发度之间权衡的结果,所以唯有部分工作隔离等级使用了。
Gap
Lock在利用唯一索引查询单行结果的时候并不会被用到,但当以此唯一索引是共同索引,并且询问条件只包罗了一部分索引列的时候照旧会被应用的。例如下边的SQL只会采用两个Record
Lock,如若id有唯一索引的话,并不影响之前索引值上的插入。

SELECT  *  FROM child WHERE id =  100;

当id没有索引,恐怕不是唯一索引的时候,那么索引值以前的到上二个索引值之间的限定也会被锁。
Gap Lock只会阻止在那个gap范围内的插入操作,所以Gap X-Lock与Gap
S-Lock的效用是一样的,并不会争辨。
https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html\#innodb-gap-locks

Next-key Lock

Next-key Lock是在某1个索引记录上的Record
Lock和那个目录记录以前的那段范围的Gap Lock的整合。
据此假使Session A拥有三个索引记录凯雷德上的共享|独占Next-key Lock,Session
B就无法在Lacrosse从前的那段索引记录范围内插入新的目录记录。
例如二个目录拥有拾,11、13、20多少个值,那么恐怕的Next-key
Lock就包括了如下的间隔

(-infinity, 10]
(10, 11]
(11, 13]
(13, 20]
(20, infinity)

InnoDB的暗中认可事务隔离级别是REPETABLE READ,InnoDB使用Next-key
Lock来寻找和围观索引,可以防止Phantom Rows。
https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html\#innodb-next-key-locks
https://dev.mysql.com/doc/refman/5.7/en/innodb-next-key-locking.html

Insert Intention Lock

Insert Intention
Lock是insert操作在插入行(获取该行的X锁)在此以前运用的一种Gap
Lock,多少个Session借使要插入同2个Gap,但假如是例外的目录地方那么是不会冲突的。
https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html\#innodb-insert-intention-locks

AUTO-INC Lock

AUTO-INC Lock是工作往有Auto
Increment字段的表插入记录时采用的一种表级锁,两个插入的工作需要等待来有限支撑主键值的三番五次性。
https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html\#innodb-auto-inc-locks
https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html\#sysvar\_innodb\_autoinc\_lock\_mode

2.Transaction Model

多版本(multi-versioning)数据库与两品级加锁(two-phase
locking)的三结合。暗中认可是行级锁以及无锁的一致性读(nonlocking consistent
reads)。

2.1Transaction Isolation Levels

隔离性是数据库在面对八个事情同时实施修改大概查询时,调节品质、可信性、一致性以及结果的可再现性的平衡的严重性。
共有如下多少个级别:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

InnoDB默认是REPEATABLE READ

REPEATABLE READ

  1. 同一个事务所有的Consistent
    reads(约等于默许意况,相当于不加锁)使用本事务第五遍读时确立的快照,相当于说同多少个事情中的各种SELECT互相具有一致性(约等于可再一次读,不会看到同时发出的任何作业对于数据的修改)。
  2. Locking reads(SELECT WITH FO卡宴 UPDATE O奥德赛 LOCK IN SHARE
    MODE),UPDATE,DELETE语句,会基于语句是或不是在唯一索引上使用唯一的标准而接纳差其余锁。

    • 唯一索引上的唯一标准,InnoDB会利用Record Lock把那几个index
      Record锁住,而不是Gap Lock。
    • 任何的意况下,InnoDB会使用Gap Lock或Next-Key
      Lock将围观的目录范围给锁住,以阻挡其余Session在那段范围插入记录。

READ COMMITTED

  1. 每一个Consistent
    read,即便是在同二个事务中,都会重设读取最新的快照(所以会见世不可重复读的难题)。
  2. Locking reads,UPDATE,DELETE语句,InnoDB只会动用Record
    Lock锁住这一个索引值,不会锁住Gap,约等于同意锁住的笔录附近的值的插入(会有幻读的题材),Gap
    Locking只会在外键检查和重复键检查中应用。
  • 对此UPDATE、DELETE语句,InnoDB只会保持它须求更新或删除的行的锁,对于并不包容的行的Record
    Locks,会在MySQL统计完WHERE语句后释放。
  • 对于1个UPDATE语句,若是三个行已经被锁,InnoDB使用3个半一致性读(semi-consistent
    read),再次回到最新提交到MySQL的数量版本,倘若这几个行匹配UPDATE的WHERE字句,那么MySQL会重读那么些行,并加锁只怕等待锁。

READ UNCOMMITTED

SELECT语句不会加锁,大概会读到二个行稍早的数量版本,由此在那几个级别上,读是不均等的。约等于脏读。其余地点这几个级别和READ
COMMITTED是近乎的。

SERIALIZABLE

以此级别类似于REPEATABLE READ

  • autocommit disabled,InnoDB会隐性地把拥有SELECT转换为SELECT IN SHARE
    MODE
  • antocommit enabled,SELECT就是协调的事务

2.2autocommit、commit、rollback

在InnoDB,所有的用户活动都发生在工作中,假如autocommit开启了,每种SQL语句都会友善组合3个业务,MySQL私行认同为逐个Session开启autocommit,所以各个SQL语句执行完并不曾出错的话,MySQL都会实行两次commit。假若语句重回错误,那么会基于错误执行commit\rollback。

  1. 对于开启了autocommit的Session,可以经过START TRANSACTION或者BEGIN语句来开启3个多语句的事体,然后通过COMMITROLLBACK来收场工作。
  2. 如若autocommit关闭了,那么session永远处于三个打开的事务中,三个COMMITROLLBACK语句会甘休近来的政工然后打开新的政工。(倘若session截至前卫未显式地交给最终的工作,那么MySQL会回滚)

少数语句会隐式地交给业务。
一个COMMIT说话讲明当前业务的改动已经持久化,并且对其它session可知;而二个ROLLBACK言语打消了近日工作做的具备修改。COMMIT与ROLLBACK会释放具有当前作业的InnoDB锁。

2.3Consistent nonblocking read

snapshot

某壹个特定时刻的数据表示,固然此外事情提交了改动也保持不变,特定的割裂级别使用那几个来落到实处一致性读(consistent
read)。

consistent read

是应用快照(snapshot)音讯来显示查询结果的1个读操作,也就表示InnoDB使用multi-versioning来展现某些时刻数据库快照的查询结果。那一个查询能看出那几个随时以前交付的事体修改,而不相会到同样时刻其余工作举行的修改,例外是能收看本事务在此以前交付的改动。如果查询的数目已经被其余业务修改,那么原来数据会通过undo
log的内容来重建(复苏)。那一个技术防止了一部分锁带来的面世难点。
REPEATABLE
READ级别,snapshot是展开本事务第两遍读操作时的数码,只有工作提交之后才能收获贰个新本子的snapshot。
READ COMMITTED级别,snapshot在每回consistent读操作时重设。
Consistent
read是InnoDB在KoleosC|Sportage中华V级别处理SELECT语句时的暗许形式,因为consistent
read不会给它访问的表加锁,其他session可以在一个consistent
read操作时自由地修改那一个表。
比方专断认同的级别上,当您执行一个consistent
read时,InnoDB会给你的事情三个时间点,你的询问看来的数据库就是其一时间点的数据库。假如其他作业在那么些时间点之后剔除了一条龙并提交,你看来的数据库中那一行并不会被删掉,插入与革新也相近。

snapshot状态适用于SELECT语句,而不是DML语句,倘若事务A插入或更新了有的行并提交,那么PAJERO奥迪Q5级其他别样事务B即使无法通过查询看来这一个变化,但事务B的DELETE/UPDATE语句也是会潜移默化到刚刚交付的这一个行,如果暴发了那种景色,那么那个变迁对于当下事务B就会可知,例如:

SELECT  COUNT(c1)  FROM t1 WHERE c1 =  'xyz';  
-- Returns 0: no rows match.  
DELETE  FROM t1 WHERE c1 =  'xyz';  
-- Deletes several rows recently committed by other transaction.  
SELECT  COUNT(c2)  FROM t1 WHERE c2 =  'abc';  
-- Returns 0: no rows match.  
UPDATE t1 SET c2 =  'cba'  WHERE c2 =  'abc';  
-- Affects 10 rows: another txn just committed 10 rows with 'abc' values.  
SELECT  COUNT(c2)  FROM t1 WHERE c2 =  'cba';  
-- Returns 10: this txn can now see the rows it just updated.

您可以通过提交业务来牵动时间点。
那也等于所谓的Multi-versioned concurrency control。
下边的例子中,session A唯有在session
B提交了插入操作并且本身也提交今后才能见到B插入的行,因为唯有在A提交将来A的时刻点才能通过B的付出。

             Session A              Session B

           SET autocommit=0;      SET autocommit=0;
time
|          SELECT * FROM t;
|          empty set
|                                 INSERT INTO t VALUES (1, 2);
|
v          SELECT * FROM t;
           empty set
                                  COMMIT;

           SELECT * FROM t;
           empty set

           COMMIT;

           SELECT * FROM t;
           ---------------------
           |    1    |    2    |
           ---------------------

一旦你须要每一天看到最新状态的数据库,使用瑞虎C级别或许locking read。

Consistent read对于特定DDL语句也不奏效:

  • DROP TABLE,因为MySQL无法使用贰个剔除了的表。
  • ALTEPAJEROTABLE,因为这么些语句会生成二个临时复制表,然后删除原表,当您再一次履行2个consistent
    read的时候,新表里的行对于你的snapshot来说是不存在的,所以事务会报错。

2.4Locking Reads

一经您在事情中询问数据,然后进行扦插只怕更新,普通的SELECT语句不或许提供丰裕的保安,其余作业可以创新恐怕去除你刚好查询的数据行。InnoDB接济三种locking
reads来提供额外的维护:

  • SELECT…LOCK IN SHARE MODE
    给要读得行上加共享锁,其余的事情可以读那几个行,但唯有你的事体提交之后才能改改它们。即使其余事情修改了那些行可是没有提交,那么你的询问须要等待那个事情停止然后利用新型的值。
  • SELECT…FOR UPDATE
    给行以及有关的目录记录加排他锁,与UPDATE语句看似。其余工作对于那一个行的翻新、Locking
    Reads、或许有个别隔离级别下的读都会阻塞。Consistent
    reads会忽视记录上的锁。
    负有被Locking reads设置的锁会在业务提交或回滚的时候释放。

SELECT FOR
UPDATE对于行的加锁唯有在autocommit禁用的时候使得,可以透过STATiguanT
TRANSACTION只怕将autocommit设为0来剥夺。

3.Locks set by different SQL Statements in InnoDB

Locking read、UPDATE、DELETE日常会给处理SQL进程中颇具扫描到的Index
Record加上Record
Lock。它并不会在意WHERE语句是还是不是将那几个行排除了。InnoDB不会铭记WHERE条件,只略知一二它扫描过的index范围。加的锁一般的话是Next-key
Lock,同时也会堵塞对Record前边的Gap举行扦插的操作。然则,gap
Locking可以被显式地剥夺,事务隔离等级也会影响所运用的锁。
一旦2个询问用了非聚簇索引并且加的Record
Lock也是排它锁,InnoDB也会取出对应的聚簇索引,并在地点加锁。
设若你的说话没有适用的目录使用,那么MySQL必须扫描整个表来处理语句,那么表中的每一行都会被加锁,也就会堵塞其他用户对于这几个表所有的插入,所以给表建立好的目录很主要,防止查询时环顾很多不须要的行。
InnoDB加锁的气象如下:

  • SELECT…FROM是consistent
    read,不加锁除非隔离级别设为SEHavalIALIZABLE。SE凯雷德IALIZABLE级别下,查询会给它遭受的目录记录加Next-key
    Lock,不过在利用唯一索引查询唯一的行时只会给索引记录加Record Lock。

  • SELECT…FROM…LOCK IN SHARE
    MODE给它碰到的装有索引记录加共享Next-key
    Lock,不过在利用唯一索引查询唯一的行时只会给索引记录加Record Lock。

  • SELECT…FROM…FO福睿斯 UPDATE给它蒙受的富有索引记录加排它Next-key
    Lock,但是在使用唯一索引查询唯一的行时只会给索引记录加Record
    Lock。
    澳门永利娱乐总站,对于查询时遇见的目录记录,SELECT-FO奥迪Q5-UPDATE会阻塞其他session举办SELECT-IN-SHARE恐怕有些级别下的读。Consistent
    read会忽视它多少视图上的笔录上的享有锁。

  • UPDATE…WHERE…给它蒙受的持有索引记录加排它Next-key
    Lock,然而在接纳唯一索引查询唯一的行时只会给索引记录加Record Lock。

  • 当UPDATE修改了八个聚簇索引记录,那么相关的非聚簇索引记录上的隐式锁会被拿掉。UPDATE操作也会把受到震慑的非聚簇索引记录上的共享锁拿掉,当执行插入新的非聚簇索引记录前再度值扫描或许插入新的非聚簇索引记录时。

  • DELETE FROM…WHERE…给它遭遇的保有索引记录加排它Next-key
    Lock,不过在使用唯一索引查询唯一的行时只会给索引记录加Record Lock。

  • INSE奔驰M级T会给插入的行加上3个排它锁。这几个锁是2个索引Record
    Lock,不是Next-key Lock(相当于没有Gap
    Lock)并且不会阻拦其余工作往插入行此前的Gap中插入记录。
    插入行在此以前,会加一种Insert intention Gap
    Lock,申明打算要插入,那样两个插入同二个Gap的工作倘使不是要插入到同3个职务那就不须求拭目以待。
    一经发生duplicate key
    error,会加二个共享锁在顶牛的行上。详见链接里的INSE奥德赛T
    https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html

  • INSE瑞鹰T…ON DUPLICATE KEY UPDATE与不难的INSE哈弗T分化,当爆发duplicate
    key error发生的时候,会加三个排它锁在急需创新的行上。

  • REPLACE

  • INSE宝马X5T INTO T SELECT…FROM S WHERE…加2个排它index Record
    Lock在每1个要插入到T的行上。详见文档。

  • AUTO_INCREMENT 详见文档。

  • LOCK TABLES
    会加表锁,但那是在比InnoDB层更高的MySQL层加的锁。InnoDB在innodb_table_locks = 1(the
    default) and
    autocommit = 0的意况下能感知到表锁,而MySQL层平素能感知到行锁。

4.Phantom Rows

5.Deadlocks

相关文章