MySQL 锁机制存在的价值是什么?

743 篇文章 3 订阅
742 篇文章 2 订阅

我们都知道 MySQL 中有各种各样的锁,例如:表锁、间隙锁、意向锁、行锁等等。但你是否想过:为啥 MySQL 要有锁机制的存在,它的存在是为了解决什么问题?今天我们就来聊聊这个问题。

没有锁的串行世界

我们先假设这样一个场景:王五现在账户里没有钱,于是向张三、李四各借 100 元,张三、李四很爽快地答应了。如果数据库这时候是串行的,没有并发执行的线程,那么其转账示意图如下所示。

王五借款串行执行 - 示意图

从上图可以看到:

  • 时间点 1 - 2 的时候,数据库处理了张三的转账请求,读取到王五的账户余额为 0,并将其余额加 100,此时王五账户余额为 100。
  • 时间点 3 - 4 的时候,数据库处理了李四的转账请求,读取到王五的账户余额为 100,并将其余额加 100,此时王五账户余额为 200。
  • 最后,在时间点 5 的时候,王五账户余额为 200 元。

可以看到最终王五的账户余额是 200 元,转账是没问题的。这种数据库访问方式虽然能保证数据一致性,但是每次只能执行一个请求,并发访问性能太差。

没有锁的并行世界

为了提高数据库的并发访问性能,MySQL 其实是支持多线程并发执行的。我们上面的例子,如果使用多线程并发处理,其可能存在的一种情况如下图所示。

这种情况的处理流程可能是这样的:

  • 在时间点 1 的时候,线程 A 读取到王五的账户余额为 0。
  • 在时间点 2 的时候,线程 B 读取到王五的账户余额为 0。
  • 在时间点 3 的时候,线程 A 将王五账户余额加 100,此时王五账户余额为 100。
  • 在时间点 4 的时候,线程 B 将王五账户余额加 100,此时王五账户余额为 100。
  • 在时间点 5/6 的时候,线程 A、B 都将王五的余额回写回去,王五账户余额为 100。

正常来说,王五最终的账户余额应该是 200 元,但实际上王五账户余额却只有 100 元。通过分析上面的转账示意图,我们会发现问题的关键点在于时间 4。

在这个时间点时,王五的账户余额应该是 100 元了,但是数据库线程 B 还是以为王五的账户余额是 0 元,所以导致了最后的数据不一致。那么如何解决数据不一致的问题呢?答案就是:锁机制。

有锁的并行世界

实际上,对于上述的转账例子,在 InnoDB 中的处理流程如下图所示。

  • 在时间点 2 的时候,线程 A 读取到王五的账户余额为 0。
  • 在时间点 3 的时候,线程 B 读取到王五的账户余额为 0。
  • 在时间点 4 的时候,线程 A 将王五账户余额加 100,并获取到锁,此时王五账户余额为 100。
  • 在时间点 5 的时候,线程 B 准备将王五账户余额加 100,但此时发现王五账户被锁了,于是阻塞等待。
  • 在时间点 6 的时候,线程 A 提交事务。
  • 在时间点 7 的时候,线程 B 重新读取王五最新的余额为 100 元,并加 100 元,最终在时间点 8 提交事务。

在时间点 4 的时候,数据库线程 A 对王五账号余额加锁,告诉其他线程:我正在更新这条数据,你们其他人不要动。 在时间点 5 的时候,当数据库线程 B 准备将对王五账号余额做加 100 操作时,其发现已经有数据库线程 A 在操作了,所以其将线程阻塞了。

等到数据库线程 A 提交事务,释放锁之后,数据库线程 B 获取到对应的锁。这时候数据库线程 B 发现王五账号的余额是 100 了,所以就在 100 余额的基础上做更新,之后提交事务,最终王五账号的余额就是 200 元。

