MySQL 架构与历史

来源:互联网 发布:sql query language 编辑:程序博客网 时间:2024/06/06 08:58

1 MySQL逻辑架构


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


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


第三层包含了存储引擎。它负责MySQL中数据的存储和提取。和GNU/Linux下的各种文件系统一样,每个存储引擎都有自己的优劣。服务器通过API与存储引擎进行通信。这些接口屏蔽了存储引擎之间的差异。存储引擎不会解析sql,不同存储引擎之间也不会相互通信,而只是简单的响应上层服务器的请求。如果能理解MySQL在存储引擎和服务层之间处理查询时如何通过API来回交互,就能抓住MySQL的核心基础架构的精髓。


2 优化与执行

MySQL会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。优化器并不关心使用的是什么存储引擎,但存储引擎对于优化查询是有影响的。


3 并发控制

无论何时,只要有多个查询需要在同一时刻修改数据,都会产生并发控制的问题。在处理并发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题。即:共享锁和排它锁,也叫读锁和写锁。读锁:共享的,或者说互不阻塞的。多个客户在同一时刻读取同一个资源,互不干扰。写锁:排他的,一个写锁会阻塞其他的写锁和读锁。加锁也需要耗费资源。锁的各种操作都会增加系统的开销。如果花费大量的时间来管理锁,而不是存取数据,那么系统的性能可能会因此受到影响。所谓锁策略,就是在锁的开销和数据的安全性之间寻求平衡。MySQL中提供了两种重要的锁策略行锁和表锁。行锁可以最大程度的支持并发,只在存储引擎层实现,服务层完全不了解存储引擎中的锁实现。


4 事务(存储引擎来实现)

在理解事务的概念之前,接触数据库系统的其他高级特性还言之过早。事务是一组原子性的操作,或者说一个独立的工作单元。事务内的语句,要么全部执行成功,要么全部执行失败。

1)说到事务,就不得不说事务的ACID属性。

原子性 atomicity: 事务内的操作,要么全部执行成功,要么全部执行失败。

一致性 consistency:事务总是从一个一致的状态转换到另一个一致的状态。事务提交前,所有的修改都不会生效。

隔离性 isolation :一个事务所做的修改在最终提交之前,对其他事务是不可见的。

持久性 durability:即使系统崩溃,修改的数据也不会丢失。

一个实现了ACID的数据库通常比一个没有实现ACID的数据库需要更强的cpu,更大的内存,更多的磁盘空间。用户可以根据业务是否需要事务处理来选择合适的存储引擎,对于一些不需要事务的应用,可以选择一个非事务型的存储引擎,以获得更高的性能。


2)事务隔离级别(存储引擎会根据隔离级别自动加锁)

在SQL中定义了4种标准的隔离级别,每一种都规定了一个事务中所做的修改,哪些在事务内和事务间可见的,哪些是不可见的。级别越低,并发性能越高。

未提交读 read uncommitted: 事务做修改时对其他事务是可见的。事务可以读取未提交的数据,这也被称为脏读。除非有非常必要的要求,在实际中一般很少使用。


提交读 read committed:大多数数据库系统的隔离级别都是这个提交读,但是MySQL不是。一个事务从开始到提交之前,对其他事务都是不可见的。但是提交读的弊端在于,A事务对表进行写操作时,B事务可以读这个表,由于不可见(B事务看不见A写的未提交的内容),所以读到的是A事务开始之前表的数据,A事务完成后,B事务读到的表数据又是新的数据。所以说这个级别也叫不可重复读。


可重复读read repeatable: 该级别保证了同一个事务中多次读取同样记录的结果是一致的。但会形成幻读。所谓幻读:当A事务在读取某个范围内的记录时,另一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。MVCC解决了幻读的问题。

这是MySQL的默认隔离级别。


可串行化 serializable:强制事务串行执行,会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁争用问题。只有在非常需要时才用这个级别。


设置隔离级别:set transaction isolation level read committed;


3)死锁

死锁之所以不放在并发控制里面来讲是因为,死锁的解决方法之一用的就是事务的回滚。将持有最少行级锁的事务进行回滚。


4)事务日志

可以提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到硬盘上的事务日志中,而不是每次都将修改的数据本身写(持久)到磁盘。事务日志写好之后,内存中被修改的数据在后台可以慢慢地刷回到磁盘。目前大多数存储引擎都是这样实现的,也叫预写式日志。如果数据还没有写回磁盘,此时系统崩溃,存储引擎在重启时能够自动修复。


5)MySQL中的事务

MySQL默认自动提交:如果不是显示的开启一个事务,则每个查询都被当做一个事务执行提交操作。

设置提交方式:show variables like 'autocommit';           set sutocommit = 0;关闭自动提交,1是开启。

在事务中混合使用存储引擎不是可取的。

MySQL服务器不管事务,事务由存储引擎实现。所以在同一个事务中使用多中存储引擎是不可靠的。



5 多版本并发控制 MVCC

在表的末尾保存两列隐藏的行来保存创建时间和过期时间,这里的时间不是实际的时间,而是系统版本号。每开启一个事务,版本号都会递增。通过版本号使大多数读操作都不用加锁。这样的设计使数据操作很简单,性能很好。


6 MySQL的存储引擎


有很多数据库存储引擎,(存储引擎实际上就是一个文件管理系统)各有优劣。当然也有MySQL集群的NDB集群引擎。对于95%的用户来说,InnoDB是最佳的选择。












1 0