PostgreSQL源码学习(2)插入数据#0

PostgreSQL源码学习(2)插入数据#0以一条insert into test values (123,'abc');的SQL语句为例,跟踪插入数据的代码逻辑。(PG版本为12.2) 插入数据主要的实现在bufpage…

PostgreSQL源码学习(2)插入数据#0

插入数据主要的实现在bufpage.c中,主要的函数是PageAddItemExtended。查看调用栈:

#0  PageAddItemExtended (page=0x7fddcac3cd00 "", item=0x141f540 "34701", 
    size=32, offsetNumber=0, flags=2) at bufpage.c:199
#1  0x00000000004d9e70 in RelationPutHeapTuple (relation=0x7fddda866178, 
    buffer=158, tuple=0x141f528, token=false) at hio.c:53
#2  0x00000000004c76d2 in heap_insert (relation=0x7fddda866178, tup=0x141f528, 
    cid=0, options=0, bistate=0x0) at heapam.c:1913
#3  0x00000000004d3ead in heapam_tuple_insert (relation=0x7fddda866178, 
    slot=0x141f3c8, cid=0, options=0, bistate=0x0) at heapam_handler.c:257
#4  0x00000000006dae8a in table_tuple_insert (rel=0x7fddda866178, 
    slot=0x141f3c8, cid=0, options=0, bistate=0x0)
    at ../../../src/include/access/tableam.h:1140
#5  0x00000000006dbf87 in ExecInsert (mtstate=0x141e8d0, slot=0x141f3c8, 
    planSlot=0x141f3c8, estate=0x141e540, canSetTag=true)
    at nodeModifyTable.c:586
#6  0x00000000006de2fa in ExecModifyTable (pstate=0x141e8d0)
    at nodeModifyTable.c:2215
#7  0x00000000006b2af7 in ExecProcNodeFirst (node=0x141e8d0)
    at execProcnode.c:445
#8  0x00000000006a8cd7 in ExecProcNode (node=0x141e8d0)
    at ../../../src/include/executor/executor.h:239
#9  0x00000000006ab053 in ExecutePlan (estate=0x141e540, planstate=0x141e8d0, 
    use_parallel_mode=false, operation=CMD_INSERT, sendTuples=false, 
    numberTuples=0, direction=ForwardScanDirection, dest=0x1419ff8, 
---Type <return> to continue, or q <return> to quit---
    execute_once=true) at execMain.c:1646
#10 0x00000000006a91b4 in standard_ExecutorRun (queryDesc=0x141d910, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at execMain.c:364
#11 0x00000000006a9059 in ExecutorRun (queryDesc=0x141d910, 
    direction=ForwardScanDirection, count=0, execute_once=true)
    at execMain.c:308
#12 0x000000000088016a in ProcessQuery (plan=0x1419f18, 
    sourceText=0x13606f0 "insert into test values(123,"abc");", params=0x0, 
    queryEnv=0x0, dest=0x1419ff8, completionTag=0x7ffd63e18570 "")
    at pquery.c:161
#13 0x00000000008818b1 in PortalRunMulti (portal=0x13c6490, isTopLevel=true, 
    setHoldSnapshot=false, dest=0x1419ff8, altdest=0x1419ff8, 
    completionTag=0x7ffd63e18570 "") at pquery.c:1283
#14 0x0000000000880eeb in PortalRun (portal=0x13c6490, 
    count=9223372036854775807, isTopLevel=true, run_once=true, dest=0x1419ff8, 
    altdest=0x1419ff8, completionTag=0x7ffd63e18570 "") at pquery.c:796
#15 0x000000000087b27f in exec_simple_query (
    query_string=0x13606f0 "insert into test values(123,"abc");")
    at postgres.c:1215
#16 0x000000000087f2ff in PostgresMain (argc=1, argv=0x138a5c8, 
    dbname=0x138a490 "postgres", username=0x138a478 "nail") at postgres.c:4247
#17 0x00000000007e6a8e in BackendRun (port=0x1382470) at postmaster.c:4437
#18 0x00000000007e628d in BackendStartup (port=0x1382470) at postmaster.c:4128
#19 0x00000000007e292d in ServerLoop () at postmaster.c:1704
#20 0x00000000007e21ed in PostmasterMain (argc=3, argv=0x135b1b0)
    at postmaster.c:1377
#21 0x000000000070f75d in main (argc=3, argv=0x135b1b0) at main.c:228

代码100分

相关数据结构

代码流程涉及的PageHeader结构体已在之前了解过。PostgreSQL源码学习(1)Page页

