MySql基础知识梳理
1、Mysql的复制原理及流程
slave有两个线程:IO线程、SQL线程
master有一个线程:Log dump线程
IO线程去请求master的binary log,并将得到的binary log写入到 relay log中
SQL线程会读取relay log文件中的日志,并解析成具体操作,用来实现主从操作一致。
Log dump线程用来给slave的IO线程传输binary log
2、myisam与innodb的区别
不同之处:
myisam不支持事务,innodb支持事务
myisam支持表级锁,innodb支持行级锁
myisam不支持外键,innodb支持外键
myisam不支持mvcc,innnodb支持
myisam支持全文索引,innodb不支持
对于count()查询来说myisam更有优势,因为myisam维护了一个行计数器,而innodb需要扫描全部数据
为什么选择innodb?
因为对一个系统而言,innodb支持事务日志和行级锁,事务日志支持数据崩溃和回滚,能给予更安全的数据保护。另外,在大多数情况下,行级锁可以提供更高的并发性能,因为用户只锁定他们正在写的数据,而读数据永远不会被阻塞。
思路:主要考虑安全性、并发性
3、表锁、页锁、行锁
myisam是表级锁引擎,不会出现死锁问题
innodb是行级锁引擎,会出现死锁问题,行级锁是mysql粒度最小的锁,粒度越小实现成本越高
行级锁可能会导致“死锁”,why?
mysql行级锁并不是直接锁记录,而是锁索引,索引又分为主键索引和非主键索引,如果一条语句操作了主键索引,会锁定主键索引,如果一条语句操作了非主键索引,会先锁定非主键索引,再锁定主键索引
死锁条件:
当两个事务同时执行,一个锁住了主键索引,在等待其他相关索引;另一个锁定了非主键索引,在等待主键索引。
死锁举例分析:
表Test:(ID,STATE,TIME) 主键索引:ID 非主键索引:STATE
当执行"UPDATE STATE =1011 WHERE STATE=1000" 语句的时候会锁定STATE索引,由于STATE 是非主键索引,所以Mysql还会去请求锁定ID索引,当另一个SQL语句与语句1几乎同时执行时:“UPDATE STATE=1010 WHERE ID=1” 对于语句2 Mysql会先锁定ID索引,由于语句2操作了STATE字段,所以Mysql还会请求锁定STATE索引。这时,彼此锁定着对方需要的索引,又都在等待对方释放锁定。所以出现了"死锁"的情况。
表级锁:开销小,加锁快,不会出现死锁,锁粒度大,锁冲突概率大,并发支持度低
行级锁:开销大,加锁慢,会出现死锁,锁粒度小,锁冲突概率小,并发支持度高
页级锁:一种折中方案,一次锁定相邻的一组记录(bdb引擎)。
怎样避免死锁?
发生死锁后,InnoDB 一般都可以检测到,并使一个事务释放锁回退(undo较小的事务),另一个获取锁完成事务。
1、死锁发生的原因是两个事务交叉更新,如Transaction 1: 更新表A -> 更新表B,Transaction 2: 更新表B -> 更新表A,这种情况要考虑,如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低发生死锁的可能性。
2、保持事务的轻量,占用的资源越少,死锁的概率越低。
3、在同一个事务中,要尽可能一次锁定所有资源,减少死锁概率。
4、对于非常容易死锁的业务,可以尝试提高锁的粒度,使用页锁或表锁。
4、innodb引擎的特性
插入缓冲(insert buffer)、二次写(double write)、自适应哈希索引(ahi)、预读(read ahead)
?待补充
4、谈谈对mysql中mvcc的理解
参考:https://blog.csdn.net/u013252072/article/details/52912385