[关闭]
@lgh-dev 2018-01-02T07:54:39.000000Z 字数 6451 阅读 630

高性能的Mysql-mysql的架构和历史

MySQL


Mysql架构和历史

简述

mysql可以在不同场景中应用并发挥好的作用,他并不完美,却足够灵活,能适应高要求的环境。MySQL既可以嵌入到应用中,也可以支持数据仓库,内容索引和部署软件,高可用的冗余系统,在线事务处理系统等各种应用类型。
MySQL的存储引擎架构将查询处理和其他任务系统和数据的存储/提取相分离。

MySQL逻辑架构图

mysql-image

存储引擎

连接管理与安全性

优化与执行

MySql 会解析查询,并创建内部数据结构(解析树),然后对其进行各种优化,比如重写查询,表读取顺序,索引选择等。优化器不关心表使用什么存储引擎,她会请求存储引擎提供容量或某个具体操作的开销信息,以及表的统计信息等。对于select语句,在解析查询之前,服务器会先查缓存,如果能找到服务器就不在解析查询,而是直接返回缓存中的结果集。

并发控制

MySQL事务

事务就是一组原子性的sql查询,或者说是一个独立的工作单元。如果数据库引擎能够成功的对数据库应用该组查询的全部语句,那就全部执行,如果有一条语句执行失败,那么所有语句都不会执行。

隔离级别

隔离级别

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。

Yes: 可能出现 No: 不会出现

隔离级别 脏读 不可重复读 幻读
Read uncommitted Yes Yes Yes
read committed No Yes Yes
repeatable read no no yes
serializable no no no

死锁

死锁是指两个或者多个事务在同一个资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务以不同的顺序锁定资源时就会产生死锁。多个事务同时锁定同一个资源时,也会产生死锁。
死锁的产生有双重原因:有些是因为真正的数据冲突,有些完全是因为存储引擎的实现方式导致的。
死锁发生以后只有部分或者全部会滚一个事务,才能打破死锁。

事务日志

存储引擎在修改表数据的时候只需要修改其内存拷贝,再把修改行为记录到持久在硬盘上的事务日志中,而不用每次将修改的数据本身持久到硬盘。
事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域的顺序I/O,不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志相对来说要快很多。
事务日至持久化后,内存中被修改后可以后台慢慢的刷回到磁盘。修改数据需要写两次磁盘。

自动提交(autocommit)

MySQL默认采用自动提交模式。 show variables like 'autocommit' 查看自动提交的状态。
set autocommit = 1; 语句来设置或者禁用自动提交,1代表启用,0代表禁用。

MySQL通过执行SET TRANSACTION IOSLATION LEVEL 来设置隔离级别,新的隔离级别在下一个事务开始时生效。

set session transaction isolation level read committed 设置当前会话的隔离级别,InnoDB支持所有的隔离级别。

事务中混合使用存储引擎

MySQL服务层不管理事务,事务是由下层的存储引擎实现的。
如果在事务中使用了事务型和非事务型的表,正常提交没有问题, 但是如果事务需要会滚,非事务表的变更无法撤销,事务最终结果无法确定。而且在非事务性的标上执行事务操作,MySQL一般不会发出提醒,也不会报错。有时候只有回滚的时候会发出警告。

隐式和显示锁定

1、InnoDB采用的是两阶段锁定协议。在事务执行的过程中,随时都可以执行锁定,只有在执行commit或者rollback后才会释放;
2、InnoDB也支持通过特定的语句显示的锁定,这是在服务器层实现的,和存储引擎无关。
3、建议是除了事务中禁用了autocommit,可以使用lock tables,其他都不要显示的执行lock tables,因为lock tables 和事务之间相互影响的话,情况会变得比较复杂。

多版本并发控制(MVCC)

MySQL存储引擎

不同的存储引擎保存数据和索引的方式是不同的,但表的定义则是在MySQL服务层统一处理的。
可以使用 show table status like 'tables'\G sql显示表的相关信息。

InnoDB存储引擎

InnoDB是MySQL的默认事务存储引擎,也是最重要,使用最广泛的存储引擎。它被谁用来处理短期事务,短期事务大部分是正常提交,很少回滚。
InnoDB的性能和自动崩溃恢复,使得他在非事务存储的需求中也很流行。
InnoDB的数据存储在表空间(tablespace)中,表空间是由InnoDB管理的一个黑盒子,由一系列数据文件组成。
InnoDB采用MVCC来支持高并发,并实现了是个标准的隔离级别,默认级别是REPAEATABLE READ,通过间隙锁策略防止幻读的出现。间隙锁不仅仅锁定查询涉及的行,还会对索引中间隙进行锁定,防止幻影行的插入。
InnoDB表是基于聚簇索引建立的。聚簇索引对逐渐查询有很高的性能。
InnoDB内部做了很多优化,包括从磁盘读取数据采用可预测性读a子,能够自动在内存中创建hash索引以加速读操作的自适应哈希索引。
InnoDB通过一些机制和工具支持真正的热备份。

MyISAM存储引擎

在MySQL5.1及之前的版本,MyISAM是默认的存储引擎。MyISAM提供了全文索引,压缩,空间函数等特性,但是不支持事务和行级锁,而且崩溃后无法安全恢复。

MyISAM把表存在两个文件,数据文件和索引文件,以.MYD和.MYI为扩展名。

MySIAM的特性

如果表在创建并导入数据后, 不会再进行修改操作,那么这样的表或许适合采用MyISAM压缩表。使用 myisampack 命令对表进行压缩。压缩表不能进行修改,可以极大减少磁盘空间,减少I/O操作,提升查询性能。压缩表支持只读索引。

其他的MySQL内建的存储引擎

面向列的存储引擎

MySQL默认是面向行的,每一行的数据一起存储,服务器的查询也是以行为单位处理。而在大数据处理的时候,面向列的方式可能效率更高。如果不需要整行的数据,面向列的方式可以传输更少的数据。

除非万不得已,否则建议不要混合使用多种存储引擎,否则可能带来一系列复杂的问题,存储引擎层和服务器层交互已经很复杂了,而且混合存储对一致性备份和服务器参数配置都带来了一些困难。

存储引擎的选择

日志型的应用用MyISAM存储引擎,开销低,插入速度非常快。MySIAM只将数据写入内存中,然后等待操作系统定期将数据刷出到磁盘上。InnoDB是订单类处理应用的最佳选择。如果要发布一个基于CD-ROM或者DVD-ROM并且使用MySQL数据文件的应用,可以考虑使用MyISAM表或压缩表,这样表之间可以隔离并且可以在不同的介质上相互拷贝。MyISAM压缩表比未压缩的表要节省很多空间,但是压缩表是只读的。

转换表的存储引擎

  1. mysql> crate table innodb_table like myisam_table;
  2. mysql> alter table innodb_table engine=InnoDB;
  3. mysql> insert into innodb_table select * from myisam_table;

数据量不大,还可以,如数据量很大,可考虑做分批处理,针对每一段数据做事务执行提交操作,避免大事务产生过多的undo。执行的过程中可以对原表加锁,确保数据一致。

总结

MySQL拥有分层的结构,上层是服务器层和查询执行引擎,下层则是存储引擎。理解MySQL在存储引擎和服务层之间处理查询时如何用API来回交互,就能抓住MySQL的核心基础架构和精髓。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注