锁优化|学习笔记

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 快速学习锁优化

开发者学堂课程【云数据库优化经典案例:锁优化】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/67/detail/1160


锁优化


内容介绍:

一、案例二:表级锁

二、案例三:Metadata lock

三、锁问题最佳实践


一、案例二:表级锁

1.分析问题方向

本章分析数据库锁的问题,从最底层的不同引擎来考虑,不同的引擎锁级别不同。

2.两种引擎的锁级别对比

Myisam 为较为古老的引擎,Innodb 为默认 redis 支持引擎。

Myisam 不支持事务,所以为表级锁,可能导致一个慢查询堵塞更新,同时索引可能损坏,不支持在线备份。Myisam 引擎在 mysql5.7 以不再维护。

Innodb 支持事务,不堵塞,锁级别为行级锁,同时支持在线备份,也不会损坏。

部分用户为了提升速度会使用 Myisam 引擎,因为该引擎的维护十分简便,如:其在备份时,常常是将整个库都锁住进而导致全部都不能使用。

Innodb 与 Myisam

引擎

支持事务

并发

索引损坏

锁级别

在线备份

Myisam 

不支持

查询堵塞更新

索引损坏

不支持

Innodb

支持

不堵塞

不损坏

支持

3.Myisam 的表级锁展示以及转换 Innobd  

通过以下代码测试 Myisam 引擎的表级锁,通过 ENGINE=MyISAM 确定其为 Myisam 引擎,同时设置 sleep(100)为100秒,而后续的 Waiting for table level lock 表示后续的操作都被锁住。解决方案为:将 Myisam 引擎改为 Innodb引擎。

代码如下:

CREATE TABLE 't_myisam`(`id`int(11)DEFAULT NULL

)ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

查询堵塞更新

Query |111 | User sleep  | select id,sleep(100) from t_myisan |

