范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Mysql索引,事务和锁

  一、索引
  1、存储引擎:InnoDB, MyISAM,Memory.
  2、InnoDB:数据会存储到磁盘上,在真正处理数据时,需要先将数据加载到内存,表中读取某些记录时,
  InnoDB不需要一条一条的把记录从磁盘上读出来,InnoDB采取的方式是:将数据划分位若干个页,以
  页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为16kb,也就是说,当需要从磁盘
  中读取数据时,每次最少从磁盘读取16kb的内容到内存,每次最少也会把内存中的16kb内容写到磁盘中。
  3、页是InnoDB管理存储空间的基本单位,一个页的默认大小是16kb
  show global status like "Innodb_page_size"; 页结构: 名称               中文名称             占用空间        描述 File Header        文件头部              38字节       页的一些通用信息 Page Header        页面头部              56字节       数据页专有的一些信息 Infimum+Supremum   最小记录和最大记录     26字节       两个虚拟的行记录 User Records       用户记录              不确定       实际存储的行记录内容 Free Space         空闲空间              不确定       页中尚未使用的空间 Page Director      页面目录              不确定       页中某些记录的相对位置(当一行的数据量很小时,会出现一页存储更多的记录数,查询时通过页目录可以提高查询效率) File Trailer       文件尾部              8字节        校验页是否完整
  4、InnoDB行格式
  一行记录可以以不同的格式存在Innodb中,行格式分别是Compact,Redundant,Dynamic和Compressed
  可以在创建或修改表的语句中指定行格式:
  create table 表名(列信息) ROW_FORMAT=行格式名称
  ALTER TABLE 表名 ROW_FORMAT=行格式名称 Compact行格式:     变长字段长度列表|NULL标志位|记录头信息|列1数据|列2数据...      1)MySQL支持一些变长的数据类型,比如VARCHAR(M)、 VARBINARY(M)、 TEXT类型,BLOB类型,这些数据类型 修饰列称为变长字段,变长字段中存储多少字节的数据不是固定的,所以我们在存储真实数据的时候需要顺便把 这些数据占用的字节数也存起来。在Compact行格式中,把所有变长字段的真实数据占用的字节长度都存放在记 录的开头部位,从而形成一个变长字段长度列表。 CHAR是一种固定长度的类型,VARCHAR则是一种可变长度的类型。 VARCHAR(M),M代表最大能存多少个字符。 ( MySQL5.0.3以前是字节,以后就是字符);     2)Compact行格式会把可以为NULL的列统一管理起来,存一个标记为在NULL值列表中,如果表中没有允许存储  NULL 的列,则 NULL值列表也不存在了。二进制位的值为1时,代表该列的值为NULL。二进制位的值为0时,代表该列的值不为NULL     3)除了变长字段长度列表、 NULL值列表之外,还有一个用于描述记录的记录头信息,它是由固定的5个字节组成。       5个字节也就是40个二进制位,不同的位代表不同的意思,如:       名称               大小(单位: 位:bit))         描述       预留位1             1                                         没有使用       预留位2             1                                         没有使用       delete_mask     1                                         标记该记录是否被删除       min_rec_mask   1                                        B+树的每层非叶子节点中的最小记录都会添加该标记       n_owned           4                                        表示当前记录拥有的记录数       heap_no           13                                       表示当前记录在记录堆的位置信息       record_type      3                                        表示当前记录的类型,0表示普通记录,1表示B+树非叶子节点记录,2表示最小记录,3表示最大记录       next_record     16                                        表示下一条记录的相对位置     4)记录的真实数据除了我们自己定义的列的数据以外,还会有三个隐藏列      列名                 是否必须        占用空间   描述      row_id                  否              6字节       行ID,唯一标识一条记录      transaction_id      是               6字节      事务ID      roll_pointer          是              7字节       回滚指针      实际上这几个列的真正名称其实是:DB_ROW_ID、 DB_TRX_ID、 DB_ROLL_PTR       一个表没有手动定义主键,则会选取一个Unique键作为主键,如果连Unique键都没有定义的话,则会为表默      认添加一个名为row_id的隐藏列作为主键。所以row_id是在没有自定义主键以及Unique键的情况下才会存在      的。       5)VARCHAR(M)类型的列最多可以占用65535个字节。其中的M代表该类型最多存储的字符数量,如果我们使用        ascii字符集的话,一个字符就代表一个字节,我们看看VARCHAR(65535)是否可用:        mysql> CREATE TABLE varchar_size_demo(        -> c VARCHAR(65535)        -> ) CHARSET=ascii ROW_FORMAT=Compact;        ERROR 1118 (42000): Row size too large. The maximum row size for the used table type,        not counting BLOBs, is 65535. This includes storage overhead, check the manual. You        have to change some columns to TEXT or BLOBs        mysql>        报错信息表达的意思是:MySQL对一条记录占用的最大存储空间是有限制的,除BLOB或者TEXT类型的列之外,        其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节。这个65535个字节        除了列本身的数据之外,还包括一些其他的数据,比如说我们为了存储一个VARCHAR(M)类型的列,其实需要占        用3部分存储空间:        1. 真实数据        2. 变长字段真实数据的长度        3. NULL值标识        如果该VARCHAR类型的列没有NOT NULL属性,那最多只能存储65532个字节的数据,因为变长字段的长度占用        2个字节,NULL值标识需要占用1个字节。        mysql> CREATE TABLE varchar_size_demo(        -> c VARCHAR(65532)        -> ) CHARSET=ascii ROW_FORMAT=Compact;        Query OK, 0 rows affected (0.02 sec)        CREATE TABLE varchar_size_demo(        c VARCHAR(65533) not null        ) CHARSET=ascii ROW_FORMAT=Compact;        Query OK, 0 rows affected (0.02 sec)       6)一个页的大小一般是16KB,也就是16384字节,而一个VARCHAR(M)类型的列就最多可以存储65533个字节,这        样就可能出现一个页存放不了一条记录。        在Compact和Reduntant行格式中,对于占用存储空间非常大的列,在记录的真实数据处只会存储该列的一部分        数据,把剩余的数据分散存储在几个其他的页中,然后记录的真实数据处用20个字节存储指向这些页的地址(当        然这20个字节中还包括这些分散在其他页面中的数据的占用的字节数),从而可以找到剩余数据所在的页.  Dynamic和Compressed行格式:      这两种行格式类似于COMPACT行格式,只不过在处理行溢出数据时有点儿分歧,它们不会在记录的真实数据处      存储一部分数据,而是把所有的数据都存储到其他页面中,只在记录的真实数据处存储其他页面的地址。另外,      Compressed行格式会采用压缩算法对页面进行压缩。
  5、聚族索引: 聚簇索引的特点:  1. 按主键值的大小进行记录和页的排序: 数据页(叶子节点)里的记录是按照主键值从小到大排序的一个单向链表。 数据页(叶子节点)之间也是是按照主键值从小到大排序的一个双向链表。 B+树中同一个层的页目录也是按照主键值从小到大排序的一个双向链表。  2. B+树的叶子节点存储的是完整的用户记录,就是指这个记录中存储了所有列的值(包括隐藏列)。 具有这两种特性的B+树称为聚簇索引,所有完整的用户记录都存放在这个聚簇索引的叶子节点处。这种聚簇索引 并不需要我们在MySQL语句中显式的使用INDEX语句去创建。 InnoDB存储引擎会自动的为我们创建聚簇索引。 在InnoDB存储引擎中,聚簇索引就是数据的存储方式(所有的用户记录都存储在了叶子节点),也就是所谓的索 引即数据,数据即索引。
  6、二级索引: 聚簇索引只能在搜索条件是主键值时才能发挥作用,因为B+树中的数据都是按照主键进行排序的。当我们想以别 的列作为搜索条件时我们可以多建几棵B+树,不同的B+树中的数据采用不同的排序规则。 二级索引与聚簇索引有几处不同: 1. 按指定的索引列的值来进行排序 2. 叶子节点存储的不是完整的用户记录,而只是索引列+主键。 3. 目录项记录中不是主键+页号,变成了索引列+页号。 4. 在对二级索引进行查找数据时,需要根据主键值去聚簇索引中再查找一遍完整的用户记录,这个过程叫做回表。
  7、联合索引: 以多个列的大小为排序规则建立的B+树称为联合索引,本质上也是一个二级索引。
  8、B+树索引: 1. 每个索引都对应一棵B+树。用户记录都存储在B+树的叶子节点,所有目录记录都存储在非叶子节点。 2. InnoDB存储引擎会自动为主键(如果没有它会自动帮我们添加)建立聚簇索引,聚簇索引的叶子节点包 含完整的用户记录。 3. 可以为指定的列建立二级索引,二级索引的叶子节点包含的用户记录由索引列 + 主键组成,所以如果想 通过二级索引来查找完整的用户记录的话,需要通过回表操作,也就是在通过二级索引找到主键值之后再 到聚簇索引中查找完整的用户记录。 4. B+树中每层节点都是按照索引列值从小到大的顺序排序而组成了双向链表,而且每个页内的记录(不论 是用户记录还是目录项记录)都是按照索引列的值从小到大的顺序而形成了一个单链表。如果是联合索引 的话,则页面和记录先按照联合索引前边的列排序,如果该列值相同,再按照联合索引后边的列排序。 5. 通过索引查找记录是从B+树的根节点开始,一层一层向下搜索。由于每个页面都按照索引列的值建立了 页目录,所以在这些页面中的查找非常快。
  9、根页: 创建表时,mysql先创建一页,当插入的数据第一页放不下时,会把第一页复制一份,然后新开辟新的一页存新插入的数据,原来的第一页改为根页。
  10、b+树
  11、mysql 数据存储结构
  二、查询优化1、开启查询优化器日志: set optimizer_trace="enabled=on"; -- 开启 -- 执行sql -- 查看日志信息: select * from information_schema.OPTIMIZER_TRACE; -- 关闭 set optimizer_trace="enabled=off";  2、常量传递(constant_propagation) a=1 and b>a 上面这个sql可以转换为: a = 1 and b > 1  3、等值传递(equality_propagation) a = b and b = c and c = 5 上面这个sql可以转换为: a = 5 and b = 5 and c = 5  4、移除没用的条件(trivial_condition_removal) a = 1 and 1 = 1 上面这个sql可以转换为: a = 1  5、成本: 一个查询可以有不同的执行方案,可以选择某个索引进行查询,也可以选择全表扫描,查询优化器会选择其中成 本最低的方案去执行查询。  6、IO成本: InnoDB存储引擎都是将数据和索引都存储到磁盘上的,当我们想查询表中的记录时,需要先把数据或者索引加载 到内存中然后再操作。这个从磁盘到内存这个加载的过程损耗的时间称之为I/O成本。  7、CPU成本: 读取以及检测记录是否满足对应的搜索条件、对结果集进行排序等这些操作损耗的时间称之为CPU成本。  InnoDB存储引擎规定读取一个页面花费的成本默认是1.0,读取以及检测一条记录是否符合搜索条件的成本默 认是0.2。 三、事务和锁1、事务 原子性(Atomicity)、隔离性(Isolation)、一致性(Consistency)、持久性(Durability)     -- 显示开启事务(提交、回滚)     begin; -- start transaction;     savepoint p1; -- 保存点(名称)     commit; -- rollback; ROLLBACK TO p1;
  2、隔离级别: 1未提交读(read uncommitted):一个事务可以读到其他事务还没有提交的数据,会出现脏读  2)已提交读(read committed):一个事务只能读到另一个已经提交的事务修改过的数据,并且其他事务每对该数据进行一次修改并提交后,该事                             务都能查询得到最新值,会出现不可重复读、幻读。                             如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先                             的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来,这就是幻读。  3)可重复读(repeatable read):一个事务第一次读过某条记录后,即使其他事务修改了该记录的值并且提交,该事务之后再读该条记录时,读到                             的仍是第一次读到的值,而不是每次都读到不同的数据,这就是可重复读,这种隔离级别解决了不可重复,但是                             还是会出现幻读。  4)串行化(serializable): 以上3种隔离级别都允许对同一条记录同时进行读-读、读-写、写-读的并发操作,如果我们不允许读-写、写-读                          的并发操作,可以使用SERIALIZABLE隔离级别,这种隔离基金因为对同一条记录的操作都是串行的,所以不会                          出现脏读、幻读等现象。   总结:    READ UNCOMMITTED隔离级别下,可能发生脏读 脏读、 不可重复读和和幻读问题。    READ COMMITTED隔离级别下,可能发生不可重复读 不可重复读和**幻读问题,但是不会发生 问题,但是不会发生脏读问题。    REPEATABLE READ隔离级别下,可能发生幻读 幻读问题,不会发生脏读 脏读和不可重复读的问题。    SERIALIZABLE隔离级别下,各种问题都不可以发生。    注意:这四种隔离级别是SQL的标准定义,不同的数据库会有不同的实现,特别需要注意的是    MySQL在在REPEATABLE READ隔离级别下,是可以禁止幻读问题的发生的 隔离级别下,是可以禁止幻读问题的发生的
  3、版本链:对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列(row_id并不是必要的,我们
  创建的表中有主键或者非NULL唯一键时都不会包含row_id列):
  trx_id:每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。
  roll_pointer:每次对某条记录进行改动时,这个隐藏列会存一个指针,可以通过这个指针找到该记
  录修改前的信息。
  4、ReadView:对于使用READ UNCOMMITTED隔离级别的事务来说,直接读取记录的最新版本就好了,对于使用
  SERIALIZABLE隔离级别的事务来说,使用加锁的方式来访问记录。对于使用READ COMMITTED和
  REPEATABLE READ隔离级别的事务来说,就需要用到我们上边所说的版本链了,核心问题就是:需要判断一下
  版本链中的哪个版本是当前事务可见的
  ReadView中主要包含4个比较重要的内容: 1. m_ids:表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。 2. min_trx_id:表示在生成ReadView时当前系统中活跃的读写事务中最小的事务id,也就是m_ids中的最小 值。 3. max_trx_id:表示生成ReadView时系统中应该分配给下一个事务的id值。 4. creator_trx_id:表示生成该ReadView的事务的事务id。 注意max_trx_id并不是m_ids中的最大值,事务id是递增分配的。比方说现在有id为1,2,3这三个事务,之 后id为3的事务提交了。那么一个新的读事务在生成ReadView时,m_ids就包括1和2,min_trx_id的值就是1, max_trx_id的值就是4。  有了这个ReadView,这样在访问某条记录时,只需要按照下边的步骤判断记录的某个版本是否可见: 如果被访问版本的trx_id属性值与ReadView中的creator_trx_id值相同,意味着当前事务在访问它自     己修改过的记录,所以该版本可以被当前事务访问。 如果被访问版本的trx_id属性值小于ReadView中的min_trx_id值,表明生成该版本的事务在当前事     务生成ReadView前已经提交,所以该版本可以被当前事务访问。 如果被访问版本的trx_id属性值大于ReadView中的max_trx_id值,表明生成该版本的事务在当前事     务生成ReadView后才开启,所以该版本不可以被当前事务访问。 如果被访问版本的trx_id属性值在ReadView的min_trx_id和max_trx_id之间,那就需要判断一下     trx_id属性值是不是在m_ids列表中,如果在,说明创建ReadView时生成该版本的事务还是活跃     的,该版本不可以被访问;如果不在,说明创建ReadView时生成该版本的事务已经被提交,该版     本可以被访问。  READ COMMITTED的实现方式:     每次读取数据前都生成一个ReadView。 REPEATABLE READ实现方式:     在第一次读取数据时生成一个ReadView。
  5、MVCC(版本链+read view)总结:
  MVCC(Multi-Version Concurrency Control ,多版本并发控制)指的就是在使用READ COMMITTD、
  REPEATABLE READ这两种隔离级别的事务在执行普通的SEELCT操作时访问记录的版本链的过程。可以使不同
  事务的读-写、写-读操作并发执行,从而提升系统性能。 READ COMMITTD、 REPEATABLE READ这两个隔离级
  别的一个很大不同就是:生成ReadView的时机不同,READ COMMITTD在每一次进行普通SELECT操作前都会
  生成一个ReadView,而REPEATABLE READ只在第一次进行普通SELECT操作前生成一个ReadView,之后的查
  询操作都重复使用这个ReadView就好了
  6、锁
  读锁:共享锁、 Shared Locks、 S锁
  写锁:排他锁、 Exclusive Locks、 X锁 1)读操作:     对于普通 SELECT 语句,InnoDB 不会加任何锁     select ... lock in share model;     将查找到的数据加上一个S锁,允许其他事务继续获取这些记录的S锁,不能获取这些记录的X锁(会阻塞)      select ... for update;     将查找到的数据加上一个X锁,不允许其他事务获取这些记录的S锁和X锁。  2)写操作:     DELETE:删除一条数据时,先对记录加X锁,再执行删除操作     INSERT:插入一条记录时,会先加隐式锁 隐式锁来保护这条新插入的记录在本事务提交前不被别的事务访问到。     UPDATE:如果被更新的列,修改前后没有导致存储空间变化,那么会先给记录加X锁,再直接对记录进行修改。             如果被更新的列,修改前后导致存储空间发生了变化,那么会先给记录加X锁,然后将记录删掉,再Insert一条新记录      隐式锁:一个事务插入一条记录后,还未提交,这条记录会保存本次事务id,而其他事务如果想来读取这个记     录会发现事务id不对应,所以相当于在插入一条记录时,隐式的给这条记录加了一把隐式锁。
  7、行锁和表锁: 1)行锁:     LOCK_REC_NOT_GAP:单个行记录上的锁     LOCK_GAP:间隙锁,锁定一个范围,但不包括记录本身。 GAP锁的目的,是为了防止同一事务                     的两次当前读,出现幻读的情况。      LOCK_ORDINARY:锁定一个范围,并且锁定记录本身。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。   2)间隙锁(LOCK_GAP、GAP锁):    a、Read Committed级别下:     主键查询:     +---+------+------+------+------+     | a | b | c | d | e |     +---+------+------+------+------+     | 1 | 1 | 1 | 1 | 1 |     +---+------+------+------+------+         begin;         select * from t1 where a = 1 for update;         select * from t1 where a = 1 for update; -- 阻塞         select * from t1 where a = 2 for update; -- 不阻塞         查询使用的是主键时,只需要在主键值对应的那一个条数据加锁即可。      唯一索引查询:    +---+------+------+------+------+    | a | b | c | d | e |    +---+------+------+------+------+    | 1 | 1 | 1 | 1 | 1 |    +---+------+------+------+------+         begin;          select * from t1 where b = 1 for update;          select * from t1 where b = 1 for update; -- 会阻塞          select * from t1 where b = 2 for update; -- 不阻塞         查询使用的是唯一索引时,只需要对查询值所对应的唯一索引记录项和对应的聚集索引上的项加锁即可。      普通索引查询:     +----+------+------+------+------+     | a | b | c | d | e |     +----+------+------+------+------+     | 6 | 6 | 1 | 4 | 6 |     | 12| 12 | 1 | 1 | 6 |     +----+------+------+------+------+         begin;         select * from t1 where e = "6" for update;         select * from t1 where a = 6 for update; -- 阻塞         select * from t1 where a = 12 for update; -- 阻塞         select * from t1 where a = 1 for update; -- 不阻塞         select * from t1 where a = 2 for update; -- 不阻塞         insert t1(b,c,d,e) values(20,1,1,"51"); -- 不阻塞         insert t1(b,c,d,e) values(21,1,1,"61"); -- 不阻塞     查询使用的是普通索引时,会对满足条件的索引记录都加上锁,同时对这些索引记录对应的聚集索引上的     项也加锁。      没有使用索引:         +----+------+------+------+------+         | a | b | c | d | e |         +----+------+------+------+------+         | 1 | 1 | 1 | 1 | 1 |         | 2 | 2 | 1 | 2 | 2 |         | 4 | 3 | 1 | 1 | 4 |         | 6 | 6 | 1 | 4 | 6 |         | 8 | 8 | 1 | 8 | 8 |         | 10 | 10 | 1 | 2 | 10 |         | 12 | 12 | 1 | 1 | 6 |         +----+------+------+------+------+         begin;         select * from t1 where c = "1" for update;          select * from t1 where a = 1 for update; --阻塞         select * from t1 where a = 2 for update; -- 阻塞         select * from t1 where a = 3 for update; -- 不阻塞         select * from t1 where a = 7 for update; --不阻塞         查询的时候没有走索引,也只会对满足条件的记录加锁。     b、Repeatable Read级别下:        查询使用主键:和ReadCommitted级别一样。       查询使用唯一索引:和ReadCommitted级别一样。       查询使用普通索引:         mysql> begin;         Query OK, 0 rows affected (0.00 sec)         mysql> select * from t1 where e = "6" for update;         +----+------+------+------+------+         | a | b | c | d | e |         +----+------+------+------+------+         | 6 | 6 | 1 | 4 | 6 |         | 12 | 12 | 1 | 1 | 6 |         +----+------+------+------+------+         2 rows in set (0.00 sec)      mysql> select * from t1 where a = 6 for update; -- 阻塞     mysql> select * from t1 where a = 12 for update; -- 阻塞     mysql> select * from t1 where a = 1 for update; -- 不阻塞     mysql> select * from t1 where a = 2 for update; -- 不阻塞     mysql> insert t1(b,c,d,e) values(20,1,1,"51"); -- 阻塞     mysql> insert t1(b,c,d,e) values(21,1,1,"61"); -- 阻塞     总结:REPEATABLE READ级别可以解决幻读,解决的方式就是加了GAP锁。      查询没有使用索引:      mysql> begin;     Query OK, 0 rows affected (0.00 sec)     mysql> select * from t1 where c = "1" for update;     +----+------+------+------+------+     | a  | b  | c | d | e  |     +----+------+------+------+------+     | 1  | 1  | 1 | 1 | 1  |     | 2  | 2  | 1 | 2 | 2  |     | 4  | 3  | 1 | 1 | 4  |     | 6  | 6  | 1 | 4 | 6  |     | 8  | 8  | 1 | 8 | 8  |     | 10 | 10 | 1 | 2 | 10 |     | 12 | 12 | 1 | 1 | 6  |     +----+------+------+------+------+     7 rows in set (0.00 sec)      mysql> select * from t1 where a = 1 for update; -- 会阻塞     mysql> select * from t1 where a = 2 for update; -- 会阻塞     mysql> select * from t1 where a = 3 for update; -- 不会阻塞     mysql> select * from t1 where a = 7 for update; -- 会阻塞(在Read Committed下不会阻塞,跟解决幻读有关系)     总结:查询的时候没有走索引,会对表中所有的记录以及间隙加锁。
  8、表锁: 表级别S锁,X锁。     在对某个表执行SELECT、 INSERT、 DELETE、 UPDATE语句时,InnoDB存储引擎是不会为这个表添加表级别的     S锁或者X锁的 在对某个表执行ALTER TABLE、 DROP TABLE这些DDL语句时,其他事务对这个表执行SELECT、 INSERT、 DELETE、 UPDATE的语句会发生阻塞,或者,某个事务对某个表执行SELECT、 INSERT、 DELETE、 UPDATE语 句时,其他事务对这个表执行DDL语句也会发生阻塞。这个过程是通过使用的元数据锁(英文名:Metadata Locks,简称MDL)来实现的,并不是使用的表级别的S锁和X锁 LOCK TABLES t1 READ:对表t1加表级别的S锁。 LOCK TABLES t1 WRITE:对表t1加表级别的S锁  尽量不用这两种方式去加锁,因为InnoDB的优点就是行锁,所以尽量使用行锁,性能更高。
  9、
  IS锁:意向共享锁、 Intention Shared
  Lock。当事务准备在某条记录上加S锁时,需要先在表级别
  加一个IS锁。
  IX锁:意向排他锁、 Intention Exclusive Lock。当事务准备在某条记录上加X锁时,需要先在表级
  别加一个IX锁
  IS、 IX锁是表级锁,它们的提出仅仅为了在之后加表级别的S锁和X锁时可以快速判断表中的记录是否被上锁,以
  避免用遍历的方式来查看表中有没有上锁的记录
  10、AUTO-INC锁:
  在执行插入语句时就在表级别加一个AUTO-INC锁,然后为每条待插入记录的AUTO_INCREMENT
  修饰的列分配递增的值,在该语句执行结束后,再把AUTO-INC锁释放掉。这样一个事务在持有
  AUTO-INC锁的过程中,其他事务的插入语句都要被阻塞,可以保证一个语句中分配的递增值是连
  续的。
  采用一个轻量级的锁,在为插入语句生成AUTO_INCREMENT修饰的列的值时获取一下这个轻量级
  锁,然后生成本次插入语句需要用到的AUTO_INCREMENT列的值之后,就把该轻量级锁释放掉,
  并不需要等到整个插入语句执行完才释放锁。 系统变量innodb_autoinc_lock_mode: innodb_autoinc_lock_mode值为0:采用AUTO-INC锁。 innodb_autoinc_lock_mode值为2:采用轻量级锁。 当innodb_autoinc_lock_mode值为1:当插入记录数不确定是采用AUTO-INC锁,当插入记录数确 定时采用轻量级锁
  11、悲观锁:
  悲观锁用的就是数据库的行锁,认为数据库会发生并发冲突,直接上来就把数据锁住,其他事务不能修改,直至
  提交了当前事务。
  12、乐观锁:
  乐观锁其实是一种思想,认为不会锁定的情况下去更新数据,如果发现不对劲,才不更新(回滚)。在数据库中往
  往添加一个version字段来实现。
  13、死锁: session1: mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> select * from t1 where a =1 for update; -- 第一步 +---+------+------+------+------+ | a | b | c | d | e | +---+------+------+------+------+ | 1 | 1 | 1 | 1 | 1 | +---+------+------+------+------+ 1 row in set (0.00 sec) mysql> update t1 set c = 2 where a = 4; -- 第三步 开始会阻塞 ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction  session2:  mysql> begin; Query OK, 0 rows affected (0.00 sec) mysql> delete from t1 where a = 4; -- 第二步 Query OK, 1 row affected (0.00 sec) mysql> delete fromt t1 where a = 1; -- 第四步,阻塞产生死锁,mysql有死锁检测机制,让死锁中断
  14、避免死锁:
  以固定的顺序访问表和行
  大事务拆小,大事务更容易产生死锁
  在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率
  降低隔离级别(下下签)
  为表添加合理的索引。

