day-7-行锁
发表于|更新于|MySQL学习笔记
|总字数:295|阅读时长:1分钟|浏览量:
行锁就是针对数据表中行记录的锁。
一、两阶段锁
在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这个就是两阶段锁协议。
如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁尽量往后放。
二、死锁和死锁检测
当并发系统中不同线程出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,就会导致这几个线程都进入无限等待的状态,称为死锁。
当出现死锁以后,有两种策略:
- 一种策略是,直接进入等待,直到超时。
- 另一种策略是,发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务得以继续执行。
三、小结
如果你的事务中需要锁多个行,要把最可能造成锁冲突、最可能影响并发度的锁的申请时机尽量往后放。
文章作者: 张晓风
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 张晓风的博客!
相关推荐
2024-07-16
day-1-MySQL的基础架构
一、 MySQL的基础架构 Server层:连接器、查询缓存、分析器、优化器、执行器等核心服务功能,以及所有的内置函数和跨存储引擎的功能(存储过程、触发器、视图等)。 存储引擎层:负责数据的存储和提取。 二、连接器连接器负责跟客户端建立连接、获取权限、维持和管理连接。 数据库里面,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。 三、查询缓存MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。 MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。 四、分析器如果没有命中查询缓存,就要开始真正执行语句了。 分析器先会做“词法分析”。你输入的是由多个字符串和空格组成的一条 SQL 语句,MySQL...
2024-07-26
day-10-MySQL为什么有时候会选错索引
一、优化器的逻辑选择索引是优化器的工作。 优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。在数据库里面,扫描行数是影响执行代价的因素之一。扫描的行数越少,意味着访问磁盘数据的次数越少,消耗的 CPU 资源越少。 扫描行数并不是唯一的判断标准,优化器还会结合是否使用临时表、是否排序等因素进行综合判断。 二、索引选择异常和处理大多数时候优化器都能找到正确的索引,但偶尔还是会碰到这两种情况:原本可以执行得很快的 SQL 语句,执行速度却比你预期的慢很多,你应该怎么办呢? 2.1 采用 force index 强行选择一个索引。2.2 可以考虑修改语句,引导 MySQL 使用我们期望的索引。2.3 可以新建一个更合适的索引,来提供给优化器做选择,或删掉误用的索引。三、小结对于由于索引统计信息不准确导致的问题,可以用 analyze table 来解决。 而对于其他优化器误判的情况,可以在应用端用 force index 来强行指定索引,也可以通过修改语句来引导优化器,还可以通过增加或者删除索引来绕过这个问题。
2024-07-30
day-11-怎么给字符串字段加索引
使用前缀索引,定义好长度,就可以做到既节省空间,又不用额外增加太多的查询成本。 一、前缀索引对覆盖索引的影响使用前缀索引可能会增加扫描行数,这会影响到性能。 使用前缀索引就用不上覆盖索引对查询性能的优化了,这也是你在选择是否使用前缀索引时需要考虑的一个因素。 二、其他方式索引选取的越长,占用的磁盘空间就越大,相同的数据页能放下的索引值就越少,搜索的效率也就会越低。 使用倒序存储 使用 hash 字段 使用倒序存储和使用 hash 字段这两种方法的异同点。相同点:都不支持范围查询。区别: 1.从占用的额外空间来看,倒序存储方式在主键索引上,不会消耗额外的存储空间,而 hash 字段方法需要增加一个字段。 2.在 CPU 消耗方面,倒序方式每次写和读的时候,都需要额外调用一次 reverse 函数,而 hash 字段的方式需要额外调用一次 crc32() 函数。 3.从查询效率上看,使用 hash...
2024-07-31
day-12-为什么我的MySQL会“抖”一下?
脏页:内存数据页跟磁盘数据页内容不一致。 干净页:内存数据写入到磁盘后,内存和磁盘上的数据页的内容一致。 一、什么情况会引发数据库的 flush 过程 InnoDB 的 redo log 写满了。 系统内存不足。 MySQL 认为系统“空闲”的时候。 MySQL 正常关闭的情况。 InnoDB 的策略是尽量使用内存,因此对于一个长时间运行的库来说,未被使用的页面很少。 影响性能的两种情况: 一个查询要淘汰的脏页个数太多,会导致查询的响应时间明显变长; 日志写满,更新全部堵住,写性能跌为 0,这种情况对敏感业务来说,是不能接受的。 二、InnoDB 刷脏页的控制策略合理地设置 innodb_io_capacity 的值,并且平时要多关注脏页比例,不要让它经常接近 75%。 三、小结利用 WAL 技术,数据库将随机写转换成了顺序写,大大提升了数据库的性能。 脏页会被后台线程自动 flush,也会由于数据页淘汰而触发 flush,而刷脏页的过程由于会占用资源,可能会让你的更新和查询语句的响应时间长一些。
2024-08-01
day-13-为什么表数据删掉一半,表文件大小不变
一、数据删除流程数据页的复用跟记录的复用是不同的。记录的复用,只限于符合范围条件的数据。而当整个页从 B+ 树里面摘掉以后,可以复用到任何位置。 如果相邻的两个数据页利用率都很小,系统就会把这两个页上的数据合到其中一个页上,另外一个数据页就被标记为可复用。 delete 命令其实只是把记录的位置,或者数据页标记为了“可复用”,但磁盘文件的大小是不会变的。 不止是删除数据会造成空洞,插入数据也会。 二、重建表MySQL 5.6 版本开始引入的 Online DDL Online 和 inplaceDDL 过程如果是 Online 的,就一定是 inplace 的;反过来未必,也就是说 inplace 的 DDL,有可能不是 Online 的。 三、小结如果要收缩一个表,只是 delete 掉表里面不用的数据的话,表文件的大小是不会变的,还要通过 alter table 命令重建表,才能达到表文件变小的目的。重建表有两种实现方式,Online DDL 的方式是可以考虑在业务低峰期使用的,而 MySQL 5.5 及之前的版本,这个命令是会阻塞 DML 的,这个需要特别小心。
2024-08-02
day-14-count(*)这么慢,我该怎么办
一、count( * ) 的实现方式 MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count( * ) 的时候会直接返回这个数,效率很高; 而 InnoDB 引擎就麻烦了,它执行 count( * ) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。 InnoDB 的默认隔离级别是可重复度。InnoDB 是索引组织表,主键索引树的叶子节点是数据,而普通索引树的叶子节点是主键值。 在保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。 MyISAM 表虽然 count( * ) 很快,但是不支持事务; show table status 命令虽然返回很快,但是不准确; InnoDB 表直接 count( * ) 会遍历全表,虽然结果准确,但会导致性能问题。 二、不同的 count 用法 count() 的语义:count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。最后返回累计值。 分析性能差别的时候要注意的几个原则:1.server...
评论