《高性能mysql 第三版》学习

本文详细探讨了MySQL的架构历史、存储引擎、事务处理、索引优化、性能剖析等方面,强调了InnoDB引擎的事务支持、MVCC机制、锁管理以及性能优势。此外,还讨论了如何选择合适的存储引擎,以及数据库复制和服务器优化策略,旨在提升MySQL的性能和可用性。
摘要由CSDN通过智能技术生成

《第一章:mysql 架构历史》

mysql 足够灵活,能够适应高要求的环境。如web 类应用。 MySQL既可以嵌入到应用程序中,也可以支持数据仓库,内容索引和部署软件,高可用的冗余系统,在线事务处理系统OLTP等各种应用类型。

每个客户端连接都会在服务器进程中拥有一个线程,这个连接的查询

只会在这个单独的线程中执行,该线程只能轮流在某个CPU核心或者CPU中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。

当客户端连接到MySQL服务器时,服务器需要对其进行认证,认证基于用户名,原始主机信息和密码如果使用了安全套接字SSL的方式连接,还可以使用X.509证书认证。一旦客户端连接成功,服务器会继续验证该客户端是否具有执行某个特定查询的权限。

优化与执行:mysql 会解析查询,并创建内部数据结构,然后对其进行各种优化,包括重写查询,决定表的读取顺序,以及选择合适的索引等。用户可以通过特殊的关键字提示 hint 优化器,影响它的决策过程。也可以请求优化器解释 explain 优化过程的各个因素,使用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema,修改相关配置,使应用尽可能高效运行。

优化器不关心表使用的是什么存储引擎,但存储引擎对于优化查询是有影响的。对于select 语句,解析查询之前,服务器会先检查查询缓存query cache,如果能够在其中找到对应的查询,服务器就不必再执行查询解析,优化,执行的整个过程,而是直接返回查询缓存中的结果集。

并发控制: 只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题。
mysql 在两个层面做并发控制: 服务器层与存储引擎层。
读写锁: 解决并发问题,可以通过实现一个由两种类型的锁组成的锁来解决问题这两种类型的锁称为共享锁shared lock和排他锁 exclusive lock,也叫读锁 read lock和写锁 write lock。
读锁和写锁的区别
读锁: 读锁是共享的,相互不阻塞。多个客户在同一时刻可以同时读取同一个资源,而互不干扰。
写锁 写锁是排他的一个写锁会阻塞其他的写锁和读锁,出于安全策略,只有这样,才能保证在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。
锁粒度: 一种提高共享资源并发性的方式就是让锁定对象更有选择性,尽量只锁定需要修改的部分数据,而不是全部资源。或者只对修改的数据片进行精确的锁定,锁定的数据量越少,系统的并发程度越高
存在问题: 加锁需要消耗资源。锁的各种操作,包括获得锁,检查锁是否已经解除,释放锁等,都会增加系统的开销。需要在锁的开销和数据的安全性之间寻求平衡[一般都是在表上施加行级锁比较好]。

MySQL提供多种选择。每种存储引擎都可以实现自己的锁策略和锁粒度。在存储引擎的设计中,锁管理是个非常重要的决定,将锁粒度固定在某个级别,可以为某些特定的应用场景提供更好的性能,但同时也会失去另外的一些应用场景的良好支持。

锁的分类
表锁table lock :

表锁是mysql 中最基本的锁策略,并且是开销最小的策略它会锁定整张表,一个用户在对表进行写操作前,需要先获得写锁,这会阻塞其他用户对该表的所有读写操作。只有没有写锁时,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的。


在特定的场景中,表锁也可能有良好的性能,read,local 表锁支持某些类型的并发写操作。写锁比读锁有更高的优先级,所以一个写锁的请求可能会被插入到读锁队列的前面。

注解:服务器会为alter table 之类的语句使用表锁。

行级锁 row lock : 行级锁可以最大程度的支持并发处理(最大的锁开销)。InnoDB 和 XtraDB ,以及其他一些存储引擎中实现了行级锁。行级锁只在存储引擎层实现,MySQL 服务层没有实现。

事务:事务内的语句,要么全部执行成功,要么全部执行失败。

事务:
名字 解释
1.原子性atomicity   : 一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,一个事务,不可能只执行其中一部分操作,这就是事务的原子性
2.一致性consistency : 数据库总是从一个一致性的状态转换到另外一个一致性的状态。
3.隔离性isolation   : 一个事务所做的修改在最终提交之前,对其他事务都是不可见的。
4.持久性durability  : 一旦事务提交,则其所做的修改就会永久保存到数据库中。就算系统崩溃,数据也不会丢失
隔离级别:
1.read uncommitted 未提交读: 在read uncommitted 级别,事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,会造成脏读dirty read。比起其他隔离级别好处不会太多,但问题不少,所以实际应用中一般很少使用。
2.read commited 提交读: 大多数数据库系统的默认级别都是read commited,一个事务开始时只能看见已经提交的事务所做的修改。也称为不可重复读。
3.repeatable read 可重复读: repeatable read 解决了脏读问题,保证了在 同一个事务中多次读取同样的记录的结果是一样的。可重复度级别无法解决幻读问题。[当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行 phantom row],InnoDB 和XtraDB 存储引擎通过多版本并发控制(MVCC )解决了幻读问题。
4.serializable 可串行化: serializable 是最高的隔离级别。它通过强制事务串行执行,避免了幻读问题serializable 会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁竞争的问题。实际开发中很少用。

 

隔离级别 脏读可能性 不可重复读可能性 幻读可能性 加锁读
read uncommitted yes yes yes no
read commited no yes yes no
repeatable read no no yes no
serializable no no no yes

死锁:死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,也会产生死锁。

1.为了解决死锁,数据库系统实现了各种死锁检测和死锁超时机制。越复杂的系统,InnoDB存储引擎,越能检测到死锁 的循环依赖,并立即返回一个错误。解决方式很有效,否则死锁会导致出现慢查询。
2.当查询的时候达到锁等待超时的设定后放弃锁请求,这种方式不太好。
3.InnoDB 处理死锁的方式是,将持有最少行级排他锁的事务进行回滚。

锁的行为和顺序是和存储引擎相关的。

死锁产生有双重原因:

1.有些是因为真正的数据冲突,这些情况通常很难避免。
2.有些则由于存储引擎的实现方式导致的。
注解:死锁发生后,只有部分或者全部回滚其中一个事务,才能打破死锁。

事务日志的作用:事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不是每次都将修改的数据本身持久到磁盘。

事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域内的顺序I/O,而不像随机I/O 需要在磁盘的多个地方移动刺头,所以采用事务日志的方式相对很快。事务日志持久以后,内存中被修改的数据在后台可以慢慢的刷回到磁盘,大多数存储引擎也是这样实现,称为写式日志write-aheadLogging。

mysql 中的事务:

mysql提供了两种事务型的存储引擎:InnoDB 和 NDB Cluster。还有一些第三方存储引擎也支持事务,比如XtraDB 和PBXT。

自动提交auto commit : mysql 默认采用自动提交模式。

mysql 可以通过set transaction isolation level 命令设置隔离级别,新的隔离级别会在下一个事务开始的时候生效。可以在配置文件中设置整个数据库的隔离级别,也可以只改变当前会话的隔离级别&#x

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值