正式官宣!广东020负于北控,老马捡漏成功,冲击季后赛概率大增北京时间10月11日CBA常规赛第1轮的比赛继续展开争夺,原定于在今天下午3点当中进行的广东和北控的一场常规赛,最终因为广东的自身原因未能够到达赛场,从而也被官方以020判负,北控新三板创新层企业首超1700家近日,全国股转中心(新三板)发布2022年第四批拟调入创新层公司名单,共计42家,这意味着创新层公司数量将首次超过1700家,较北交所设立前增加约三成。充足的新三板创新层企业后备军碳中和革命为绿能人民币崛起提供良机摘要碳中和目标对全球政治经济的影响,可能被很多人低估了。这不仅是一个新能源替代的问题,还将完全改变全球地缘政治石油大国石油战争和石油美元将失去根基。能源是国民经济的基础,能源革命不推动中国之治进入新境界1。2018年12月3日,安徽省合肥市经开区明珠居委会法律援助律师在给明珠小学的学生们讲解宪法知识。新华社发2。2020年4月22日,重庆市巫溪县检察院联合陕西省镇坪县检察院组成的在这里读懂良法善治小宝的法力能否战胜洗脑的魔力?视频加载中不听!不听!不听!我转!我转!我转!被诈骗分子洗脑而着魔,非要转钱怎么办?攒了一辈子的养老钱被骗走,还能追回不?看法治小精灵法小宝使用了哪些神奇法力对抗这些魔力陷阱!防范中国人的故事二十大代表陈望慧在大山播撒致富种子编者按在以习近平同志为核心的党中央坚强领导下,按照党章规定和党中央统一部署,全国38个选举单位选举产生了2296名党的二十大代表。党的二十大代表是共产党员中的优秀分子,具有先进性和三路资金流向存款,利率下调趋势下有哪些理财选择?丨21理财私房课视频加载中开开心心生活,明明白白理财。这里是21理财私房课。今年以来居民存款增加比较猛,包括过去买房的钱投资的钱甚至消费的钱,很多都存进了银行,这部分钱现在面临存款利率下调,最近银武汉贵阳房贷利率最低可至3。9专家称地产企稳利好银行板块估值修复21世纪经济报道记者唐婧北京报道贵阳首套房贷利率最低可以到3。9,不过暂时只有三个银行能做,分别是农行交行和中行,其余的银行可能还在走流程。政策只持续到年底,现在差不多就是抄底买房人民币大幅贬值,房地产市场负增长?来听中国人民银行调查统计司原司长盛松成的分析前三季度经济数据即将发布,当此时刻,人们试图以各种分析方式找到宏观经济运行对接微观投资理财操作的密钥。围绕百姓关注的抗通胀汇率利率以及投资理财话题,人民政协报记者对中欧国际工商学院上海迎来离沪潮,3个原因很真实,这4个新兴城市成了热门文华夏2022年上半年,在复杂严峻的外部环境和局部疫情等意外因素的严重影响下,上海GDP为19349。31亿元,按可比价格计算,比去年同期下降5。7。上海市统计局和国家统计局上海调香港举办研讨会聚焦共同建设香港,增强发展动能新华社香港10月11日电(记者刘明洋)香港再出发大联盟11日在港举办共同建设香港,增强发展动能线上线下研讨会。来自金融创科再工业化航运物流等多个领域的十余位业内人士,分享了相关业界
抄书打卡第246天新的一年已经开启,我也想改变一下自己抄书的方式。想把抄书时的一些心得体会,或是感想,或是心境,也记录下来。很多朋友问我抄书赚了多少钱?说实话,不论我在头条上发表文章还是视频,从来没猛男!41岁伊布晒照,8块腹肌地垄沟新发型,52岁妻子身材傲人意甲重燃战火后,AC米兰暂时以36分排名联赛第二,落后榜首那不勒斯5分。作为上赛季意甲冠军,AC米兰已经沉沦多年,如今总算逐渐回归正轨,但距离重返欧洲顶尖行列依然有很长的路要走。A为什么和珅自称奴才,纪晓岚却自称臣,编剧搞错了吗?铁齿铜牙纪晓岚应该是许多人的童年回忆了,细心的人已经发现剧中有一个从头贯穿到尾的细节,那就是纪晓岚以及和珅对乾隆皇帝的称呼。和珅在乾隆面前总是自称奴才,纪晓岚却自称臣。以前总觉得这出席这样的宴会,她就坐在一旁,用扇子遮住脸,既不看,也不笑刘彧(439472年)为南朝宋文帝第十一子,十岁受封为淮阳王,食邑二千户452年,改封湘东王。453年三哥宋孝武帝即位后,因为同年刘彧生母沈容姬过世,年仅十五岁的刘彧就改由宋孝武帝华外说胡天下第二胡东胡(十八)孝文帝的儿子元恪攻取南期梁之四川,北击柔然,32岁时病故。他唯一的孙子6岁的元诩继位,由生母胡太后总揽朝政。胡太后多情而又浪漫,面首一茬一茬地换。528年,元鞍山市的区划变动,辽宁省的重要城市,7个区县是怎么来的?在之前的文章中给大家说了很多城市的区划变迁沿革,每个城市区划变迁沿革都极其复杂,因为我国的历史非常悠久,5000年文化传承,让我国历经了诸多政权,在每一个政权统治期间,对于地域的划从萌到猛!看毛孩子的成长之路多吉,搜!恩主培楚一声呼唤,一只史宾格犬闻令而动,在二十个搜索训练箱体中逐一甄别,20秒不到,便将藏有助训员的箱子找了出来并吠叫示警。恩主培楚多次试图将它拉走,它却纹丝不动,固执地孩子总怯场怎么办?导语在养育孩子的过程中,父母经常关注孩子的学习,身心健康容易被忽略。有的孩子有时会出现自卑问题,在人多的时候或者大的场面上就会怯场。孩子怯场最大的问题是什么呢?孩子的安全感是怎么建个头虽小聚集爆炸威力巨大,临近春节玩摔炮孩子多,消防这样提醒近日,记者在大兴的居民小区看到,有家长带着孩子在玩摔炮。记者从消防部门了解到,摔炮个头虽小,但成百上千的聚集在一起,发生碰撞后会产生巨大爆炸。另外,切勿大量存储并远离火源。临近春节家族财富传承中的那些坑!改革开放以来,创业者们投身时代浪潮,积极创富,中国私人财富迅速增长。目前,我国创一代已步入退休年龄,家族财富安全与传承逐渐成为高净值圈子的热议话题,传一代时代逐渐到来。然而,近年来河南省产业园区系列报道郑州鲲鹏软件小镇中部数字产业新中心崛起在中原科技城拓展区,蓄势待发的鲲鹏软件小镇,建设与招商并驾齐行,快速推进,不断勃发生机与活力。一边,117栋建筑已顺利完成封顶纵横的道路与飞架的桥梁连通四面八方,清澈唯美的云溪湾里