美文网首页
MySQL中的锁(InnoDB存储引擎)

MySQL中的锁(InnoDB存储引擎)

作者: 何甜甜在吗 | 来源:发表于2018-08-17 14:10 被阅读0次
MySQL中的锁(lock)

lock对象:数据库中的对象,如表、页、行。
lock释放:事务commit或者rollback以后(不同事务隔离级别释放的时间可能不同)

锁的分类
  • 行级锁
    1.共享锁
    2.排他锁
    共享锁是兼容锁,排他锁是不兼容锁。
    兼容指的是对同一记录锁的兼容性情况
  • 2意向锁(表锁show)
    1.意向共享锁
    2.意向排他锁
    目的:支持在不同粒度上进行加锁操作,这种锁允许事务在行级上的锁和表级上的锁同时存在
查看锁的信息

在INFORMATIOIN_SCHEMA架构上添加了表INNODB_TRX INNODB_LOCKS INNODB_LOCK_WAITS,通过查看这三张表可以分析事务中可能存在的锁的情况

前期准备:
1.创建表

CREATE TABLE t_bitfly (
  id bigint(20) NOT NULL DEFAULT '0',
  value varchar(32) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2.插入数据

 mysql> insert into t_bitfly (1, 'a'),(2, 'b'),(3,'c'),(4,'d'),(5,'e');
  • 查看INNODB_TRX表

session1:

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

mysql> select * from t_bitfly where id < 4 for update;
+----+-------+
| id | value |
+----+-------+
|  1 | a     |
|  2 | b     |
|  3 | c     |
+----+-------+
3 rows in set (0.00 sec)

session2:

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t_bitfly where id >= 4 for update;

session1:

mysql> select * from information_schema.INNODB_TRX\G;
*************************** 1. row ***************************
                    trx_id: 2754
                 trx_state: LOCK WAIT
               trx_started: 2018-04-20 13:44:49
     trx_requested_lock_id: 2754:116:3:5
          trx_wait_started: 2018-04-20 14:00:04
                trx_weight: 2
       trx_mysql_thread_id: 13
                 trx_query: select * from t_bitfly where id >= 4 for update
       trx_operation_state: starting index read
         trx_tables_in_use: 1
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 2
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
*************************** 2. row ***************************
                    trx_id: 2753
                 trx_state: RUNNING
               trx_started: 2018-04-20 13:42:45
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 2
       trx_mysql_thread_id: 12
                 trx_query: select * from information_schema.INNODB_TRX
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 2
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 4
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
2 rows in set (0.00 sec)

为什么会引起死锁,可以查看之前写的文章InnoDB存储引擎行级锁引起锁争用问题
字段说明:
trx_id:事务ID
trx_state:当前事务的状态
trx_started:事务开始的时间
trx_requested_lock_id:等待事物的锁ID,只有当trx_stateLOCK_WAIT时才会有值,否则为null
trx_weight:事务的权重,反映了一个事务修改和锁住的行数。在InnoDB存储引擎中,当发生死锁需要进行回滚时,会选择该值最小的事务进行回滚
trx_wait_started:事务等待开始的时间
trx_mysql_thread_id:MySQL中的线程ID
trx_query:事务运行的SQL语句
通过查看INNODB_TRX表信息后知道了trx_id为2754的事务处于LOCK WAIT状态,而trx_id为2753的事务处于RUNNING状态

  • 查看INNODB_LOCKS表
mysql>  select * from information_schema.INNODB_LOCKS\G;
*************************** 1. row ***************************
    lock_id: 2754:116:3:5
lock_trx_id: 2754
  lock_mode: X
  lock_type: RECORD
 lock_table: `study`.`t_bitfly`
 lock_index: PRIMARY
 lock_space: 116
  lock_page: 3
   lock_rec: 5
  lock_data: 4
*************************** 2. row ***************************
    lock_id: 2753:116:3:5
lock_trx_id: 2753
  lock_mode: X
  lock_type: RECORD
 lock_table: `study`.`t_bitfly`
 lock_index: PRIMARY
 lock_space: 116
  lock_page: 3
   lock_rec: 5
  lock_data: 4
2 rows in set, 1 warning (0.00 sec)

字段说明
lock_id: 锁的ID
lock_trx_id: 事务ID
lock_mode: 锁的模式
lock_type: 锁的类型,表锁还是行锁
lock_table: 要加锁的表
lock_index: 锁住的索引
lock_space: 锁对象的space id
lock_page: 事务锁定页的数量,若是表锁,则该值为NULL
lock_rec: 事务锁定行的数量,若是表锁,则该值为NULL
lock_data: 事务锁定记录的主键值,若是表锁,则该值为NULL。该值并不是“可信的”值
通过查看INNODB_LOCKS表信息后知道了锁等待是因为两个事务都往tx_bitfly表上加X锁

  • 查看INNODB_LOCK_WAITS表
mysql>  select * from information_schema.INNODB_LOCK_WAITS\G;
*************************** 1. row ***************************
requesting_trx_id: 2754
requested_lock_id: 2754:116:3:5
  blocking_trx_id: 2753
 blocking_lock_id: 2753:116:3:5
1 row in set, 1 warning (0.00 sec)

字段说明
requesting_trx_id: 申请锁资源的事务ID
requested_lock_id: 申请的锁的ID
blocking_trx_id: 阻塞的事务ID
blocking_lock_id: 阻塞的锁的ID
通过查看INNODB_LOCKS表信息后知道了事务2754申请2753事务上面的锁
因此我们可以通过分析三张表的信息来分析锁的执行情况

MVCC(多版本并发控制)

上面介绍的锁都是悲观锁,类似于java并发中的synchronize、Lock,MVCC则像乐观锁,类似于java并发中的cas,并不会对数据进行加锁,可以提高数据库的并发性

auto_increment实现使用的锁

参考
书籍:

相关文章

  • mysql规范

    一、基础规范【强制】使用InnoDB存储引擎解读:InnoDB存储引擎是MySQL默认存储引擎,支持事务和行级锁,...

  • Mysql存储引擎Innodb小结

    innodb是mysql支持事务的存储引擎,也是当前mysql默认的存储引擎。innodb支持行级别锁,对并发性事...

  • InnoDB介绍

    InnoDB介绍 InnoDB是事务安全的mysql存储引擎,也是mysql的默认存储引擎,特点是行锁设计、支持M...

  • Innodb的锁

    Innodb的锁是行级锁 mysql delete是否会锁表 MySQL的InnoDB存储引擎支持行级锁,Inno...

  • 【原创】因酷数据库开发规范

    基本规范 所有表必须使用Innodb存储引擎Innodb存储引擎是Mysql5.6以后默认引擎支持事务,行级锁,更...

  • Mysql InnoDB行格式、数据页结构

    InnoDB存储引擎 从Mysql5.5版本开始,InnoDB是默认的表存储引擎。其特点是行锁设计、支持MVCC、...

  • 淘宝MySQL文档整理

    MySQL · 引擎特性 · InnoDB 事务锁系统简介 MySQL · 引擎特性 · Innodb 锁子系统浅...

  • mysql(七)

    MySQL存储引擎-innodb 查看存储引擎 innodb和myisam的物理区别 innodb 核心特性 MV...

  • 推荐书单

    MySQL 内核 INNODB存储引擎第1版 MySQL技术内幕 InnoDB存储引擎 第2版 RabbitM...

  • MySQL-存储引擎

    零、本文纲要 一、MySQL存储引擎 二、InnoDB存储引擎1、InnoDB逻辑存储结构2、InnoDB架构3、...

网友评论

      本文标题:MySQL中的锁(InnoDB存储引擎)

      本文链接:https://www.haomeiwen.com/subject/pivakftx.html