一、并发控制
a、什么时候会产生并发控制的问题:
只要有多个查询需要在同一时刻修改数据。
b、MySQL在哪两个层面的并发控制:
服务器层和存储引擎层
c、举个例子
1、以Unix系统的email box为例,典型的mbox文件格式是非常简单的,一个mbox邮箱中的所有邮件都串行在一起,彼此首尾相连,这种格式对于读取和分析邮件信息非常友好的,同时投递邮件也是很容易的。
2、但是如果两个进程在同一时刻对同一个邮箱投递邮件,会把邮箱的数据给破坏,所以设计良好的邮箱投递系统会通过锁的方式来防止数据被锁坏。
但是这种锁的方案在实际应用环境中虽然工作良好,但是并不支持并发处理,因此在任意时刻,只有一个进程可以修改邮箱的数据,这在大容量的邮箱系统中是个问题。
d、读写锁
1、从邮箱中读取数据的时候不会这么麻烦的,即使同一时刻多个用户并发读取也不会有什么问题,因为读取不会修改数据,所以不会出错。
2、但是如果一个客户端正在读取邮箱的时候,另外一个客户端可能在同一时刻正好去修改同一编号的邮件。造成的结果是不确定的。读的客户可能会报错退出,也可能会读取到不一致的邮箱数据,所以,这时读的客户端也需要特别注意。
3、可以把邮箱比喻成数据库中的一张表,而邮件比喻成表中的一行记录,所以也会出现上面的问题。
4、解决这样的并发控制的问题,其实是很简单的,在处理并发读或者写时,可以通过实现一个由两种类型的锁组成的锁系统来解决问题,这两种类型的锁通常被叫做共享锁和排他锁,也叫读锁和写锁。
5、读锁是共享的,或者说是互相不阻塞的,多个客户在同一个时刻可以同时读取同一个资源,互不干扰。写锁是排他的,也就是说一个写锁会阻塞其他的写锁和读锁,只有这样,才能确保在给定的时间里,只有一个用户能执行写入,并防止其他用户读取正在写入的同一资源,大多数的时候,MySQL锁的内部管理都是透明的。
e、锁粒度
1、一种提高共享资源并发性的方式就是让锁定的对象更有选择性。尽量只锁定需要修改的部分数据,而不是所有的资源,更好的方式是只对会修改的数据片进行精确的锁定,这样系统的并发程度越高,只要相互之间不发生冲突即可。
2、加锁,锁的各种操作,获得锁,检查锁是否已经解除,释放锁。都会增加系统的开销,如果系统花费大量的时间来管理锁的话,而不是存取数据,那么系统的可能性会受到很大的影响。
3、锁策略,就是在锁的开销和数据的安全性之间寻求平衡。大多数商业数据库系统没有提供更多的选择,一般都是加行级锁。
4、在MySQL中提供了多种选择,但是每种选择都是对不同的场景有好的性能,但是对另外一些的场景没有很好的性能支持。但是MySQL中有多种存储引擎的架构,所以不需要单一的解决方案。
f、锁策略
1、表锁:
1)、表锁是MySQL中最基本的锁策略,并且是开销最小的策略。它会锁定整张表,一个用户对表进行增删改的时候,需要先获得写锁,这时会对其他用户对表进行的读和写操作是阻塞的,只有没有写锁的时候,其他读取的用户才能获得读锁,读锁之间是不会阻塞的。
2)、在特定的场景中,表锁也可能会有良好的性能,比如,READ LOCAL 表锁支持某些类型的并发写操作。写锁也比读锁有更高的优先级。
3)、尽管存储引擎可以管理自己的锁,MySQL本身还是会使用各种有效的表锁来实现不同的目的,比如服务器会使用ALTER TABLE之类的语句使用表锁,而忽略存储引擎中的锁机制。这里容易被面试问到哦,我是被问到过。
g、行级锁
行级锁可以最大程度上支持并发处理,同时也带来了最大的锁开销。行级锁只是在存储引擎中实现,而MySql服务器层并没有实现。服务器层完全不了解存储引擎中的锁实现。
明天见~~,争取每天至少一篇。