本文章记录在读《高性能mysql》时的笔记,持续更新。章节内容会按照书中章节进行梳理。
一、Mysql 架构与历史
1.1Mysql逻辑架构
- 最上层负责链接处理、认证授权、安全等
- 中间一层涵盖了mysql的大多数核心功能。包括查询解析、分析、优化、缓存、内置函数;所有的夸存储引擎的功能都在这一层实现(存储过程、触发器、视图等)
- 第三层包含了存储引擎,存储引擎与上层使用API进行通讯,引擎之间不会有交互。
1.1.1连接管理与安全性
每个客户端对应着服务器的一个线程,客户端的请求会单独的在这个线程中执行。安全认证基于用户名密码或SSL。
1.1.2优化与执行
mysql会即系查询,并创建内部解析树用于进行各种优化操作。可使用explain
或hint
进行查看解析、优化过程。如果执行时,发现查询引擎中有对应的查询,则直接返回结果,不会再进行查询解析、优化、执行等步骤。
1.2 并发控制
并发控制在任何一个领域都是一个重要的话题,数据库尤其明显。
1.2.1 读写锁
当一个数据多线程在读,则不会发生问题。但是当出现了有的线程在写,有的线程在读的情况,则会发生问题(不一致、脏数据)。使用共享锁(share lock)、排它锁(exclusive lock)、读写锁可以解决问题。读锁之间是不互斥的,写锁和其他的写锁和读锁互斥。
1.2.2 锁粒度
大多数数据库直接使用行级锁(row-level lock)更细粒度的锁能保证更高的性能,但是会带来更复杂的开销。mysql提供灵活定制的锁策略。
表锁
开销最小的锁策略,但是某种程度上性能会最差(因为执行某些操作会锁死整张表),当执行比如ALERT TABLE
时,会使用表锁。并且表的写锁比读锁有更高的优先级。服务器可能会使用表锁。
行级锁
行级锁并发性能最好,但是锁开销也最大。行级锁仅仅在存储引擎层实现,服务器层不关心行级锁内容。
1.3事务
事务内的语句,要么全成功,要么全失败。
ACID,原子性、一致性、隔离性、持久性是一个事务处理系统必备的条件。
1.3.1 隔离级别
较低的隔离级别代表着更高的并发性,系统开销也更低。
READ UNCOMMITED
(读未提交)
即使没有提交,对其他事务也是可见的。也成为脏读(DIRTY READ)READ COMMIT
(读提交)
一个事务从开始到提交前,任何操作对其他事务都是不可见的。
也叫作不可重复读(NONREPEATABLE READ)REPEATABLE READ
(可重复读)
同一个事务中多次读取同样的记录的结果是一致的
mysql默认采用该事物隔离级别SERIALIZABLE
(可串行化)
所有事务串行执行。采用
1.3.2死锁
两个及以上事务在同一资源上相互占用。
Tx1:
START TRANSACTIOIN;
UPDATE T SET NAME = "A" WHERE ID = 1;
UPDATE T SET NAME = "B" WHERE ID = 2;
COMMIT;
Tx2:
START TRANSACTION;
UPDATE T SET NAME = "C" WHERE ID = 2;
UPDATE T SET NAME = "D" WHERE ID = 1;
COMMIT;
如果两个事务都执行了第一个语句,同时也锁定了该数据,接着尝试去执行第二个语句,就会发生死锁。除非有外部因素介入,不然死锁会一直持续。
InnoDB解决死锁的办法是:将持有最少排它锁的事务进行回滚。