Mysql Innodb 引擎解决并发问题

并行与并发根本区别在于是否会竞争共享资源,解决并发问题两个大的方向: 解决资源资源和解决并发问题 。
解决竞争资源
共享资源是引起问题的根本原因,如果将共享资源变为非共享,这样降低了并发问题产生的几率,关系数据库的分库分表,NoSql/NewSql的水平扩展都属于这个思路,MySQL多个buffer pool,JAVA的ConcurrentHashMap等都属于这种思路 。解决竞争资源可以提高效率,但不能根本上解决问题:并发问题还是存在的 。
解决并发问题
可以通过CAS,多版本,悲观锁的方式从根本上解决 。
CAS
CAS可以理解成乐观锁的一种,在数据库层面一般是采用version的方式实施 。应用在写的场景上 。
多版本
多版本的典型用法就是MVCC方式,在各种数据库中被大量采用:主要思路是保留多版本数据,在请求时根据请求时间返回数据 。只能用于读场景 。
Mysql的MVCC仅在RC/RR两种隔离级别下工作:
RC隔离级别: 会对每次请求(select)都重新生成ReadView(记录活跃的Transaction),因此多次请求返回的结果可能不同,所以存在重复读取的问题 。
RR隔离级别:
仅在Transaction第一次访问的时候生成一次ReadView,因此多次请求返回的结果相同,避免了重复读取的问题 。
锁(悲观锁)
锁是解决问题的根本方法,在多写竞争的时候只能采用锁的方式 。mysql的锁分为行锁和表锁,在获取行锁(Share或Exclude)时,会同时在表中加入相应的意向锁(IS,IX),方便在加表锁时判断是否有行级别锁 。
其他
区间锁:在RR隔离界别下,通过二级非唯一索引或区间查询的方式,添加区间锁,防止出现幻读问题 。
Select加锁: RR,RC隔离界别下,默认select不加锁,可通过for update,in share mode等语句显示加锁 。
事务:锁是同事务绑定的,非更新操作(即使是读写事务)不会生成事务id,锁仅在事务释放后才释放 。全表扫描会在所有记录上加锁,并不会在表上加锁 。
其他存储引擎:因为使用MyISAM、MEMORY、MERGE这些存储引擎的表在同一时刻只允许一个会话对表进行写操作,所以这些存储引擎实际上最好用在只读,或者大部分都是读操作,或者单用户的情景下 。


【Mysql Innodb 引擎解决并发问题】


    推荐阅读