高性能MySQL—第一章 MySQL架构与历史

1 MySQL架构与历史

1.1 MySQL逻辑架构

  1. MySQL服务器逻辑架构图

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

第二层:大多数核心服务,包括解析、分析、优化、缓存等,跨存储引擎的功能都在这一层体现:存储过程、触发器、视图等。

第三层:包含了存储引擎,负责数据存储与提取。

1.2 并发控制

1.读写锁

共享锁(shared lock)和排他锁(exclusive lock)又称为读锁(read lock)和写锁(write lock)。

读锁:共享,相互不阻塞。

写锁: 会阻塞其他读写锁。

2.锁粒度

锁策略:锁开销和数据安全性之间求平衡。

分为 行级锁(row-level lock)、表级锁(table lock)

每个MySQL存储引擎都可以实现自己的锁策略和锁粒度。

表锁:开销小,锁整个表。一般alert table 之类的语句使用表锁。

写锁可以插入锁队列中读锁的前面,反之不行。

1.3 事务

事务:一组原子性的SQL查询,要么全成功,要么全失败。

开启事务:start transaction或 begin

结束事务:要么commit提交(持久化保留),要么rollback回滚(撤销修改)。

ACID特性:A原子性(actomicitty)、C一致性(consistency)、I 隔离性(isolation)、D持久性(durability)。

原子性:要么全提交成功,要么全失败回滚。

一致性:转账前后总金额不变。

隔离性:一个事务所作修改在提交前,对其他事务不可见。

持久性:一旦失误提交,永久保存到数据库。

隔离级别

read uncommitted(未提交读):即使A事务未提交,其他事务也能可见。出现脏读。较少使用。

read committed(提交读):大多数默认级别(不是MySQL级别),只能看见已提交数据,事务A从开始到结束所做的任何修改对其他事务不可见。也被称为不可重复读,两次查询结果可能不同。

repeatable read(可重复读):多次读结果一样(MySQL默认级别)。解决脏读,出现幻读(事务A读某个范围内记录,另一事务B在该范围插入新纪录,A再读会和原来不一致)。用MVCC(多版本并发控制)和间隙锁(next-key locking) 策略解决幻读。

serializable(可串行化):强制事务串行执行,避免幻读,每一行记录都加锁。

InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务回滚,

MyISAM不会出现死锁,因为不存在事务,即一次获得全部需要的锁,要么全部满足要么全部不满足。

MySQL有两种事务型的存储引擎:InnoDB 和 NDB Cluster

默认采用自动提交(AUTOCOMMIT)模式,每个事务被当做一个事务执行提交操作。

当AUTOCOMMIT=0时,所有的查询都在一个事务中,直到显示执行COMMIT提交或ROLLBACK回滚。

事务都由下层的存储引擎实现。

 

1.4 多版本并发控制

MVCC:保存数据在某个时间点的快照实现的。不管多久,每个事务看到的数据都是一致的,但每个事务对同一张表,同一时刻看到的数据可能不一样。

InnoDB的MVCC, 是通过在每行记录后面保存两个隐藏的列来实现的。 这两个列, 一个保存了行的创建时间, 一个保存行的过期时间(或删除时间) 。 当然存储的并不是实际的时间值, 而是系统版本号(system version number) 。 每开始一个新的事务, 系统版本号都会自动递增。 事务开始时刻的系统版本号会作为事务的版本号, 用来和查询到的每行记录的版本号进行比较。 下面看一下在REPEATABLE READ 隔离级别下, MVCC具体是如何操作的。
 

MVCC只在REPEATABLE READ 和READ COMMITTED 两个隔离级别下工作。 其他两个隔离级别都和MVCC不兼容 , 因为READ UNCOMMITTED总是读取最新的数据行, 而不是符合当前事务版本的数据行。而SERIALIZABLE 则会对所有读取的行都加锁。
 

1.5 MySQL的存储引擎

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

MyISAM支持全文索引、压缩、空间函数等,不支持事务和行级锁,且崩溃后无法安全恢复(因为每次修改执行完成时, 不会立刻将修改的索引数据写入磁盘, 而是会写到内存中的键缓冲区(in-memory key buffer) , 只有在清理键缓冲区或者关闭表的时候才会将对应的索引块写入到磁盘)。

日志型应用:MyISAM或者Archive存储引擎, 因为它们开销低, 而且插入速度非常快。

只读或者大部分情况下只读的表:不介意MyISAM的崩溃恢复问题, 选用MyISAM引擎是合适的。MyISAM只将数
据写到内存中, 然后等待操作系统定期将数据刷出到磁盘上。

订单处理:支持事务InnoDB。

电子公告牌和主题讨论论坛:经常刷新时间、榜等。MyISAM快。

CD-ROM应用:MyISAM表或者MyISAM压缩表,压缩表只是只读。

大数据量:Infobright是MySQL数据仓库最成功的解决方案。

存储引擎转换:表的存储引擎转换成另外一种引擎

1.ALTER TABLE

ALTER TABLE mytable ENGINE=InnoDB;
上述方法适用任何存储引擎,时间长,按行复制到新表,IO能力要求高。
 

2.导入与导出

mysqldump 工具将数据导出到文件, 然后修改文件中CREATE TABLE 语句的存储引擎选项, 注意同
时修改表名,因为同一个数据库中不能存在相同的表名,

3.创建与查询(CREATE和SELECT)

mysql> CREATE TABLE innodb_table LIKE myisam_table;
mysql> ALTER TABLE innodb_table ENGINE=InnoDB;
mysql> INSERT INTO innodb_table SELECT * FROM myisam_table;

数据量过大可分批处理,可以在执行的过程中对原表加锁, 以确保新表和原表的数据一致。
 

1.6 MySQL时间线

旧的版本在高并发时存在问题。

新的版本在单线程的时候性能比旧版本更差。


一开始可能无法理解为什么会这样, 仔细想想就能明白, 这是一个非常简单的只读测试。 新版本的SQL语法更复杂, 针对复杂查询增加了很多特性和改进, 这对于简单查询可能带来了更多的开销。 旧版本的代码简单, 对于简单的查询反而会更有利
 

1.7 MySQL的开发模式

遵循GPL开源协议,大部分在社区开源;部分性能插件收费。

猜你喜欢

转载自blog.csdn.net/weichi7549/article/details/108894768