代码100分OffsetNumber
PageAddItemExtended(Page page,
					Item item,
					Size size,
					OffsetNumber offsetNumber,
					int flags);

PageAddItemExtended函数

// src/backend/storage/page/bufpage.c

/* 获取最后一个item(行指针)的偏移量的下一个位置 */
limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));

/* 是否由参数指定了偏移量 */
if (OffsetNumberIsValid(offsetNumber))
{
	if ((flags &amp; PAI_OVERWRITE) != 0)
		/* 如果设置了PAI_OVERWRITE,必须检查确保参数指定的offsetNumber
		    指向未使用的item,或指向的位置在最后一个item之后 */
	else
		/* 否则会将item插入到指定位置,如果位置已占,会进行移动以腾出空间 */
}
else
{
	/* 没有参数指定偏移量的话,就寻找一个未使用并且已释放的slot,
	    若没有已释放的slot,就指定偏移量为limit,将数据存入free space中 */
}

if ((flags &amp; PAI_IS_HEAP) != 0 &amp;&amp; offsetNumber &gt; MaxHeapTuplesPerPage)
	/* 如果指定了PAI_IS_HEAP,那么存储的位置不能超过此限制 */;

/* 计算新的或复用pd_lower和pd_upper(略) */

if (needshuffle)
	/* 使用memmove对现有的行指针进行移动 */
	memmove(itemId + 1, itemId,
				(limit - offsetNumber) * sizeof(ItemIdData));

/* 设置新数据的行指针(ItemData) */
ItemIdSetNormal(itemId, upper, size);

/* 使用memcpy拷贝数据到page页中的指定位置 */
memcpy((char *) page + upper, item, size);

/* 调整page header的信息(略) */

/* 返回新数据的偏移量 */
return offsetNumber;

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/9104.html

(0)
上一篇 2023-02-15
下一篇 2023-02-15

相关推荐

  • Python Click模块指南

    Python Click模块指南在Python开发中,命令行界面是很重要的一个部分。为了帮助开发者快速方便地构建命令行界面,Click模块应运而生。Click是一个用于快速创建命令行界面的Python模块,它能够轻松构建命令行工具,帮助开发者提升开发效率。

    2024-08-27
    29
  • sqlplus显示设置_plsql sql窗口

    sqlplus显示设置_plsql sql窗口1、设置行的长度 set linesize n; 2、设置指定列的长度 col 指定修改的列 for a(指定多少字符) eg: col name for a20;

    2023-02-27
    183
  • 关系模式范式分解教程 3NF与BCNF口诀「终于解决」

    关系模式范式分解教程 3NF与BCNF口诀「终于解决」https://blog.csdn.net/sumaliqinghua/article/details/86246762 【通俗易懂】关系模式范式分解教程 3NF与BCNF口诀!小白也能看懂原创置顶

    2023-01-31
    146
  • Python绘制箱线图

    Python绘制箱线图在数据分析和可视化过程中,箱线图是一种非常重要的图形,它可以帮助我们更好的了解数据分布情况、异常值的存在以及数据的极值、中位数等统计信息。

    2024-08-15
    34
  • Oracle密码延迟验证导致的系统HANG住[通俗易懂]

    Oracle密码延迟验证导致的系统HANG住[通俗易懂]问题现象: 更改密码后,每次连接异常慢,就算用正确的密码连接,验证延时也非常大,导致应用程序连接反复出现超时现象; 问题分析: 经查实,这是由于11G的延迟密码特性引起,特别在一些自动连接特性的应用…

    2022-12-22
    152
  • mysql数据库多表关联查询的慢SQL优化[通俗易懂]

    mysql数据库多表关联查询的慢SQL优化[通俗易懂]工作中我们经常用到多个left join去关联其他表查询结果,但是随着数据量的增加,一个表的数据达到百万级别后,这种普通的left join查询将非常的耗时。 举个例子:     现在porder表…

    2023-02-10
    143
  • [命令行]Mysql 导入 excel 文件

    [命令行]Mysql 导入 excel 文件将 excel 表格中的数据批量导入数据库中 将要导入的表删除字段名,只留下要导入的数据。 将文件另存为 *.csv格式,可以用记事本打开(实际上就是标准的逗号分隔的数据 进入mysql,输入命令,打

    2023-04-26
    163
  • 利用pyspark实现contains操作,高效的查找对应数据

    利用pyspark实现contains操作,高效的查找对应数据在处理海量数据时,快速、高效地查找对应数据至关重要。和关系型数据库中的like操作类似,在pyspark中可以使用contains操作来实现类似的功能。本文将从以下几个方面阐述pyspark中contains操作的使用:

    2024-02-04
    96

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注