mysql

lobo · · 1700 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1、mvcc 多版本控制(可重复读隔离级别) 在Mysql中MVCC是在Innodb存储引擎中得到支持的,Innodb为每行记录都实现了三个隐藏字段: (1)、事务ID(DB_TRX_ID 6-byte ):最新插入或修改行的事务ID,删除是特殊的修改,会有1bit标示;InnoDB内部维护了一个递增的tx id counter,其当前值可以通过show engine innodb status获得 (2)、回滚指针(DB_ROLL_PTR 7-byte):指向回滚日志的undo log (3)、隐藏的ID 6-byte ![image.png](https://static.studygolang.com/180928/447becae50d66a1290338e931ff53172.png) 当事务更改某行的值时,操作如下: (1)、用排他锁锁定该行 (2)、记录redo log (3)、把该行修改前的值Copy到undo log (4)、修改当前行的值,填写事务编号,使回滚指针指向undo log中的修改前的行 ![image.png](https://static.studygolang.com/180928/28b21afcddb49c9e056e7b68233bcc47.png) (5)、如果事务1最后执行COMMIT操作,则什么操作都不用做。如果执行ROLLBACK操作,则需要通过回滚指针从undo log中还原修改前的数据。 (6)、释放该行的排它锁 ===================================================================== read view 判断当前版本数据项是否可见: 在InnoDB中,创建一个新事务的时候,InnoDB会将当前系统中的活跃事务列表(trx_sys->trx_list)创建一个副本(read view),副本中保存的是系统当前不应该被本事务看到的其他事务id列表。 当用户在这个事务中要读取该行记录的时候,InnoDB会将该行当前的版本号与该read view进行比较。 注:新建事务(当前事务)与正在内存中commit 的事务不在活跃事务链表中。 函数:read_view_sees_trx_id。 read_view中保存了当前全局的事务的范围:【low_limit_id, up_limit_id】 1. 当行记录的事务ID小于当前系统的最小活动id,就是可见的。   if (trx_id < view->up_limit_id) {     return(TRUE);   } 2. 当行记录的事务ID大于当前系统的最大活动id(也就是尚未分配的下一个事务的id),就是不可见的。   if (trx_id >= view->low_limit_id) {     return(FALSE);   } 3. 当行记录的事务ID在活动范围之中时,判断是否在活动链表中,如果在就不可见,如果不在就是可见的。   for (i = 0; i < n_ids; i++) {     trx_id_t view_trx_id       = read_view_get_nth_trx_id(view, n_ids - i - 1);     if (trx_id <= view_trx_id) {     return(trx_id != view_trx_id);     }   } 理想状态下,事务1的事务id=1,事务2的事务id=2。因为事务2执行时查询时,事务1正处于事务执行状态。 所以read view为{1},事务2读取的数据行 trx_id=1,read view中最早的事务id为trx_id_min=1, 最迟的事务id为trx_id_max=1。 因为trx_id_min <= trx_id <= trx_id_max,并且trx_id_min = trx_id = trx_id_max,说明该行记录所在事务在本次新事务创建的时候处于活动状态,不可见。 所以从该行记录的DB_ROLL_PTR指针所指向的回滚段中取出最新的undo-log的版本号的数据,将该可见行的值返回。所以不会出现脏读的现象。 ===================================================================== InnoDB行锁: 是通过索引上的索引项来实现的,通过在数据中对相应数据行加锁来实现的。 InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁! Mysql中的间隙锁: 1、间隙划分; 2、间隙锁锁定区域,根据检索条件向左寻找最靠近检索条件的记录值A,作为左区间,向右寻找最靠近检索条件的记录值B作为右区间,即锁定的间隙为(A,B); 3、间隙锁的目的是为了防止幻读: (1)防止间隙内有新数据被插入; (2)防止已存在的数据,更新成间隙内的数据(例如防止numer=3的记录通过update变成number=5); 4、nnodb自动使用间隙锁的条件: (1)必须在RR级别下; (2)检索条件必须有索引(没有索引的话,mysql会全表扫描,那样会锁定整张表所有的记录,包括不存在的记录,此时其他事务不能修改不能删除不能添加);

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1700 次点击  
加入收藏 微博
3 回复  |  直到 2019-04-03 10:33:40
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传