MySql数据库出现死锁的情况(一)
在临近上线之前,我们系统做了一次压力测试,发现有一个接口在高并发情况下会出现一个死锁的情况。。首先申明…不是我写的,我只是帮忙排查下。
随着对Mysql锁的深入了解,于是就准备写几篇文章来记录下Mysql各种事物和索引的情况下出现死锁的情况。
今天就介绍下在并发插入的情况下,哪几种情况会出现死锁:
INNODB下的各种锁
在介绍锁的时候只会介绍跟本节相关的锁,而且只会讲述大概是什么,至于锁的更加详细的讲解可能会到以后再详细介绍。
在临近上线之前,我们系统做了一次压力测试,发现有一个接口在高并发情况下会出现一个死锁的情况。。首先申明…不是我写的,我只是帮忙排查下。
随着对Mysql锁的深入了解,于是就准备写几篇文章来记录下Mysql各种事物和索引的情况下出现死锁的情况。
今天就介绍下在并发插入的情况下,哪几种情况会出现死锁:
在介绍锁的时候只会介绍跟本节相关的锁,而且只会讲述大概是什么,至于锁的更加详细的讲解可能会到以后再详细介绍。
在上一篇文章中,我们有一个表,里面的内容如下:
1 | mysql> select * from org_copy; |
这应该是一个很基本的一个mysql表,同时我们在上一篇文章中,也执行了如下SQL。
1 | mysql> explain SELECT * FROM org_copy WHERE org_name>'一级部门' and org_parent_id=1; |
本次的实验是基于Mysql8
版本。首先在数据库中有一个表,其结构如下:
1 | mysql> show create table org; |
可以看到在这个表中,有一个主键org_id
以及一个联合索引index_name
。其他的并无特别之处。
在Mysql里面,有一个最左原则,官网的介绍如下:
注意,此文章使用的Mysql变量均是用户变量
首先看一个需求,有如下数据表:
1 | mysql> select * from t1 order by area_id; |
可以看到,这是一个很非常普通的数据表。
假设有一个如下的业务场景如下:
需要记录一个商品或者股票的实时价格,每一个小时记录一次,而商品或者股票的数量十分多,这时业务发展到一定的程度之后就需要考虑数据库的设计。首先商品每个小时的价格肯定是需要入库的。其次每小时的购买人群以及各种埋点数据随之一起也要入库。以便于日后的数据分析。
随着数据量的增大,一般的解决方案是设置索引,然后再考虑是进行垂直还是水平分库分表。
但是一旦使用水平分库分表就会无形之间增加开发的复杂程度,而且分库分表之后考虑的各种因素也会随之而来增加数倍。例如各种表的唯一ID
以及如何进行维度的划分。
事物通俗的来讲就是就是一组操作事件,可以类比于Java里面的原子操作。在一个事物中,要么全部成功,要么就是全部失败。
在Mysql的innodb
中,事物的默认级别是 可重复读
,在该级别下,事物可能出现幻读。出现幻读的情况是该引擎为行级锁,导致mysql在进行一个事物的时候只会锁定与该事物有关的几行。
今天突然有一个写sql的机会,但是是手写,不像之前那样可以在数据库上做测试。这突然让我感觉有的语法有点生疏了,所以乘着这个机会来做一个全部的梳理。
今天是有两表做一个等值连接查询的,在这里应该是先where之后再进行group by,group by
是对where
条件过滤之后再进行分组处理,所以where在前。
这个函数可以将日期往前加上规定的年,月或者日,从而方便统计,例如需要统计本月的某些数据的话,一般来讲肯定是只需要大于本月月初即可,但是为了考虑程序的健壮性的话肯定是需要再加一个限制条件,比如说小于下个月1号。那么就需要一个一个DATE_ADD()函数:
1 | SELECT |
这条sql便是求的本月的数据。同时在这里也对当前时间的函数进行一个对比:
1 | mysql> SELECT CURDATE(); |
先看在mysql 5.7版本中的一个的group by,以下是这个数据库表:
1 | mysql> select * from testgroupby; |
这是一个学生成绩数据库表。那么在MySQL5.7版本中执行它的话是会出现一个error的。如下所示:
1 | mysql> select * from testgroupby group by user_name; |
由于自己有点需求需要在mysql中按照时间段进行查询,而自己又对这些不太了解,所以趁着这次机会将mysql和时间段相关的查询语句做一个记录:
DATE_SUB(date,INTERVAL expr type)
这个函数的date是一个时间表达式,一般取得是数据库中的一个字段。后面的INTERVAL
一般来讲是不变的,expr
一般是一个时间段,代表过去的,比如是30天,那么这里就是30,若是60,这里就是60,type
则表示的是一个时间属性(可能表达的不是很准确),如下: