高性能MySQL---(一)MySQL的架构

1.1 MySQL逻辑架构

在这里插入图片描述

1.2 并发控制

1、读写锁

  • 读锁/共享锁:相互不阻塞。多个客户在同一时刻可以同时读取同一个资源。
  • 写锁/排它锁:一个写锁会阻塞其他的写锁和读锁。

2、锁粒度

在任何时候,在给定的资源上,锁定的数据量越少,则系统的并发程度越高,只要相互之间不发生冲突即可。

  • 表锁: 表锁是MySQL中最基本的锁策略,并且是开销最小的策略。 在特定的场景下,表锁也有良好的性能(如,READ LOCAL表锁支持某些类型的并发写操作)。另外,写锁比读锁有更高的优先级(即一个写锁请求可能会被插入到读锁队列的前面)。
  • 行级锁:行级锁可以最大程度地支持并发处理(同时也带来了最大的锁开销)。行级锁只在存储引擎层实现,而MySQL服务器层没有实现。

1.3 事务

事务就是一组原子性的SQL查询,或者说一个独立的工作单位。
ACID:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)。

  • 原子性:整个事务中的所有操作要么全部提交成功,要么全部失败回滚。
  • 一致性:数据库总是从一个一致性状态转换到另一个一致性的状态。
  • 隔离性:并发时,事务间相互不影响。
  • 持久性:一旦事务提交,则其所做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

1.3.1 隔离级别

  • 脏读:事务B可以读到事务A没有提交的数据。隔离级别READ COMMITTED以上可以避免。
  • 不可重复读:事务B在事务A不断读取的情况下做了修改,导致事务A每次读到的数据不一致。隔离级别REPEATABLE READ以上可以避免。REPEATABLE READ是MySQL默认的事务隔离级别。
  • 幻读:事务A读取与搜索条件匹配的若干行,事务B以删除或插入等方式修改A的结果集,导致事务A再进行操作时行数发生变化。隔离级别SERIALIZABLE可以避免。
  • 加锁读:SERIALIZABLE会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用问题。实际应用中很少使用SERIALIZABLE这个隔离级别,只有在非常需要确保数据一致性而且可以接受没有并发的情况下,才考虑使用该级别。
    在这里插入图片描述

1.3.2 死锁

  • 定义:死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。
  • 原因:锁的行为和顺序和存储引擎有关。
    • 有些是因为真正的数据冲突,这种情况难以避免。
    • 有些完全是由于存储引擎的实现方式导致的。
  • 解决:
    • 复杂的系统(如InnoDB存储引擎)能检测到死锁的循环依赖,并立即返回一个错误。
    • 当查询的时间到达锁等待超时的设定后放弃锁请求(不推荐)。
    • InnoDB目前处理的方法是:将持有最少行级排他锁的事务进行回滚。

1.3.3 事务日志

  • 使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为以追加的方式记录到持久在硬盘的事务日志中,内存中被修改的数据在后台慢慢地被刷回到磁盘,即预写式日志
  • ACID中持久化的实现:如果数据的修改已经记录到事务日志并持久化,但数据本身还没有写回磁盘,此时系统崩溃,存储引擎在重启时能够根据事务日志自动恢复这部分修改的数据。

1.3.4 MySQL中的事务

MySQL中提供了两种事务型的存储引擎:InnoDB和NDB Cluster。

  • 自动提交(AUTOCOMMIT):MySQL默认采用自动提交模式。如果不是显示地开始一个事务,则每个查询都被当作一个事务执行提交操作。
  • 在事务中混合使用存储引擎:事务是由下层的存储引擎实现的,所以在同一个事务中,使用多种存储引擎是不可靠的。在事务中混合使用了事务型和非事务型的表,在正常提交的情况下不会有什么问题,但是需要回滚时,非事务型的表上的操作就无法撤销,会导致数据库处于不一致的状态。在非事务型的表上执行事务相关操作时不会发出提醒,只会在回滚时发出警告。
  • 隐式和显式锁定:
    • InnoDB会根据隔离级别在需要的时候自动加锁。InnoDB采用的是两阶段锁定协议。在事务执行过程中,随时都可以锁定,锁只有在执行COMMIT或者ROLLBACK的时候才会释放,并且所有的锁在同一时刻被释放。
    • InnoDB支持通过特定的语句进行显式锁定(这种锁定提示经常被滥用,实际上应当尽量避免使用):
select ... lock in share mode <!--显式加读锁-->
select ... for update <!--显式加写锁-->

1.4 多版本并发控制(MVCC)

  • MVCC是行级锁的一个变种,是通过保存数据在某个时间点的快照来实现的,具有乐观和悲观两种并发控制,MVCC没有正式的规范,各个存储引擎和数据库系统的实现都是各异的。
  • InnoDB的MVCC是通过在每行记录后保存两个隐藏的列来实现,一个保存了行的创建时间,一个保存行的过期时间(或删除时间),这个时间是即系统版本号。每开始一个新事物,系统版本号都会自动递增,事务开始时刻的系统版本号会作为事务的版本号。
    • select:只有符合下述两个条件的记录才能返回作为查询结果:
      • InnoDB只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或修改过的。
      • 行的删除版本要么未定义,要么大于当前事务版本号,这可以确保事务读取到的行,在事务开始之前未被删除。
    • insert:InnoDB为新插入的每一行保存当前系统版本号作为行版本号。
    • delete:InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
    • update:InnoDB为插入一行新记录保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

1.5 MySQL的存储引擎

  • MyISAM适用场景:
    • 频繁执行全表count语句(有一个变量保存)
    • 对数据进行增删改频率不高,查询非常频繁(数据、文件分离)
    • 没有事务
  • InnoDB适用场景:
    • 数据增删改查都相当频繁(行级锁)
    • 可靠性要求高,要求支持事务
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值