数据库并发

  • 一、数据库锁
  • 二、锁的种类
  • 三、引擎内部锁的使用
  • 1、MyISAM引擎
  • 2、InnoDB引擎
  • 四、如何控制数据库并发问题?
  • MVCC(MultiVersion Concurrency Control)
  • MVCC可以解决什么问题?
  • MVCC的流程
  • 关于Read View
  • 五、InnoDB如何存储记录的多个版本?


一、数据库锁

锁是计算机协调多个线程或线程并发访问某一资源的机制。
锁保证数据并发访问的一致性、有效性;
锁冲突也是影响数据库并发访问性能的一个重要因素、锁是MySQL在服务器层和存储引擎层的并发控制。
加锁是消耗资源的,包括还有锁的其他各种操作——其中有获得锁、检测锁是否已解除、释放锁。

二、锁的种类

共享锁: 也叫读锁,其他事务可以读,但不能写。就是我们对数据进行读取操作的时候,其实是不会改变数据的值的。
————SELECT * FROM table_name WHERE … LOCK IN SHARE MODE。
其他session仍然可以查询记录,并也可以对该纪录加share mode的共享锁。但是如果当前事务需要对该记录进行更新操作,则很有可能造成死锁。
排他锁: 其他事务不能读取,也不能写。
————SELECT * FROM table_name WHERE … FOR UPDATE。
其他session可以查询该记录,但是不能对该记录加共享锁或排他锁,而是等待获得锁。

三、引擎内部锁的使用

1、MyISAM引擎

——》表级锁:
①查询【读锁】
②修改【写锁】

2、InnoDB引擎

(对于普通SELECT语句InnoDB不会加任何锁,但是对于UPDATE,DELETE,INDERT语句,InnoDB会自动给涉及数据集加排他锁)
——》行级锁:(InnoDB引擎默认采用行级锁)
对索引加锁
——》表级锁
修改【写锁】
锁在InnoDB内部的使用:
①意向共享锁(IS):当事务打算给数据加行共享锁时,即事务在给一个数据行加共享锁前必须先获得该表的IS锁。
②意向排他锁(IX):当事务打算给数据加行排他锁时,即事务在给一个数据行加行排他锁前必须先取得该表的IX锁。

四、如何控制数据库并发问题?

MVCC(MultiVersion Concurrency Control)

多版本并发控制
原理是:通过数据行的多个版本管理来实现数据库的并发控制,简单来说就是***保存数据的历史版本***。可以***通过比较版本号决定数据是否显示出来***。读取数据的时候不需要加锁可以保证事务的隔离效果。

MVCC可以解决什么问题?

①通过 MVCC 可以让读写互相不阻塞,读不阻塞写,写不阻塞读,这样可以提升数据并发处理能力。

②降低了死锁的概率,这个是因为 MVCC 采用了乐观锁的方式,读取数据时,不需要加锁,写操作,只需要锁定必要的行。

③解决了一致性读的问题,当我们朝向某个数据库在时间点的快照是,只能看到这个时间点之前事务提交更新的结果,不能看到时间点之后事务提交的更新结果。
PS: MVCC里面的读取属于是是***快照读***,***不加锁的简单Select***就属于快照读。

MVCC的流程

1、获取事务自己的版本号——事务ID
2、获取Read View——就是事务进行快照读操作的时候生产的读视图(Read View)
3、查询的得到数据,然后Read View中的事务版本号进行比较。
4、如果不符合Read View规则,就需要UndoLog中的历史快照。
5、返回符合规则的数据。

关于Read View

Read View就是事务进行快照操作的时候产生的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID,这个ID是递增的,所以***最新的事务,ID值越大***)
trx_list:一个数值列表,用来维护Read View生成当前活跃的事务ID。
up_limit_id:记录trx_list列表中活跃的事务ID最小的ID(即活跃的事务中最不新(或者说最久远)的事务)
low_limit_id:Read View生成尚未分配的下一个事务ID,也就是当前事务+1。

五、InnoDB如何存储记录的多个版本?

Undo Log: 用于回滚,具体内容就是copy事务前的数据库内容(行)到Undo buffer,在适合的时间把Undo buffer中的内容刷新到磁盘。
事务版本号: 每开启一个日志,都会从数据库中获得一个事务ID(也称为事务版本号),这个事务 ID 是自增的,通过 ID 大小,可以判断事务的时间顺序。
行记录中的隐藏列 : ROW_ID,DB_TRX_ID,DB_ROOL_PTR
ps:行记录中的隐藏列:
ROW_ID:隐藏的行ID,用来生成默认的聚簇索引
DB_TRX_ID: 操作这个事务的ID,也就是最后一个对数据插入或者更新的事务id。
DB_ROOL_PTR: 回滚指针,指向这个记录的Undo Log信息