《高性能MySQL》 第一章 Mysql架构与历史

16 篇文章 0 订阅
1 篇文章 0 订阅

本章概要地描述Mysql的服务器架构、各种存储引擎之间的主要区别,以及区别的重要性。

1.1 Mysql逻辑架构

-w312
最上层的连接处理、授权认证、安全都是cs模式类似架构。
第二层是核心的一层,包括**查询、分析、优化、缓存以及所有的内置函数(日期、时间、数据和加密等)**所有跨存储引擎的功能都在这一层实现:存储过程、触发器、视图等。
第三层包括了存储引擎,负责mysql中数据的存储和提取。和GNU/Linux下的各种文件系统一样,每个存储引擎都有它的优势和劣势,服务器通过API与存储引擎通信,屏蔽差异。

1.1.1 连接管理与安全性

mysql5.5之后又线程池插件,支持少量的线程服务大量的连接。

1.1.2 优化与执行

mysql会创建内部的解析树,我们也可以手动添加参数关键字提示来影响决策,重写查询、表的读取顺序,选择合适的索引。优化器细节在第六章会讲到。

mysql查询会先检查缓存,如果缓存命中,就不必在查询解析、优化和执行了,而是直接返回结果,在第7章讨论。

优化器不关心什么存储引擎,但是某些存储引擎的某种索引会对结果又影响,在第4、5章会讨论。

1.2 并发控制

只要多个查询需要在同一时刻修改数据,就会产生并发的问题。

**通过锁来防止数据损坏,但是锁的方案有很多种,对应的场景也不同。
**

1.2.1 读写锁

在处理并发读或者写时,可以通过实现一个两种类型的锁组成的系统来解决问题,两种类型的锁通常被称为共享锁和排他锁、也叫读锁写锁
读锁:共享的、互不影响的,同时读取一个资源不干扰
写锁:排他的,写锁会阻塞写锁和读锁,只有这样才能确保在给定的时间里,只有一个用户能执行写入。

在实际的数据库中,每时每刻都在发生锁定,当某个用户在修改某一部分数据的时候,mysql通过锁定防止其他用户度统一数据。

1.2.2 锁粒度

锁的各种操作包括创建、获得、检查所是否解除、释放锁都会增加开销,如果话费大量时间来管理锁而不是存取数据,那么系统的心梗会受影响。

锁策略:就是在开销和数据安全性之间寻求平衡,大多数商业数据库都是在表上加行级锁

表锁是mysql中最基本的所策略,开销最小,类似邮箱系统,一个用户对表进行写操作(插入、更新、删除等)都要先获得写锁,阻塞其他用户对该表的所有读写操作。

尽管存储引擎可以管理自己的锁,但是mysql本身还是会使用各种有效的表锁实现不同的目的。例如ALTER TABLE之类的语句

行级锁最大程度支持并发处理,同时带来了最大的所开销。例如InnoDb和XtraDB就实现了行级锁。行级锁只在存储引擎层实现。

1.3 事务

事务的ACID特性(原子性、一致性、隔离性、持久性)

银行储蓄是一个经典的例子如:
-w650
代码如下:
-w538
原子性:要么成功要么失败
一致性:数据库状态总是从一个一致性状态到另外一个一致性状态。
隔离性:事务未完成时,其他线程不可见更改(隔离级别)
持久性:一旦事务提交,修改永远保存到数据库中

即使选择不支持事务的存储引擎也可以用LOCK TABLES来一定程度保护数据。

1.3.1 隔离级别

在SQL标准中四种隔离界别,每一种界别都规定了一个事务中所做的修改,哪些在事务内核事务间是可见的。

