高性能Mysql-Mysql架构与历史

和其他数据库系统相比, MySQL有点与众不同, 它的架构可以在多种不同场景中应用并发挥好的作用, 但同时也会带来一点选择上的困难。MySQL井不完美, 却足够灵活,能够适应高要求的环境, 例如Web类应用。

1、MySQL逻辑架构

为了更好的学习mysql,首先我们需要先了解一下mysql的逻辑架构图,如下:

mysql逻辑架构图

 最上层的服务并不是MySQL所独有的, 大多数基于网络的客户端/服务器的工具或者 服务都有类似的架构。 比如连接处理、 授权认证、 安全等等。

第二层架构是MySQL比较有意思的部分。 大多数MySQL的核心服务功能都在这一层, 包括查询解析、 分析、 优化、 缓存以及所有的内置函数(例如, 日期、 时间、 数学和加密函数), 所有跨存储引擎的功能都在这一层实现:存储过程、 触发器、视图等。

第三层包含了存储引擎。 存储引擎负责MySQL中数据的存储和提取。 和GNU/Linux下的各种文件系统一样, 每个存储引擎都有它的优势和劣势。 服务器通过API与存储引擎 进行通信。 这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对上层的查询过程透明。 存储引擎API包含几十个底层函数, 用于执行诸如 “开始一个事务” 或者 “根据主键提取一行记录” 等操作。 但存储引擎不会去解析SQL,不同存储引擎之间也不会相直通信, 而只是简单地晌应上层服务器的请求。

2、并发控制

无论何时, 只要有多个查询需要在同一时刻修改 数据, 都会产生井发控制的问题。那么我们将了解MySQL在两个层面的井发控制:服务器层与存储引擎层。

2.1 读写锁

在处理井发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。这两种类型的锁通常被称为共享锁(shared lock) 和排他锁(exclusive lock),也叫读锁(read lock) 和写锁(write lock)。读锁是共享的,或者说是相互不阻塞的。多个客户在同一时刻可以同时读取同一个资源,而互不干扰。写锁则是排他的,一个写锁会阻塞其他的写锁和读锁。

2.2 锁粒度

一种提高共享资源并发性的方式就是让锁定对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有的资源。问题是加锁也需要消耗资源,所得各种操作,包括获得锁,检查锁是否被删除、释放锁等,都会增加系统的开销。

所谓的锁策略,就是在锁的开销和数据的安全性之间寻找平衡,这种平衡当然也会影响到性能。而Myslq存储引擎可以实现自己的所策略和锁粒度。

表锁

表锁是MySQL中最基本的锁策略, 井且是开销最小的策略。  一个用户在对表进行写操作(插入 删除 更新等)前, 需要先获得写锁, 这会阻塞其他用户对该表的所有读写操作。 只有没有写锁时, 其他读取的用户才能获得读锁, 读锁之间是不相互阻塞的。
在特定的场景中, 表锁也可能有良好的性能。 例如, READ LOCAL 表锁支持某些类型的井发写操作。 另外, 写锁也比读锁有更高的优先级, 因此一个写锁请求可能会被插入到读锁队列的前面。

行级锁

行级锁可以最大程度地支持井发处理(同时也带来了最大的锁开销)。众所周知,在 InnoDB和XtraDB,以及其他一些存储引擎中实现了行级锁。行级锁只在存储引擎层实现,而MySQL服务器层没有实现。服务器层完全不了解存储引擎中的锁实现。

3、事物

事物就是一组原子性的sql查询,或者说一个独立的工作单元。也就是说,事物内的sql语句要么全部执行成功,要么全部执行失败。

ACID

原子性(atomicity):一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功, 要么全部失败回滚,对于一个事务来说, 不可能只执行其中的一部分操作,这就是事务的原子性。

一致性 (consistency):数据库总是从一个一致性的状态转换到另外一个一致性的状态。

隔离性(isolation):通常来说, 一个事务所做的修改在最终提交以前,对其他事务是不可见的。

持久性(durability):一旦事务提交,则其所做的修改就会永久保存到数据库中。

事物的隔离级别

死锁

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

4、存储引擎

4.1 InnoDB存储引擎

InnoDB是MySQ上的默认事务型引擎, 也是最重要、 使用最广泛的存储引擎。 它被设计用来处理大量的短期(short-lived)事务, 短期事务大部分情况是正常提交的, 很少会被回滚。InnoDB的性能和自动崩榄恢复特性,使得它在非事务型存储的需求中也很流行。

InnoDB采用MVCC来支持高并发, 井且实现了四个标准的隔离级别。 其默认级别是REPEATABLE旺AD(可重复读),井且通过间隙锁(nex t-key locking)策略防止幻读的出现。间隙锁使得InnoDB不仅仅锁定查询涉及的行, 还会对索引中的间隙进行锁定, 以防止幻影行的插入。

InnoDB表是基于聚簇索引建立的。InnoDB的索引结构和MySQL的其他存储引擎有很大的不同,聚簇索引对主键查询有很高的性能。不过它的二级索引(secondary index, 非主键索引)中必须包含主键列, 所以如果主键列很大的话, 其他的所有索引都会很大。 因此, 若表上的索引较多的话, 主键应当尽可能的小。

4.2 MylSAM存储引擎

在MySQL 5.1 及之前的版本,MyISAM是默认的存储引擎。MyISAM提供了大量的特性, 包括全文索引、压缩、空间函数(GIS)等, 但MyISAM不支持事务和行级锁, 而且有一个毫无疑问的缺陷是崩溃后无法安全恢复。但是对于只读的数据,或者表比较小、可以忍受修复操作,则依然可以继续使用MyISAM。

5、选择合适的存储引擎

事物

如果应用需要事务支持, 那么InnoDB(或者XtraDB) 是目前最稳定井且经过验证 的选择。 如果不需要事务, 井且主要是SELECT和INSE盯操作, 那么MyISAM是不 错的选择。 一般日志型的应用比较符合这一特性。

备份

备份的需求也会影响存储引擎的选择。 如果可以定期地关闭服务器来执行备份, 那么备份的因素可以忽略。 反之,如果需要在线热备份,那么选择InnoDB 就是基本的要求。

崩溃恢复

数据量比较大的时候,系统崩愤后如何快速地恢复是一个需要考虑的问题。相对而言,MyISAM崩愤后发生损坏的概率比InnoDB 要高很多,而且恢复速度也要慢。 因此,即使不需要事务支持,很多人也选择InnoDB引擎,这是一个非常重要的因素。

特有的特性

最后,有些应用可能依赖一些存储引擎所独有的特性或者优化,比如很多应用依赖聚簇索引的优化。 另外,MySQL中也只有MyISAM支持地理空间搜索。 如果一个存储引擎拥有一些关键的特性,同时却又缺乏一些必要的特性,那么有时候不得不做折中的考虑,或者在架构设计上做一些取舍。

猜你喜欢

转载自blog.csdn.net/dongzl0230/article/details/82964436