数据库概述09(数据库中的锁机制)

Innodb中的锁机制

使用数据库的目的在于数据共享,需要考虑数据并发访问问题。解决方案就是锁机制
锁主要包括全局锁、表锁、行锁、乐观锁和悲观锁,需要解决的问题是死锁

存储引擎

存储引擎定义MySQL中的数据、索引以及其它的数据库对象如何存储,是一套文件系统的实现
查看所有的存储引擎 show engines;
在这里插入图片描述

常见的存储引擎:MyISAM、Innodb、memory

  • MyISAM采用的是全表锁,具有较高的查询执行速度,不支持事务和外键,并发性能差,但是占用空间相对较小,对于事务没有要求,一般主要以select和insert为主的应用可以使用这个引擎
  • Innodb采用的是行级锁,可以提供具有提交、回滚和恢复能力的事务安全,支持自增长类,支持外键约束,并发性能强,一般所需要占用的空间是MyISAM的2.5倍以上,处理效率相对差一些
  • Memory采用的是全表锁,存储数据在内存中,速度快,但是占用和数据量成正比的内存空间,而且数据在MySQL重启时丢失,默认使用hash索引,检索效率高,但是不适合范围查找,主要用于缓存内容变化不频繁的表
  • archive 这种类型的表只支持insert、select,不支持delete、update、replace,不使用索引
  • csv这些表保存在服务器的单个文件中,它包含了用逗号间隔的数据。
Innodb和MyISAM的区别
  • Innodb支持事务,MyISAM不支持,Innodb针对每条SQL语句都默认封装为事务,自动提交,这样会影响执行速度
  • Innodb支持外键约束,MyISAM不支持。所以对于一个包含外键的innodb表转换为MyISAM会失败
  • Innodb采用的时聚集索引,数据文件和索引绑定,必须有主键,通过主键查询效率很高;但是辅助索引需要两次查询,因此在Innodb中主键不应该过大;MyISAM采用的是非聚集索引,所以数据文件分离
  • innodb不保存数据的总行数,执行 select count() 需要全表扫描;而MyISAM使用一个变量保存了表的总行数,所以执行 count() 查询时速度很快
  • Innodb5.5-不支持全文索引,MyISAM支持全文索引,查询效率上MyISAM高
    选择依据:
  • 如果没有特殊要求,使用默认的innodb即可
  • MyISAM:以读取和插入为主的应用,比如博客系统、新闻网站等。搜索引擎采用NoSQL类型的数据库ES提供
  • Innodb:更新删除操作效率要求较高或者要求保证数据的完整性,同时考虑并发量要求高的场景
    下使用,例如OA之类的管理系统。因为支持事务和外键所以能够很好的保证数据完整性
    在这里插入图片描述

Innodb存储引擎即支持行级锁,也支持表级锁,默认情况下使用行级锁。锁类型包括共享S锁、排他X锁、意向共享IS锁和意向IX排他锁。

    • 所谓的意向锁就是如果对一个节点添加意向锁就说明该节点的下层节点正在被枷锁,对任意一个节点加锁时,实际上必须先对它的上层添加意向锁
      在这里插入图片描述
  • 意向锁就是为了让表锁可以快速感知是否有行级锁的存在,以防止表锁干扰行锁的执行

表级锁

锁的颗粒度为整个表
lock tables 表名称 read/write ,其中read是共享锁,一旦锁定则共享读取数据,write是排他锁,
只有加锁的客户端可以读写,其它客户端不可读也不可写
解锁 unlock tables

行级锁

锁的颗粒度为表中的特定的一行或者多行
共享锁 select * from 表名称 where 条件 lock in share mode;
排他锁 select * from 表名称 where 条件 for update;
注意:所谓的行锁并不是直接锁定特定行的数据,实际上是锁定一个子范围,所以也称为间隙锁。例如
select * from tb_student where id<20 lock in share mode 实际上并不是锁定id<20的现有数据,而是锁定id<20的范围,例如插入id为18的新记录失败

死锁问题

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方的资源,从而导致恶性循环的现象。
常见的解决死锁的方法

  • 如果不同程序会并发存取多个表, 尽量约定以相同的顺序访问表,可以大大降低死锁机会。
  • 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁产生概率;
  • 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁产生的概率;
    如果业务处理不好可以用分布式事务锁或者使用乐观锁
  • update tb_users set salary=? where id=1
  • update tb_users set salary=?,version=2 where id=1 and version=1 [version是一个额外的列,用于记录当前行的版本号]
查询缓存

可以缓存select语句的查询结果,以浪费内存为代价换取高执行效率
这个下载版本可能会有不能启动的问题,请大家使用其它版本进行测试
配置参数query_cache_type

  • 0 不开启
  • 1开启缓存,默认缓存所有select,如果需要不缓存则需要在select语句中添加sql-no-cache提示放弃缓存
  • 2开启缓存,默认都不缓存,需要在sql语句中添加select sql-cache主动缓存
    需要添加mysql配置文件,windows上my.ini,Linux上my.conf
    • query_cache_type=1
      查看MySQL是否开启缓存
    • show variables like ‘query_cache_type’;
      配置打开查询缓存大小
    • set global query_cache_size=6410241024; – 配置查询缓存为64M
    • show variables like ‘query%’;
      将查询结果进行
    • select sql_cache * from tb_users where …;
      重置缓存
    • reset query cache;
应用中的问题

1、应用程序不应该关心query cache的使用情况,因为使用查询缓存需要修改数据库的配置信息,所以实际上是由DBA决定的
2、缓存是以SQL语句为key进行存储的,因此即使SQL语句功能相同,然是如果多一个空格或者大小写有差异都会导致匹配不到缓存数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值