mysql day01

1.什么是MVCC

  MVCC 全称Multi-Version-Concurrenct    Control,多版本并发控制.MVCC是一种并发控制的方法,一般在数据库管理系统中应用,实现对数据库的并发访问,在编程语言实现事务内存。

MVCC在mysql中InnoDb的实现主要是为了提高数据库并发性能,用更好的方式处理读写冲突,做到即使有读写冲突,也能做到不加锁,非阻塞并发读。

2.快照读和当前读(innoDB)

1.当前读

  读取是当前记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的进行加锁操作

2.快照读

  像不加锁的select操作就是快照读,即不加锁的非阻塞读,快照读的前提时隔离几倍不是串行级别,串行级别的快照读会退化称当前读,之所以出现快照读的情况,是基于提高并发性能的烤炉,快照读的实现是基于多版本并发控制,即mvcc可以认为mvcc是行锁的一个变种,但它在很多情况下,避免了枷锁操作,降低了开销,基于多版本,即快照读可能读到的数据不一定是数据的最新版本,可能是历史版本。

  说白了mvcc就是为了实现读写冲突不加锁,而这个读是快照读而不是当前读,当前读实际上是一种枷锁的操作,是悲观锁的实现。

3.MVCC与当前读,快照读的关系

  准确来说,mvcc多版本并发控制是维持一个数据的多个版本,使得读写操作没有冲突。   

在mysql中实现mvcc理想概念,我们需要mysql提供具体的功能去实现它,快照读是msql为我们实现mvcc理想模型中的一个具体非阻塞读功能,而相对而言,当前读就是悲观锁的具体实现。

  在mysql中 具体实现用undo日志,read view 三个隐式实现的。

4.数据库并发场景有三种

1.读-读 不存在任何问题,也不需要并发控制

2.读-写 有线程安全问题,可能造成事务隔离问题 可能遇到脏读,幻读,不可重复读

3.写-写 有线程安全问题 ,可能造成存在更新丢失问

5 MYSQL锁

1.Mysql里面的锁大致可以分为三种 全局锁、表级锁和行锁

全局锁:全局锁是对整个数据库实例加锁,mysql提供FTWRL(Flush table with read lock)来开启全局锁,当开启全局锁的时候,整个数据库只能进行读操作,数据更新语句,数据定义语句,更新类事务的语句都不能提交。

应用场景: 一般应用在数据库备份的时候,这样只有读操作可以进行

?为什么使用(set global readonly=true),来设置数据库只读,他和全局锁有什么区别 ,如果使用FTWRL在客户端链接出现错误时候,全局锁会自动释放,而set golbal readonly = true 不会释放,导致只读时间长。

为什么不使用mysqldump参数songle-transation,在导出数据之前开启事务,通过mvvc机制保证读取的时候一致性 ? 因为mysql不是所有存储引擎都支持事务,例如MYISAM。

表级锁分为两类锁,表锁和元数据锁(MDL-meta data-lock)

表锁:可以用lock tableName ...read/write进行上锁,客户端断开链接的时候自动释放,也可以通过unlock tables手动释放。

MDL: 无需显示使用,访问表的时候自动带上,主要是DDL语句和DML语句查询更新语句之间进行枷锁,保证表结构更新时,dml等语句阻塞。

应用场景
  在DDL更新表的时候,因为需要便利所有表数据,我们执行的时候都比较小心,给DBA来执行当时在ddl小表的时候,如果ddl比较小但是访问量很大,那么使用不当一样会出现问题,在ddl的时候,会增加mdl锁这时,所有查询请求都会阻塞,如果客户端有重试机制,那么请求超时马上会在创建一个session,这时会很快占用满数据库的链接,这时应该给ddl语句增加一个超时时间,如果执行的时间比较长则直接超市断开,不要影响后面的请求。

 行锁(Record Locks)

行锁(记录锁),为了某行记录加锁,它封锁该行的索引记录。(select * from table where id = 1 for update),id 为1的记录会被锁住,需要注意的时:id列必须为唯一索引列和主键列,则上述语句中会把行锁退化成间隙锁

间隙锁(Gap Locks)

 间隙锁基于非唯一索引,它锁定一段范围内的索引记录,当更新语句更新一定范围的数据时
列入 update user set del_fag = 1 where age > 100 (删除年纪大于100岁的人),这时如果事务的隔离级别设置为可重复读时候,则会增减间隙锁,其他ddl语句无法执行,事务的隔离级别如果时读提交的话,则会成功

你可能感兴趣的:(mysql day01)