提示:该例子只是为了粗略说明 InnoDB 是如何通过锁解决数据一致性问题的,在一些细节上大家不必对于纠结。例如这个例子在事务隔离级别为 READ COMMIT 的时候适用,但是在 REPEATABLE READ 隔离级别时存在问题。

看到这里,相信大家已经明白:锁的存在就是为了解决并发访问下数据的不一致问题。而数据库之所以要提供并发访问,是为了提高数据库的运行效率。

前言
作为一名编程人员,对MySQL一定不会陌生,尤其是互联网行业,对MySQL的使用是比较多的。对于求职者来说,MySQL又是面试中一定会问到的重点,很多人拥有大厂梦,却因为MySQL败下阵来。实际上,MySQL并不难,今天这份最全的MySQL总结,助你向大厂“开炮”,面试不再被MySQL难倒。

  1. 注意:关于MySQL的内容整理,包括了面试题、学习笔记、使用文档以及Xmind思维图几个部分,需要高清完整版《MySql学习资源大礼包》的朋友点击文章下方公众号

01、MySQL 面试题集合总结
1.1 MySQL 面试题(基础部分):

drop、truncate、 delete区别
数据库三范式是什么?
union和union all有什么不同?
char、varchar2、varchar有什么区别?
合并查询有哪些?
SQL语句执行顺序
null的含义
MySQL、SqlServer、oracle写出字符存储、字符串转时间
update语句可以修改结果集中的数据吗?
B树和B+树的区别
你见过索引吗? 建索引的原则
索引的类型, 如主键索引
查看SQL执行计划
有十万条数据, 写SQL语句查询其中某字段较大值的几条数据
子查询与关联查询的区别
MySQL InnoDB、Mysaim的特点?
乐观锁和悲观锁的区别??
行锁和表锁的区别?
数据库隔离级别是什么?有什么作用?
MySQL主备同步的基本原理。
如何优化数据库性能(索引、分库分表、批量操作、分页算法、升级硬盘SSD、业务优化、主从部署)
SQL什么情况下不会使用索引(不包含,不等于,函数)
一般在什么字段上建索引(过滤数据最多的字段)
MySQL,B+索引实现,行锁实现,SQL优化
如何解决高并发减库存问题
数据库事务的几种粒度
1.2 MySQL 面试题(实战部分):

数据库三范式,根据秒杀场景设计数据表
数据库的主从复制
死锁怎么解决
mysql并发情况下怎么解决(通过事务、隔离级别、锁)
触发器的作用?
什么是存储过程?用什么来调用?
存储过程的优缺点?
存储过程与函数的区别
索引的作用?和它的优点缺点是什么?
什么样的字段适合建索引
索引类型有哪些?
什么是事务?什么是锁?
什么叫视图?游标是什么?
视图的优缺点
列举几种表连接方式,有什么区别?
主键和外键的区别?
在数据库中查询语句速度很慢,如何优化?
数据库三范式是什么?
Varchar2和varchar有什么区别?
Oracle和Mysql的区别?
order by与group by的区别
1.3 MySQL 面试题(高级进阶部分):

请解释关系型数据库概念及主要特点?
请说出关系型数据库的典型产品、特点及应用场景?
请解释非关系型数据库概念及主要特点?
请说出非关系型数据库的典型产品、特点及应用场景?
请详细描述 SQL 语句分类及对应代表性关键字。
请详细描述 char(4)和 varchar(4)的差别。
如何授权 oldboy 用户从 172.16.1.0/24 访问数据库。
什么是 MySQL 多实例,如何配置 MySQL 多实例?
如何加强 MySQL 安全,请给出可行的具体措施?
delete 和 truncate 删除数据的区别?
MySQL Sleep 线程过多如何解决?
sort_buffer_size 参数作用?如何在线修改生效?
如何在线正确清理 MySQL binlog?
Binlog 工作模式有哪些?各什么特点,企业如何选择?
误操作执行了一个 drop 库 SQL 语句,如何完整恢复?
mysqldump 备份使用了-A -B 参数,如何实现恢复单表?
详述 MySQL 主从复制原理及配置主从的完整步骤。
如何开启从库的 binlog 功能?
MySQL 如何实现双向互为主从复制,并说明应用场景?
MySQL 如何实现级联同步,并说明应用场景?
MySQL 主从复制故障如何解决?
如何监控主从复制是否故障?
MySQL 数据库如何实现读写分离?
生产一主多从从库宕机,如何手工恢复?
MySQL面试答案与解析:

