大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说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 & PAI_OVERWRITE) != 0)
/* 如果设置了PAI_OVERWRITE,必须检查确保参数指定的offsetNumber
指向未使用的item,或指向的位置在最后一个item之后 */
else
/* 否则会将item插入到指定位置,如果位置已占,会进行移动以腾出空间 */
}
else
{
/* 没有参数指定偏移量的话,就寻找一个未使用并且已释放的slot,
若没有已释放的slot,就指定偏移量为limit,将数据存入free space中 */
}
if ((flags & PAI_IS_HEAP) != 0 && offsetNumber > 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