1.1 Mysql执行架构图
1.2 客户端连接Mysql服务器需要知道的知识
每个客户端连接都会在mysql服务器中拥有一个线程,这个连接只会在这个线程里执行操作,这个线程会轮流在某个cpu核心或cpu中运行。服务器也会缓存创建过的线程,有新的连接只需要去拿去线程就可以,不需要重复创建或者销毁线程(因为一个客户端连接执行完操作后会归还线程,mysql5.5有一个线程池插件,那些使用完的线程会存放在这里,新的连接只需要去线程池里获取就可以了)
1.3 客户端连接服务器时进行的安全验证操作
当客户端连接服务器时,服务器会进行安全验证,认证用户名,原始主机信息,密码,使用使用ssl方式,还可以使用X.509证书认证,如果认证通过,就会验证该连接是否具有执行某个特定的权限
1.4 Mysql内部优化机制和执行指令简述
mysql解析sql语句,创建解析树,然后进行优化,包括重写查询,决定表的读取先后顺序,选择合适的索引等。我们也可以人工干预mysql内部的优化机制(后边说,先了解一下),mysql的优化器不关心使用什么存储引擎,但是使用什么存储引擎会影响优化器怎么去优化。简单说就是不同的存储引擎有不同的优化策略,所以优化后的速度也是不一样的。
mysql执行一条查询指定时, 会先去查缓存区,如果缓存区没有,就会由服务器进行解析,然后进行一系列优化后查到结果放在缓存区后返回, 下次相同的查询指令就不需要再去执行一遍解析,优化这些过程,直接拿到缓存区的数据返回给客户端
1.5 Mysql的并发场景
什么是并发,假设有两个客户端连接A和B, A要查看数据表中的数据, B要修改数据表中的数据, 这时会发生什么?A读取到了B修改后的数据?还是B修改前的数据?这就是并发, 既然发生了这种问题,那么就要有一种解决的办法,这时候就有了锁的概念
1.5.1 读写锁
读写锁是一个统称, 她其实是两个锁组成, 一个是共享锁(读锁),一个是排他锁(写锁) (这里有一个概念, 就是一个客户端连接独自用拥有一把锁)
读锁是共享的, 也就是说所有的客户端连接都可以同时查询数据, 而写锁不是, 同一时刻只能有一个客户端连接可以操作数据,当有写锁时, 其他连接的写锁和读锁都不可以访问数据资源,这样就不会发生上边说的并发问题了, 但是这时又遇到了一个新的问题, 同一时刻只能有一个写锁,其他连接只能等待写锁释放, 这时可以想象一下, 系统性能会大大降低。严重还会导致超时数据丢失等情况,因为如果当前正在操作数据的连接有问题或者其他原因一直不进行释放锁操作,那么就会连接超时导致数据丢失, 也有可能因为操作的数据量太大导致服务器崩溃也有可能, 那么这个时候又需要一种办法来解决这个问题, 锁粒度就出现了
1.5.2 锁粒度
锁粒度简单理解就是一种提高系统并发能力,提升性能的一种方式策略,通过锁定对象的大小范围来控制其他连接可以访问的数据资源, 简单来说就是锁的范围越小, 那么其他的连接就可以更多得访问没有锁住的数据,但是又有问题了, 锁也是会消耗系统资源的,如果特别频繁的加锁,然后检查锁是否释放,然后释放锁等等操作就会增加服务器的消耗,服务器需要大量时间来处理这些锁而不是进行数据处理,降低服务器性能, 这时候我们就要有一种方式可以让服务器即可以更好的处理数据, 又不会造成并发的情况,这时就有了一个名词----锁策略
1.5.3 锁策略
锁策略简单来说就是一种在数据处理和并发控制之间找到一种平衡,极大可能的降低服务器的消耗,当然,只是降低。。。MySQL中的每个存储引擎都可以实现属于自己的锁策略和锁粒度,在不同的应用场景使用不同的锁粒度会更好的提升性能,下面时最常用的两种锁策略
表锁
表锁是锁开销最小的一种策略,当然,从字面上也可以理解出, TA是锁住了整张数据表, 当有线程对表进行写操作时,整个数据表都会锁住,其他线程无法进行读写操作。这里有一个知识点,写锁的优先级时是高于读锁的, 也就是说如果有多个线程在排队进行写操作,那么这些拥有写锁的线程会优先于读操作的线程执行。
行级锁
行级锁是支持并发最高的一种锁策略,同时,他也是锁操作消耗资源最大的一种策略,她锁的只是行级数据,其他客户端连接依旧可以访问或者操作这条行级数据之外的资源
间隙锁
间隙锁是为了解决幻读的一种锁,他锁的是你查询条件的一个范围。PS:这里先知道有这么个锁,是干什么的,后边我们细谈
1.6 服务器锁和存储引擎锁概念
这里不清楚的可以看上边的服务器架构图,就会清楚什么是服务器什么是存储引擎
什么是服务器锁, 像一些alter, table之类的指令,服务器就会给这些指令使用表锁,而忽略存储引擎的锁机制
什么是存储引擎锁, 就是一条写指令到达存储引擎后,存储引擎为了避免并发,会自己使用行级锁来保证数据完整