PostgreSQL TID及tuple slot
1)postgresql預設儲存的是堆表,資料按行儲存在heap page中。行記錄除了儲存欄位的值外還會儲存對應的ctid即行號,表示在哪個頁第幾個記錄。
2)進行select的時候也可以直接指定ctid進行掃描: heap handler中表訪問方法的函式為table_tuple_fetch_row_version函式,它來完成通過ctid獲取元組。
postgres=# select *from t where ctid='(0,2)'; id1 | id2 -----+----- 2 | b (1 row)
3)根據ctid掃描的堆疊為
Breakpoint 4, table_tuple_fetch_row_version (rel=0xae9da164, tid=0xbfb2d4c6, snapshot=0x8c06364, slot=0x8c4b7f4) at ../../../src/include/access/tableam.h:1026 1026 return rel->rd_tableam->tuple_fetch_row_version(rel, tid, snapshot, slot); (gdb) s heapam_fetch_row_version (relation=0xae9da164, tid=0xbfb2d4c6, snapshot=0x8c06364, slot=0x8c4b7f4) at heapam_handler.c:190 190 BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; (gdb) bt #0 heapam_fetch_row_version (relation=0xae9da164, tid=0xbfb2d4c6, snapshot=0x8c06364, slot=0x8c4b7f4) at heapam_handler.c:190 #1 0x082f7e08 in table_tuple_fetch_row_version (rel=0xae9da164, tid=0xbfb2d4c6, snapshot=0x8c06364, slot=0x8c4b7f4) at ../../../src/include/access/tableam.h:1026 #2 0x082f86ee in TidNext (node=0x8c4b67c) at nodeTidscan.c:386 #3 0x082cbb1a in ExecScanFetch (node=0x8c4b67c, accessMtd=0x82f85bc <TidNext>, recheckMtd=0x82f8751 <TidRecheck>) at execScan.c:133 #4 0x082cbb70 in ExecScan (node=0x8c4b67c, accessMtd=0x82f85bc <TidNext>, recheckMtd=0x82f8751 <TidRecheck>) at execScan.c:183 #5 0x082f8784 in ExecTidScan (pstate=0x8c4b67c) at nodeTidscan.c:443 #6 0x082c9d5f in ExecProcNodeFirst (node=0x8c4b67c) at execProcnode.c:445 #7 0x082c10ef in ExecProcNode (node=0x8c4b67c) at ../../../src/include/executor/executor.h:239 #8 0x082c319f in ExecutePlan (estate=0x8c4b554, planstate=0x8c4b67c, use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=ForwardScanDirection, dest=0x8b941dc, execute_once=true) at execMain.c:1646 #9 0x082c1574 in standard_ExecutorRun (queryDesc=0x8bb3e34, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:364 #10 0x082c1411 in ExecutorRun (queryDesc=0x8bb3e34, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:308 #11 0x0846d38b in PortalRunSelect (portal=0x8bde6f4, forward=true, count=0, dest=0x8b941dc) at pquery.c:929 #12 0x0846d0b0 in PortalRun (portal=0x8bde6f4, count=2147483647, isTopLevel=true, run_once=true, dest=0x8b941dc, altdest=0x8b941dc, completionTag=0xbfb2d886 "") at pquery.c:770 #13 0x0846772a in exec_simple_query (query_string=0x8b922e4 "select *from t where ctid='(0,2)';") at postgres.c:1215 #14 0x0846b7e4 in PostgresMain (argc=1, argv=0x8bb7fec, dbname=0x8b8f824 "postgres", username=0x8bb7f14 "pg") at postgres.c:4236 #15 0x083db09d in BackendRun (port=0x8bb49b8) at postmaster.c:4431 #16 0x083da896 in BackendStartup (port=0x8bb49b8) at postmaster.c:4122 #17 0x083d6dff in ServerLoop () at postmaster.c:1704 #18 0x083d674d in PostmasterMain (argc=1, argv=0x8b8d808) at postmaster.c:1377 #19 0x0831d0f4 in main (argc=1, argv=0x8b8d808) at main.c:228
4)
而postgres=# set enable_tidscan=off;將這個引數關閉後,就不能通過TID快速進行行掃描了,會走全表掃描,即通過heap handler表方法方法heap_getnextslot函式獲取元組。
Breakpoint 1, heap_getnextslot (sscan=0x8c4c21c, direction=ForwardScanDirection, slot=0x8c4b774) at heapam.c:1351 1351 HeapScanDesc scan = (HeapScanDesc) sscan; (gdb) bt #0 heap_getnextslot (sscan=0x8c4c21c, direction=ForwardScanDirection, slot=0x8c4b774) at heapam.c:1351 #1 0x082f26c2 in table_scan_getnextslot (sscan=0x8c4c21c, direction=ForwardScanDirection, slot=0x8c4b774) at ../../../src/include/access/tableam.h:875 #2 0x082f2764 in SeqNext (node=0x8c4b67c) at nodeSeqscan.c:80 #3 0x082cbb1a in ExecScanFetch (node=0x8c4b67c, accessMtd=0x82f26e7 <SeqNext>, recheckMtd=0x82f2774 <SeqRecheck>) at execScan.c:133 #4 0x082cbb9c in ExecScan (node=0x8c4b67c, accessMtd=0x82f26e7 <SeqNext>, recheckMtd=0x82f2774 <SeqRecheck>) at execScan.c:200 #5 0x082f27a7 in ExecSeqScan (pstate=0x8c4b67c) at nodeSeqscan.c:112 #6 0x082c9d5f in ExecProcNodeFirst (node=0x8c4b67c) at execProcnode.c:445 #7 0x082c10ef in ExecProcNode (node=0x8c4b67c) at ../../../src/include/executor/executor.h:239 #8 0x082c319f in ExecutePlan (estate=0x8c4b554, planstate=0x8c4b67c, use_parallel_mode=false, operation=CMD_SELECT, sendTuples=true, numberTuples=0, direction=ForwardScanDirection, dest=0x8b941dc, execute_once=true) at execMain.c:1646 #9 0x082c1574 in standard_ExecutorRun (queryDesc=0x8bb3e34, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:364 #10 0x082c1411 in ExecutorRun (queryDesc=0x8bb3e34, direction=ForwardScanDirection, count=0, execute_once=true) at execMain.c:308 #11 0x0846d38b in PortalRunSelect (portal=0x8bde6f4, forward=true, count=0, dest=0x8b941dc) at pquery.c:929 #12 0x0846d0b0 in PortalRun (portal=0x8bde6f4, count=2147483647, isTopLevel=true, run_once=true, dest=0x8b941dc, altdest=0x8b941dc, completionTag=0xbfb2d886 "") at pquery.c:770 #13 0x0846772a in exec_simple_query (query_string=0x8b922e4 "select *from t where ctid='(0,2)';") at postgres.c:1215 #14 0x0846b7e4 in PostgresMain (argc=1, argv=0x8bb7fec, dbname=0x8b8f824 "postgres", username=0x8bb7f14 "pg") at postgres.c:4236 #15 0x083db09d in BackendRun (port=0x8bb49b8) at postmaster.c:4431 #16 0x083da896 in BackendStartup (port=0x8bb49b8) at postmaster.c:4122 #17 0x083d6dff in ServerLoop () at postmaster.c:1704 #18 0x083d674d in PostmasterMain (argc=1, argv=0x8b8d808) at postmaster.c:1377 #19 0x0831d0f4 in main (argc=1, argv=0x8b8d808) at main.c:228
4)元組結構參考
https://blog.csdn.net/yanzongshuai/article/details/84195910
5)slot
a)記憶體中slot結構如上圖所示。TupleTableSlot為儲存行記錄的結構。從資料頁讀取出記錄後,會將其儲存到slot中,返回上層。
b)BufferHeapTupleTableSlot結構中第一個成員為HeapTupleTableSlot,而HeapTupleTableSlot第一個成員為TupleTableSlot,為第一個成員方便進行型別強制轉換。
c)將TupleTableSlot傳到上層後,上層強制轉換成HeapTupleTableSlot,進而解析出他的第二個成員tuple,這個tuple的結構為HeapTupleData,包括:t_len:t_data的長度,t_self:TID了,t_tableOid:所屬表的OID,t_data:這個為記錄頭及其資料。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2676288/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL 原始碼解讀(235)- 查詢#128(獲取屬性值:slot_deform_heap_tuple)SQL原始碼ORM
- PostgreSQL DBA(158) - Locks(tuple locks)SQL
- PostgreSQL儲存引擎之heap tuple結構SQL儲存引擎
- PostgreSQL DBA(21) - MVCC#1(Multi Version Heap Tuple)SQLMVCC#
- PostgreSQL DBA(25) - MVCC#5(Tuple可見性判斷)SQLMVCC#
- [Vue] slot詳解,slot、slot-scope和v-slotVue
- PostgreSQL 原始碼解讀(118)- MVCC#3(Tuple可見性判斷)SQL原始碼MVCC#
- PostgreSQL DBA(26) - MVCC#6(Tuple可見性判斷-簡化版)SQLMVCC#
- __slot__ 限制
- vue slot 用法Vue
- vue插槽slotVue
- VUE 插槽 slotVue
- PostgreSQL 工具及mysql、mongoMySqlGo
- 深入理解vue中的slot與slot-scopeVue
- PostgreSQL 原始碼解讀(135)- MVCC#19(vacuum過程-heap_execute_freeze_tuple函式)SQL原始碼MVCC#函式
- PostgreSQL簡介及安裝SQL
- Vue slot的用法Vue
- Vue 中的 slotVue
- Python中的tuplePython
- 使用list和tuple
- Python元組tuplePython
- Python tuple(元組)Python
- PostgreSQL:字元——型別及函式SQL字元型別函式
- Python中元組tuple的作用以及tuple和list的轉換Python
- Vue 作用域插槽slotVue
- 細談 vue - slot 篇Vue
- 元組tuple的方法
- vue函式元件,slot分發,只實現default slot的問題Vue函式元件
- 請你說說 Vue 中 slot 和 slot-scope 的原理(2.6.11 深度解析)Vue
- PostgreSQL簡介及安裝步驟SQL
- postgresql的yum安裝及配置方法SQL
- 分散式 PostgreSQL - Citus 架構及概念分散式SQL架構
- 分散式 PostgreSQL - Citus 架構及概念分散式SQL架構
- vue的內建元件slotVue元件
- 對Vue插槽slot的理解Vue
- react 實現插槽slot功能React
- Vue(14)slot插槽的使用Vue
- Python基礎:使用list & tuplePython