需要高清完整版《MySql学习资源大礼包》的朋友请点击文章下方公众号获得免费领取方式

02、关于MySQL 的实际使用
2.1 MySQL 性能优化的21个最佳实践

为查询缓存优化你的查询
EXPLAIN 你的 SELECT 查询
当只要一行数据时使用 LIMIT 1
为搜索字段建索引
在 Join 表的时候使用相当类型的例,并将其索引
千万不要 ORDER BY RAND()
避免 SELECT *
永远为每张表设置一个 ID
使用 ENUM 而不是 VARCHAR
从 PROCEDURE ANALYSE() 取得建议
尽可能的使用 NOT NULL
Prepared Statements
无缓冲的查询
把 IP 地址存成 UNSIGNED INT
固定长度的表会更快
垂直分割
拆分大的 DELETE 或 INSERT 语句
越小的列会越快
选择正确的存储引擎
使用一个对象关系映射器(Object Relational Mapper)
小心“永久链接”


2.2 MySQL 性能调优与架构设计——全册

基础篇:
MySQLI基本介绍、MySQL架构组成、MySQL存储引擎简介、MySQL安全管理、MySQL备份与恢复

性能优化篇:
影响MySQLServer性能的相关因素、MySQI数据库锁定机制、MySQL数据库Query的优化、MySQL数据库Schema设计的性能优化、MySQLServer性能优化、常用存储引擎优化

架构设计篇:
MySQL可扩展设计的基本原则、可扩展性设计之MySQLReplication、可扩展性设计之数据切分、可扩展性设计之C ache与Se ar ch的利用、MySQLCluster、高可用设计之思路及方案、高可用设计之MySQL监控


2.3 MySQL从入门到项目实践

第1篇 基础知识
Hello MySQL、数据库初探、MySQL常用管理工具的使用、MySQL 数据库的基本操作

第2篇 核心应用
数据表的基本操作、MySQL视图、MySQL的数据类型和运算符、MySQL函数、MySQL 数据库查询语句详解、MySQL数据库的数据与索引操作、存储过程与存储函数、使用MySQL触发器

第3篇 核心技术
MySQL数据库的权限管理与恢复、MySQL数据库的复制、MySQL的日志管理、利用MySQL构建分布式应用、MySQL查询缓存、MySQL错误代码和消息的使用

第4篇 高级应用
在C#中实现MySQL数据库的连接、在Java中实现MySQL数据库的连接、在PHP中实现MySQL数据库的连接

第5篇 项目实战
项目实战统筹阶段——项目开发与规划、项目实战入门阶段——论坛管理系统数据库开发、项目实战提高阶段——企业会员管理系统数据库开发、项目实战高级阶段——新闻发布系统数据库开发


需要高清完整版《MySql学习资源大礼包》的朋友请转发+关注下方公众号

03、关于学习 MySQL的思维脑图(Xmind)
MySQL 优化问题(Xmind)

事务、锁、sql优化原则、JION的原理、执行计划与执行明细、执行流程、表结构对性能的影响、索引


总结
总而言之,学习是自己的事,作为开发人员,MySQL是必须要掌握的,如果拥有大厂梦,基础可不能太差,如果你对MySQL还有很多不解问题,那么这份MySQL总结大礼包一定要拥有!

需要高清完整版《MySql学习资源大礼包》的朋友点击文章下方公众号获得免费领取方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值