《高性能mysql》一mysql架构与历史

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43928720/article/details/102630785

1. mysql的线程控制

每个客户端连接都会在服务器进程中拥有一个线程,这个连接的查询只会在这个单独的线程中执行,该线程只能轮流的在某个cpu核心或者cpu中运行。服务器会负责缓存线程,因此不需要为每一个新建的连接创建或者销毁线程。

2. 共享锁(读锁)和排他锁(写锁)

读锁是共享的,或者说是相互不阻塞的。多个客户在同一时刻可以读取同一个资源,而互不干扰。写锁是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,这是出于安全策略的考虑,还有这样,才能确保在给定的时间里,还有一个用户能执行写入,并防止其他用户读取正在写入的同一资源。

3. 锁粒度

数据库引擎具有多粒度锁定,允许一个事务锁定不同类型的资源。 为了尽量减少锁定的开销,数据库引擎自动将资源锁定在适合任务的级别。 锁定在较小的粒度(例如行)可以提高并发度,但开销较高,因为如果锁定了许多行,则需要持有更多的锁。 锁定在较大的粒度(例如表)会降低了并发度,因为锁定整个表限制了其他事务对表中任意部分的访问。 但其开销较低,因为需要维护的锁较少。

4. 行级锁和表级锁

表锁是mysql中最基本的锁策略,并且hi开销最小的策略。表锁非常类似于邮箱加锁机制:他会锁定整张表。一个用户在对表进行写操作(插入、删除、更新等)前,需要先获得写锁,这会阻塞其他用户对该表得所有读写操作。只有没有写锁时,其他读取的用户才可以获得写锁,读锁之间是不相互阻塞的。服务器会为诸如alter table之类的语句使用表锁,而忽略存储引擎的锁机制。
行级锁可以最大程度的支持并发处理(同时也带来了最大的锁开销)。

5. 事务

事务内的语句,要么全部执行成功,要么全部执行失败。
可以用start transaction语句开始一个事务,然后要么使用commit提交事务将修改的数据持久保留,要么使用rollback撤销所有的修改。

6. 事务的ACID

ACID表示原子性(atomicity),一致性(consistency),隔离性(isolation)和持久性(durability)。
(1)原子性
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部回滚失败,对于一个事务来说,不可能只执行其中的一部分,这就是事务的原子性。
(2)一致性
数据库总是从一个一致性的状态转换到另外一个一致性的状态。
(3)隔离性
通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。
(4)持久性
一旦事务提交,则其做的修改就会永久保存到数据库中。此时即使系统崩溃,修改的数据也不会丢失。

7. 事务的隔离级别

(1)未提交读
事务中的修改,即使没有提交,对其他事务也都是可见的。事务可以读取未提交的数据,这也被称为脏读。这个级别会导致很多问题,从性能上来说,未提交读不会比其他的级别好太多,但却缺乏其他级别的很多好处,除非真的有非常必要的理由,在实际应用中一般很少使用。
(2)提交读
大多数的数据库的默认隔离级别都是提交读(但mysql不是)。在提交读中,一个事务从开始直到提交之前,所做的任何修改对其他事务都是不可见的。这个级别有时候又叫不可重复读,因为两次执行同样的查询,可能会得到不一样的结果。
(3)可重复读
可重复读解决了脏读的问题,该级别保证了在同一事务中多次读取同样记录的结果是一致的。但是理论上,可重复读隔离级别还是无法解决另外一个幻读的问题。所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录。当之前的再次读取该范围内的记录时,会产生幻行。InnoDB和XtraDB通过多版本并发控制解决了幻读的问题。
可重复读是mysql的默认事务隔离级别。
(4)可串行化
可串行化是最高的隔离级别。它通过强制事务串行执行,避免了幻读的问题。简单来说,该隔离级别会在读取的每一行数据上都加锁,所以可能导致大量的超时和锁竞争的问题。实际应用中也很少使用这个隔离级别,只有在非常需要确保数据的一致性而且可以接受没有并发的情况下,才考虑采用该级别。

在这里插入图片描述

8. 死锁

死锁是指两个或者多个事务在同一资源上相互占用,并请求锁定对方占用的资源。从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,就可能产生死锁。多个事务同时锁定同一资源时,也会产生死锁。
为了解决这种问题,数据库系统实现了各种死锁检测和死锁超时机制。InnoDB目前处理死锁的方法是,将持有最少行级排他锁的事务进行回滚。

9. mysql中的事务

mysql默认采用自动提交模式。也就是说,如果不是显示的开始一个事务,则每个查询都被当做一个事务执行提交操作。在当前连接中,可以通过设置autocommit变量来启用或者禁用自动提交模式。同时,mysql可以通过执行 set transaction isolation level命令来设置隔离级别。

10. 多版本并发控制(MVCC)

可以认为MVCC是行级锁的一个变种。但是它在很多情况下避免了加锁操作,因此开销更低。
MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事物看到的数据都是一致的。
InnoDB中的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两列,一个保存了行的创建时间,一个保存了行的过期时间(或删除时间)。当然存储的并不是实际的是时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
(1)select
a. InnoDB只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。
b. 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。
只有符合以上两个条件的记录,才能返回作为查询条件。
(2)insert
InnoDB为新插入的每一行保存当前版本号作为行版本号。
(3)delete
InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
(4)update
InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。
MVCC只在可重复读和提交读两个隔离级别下工作。

11. InnoDB存储引擎

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

12. MyISAM存储引擎

MyISAM不支持事务和行级锁,而且有一个毫无疑问的缺陷就是崩溃后无法安全恢复。对于只读的数据,或者表比较小、可以忍受修复操作,则依然可以使用MyISAM。

猜你喜欢

转载自blog.csdn.net/weixin_43928720/article/details/102630785