高性能Mysql读书笔记#第一章

原文链接: https://blog.csdn.net/ya_1249463314/article/details/78692117

转自:https://blog.csdn.net/ya_1249463314/article/details/78692117

1.Mysql的逻辑架构

解释:高性能Mysql读书笔记#第一章_第1张图片
①第一层客户端:这个不是Mysql特有,譬如Navicat等客户端工具。
②第二层Mysql核心服务功能:譬如查询解析,优化,缓存处理,以及内置函数,存储过程,视图,触发器等操作。
③第三层存储引擎:存储引擎层负责数据的存储和提取。

2.Mysql并发控制

读写锁

并发控制方式多是采用锁机制。通常是共享锁(读锁)和排他锁(写锁)。多个客户在同一个时刻可以同时读取同一个资源,互不干扰。写锁是排他的,也就是说在写的同时不允许其他的写锁来写和读锁来读。这样就能防止脏数据的进入。

锁粒度

提高资源的并发性关键在于锁粒度。在给定的资源上,锁定的数据量越少,则系统的并发程度越高,只要相互不冲突即可。但是一味的细化锁,让锁的数量上升也会增加系统对资源的消耗。所以真正的锁策略是在锁的开销和数据的安全性之间寻求一种平衡。

①表锁:

表锁是Mysql中开销最小的锁。它的策略是会锁定一张表,如果用户对表写入(插入,更新,删除),就会将表锁住,同时阻塞其他的用户对这张表的读和写。在某些场景下,写锁比读锁更高的优先级。写锁请求会插入到读锁队列的前面。

②行锁:

行锁是最大程度支持并发处理(锁开销最大)。像默认的存储引擎InnoDB等实现了行锁。行锁只在存储引擎层实现。

隔离度

read uncommitted(读未提交):能够读未提交的数据;回滚造成脏读
read committed(读已提交):不会读取还未提交的数据,但可读取事务进行之前的数据以及事务完成之后的数据,造成不可重复读。
repeatable read(可重复读):不能读取还未提交的数据,也就是类似于对读的那一行加锁(行级锁),不允许读。保障重复读,但插入新行会导致幻读(select count(*))。
serializable(可串行化):为表加锁(表级锁)。

3.Mysql事务

①事务的特性ACID

原子性(atomicity):一个事务必须被视为一个不可分割的最小工作单元。
一致性(consistency):数据库总是从一个一致性状态转换到另一个一致性状态。
隔离性(isolation):一个事务所做的修改在最终提交以前,对其他事务是不可见的。可重复读(REPEATABLE READ)是Mysql的默认事务隔离级别。
持久性(durabilty):一旦事务提交,则其所做的修改就会永久保存到数据库中。

②死锁

死锁是指两个或者多个事务之间再同一个资源上的相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。InnoDB存储引擎处理死锁的方法是将持有最少行级排他锁的事务进行回滚。

死锁的4个必要条件

1、互斥:某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、占有且等待:一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3、不可抢占:别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4、循环等待:存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。

③Mysql中的事务

Mysql默认采用自动提交模式,如果不是显式地开始一个事务,则每个查询都被当作一个事务执行提交操作。
设置自动提交:SET AUTOCOMMIT=1;
设置Mysql事务隔离级别:SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

4.多版本并发控制MVCC

MVCC的出现是为了提高并发性能。策略就是读操作是非阻塞的,写操作只是在需要的行上面阻塞。MVCC的实现就是通过保存数据在某个时间点的快照来实现的。不同存储引擎对于MVCC的实现是不同的。典型的有乐观锁和悲观锁。

乐观锁与悲观锁:

悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步原语synchronized关键字的实现也是悲观锁。
  乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。

存储引擎InnoDB的MVCC

InnoDB的MVCC采用系统版本号(此处是两个版本号,一个是删除版本号,一个是创建版本号),每开始一个新事务,系统版本号都会自动递增。而当前的快照版本号会和当前的版本号进行比较来操作。

查询:
a. InnoDB只查找版本号早于当前事务版本的数据行(行的版本号小于等于事务的系统版本号)。这样就会避免出现脏读。
b. 行的删除版本号要么未定义,要么大于当前事务版本号(保证事务读取的行,在读之前未被删除),这样就不会出现脏读。

插入:
InnoDB为新插入的每一行保存当前系统版本号作为行版本号。

删除:
InnoDB为删除的每一行保存当前系统版本号作为删除标识。

更新:
InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识符。

5.Mysql存储引擎

在文件系统中,Mysql将每个数据库保存为数据目录下的一个子目录。创建表时,Mysql会在数据库子目录下创建一个和表同名的.frm文件中保存该表的定义。Mysql的大小写敏感性和具体的平台有关。windows上是不敏感的,而linux上是敏感的。

查询表本身的信息:
高性能Mysql读书笔记#第一章_第2张图片

InnoDB存储引擎:

InnoDB是Mysql的默认事务型引擎。InnoDB采用MVCC高并发,并且实现了四个标准的隔离级别。其默认级别是REPEATABLE READ(可重复读),并且通过间隙锁策略防止出现幻读。InnoDB表是基于聚簇索引建立的。聚簇索引对主键查询有很高的性能。不过它的二级索引中必须包含主键列。所以如果主键列很大,其他的所有索引都会很大。

MyISAM存储引擎:

在Mysql5.1及之前的版本,MyISAM是默认的存储引擎。MyISAM不支持事务和行级锁。再有就是崩溃后无法安全恢复。
MyISAM的加锁与并发:MyISAM对整张表加锁,而不是行级别。读取时会对需要读到的所有表加共享锁,写入时对表加排他锁。在表读的时候也可以插入,使用了Mysql的并发控制。

你可能感兴趣的:(Mysql)