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

database

插入数据主要的实现在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

相关数据结构

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

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;

以上是 PostgreSQL源码学习(2)插入数据#0 的全部内容, 来源链接: utcz.com/z/533060.html

回到顶部