October 29, 2012

[MySQL 学习] Innodb Optimistic Delete 简述

接口函数是btr_cur_optimistic_delete Innodb的Optimistic Delete操作主要是由purge线程来进行的,用户线程仅仅做了删除标记(包括删除记录,更新二级索引以及更新主键), 另外如果插入/更新操作回滚了,用户也会调用到函数btr_cur_optimistic_delete 例如回滚insert操作的调用栈为 trx_general_rollback_for_mysql–>…..->row_undo->row_undo_ins->row_undo_ins_remove_clust_rec->btr_cur_optimistic_delete 当我们正常删除记录时,一般仅仅是做一个标记,例如更新主键值的update函数栈 row_update_for_mysql->row_upd_step->row_upd->row_upd_clust_step->row_upd_clust_rec_by_insert->btr_cur_del_mark_set_clust_rec->btr_rec_set_deleted_flag 随后的purge线程调用栈为: trx_purge->….->row_purge_step->row_purge->row_purge_del_mark->row_purge_remove_clust_if_poss->row_purge_remove_clust_if_poss_low->btr_cur_optimistic_delete 事实上btr_cur_optimistic_delete的流程也很简单,如果无需重组织btree(btr_cur_can_delete_without_compress),直接调用 a.lock_update_delete(block, rec);  //移除记录锁 b.btr_search_update_hash_on_delete(cursor)//更新adaptive hash index c.page_cur_delete_rec删除记录 d.更新insett buffer 的free bits (压缩表调用ibuf_update_free_bits_zip,非压缩表调用ibuf_update_free_bits_low) 显然,在这里并没有对压缩页的mlog写入数据,实际上写入mlog是由用户线程执行的,对应函数为page_zip_rec_set_deleted.(;例如:row_upd->row_upd_clust_step->row_upd_del_mark_clust_rec->btr_cur_del_mark_set_clust_rec->page_zip_rec_set_deleted) 他的实现也很简单,只是将记录对应的slot设置一个删除标记位。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: [MySQL 学习] Innodb Optimistic Delete 简述 Post Footer automatically generated by wp-posturl plugin for wordpress.

[MySQL 学习] Innodb Optimistic Update流程

更新一条聚集索引记录,接口函数是btr_cur_optimistic_update,这里的更新不涉及到标记删除/插入(二级索引更新或更新主键值,row_upd->row_upd_clust_rec_by_insert->btr_cur_del_mark_set_clust_rec->btr_rec_set_deleted_flag) a.首先判断记录更新是否改变了大小或者需要外部存储,调用函数row_upd_changes_field_size_or_external b.如果a返回的是false,则调用btr_cur_update_in_place进行in-place更新,然后返回, in-place更新的流程如下: 1.调用btr_cur_update_alloc_zip检查压缩page的mlog空间是否足够进行in-place 更新 (1)调用page_zip_available检查是否空间足够,如果有足够空间,直接返回TRUE (2)当page_zip->m_nonempty为false时,直接返回FALSE,表明刚刚可能做过一次压缩,无需再进行下面的流程 (3)调用page_zip_compress进行压缩,如果压缩失败,返回FALSE (4)再次调用page_zip_available检查压缩页的空闲空间 2.如果有足够的空间,则继续往下,调用btr_cur_upd_lock_and_undo检查锁并记录undo信息 (1)如果是非聚集索引,则直接调用lock_sec_rec_modify_check_and_lock,检查并对二级索引加锁,并更新该page的最大事务ID(page_update_max_trx_id), 然后从btr_cur_upd_lock_and_undo返回 (2)如果是聚集索引,调用lock_clust_rec_modify_check_and_lock检查记录锁 (3)调用trx_undo_report_row_operation记录undo 3.向记录中写入trx_id和roll_ptr信息(row_upd_rec_sys_fields) 4.对于聚集索引,如果当前block使用了adaptive hash index(block->index != NULL),则调用row_upd_changes_ord_field_binary//Checks if an update vector changes an ordering field of an index record,不是很明白,待分析,然后再调用btr_search_update_hash_on_delete从adaptive hash index中删除该记录 5.更新记录row_upd_rec_in_place 直接In-place更新记录,并调用page_zip_write_rec向压缩页的mlog中写入记录 //如果进行了多次In-place update,是否会产生多条mlog?? 这可能加大re-compress/re-orgnize的概率 6.对于非聚集索引的压缩page,更新insert buffer的空闲空间信息     if (page_zip && !dict_index_is_clust(index)         && page_is_leaf(buf_block_get_frame(block))) { […]