前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PostgreSQL的insert解析

PostgreSQL的insert解析

原创
作者头像
yzsDBA
修改2020-02-25 10:15:10
1.5K0
修改2020-02-25 10:15:10
举报
文章被收录于专栏:PostgreSQL研究与原理解析

其insert由函数heapam_tuple_insert完成。

heapam_tuple_insert
heapam_tuple_insert

1、首先需要从slot中取出tuple值,HeapTupleTableSlot.tuple

2、从relation中得到该记录即将插入表的OID:relation->rd_id,然后slot->tts_tableOid和tuple->t_tableOid更新为该OID

3、调用heap_insert将tuple插入heap 页中,这个过程中产生WAL日志并写入WAL BUFFER中:

  1)生成事务ID:xid

  2)调用函数heap_prepare_insert:设置tup->t_data的t_infomask和t_infomask2;tup->t_data->t_choice.t_heap.t_xmin为xid;

(tup->t_data)->t_choice.t_heap.t_field3.t_cid为入参cid

(tup->t_data)->t_choice.t_heap.t_xmax为0

即insert的xmin为事务ID,xmax为0

  3)调用RelationGetBufferForTuple,从fsm中找到一个满足空间大小的数据页,并将该数据页加载到内存,返回内存块的块号Buffer

  4)CheckForSerializableConflictIn隔离级别处理

  5)调用RelationPutHeapTuple从页面中最后一个free slot并将记录插入。如何找free slot,PageAddItemExtended完成。

  6)如果该页此时pd_flags & PD_ALL_VISIBLE,即该页内所有记录都可见,但此时插入了一个记录,需要清除该标签。

  7)标记该buffer为脏页,以供后续checkpoint刷脏

  8)生成WAL日志,并将WAL日志写入WAL BUFFER

  9)将此时lsn写入页头pd_lsn

4、更新tuple->t_self为slot->tts_tid,即记录在页内位置。

如何在页内找一个free slot由函数PageAddItemExtended完成。

PageAddItemExtended
PageAddItemExtended

1、计算出pd_linp数组的最大值后新增一个后的个数:

limit=[pg_lower-sizeof(PageHeader)]/Sizeof(ItemIdData)+1

2、如果页头中pd_flags & PD_HAS_FREE_LINES为TRUE,即该数组中有free slot,那么首先从这个数组中找一个可用的ItemIdData,从pd_linp[0]开始一个一个的进行判断,一旦(itemId)->lp_flags == LP_UNUSED && (itemId)->lp_len != 0,表明这个slot可用,那么取这个offsetNumber返回

3、如果该页中没有free slot,则在pd_linp[limit-1]当前最后一个ItemIdData后面添加一个ItemIdData,设置该ItemIdData的值将其lp_off指向pd_upper位置并调整其lp_len=tuple->t_len,lp_flags = LP_NORMAL

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档