READ UNCOMMITTED(未提交读、脏读): 事务中的修改,即使没有提交,对其他事务也是课件的。 级别最低,会有脏读。
READ COMMITTED(提交读、不可重复读):一个事务开始时只能看见已经提交的事务所做的修改即一个事务在没有提交前。这个级别有时候叫做不可重复读,因为两次查询的结果可能不一样。
REPEATABLE READ(可重复读):保证同一个事务中多次读取同样记录的结果是一致的。但是可重复读仍然是没有办法解决一个幻读的问题。指的是某个事务在读取范围内的记录时,另外一个事务又在该事务内插入了新的数据,当之前的事务再次读取该范围的记录时,会产生Phantom Row幻行。 InnoDb和XtraDB通过多版本并发控制(乐观锁)解决了幻读的问题。
SERIALIZABLE(可串行化):最高的隔离级别,强制事务串行执行,避免了幻读,简单来说就是在读取的每一行都加锁,导致大量的超时和锁征用问题。

-w586
不可重复读和幻读的区别
关于幻读,可重复读的真实用例是什么? - 无关所以的回答 - 知乎

大概就是幻读是insert进去的,不可重复读在update、delete。

1.3.2 死锁

死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源,导致恶性循环,T1有r1,r2想要r3,T2有r3 r4想要r1
-w622
-w628
为了解决这样的问题,有死锁检测、死锁超时机制,也有死锁预防、死锁解除、死锁避免。

1.3.3 事务日志

修改数据只需要修改其内存拷贝,再把修改行为记录到持久评判中,不用每次修改数据本身的持久硬盘,事务日志是追加方式,故顺序IO会快很多。

预写式日志,修改数据需要写2次磁盘。

1.3.4 mysql中的事务

-w655

-w615
隐式和显式锁定
InnoDB采用的是2pc两阶段提交协议。

-w630

1.4 多版本并发控制

Mysql大多数事务型存储引擎实现得都不是简单的行级锁,基于并发性能考虑,都同时实现了多版本并发控制。MVCC。

mvcc可以认为是行级锁的变种,多种情况下避免加锁,开销耕地。

MVCC是用某个时间点的快照来实现的,每个事务看到的数据都是一致的,根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

-w620
-w641
MVCC只在可重复与提交读两个级别下工作。

与悲观锁相对的,我们有了乐观锁。乐观锁一开始也说了,就是一开始假设不会造成数据冲突,在最后提交的时候再进行数据冲突检测。

比如同样有2个session同样对某条数据进行操作。两者都取到当前的数据的版本号为1,当第一个session进行数据更新后,在提交的时候查看到当前数据的版本还为1,和自己一开始取到的版本相同。就正式提交,然后把版本号增加1,这个时候当前数据的版本为2。当第二个session也更新了数据提交的时候,发现数据库中版本为2,和一开始这个session取到的版本号不一致,就知道别人更新过此条数据,这个时候再进行业务处理,比如整个Transaction都Rollback等等操作。
在用版本戳的时候,可以在应用程序侧使用版本戳的验证,也可以在数据库侧采用Trigger(触发器)来进行验证

1.5 Mysql的存储引擎

在文件系统中,mysql将每个数据库(schema)保存为数据目录下的子目录,创建表是,mysql会在数据库子目录下创建一个和表同名的.frm文件保存。

-w598

1.5.1 InnoDB存储引擎

被设计处理大量的短期事务,短期事务大部分情况正常提交,很少回滚。

-w635
-w610
1、myisam查询效率更高,支持全文索引。innodb不支持全文索引,查询效率差myisam6-7倍。

2、innodb支持事务,行锁,外键。myisam不支持。

  1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

  2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;

  3. InnoDB是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而MyISAM是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

  4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

  5. Innodb不支持全文索引,而MyISAM支持全文索引,查询效率上MyISAM要高;

1.5.2 MyISAM存储引擎

-w623
数据崩溃后无法安全恢复。

1.5.3 Mysql内建的其他存储引擎

Archive\blackhole\csv\federated\Mermory引擎。

1.5.4 第三方引擎

-w627

1.5.5 选择合适的引擎

-w623
-w618

1.5.6 转换表引擎

-w624

1.6 Mysql时间线

2001-2010(5.5)

1.7 mysql的开发模式

好。

1.8 总结

mysql拥有分层架构,上层查询、下层存储引擎,有许多插件API。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值