《mysql高性能》系列1:mysql总体构架

发布时间 2023-05-19 23:23:37作者: 涅槃的凤凰

1 mysql构架

mysql构架可以分为三层,分别是客户端、服务层和存储引擎层,如下图所示。

  • 客户端
    可以认为是提供给用户使用的一个工具,方便用户使用,同时,提供了连接管理、授权认证和安全的功能。比如,对于每一个客户端发过来的请求,服务层都会从线程池中取出一个线程来处理请求。客户端连接到服务层时,需要输入用户名、主机信息和密码来进行安全认证,也可以使用ssl方式连接。

  • 服务器层
    实现了mysql的一些核心服务功能,比如,查询解析、优化和缓存,还有所有的内置函数(日期、时间、数学和加密功能)、所有的跨存储引擎的功能(如,存储过程、触发器和视图),都在服务层实现。
    对于select语句,服务层在执行真正的语句解析和优化之前,都会到查询缓存中查询是否有缓存结果,如果有,直接返回结果。如果没有,则执行语句解析和优化,再调用存储引擎层的api去查询数据。

  • 存储引擎层
    存储引擎负责mysql中数据的存储和提取。服务层通过api与存储引擎层通信。常见的存储引擎有InnoDB和MyISAM。不同的存储引擎,有着不同的特性。如,InnoDB支持事务,MyISAM不支持事务。

2 并发控制

当客户端同一时刻对修改数据时,就会产生并发控制的问题。针对并发请求,可以使用锁来进行控制并发访问。为了应对不同的场景,锁可以分为多种。

2.1 锁的分类

  • 1)区分读和写,可以分为读锁和写锁
    很多服务都是读多写少,读和读之间是相互不影响,写和(读、写)都会影响,因此,可以针对这两种不同的情况,将锁分为读锁和写锁。读的时候加读锁,写的时候加写锁。

  • 2)区分锁的粒度
    如果两个请求同时update一张表的不同的行,那么,理论上,应该允许他们同时进行,因为,他们之间不会相互影响。那么,我们可以从锁的粒度的角度,将锁分为表锁和行锁。表锁会对整张表加锁,行锁只会对某行或者邻近的几行加锁。

  • 3)悲观锁和乐观锁
    悲观锁:系统从一种保守的角度来看待并发问题,认为每次访问数据库都有可能发生并发修改的问题。因此,每次访问数据时,都需要加锁。
    乐观锁:系统从一种乐观的角度看问题,认为每次访问数据库不太可能出现并发修改的问题,因此,只需要做好最基本的兜底保证(例如,使用多版本并发控制MVCC可以实现的乐观锁,比较修改前后的版本号是否一样,来判断某线程修改期间是否有其它线程修改过改行数据)就可以了。每次访问数据,可以不用加锁。
    mysql的锁在服务器层和存储引擎层都有实现。mysql的表锁在服务器层实现,行级锁在存储引擎层实现。

3 事务和隔离级别

事务的概念:有些情况下,我们会要求多个sql语句要么都执行成功,要么都执行失败。例如,a给b转账10元这个业务,a的账户减去10元,b的账户增加10元。这两个操作要么都成功,要么都失败。这样,才可以保证安全。经过分析,用书面语来讲,一个事务应该拥有如下四个特性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。称为ACID特性。
原子性是对多个操作而言的,多个操作要么都成功,要么都失败。
一致性对于数据而言,a的账户减去10元,b的账户增加10元,这里必须要符合逻辑,b的账户不能只增加9元,或者b的账户没有增加。一致性需要通过原子性来保证。
隔离性则保证了多个并发的请求(事务)之间不会相互影响。
持久性则是对数据持久保存的要求。

事务是在存储引擎层实现的。InnoDB支持事务,MyISAM不支持事务。

4 mysql的存储引擎

mysql使用文件系统来保存数据库和表的定义,因此,大小写敏感是和具体的操作系统有关系的。创建表时,mysql会在数据库子目录下创建一个和表名同名的.frm文件保存表的定义。例如,表名为mytable,则保存表的定义的文件名为mytable.frm。

4.1 InnoDB存储引擎

是mysql5.1版本之后的默认存储引擎。
1)支持事务,默认的隔离级别是可重复读,并通过间隙锁来防止幻读的出现。
2)使用MVCC(一种可以认为是一种乐观锁)来保证高并发。
3)使用聚簇索引(一种数据和索引的存储方式,将数据和索引存储在叶子节点上)来存储数据和索引。二级索引(非主键索引)则必须包含主键。

4.2 MyISAM存储引擎

是mysql5.1及之前的默认存储引擎。
1)支持全文索引(例如,全部内容的字符串查找)、压缩和空间函数(例如,可以存储几何上的点、线、面)等
2)不支持事务和行级锁
3)崩溃后无法安全恢复
由于以上的几个特性,因此,MyISAM可以用在一些只读的数据。
4)MyISAM将表存储为两个文件:数据文件和索引文件(数据和索引单独存放,不是聚簇索引)。数据文件存放数据,以.MYD为扩展名;索引文件存放索引,以.MYI为扩展名。

5 选择合适的存储引擎

选择InnoDB还是MyISAM,主要考虑几个方面
1)是否需要事务
如果应用需要事务的支持,则考虑使用InnoDB。如果不需要事务,并且主要是简单的select和insert操作,则可以使用MyISAM。
2)备份
如果可以定期的关闭服务器进行数据备份,则忽略备份这个因素。如果需要在线备份,则使用InnoDB。
3)崩溃恢复
由于MyISAM崩溃后无法安全的恢复,而且恢复速度也慢,所以,如果对崩溃恢复有要求,则使用InnoDB。
4)固有的特性
如果只是做数据分析,且需要使用空间函数,容许数据有些丢失,那么,可以使用MyISAM,因为mysql只有MyISAM引擎支持空间函数。
如果需要使用聚簇索引,则考虑使用InnoDB。