Query [108 | Waiting for table level lock | update t_myisam set id=2 where id=1|

Query | 3 | Waiting for table level lock | update t_myisam set id=2 where id=1|

解决:

Alter table t_myisam engine=innodb;


二、案例三:Metadata lock

1.DDL 操作的 Metadata lock

Metadata 锁是 mysql 为了保护 to DDL 时而去冻结元数据信息,为了保持数据一致性,会在表上添加一个元数据锁,但元数据锁还存在一些问题,如该案例。

此案例中表 t 为仅有几百行数据的表,对该表添加一个字段,有可能造成数据库故障,如该表和另一个大表作关联查询时,查询较长,对其做 DDL 时,就必须等待慢查询执行完成才可以执行 DDL 操作,但由于 DDL 操作对表在 Metadata锁时,表上的访问都会被 block 住。

代码如下:

DDL 操作: alter table t add column gmt_create datetime

数据库连接状态:

//设置 sleep 时间

Query | 6 | User sleep select id ,sleep(50) from t

//对表添加索引和字段

Query | 4 | Waiting for table metadata lock | alter table t add column gmt_create database

//而因为慢查询并未完成,所以之后的访问都会 block 住

Query | 2 | Waiting for table metadata lock | select * from t where id=1

Query | 1 | Waiting for table metadata lock | select * from t where id=2

Query | 1 | Waiting for table metadata lock | update t set id =2 where id=1

Tips :注意 DDL 过程中注意数据库中是否有大长事务,大查询。如:全表查询,批量数据灌入的大操作。

2.注意

在一些线上繁忙系统或数据库中已有许多 MySQL 中添加索引优化时,要注意将慢查询问题解决,再去添加索引,否则就会出现之前的慢查询还未结束,导致之后操作全部堵住,数据库崩溃。


三、锁问题最佳实践

不同阶段的注意事项

(1)设计开发阶段--准备期间

①避免使用 myisam 存储引擎,改用 innodb 引擎;

②避免大事务,长事务导致事务在数据库中的运行时间加长,表上的操作无法完成;

③因 ddl 本身也含有锁,在加索引和字段时容易锁全表,所以选择升级到 MySQL5.6版本,支持 online ddl,online ddl 只支持加字段和索引,而修改长度、字符集或主键需要锁表;

以上即在数据库开发设计阶段的注意事项。

(2)管理运维阶段--上线之后

①在业务低峰期执行上述操作,比如创建索引,添加字段;

②在结构变更前,观察数据库中是否存在长 SQL,慢 SQL、大事务;

③结构变更期间,监控数据库的线程状态是否存在 lock wait ;

④ApsaraDB 支持在 DDL 变更中加入 wait timeout,wait timeout 超时后 ddl 会自动结束,以此保护上述情况  

(3)案例分享

一客户在数据库插入的时候超时,其共有两个事务,A 事务做表操作但其事务仍有其他操作,其中某个操作导致调入了其他业务模块,导致此 A 事务一直未提交,而B事务进入后同样对 A 事务上的行进行操作,因为 A 事务并未提交所以 B事务必须等待,最后就导致系统出现大量超时。

感悟:应该尽可能减少事务的操作范围

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
安全 Java 程序员
Java并发编程中的锁机制与优化策略
【6月更文挑战第17天】在Java并发编程的世界中,锁是维护数据一致性和线程安全的关键。本文将深入探讨Java中的锁机制,包括内置锁、显式锁以及读写锁的原理和使用场景。我们将通过实际案例分析锁的优化策略,如减少锁粒度、使用并发容器以及避免死锁的技巧,旨在帮助开发者提升多线程程序的性能和可靠性。
|
5月前
|
安全 Java 编译器
Java并发编程中的锁优化策略
【5月更文挑战第30天】 在多线程环境下,确保数据的一致性和程序的正确性是至关重要的。Java提供了多种锁机制来管理并发,但不当使用可能导致性能瓶颈或死锁。本文将深入探讨Java中锁的优化策略,包括锁粗化、锁消除、锁降级以及读写锁的使用,以提升并发程序的性能和响应能力。通过实例分析,我们将了解如何在不同场景下选择和应用这些策略,从而在保证线程安全的同时,最小化锁带来的开销。
|
5月前
|
Java
什么锁比读写锁性能更高?
Java并发编程中,ReentrantReadWriteLock是高效的锁机制,但在高并发环境下,乐观锁(如CAS)和JDK 8引入的StampedLock可提供更高性能。StampedLock支持读锁、写锁和乐观读锁,其乐观读锁在读多写少的场景下能提升并发性能,通过tryOptimisticRead方法实现。当乐观读锁无效时,可无缝切换至悲观读锁。
|
12月前
|
安全 算法 Java
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
|
5月前
|
安全 Java 开发者
Java并发编程中的锁优化技巧
【2月更文挑战第18天】 在Java并发编程中,锁是一种常用的同步机制,用于保证多个线程之间的数据一致性。然而,不当的使用锁可能会导致性能下降,甚至引发死锁等问题。本文将介绍一些Java并发编程中的锁优化技巧,帮助开发者提高程序的性能和稳定性。
42 7
|
5月前
|
安全 编译器 Linux
多线程(进阶一:锁策略)
多线程(进阶一:锁策略)
158 0
|
5月前
|
安全 编译器
互斥锁的优化与应用
互斥锁的优化与应用
79 0
|
安全 Java
锁升级原理
锁升级是指在多线程环境下,当一个线程持有了低级别的锁(如偏向锁或轻量级锁)时,如果有其他线程也要获取这个锁,那么就需要将锁升级为重量级锁。这样可以保证在并发情况下,多个线程之间的互斥访问。
230 1
|
Java 编译器 调度
锁的优化过程
锁的优化过程
|
并行计算 安全 算法
Oh!老伙计,提高自己的并发技能,先从锁优化开始吧
锁是最常用的同步方法之一。在高并发的环境下,激烈的锁竞争会导致程序的性能下降。 对于单任务或者单线程的应用而言,其主要资源消耗都花在任务本身,它既不需要维护并行数据结构间的一致性状态,也不需要为线程的切换和调度花费时间。对于多线程应用来说,系统除了处理功能需求外,还需要额外维护多线程环境的特有信息,如线程本身的元数据、线程的调度、线程上下文的切换等。并行计算之所以能提高系统的性能,并不是因为它"少干活"了,而是因为并行计算可以更合理地进行任务调度,充分利用各个CPU资源。