最近在研究mysql一些功能的实现机制,比如最基本的增删改查,具体内部是如何实现的?不同表类型(innodb,myisam),不同搜索方式(btree,hash)的搜索结果谁优谁劣?之前都是之其然不知其所以然,现在一直在看“mysql高性能书籍”这本书,很多迷惑的问题都迎刃而解,缺点就是太厚了,1000多页,更适合作为一本参考书,发现问题就去具体的地方查找一番。
接下来说说mysql各种锁的总结,如果未加注释,那就都是在innodb的存储引擎环境下。
事务和回滚
要讲锁就要提到死锁,要提到死锁就要提到事务和回滚,这些内容都是息息相关的。先说事务和回滚,事务是mysql操作的最小粒子,其中可能会包含多条语句,不过只要其中一条语句无法实现,整个事务就没法继续进行,需要回滚到最初状态。回滚的意思也就出来了,是将当前状态恢复到操作之前状态的行为。
事务的特点:ACID
一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
举个类似书中的例子:
我要给你汇款1W元,如果把这个操作当做一个事物的话,他包括如下三条语句,那么当我在自助机上输入账号、金额,点击确定后,后台将执行如下语句:
1、检查我账户余额大于1W
2、扣掉我账户1W
3、给你账户加入1W
如果在第三步操作时,由于未知原因挂掉了,怎么办呢?我的钱扣了你也没收到,这时就需要回滚出场了,在这个流程中只要有任何问题导致流程终止,都会自动回滚到第一步操作之前的状态。
死锁
死锁就是两个进程在执行操作时,分别拿到了另一个进程需要的权限,并且需要另一个进程手中的权限来执行下一步操作,描述起来有点乱,不过仔细想想也很好明白。当死锁发生时,需要外部来打破,否则死锁将会一直进行下去,常用的方法是检测到死锁发生后,让其中一个进程(有些是随机选择一个,有些是选择有最少行级排他锁的进程,例如innodb)放弃权限并回滚。
表级锁、行级锁、页级锁
仅从锁的角度来说:表级锁更适合于以查询为主,只有少量按索引条件更新数据的应用,如Web应用;而行级锁则更适合于有大量按索引条件并发更新少量不同数据,同时又有并发查询的应用,如一些在线事务处理(OLTP)系统。
MySQL的表级锁有两种模式:表共享读锁(Table Read Lock)和表独占写锁(Table Write Lock)。顾名思义,当一个表被加了读锁,其他进程仍可以对其加读锁,可是不能加写锁,当一个表被加了写锁,其他进程不能对其加读写锁。
MYSQL的行级锁有四种:共享锁(S),排他锁(X),意向共享锁(IS)和意向排他锁(IX),他们之间的关系如下表所示:
共享锁(S) | 排他锁(X) | 意向共享锁(IS) | 意向排他锁(IX) | |
共享锁(S) | 兼容 | 冲突 | 兼容 | 冲突 |
排他锁(X) | 冲突 | 冲突 | 冲突 | 冲突 |
意向共享锁(IS) | 兼容 | 冲突 | 兼容 | 兼容 |
意向排他锁(IX) | 冲突 | 冲突 | 兼容 | 兼容 |
更详细的概念还有介绍,不过我感觉对于现在的我来说还用不上,所以看了也很难记住,等到以后用到再继续琢磨吧。
有一部分内容引自http://www.cnblogs.com/ggjucheng/archive/2012/11/14/2770445.html