美文网首页
(1)mysql 锁、索引、事务

(1)mysql 锁、索引、事务

作者: lucode | 来源:发表于2018-12-30 22:37 被阅读27次

这里放一张 mysql 的架构图

image.png
一个大佬博客地址 http://hedengcheng.com/

在开发中遇到问题场景描述

看到日志

SQL []; Deadlock found when trying to get lock; 
try restarting transaction; nested exception is 
com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: 
Deadlock found when trying to get lock; try restarting transaction

哪个语句造成的?(promotion_id 和 spu_id 是单独建立的索引)

 update activity_spu
        set total_purchased_qty = total_purchased_qty +?
        where promotion_id = ?
        and spu_id = ?
        and is_delete = 0;

为什么会出现死锁?展开的一些知识的调研,下面内容都比较零散,希望,日后希望 mysql 的知识成为全面的时候在做归纳。

两阶段锁(可能出现死锁)

首先 事务 A 拿到锁,第一个 update 和第二个 update 分别再拿到锁,
这时候在事务提交之前是不会释放锁,只有在事务提交后缩才会分别被释放,事务 B 也就是说一直在等待 id=1的锁.


image.png

在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议
如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
但是这样子的话可能就出现死锁的问题了


image.png
话说回来这样的字死锁很好解决,调整一下 update 顺序就可以解决,但是更多的出现的问题是这样子的。

根据主键索引更新语句的过程

 update activity_spu
        set total_purchased_qty = total_purchased_qty +?
        where promotion_id = ?
        and spu_id = ?
        and is_delete = 0;

这里肯定会加上行级锁。
行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;
如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。
这个update语句会执行以下步骤:

1、由于用到了非主键索引,首先需要获取普通索引上的行级锁

2、紧接着根据主键进行更新,所以需要获取主键上的行级锁;

3、更新完毕后,提交,并释放所有锁。

InnoDB 的索引模型

InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+ 树中的
索引类型分为主键索引和非主键索引

主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)

非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

image.png

基于主键索引和普通索引的查询有什么区别?

  • 如果语句是 select * from T where ID=500,即主键查询方式,则只需要搜索 ID 这棵 B+树;
  • 如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索 k 索引树,得到 ID 的值为 500,再到 ID 索引树搜索一次。这个过程称为回表。

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此,我们在应用中应该尽量使用主键查询。

索引是如何维护的

叶节点有在删除的时候合并,在增加的时候会分裂

要求建表语一定要有自增主键?

效率角度:自增主键的插入数据模式,正符合了我们前面提到的递增插入的场景。每次插入一条新记录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶子节点的分裂。

空间角度:由于每个非主键索引的叶子节点上都是主键的值。如果用身份证号做主键,那么每个二级索引的叶子节点占用约 20 个字节,而如果用整型做主键,则只要 4 个字节,如果是长整型(bigint)则是 8 个字节。

相关文章

  • Mysql数据库

    MySQL知识图谱 MySQL索引 MySQL架构 MySQL锁 MySQL事务 MySQL集群 MySQL分库分...

  • (1)mysql 锁、索引、事务

    这里放一张 mysql 的架构图 在开发中遇到问题场景描述 看到日志 哪个语句造成的?(promotion_id ...

  • 2017.07.23 周日【技术文章】《Mysql集群架构》

    1.主要内容 1)mysql的架构,锁,最佳实践,事务 2)mysql的命令行,主从复制,索引,数据备份/恢复...

  • MySQL索引、事务、锁、MVCC简述

    目录 MySQL索引、事务、锁、MVCC简述一、索引1.1 执行计划 Explain1.2 索引结构1.2.1 H...

  • 高性能Mysql笔记

    一、Mysql架构与历史 1、架构图 2、锁 表锁 行级锁 3、事务 死锁 Mysql中的事务 1

  • face_mysql

    Mysql有什么数据引擎 InnoDB,支持行级锁、表级锁、事务、索引、独立表空间,其他引擎均不支持事务Myisa...

  • mysql高级:视图、事务、索引

    # mysql高级:视图、事务、索引 * 视图 * 事务 * 索引 * 账户管理 * 主从 ## 1.视图 动态抽...

  • 【学习】MySQL数据库

    存储引擎 存储引擎 索引 InnoDB索引原理索引 锁 锁不同Select加锁分析 事务 事务事务隔离级别XAMV...

  • MySQL与Redis

    MySQL常见面试题及答案 1.MySQL的索引(索引的结构) 2.MySQL的事务 3.事务的隔离级别 4.My...

  • MySQL 事务&锁

    MySQL(事务&锁) 引擎 InnoDB 索引默认聚簇索引主键索引-叶子节点包含整行数据、回滚指针、更新版本号、...

网友评论

      本文标题:(1)mysql 锁、索引、事务

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