Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

PostgreSQL Source Code interpretation (89)-query statement # 74 (SeqNext function # 2)

2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)06/01 Report--

< scan->

< scan->

< GetOldSnapshotThresholdTimestamp()) ereport(ERROR, (errcode(ERRCODE_SNAPSHOT_TOO_OLD), errmsg("snapshot too old")));}//--------------------------------------------------- HeapKeyTest/* * HeapKeyTest * * Test a heap tuple to see if it satisfies a scan key. * 验证heap tuple是否满足扫描键要求 */#define HeapKeyTest(tuple, \ tupdesc, \ nkeys, \ keys, \ result) \do \{ \ /* Use underscores to protect the variables passed in as parameters */ \ /* 使用下划线来保护作为参数传入的变量*/ \ int __cur_nkeys = (nkeys); \ ScanKey __cur_keys = (keys); \ \ (result) = true; /* may change */ \ for (; __cur_nkeys--; __cur_keys++) \ { \ Datum __atp; \ bool __isnull; \ Datum __test; \ \ if (__cur_keys->

Sk_flags & SK_ISNULL)\ {\ (result) = false;\ break \}\ _ _ atp = heap_getattr ((tuple),\ _ cur_keys- > sk_attno,\ (tupdesc),\ & _ _ isnull) \ if (_ _ isnull)\ {\ (result) = false;\ break \}\ _ _ test = FunctionCall2Coll (& _ cur_keys- > sk_func,\ _ _ cur_keys- > sk_collation,\ _ _ atp, _ _ cur_keys- > sk_argument) \\ if (! DatumGetBool (_ _ test))\ {\ (result) = false;\ break;\}\} while (0) 3. Tracking analysis

The test script is as follows

Testdb=# explain select dw.*,grjf.grbh,grjf.xm,grjf.ny,grjf.je testdb-# from t_dwxx dw,lateral (select gr.grbh,gr.xm,jf.ny Jf.je testdb (# from t_grxx gr inner join t_jfxx jftestdb (# on gr.dwbh = dw.dwbh testdb (# and gr.grbh = jf.grbh) grjftestdb-# order by dw.dwbh QUERY PLAN -Sort (cost=20070.93..20320.93 rows=100000 width=47) Sort Key: dw.dwbh-> Hash Join (cost=3754.00..8689.61 rows=100000 width=47) Hash Cond: (gr.dwbh):: text = (dw.dwbh):: text)-> Hash Join (cost=3465.00..8138.00 rows=100000 width=31) Hash Cond: (jf.grbh):: text = gr.grbh:: text)-> Seq Scan on t_jfxx jf (cost=0.00..1637.00 rows=100000 width=20)-> Hash (cost=1726.00..1726.00 rows=100000 width=16)-> Seq Scan on t_grxx gr (cost=0.00..1726.00 rows=100000 width=16)-> Hash (cost=164.00..164.00 rows=10000 width=20) -> Seq Scan on t_dwxx dw (cost=0.00..164.00 rows=10000 width=20) (11 rows)

Start gdb, set breakpoints, and enter heap_getnext

(gdb) b heap_getnextBreakpoint 1 at 0x4de01f: file heapam.c, line 1841. (gdb) cContinuing.Breakpoint 1, heap_getnext (scan=0x2aadc18, direction=ForwardScanDirection) at heapam.c:18411841 if (scan- > rs_pageatatime)

Check the input parameters, notice that rs_pageatatime = true, query using page-at-a-time mode

(gdb) p * scan$1 = {rs_rd = 0x7efdb8f2dfd8, rs_snapshot = 0x2a2a6d0, rs_nkeys = 0, rs_key = 0x0, rs_bitmapscan = false, rs_samplescan = false, rs_pageatatime = true, rs_allow_strat = true, rs_allow_sync = true, rs_temp_snap = false, rs_nblocks = 726, rs_startblock = 0, rs_numblocks = 4294967295, rs_strategy = 0x0, rs_syncscan = false, rs_inited = false, rs_ctup = {t_len = 2139062143 T_self = {ip_blkid = {bi_hi = 65535, bi_lo = 65535}, ip_posid = 0}, t_tableOid = 16742, t_data = 0x0}, rs_cblock = 4294967295, rs_cbuf = 0, rs_parallel = 0x0, rs_cindex = 2139062143, rs_ntuples = 2139062143, rs_vistuples = {32639}}

Enter the heapgettup_pagemode function

(gdb) n1842 heapgettup_pagemode (scan, direction, (gdb) stepheapgettup_pagemode (scan=0x2aadc18, dir=ForwardScanDirection, nkeys=0, key=0x0) at heapam.c:794794 HeapTuple tuple = & (scan- > rs_ctup); (gdb)

Heapgettup_pagemode- > variable assignment, note that tuple is still a "wild" pointer; p scan- > rs_inited = false has not been initialized

794 HeapTuple tuple = & (scan- > rs_ctup); (gdb) n795 bool backward = ScanDirectionIsBackward (dir); (gdb) p * tuple$2 = {t_len = 2139062143, t_self = {ip_blkid = {bi_hi = 65535, bi_lo = 65535}, ip_posid = 0}, t_tableOid = 16742, t_data = 0x0} (gdb) n808 if (ScanDirectionIsForward (dir) (gdb) p scan- > rs_inited$3 = false

Heapgettup_pagemode- > non-parallel scan, page = scan- > rs_startblock (i.e. page = 0)

(gdb) n815 if (scan- > rs_nblocks = = 0 | | scan- > rs_numblocks = = 0) (gdb) n821 if (scan- > rs_parallel! = NULL) (gdb) 836 page = scan- > rs_startblock; / * first page * / (gdb)

Enter heapgetpage

(gdb) n837 heapgetpage (scan, page); (gdb) stepheapgetpage (scan=0x2aadc18, page=0) at heapam.c:362362 Assert (page)

< scan->

Rs_nblocks)

Heapgetpage- > check validation & read page

362Assert (page

< scan->

Rs_nblocks); (gdb) n365 if (BufferIsValid (scan- > rs_cbuf)) (gdb) p scan- > rs_cbuf$4 = 0 (gdb) n376 CHECK_FOR_INTERRUPTS (); (gdb) 379 scan- > rs_cbuf = ReadBufferExtended (scan- > rs_rd, MAIN_FORKNUM, page, (gdb) 381scan- > rs_cblock = page; (gdb) 383if (! scan- > rs_pageatatime)

Heapgetpage- > rs_cbuf is 0 for 346/rs_cblock

(gdb) p scan- > rs_cbuf$5 = 346 (gdb) p scan- > rs_cblock$6 = 0

Heapgetpage- > page-at-a-time mode read, variable assignment, lock buffer

(gdb) n386 buffer = scan- > rs_cbuf; (gdb) n386 buffer = scan- > rs_cbuf; (gdb) 387 snapshot = scan- > rs_snapshot; (gdb) 392heap_page_prune_opt (scan- > rs_rd, buffer); (gdb) 399 LockBuffer (buffer, BUFFER_LOCK_SHARE); (gdb) p buffer$7 = 346

Heapgetpage- > get page, check whether the snapshot is too old, and get the number of rows

(gdb) n401 dp = BufferGetPage (buffer); (gdb) 402 TestForOldSnapshot (snapshot, scan- > rs_rd, dp); (gdb) p dp$8 = (Page) 0x7efda4b7ac00 "\ 001" (gdb) n403 lines = PageGetMaxOffsetNumber (dp); (gdb) 404 ntup = 0; (gdb) p lines$11 = 158

Heapgetpage- > verify visibility

(gdb) n426 all_visible = PageIsAllVisible (dp) & &! snapshot- > takenDuringRecovery; (gdb) 428 for (lineoff = FirstOffsetNumber, lpp = PageGetItemId (dp, lineoff); (gdb) p all_visible$12 = false (gdb) n429 lineoff rs_rd); (gdb) 438 loctup.t_data = (HeapTupleHeader) PageGetItem ((Page) dp, lpp); (gdb) 439 loctup.t_len = ItemIdGetLength (lpp) (gdb) 440 ItemPointerSet (& (loctup.t_self), page, lineoff); (gdb) 442 if (all_visible) (gdb) 445 valid = HeapTupleSatisfiesVisibility (& loctup, snapshot, buffer); (gdb) 447 CheckForSerializableConflictOut (valid, scan- > rs_rd, & loctup, (gdb) 450 if (valid) (gdb) 451 scan- > rs_ vistures [ntup + +] = lineoff (gdb) 430 lineoff++, lpp++) (gdb).

Heapgettup_pagemode- > exit heapgetpage, return to heapgettup_pagemode, initialize lineindex to 0, set rs_inited to T

(gdb) finishRun till exit from # 0 heapgetpage (scan=0x2aadc18, page=0) at heapam.c:430heapgettup_pagemode (scan=0x2aadc18, dir=ForwardScanDirection, nkeys=0, key=0x0) at heapam.c:838838 lineindex = 0; (gdb) n839 scan- > rs_inited = true; (gdb) 848 dp = BufferGetPage (scan- > rs_cbuf)

Heapgettup_pagemode- > get page to verify whether the snapshot is too old

(gdb) n849 TestForOldSnapshot (scan- > rs_snapshot, scan- > rs_rd, dp); (gdb) p dp$18 = (Page) 0x7efda4b7ac00 "\ 001"

Heapgettup_pagemode- > count the number of Item and start the loop

(gdb) n850 lines = scan- > rs_ntuples; (gdb) 853 linesleft = lines-lineindex; (gdb) 948 while (linesleft > 0) (gdb) p lines$19 = 158 (gdb) p linesleft$20 = 158 (gdb)

Heapgettup_pagemode- > get Item offset (lineoff) and ItemId

(gdb) p lineoff$21 = 1 (gdb) p lpp$22 = (ItemId) 0x7efda4b7ac18 (gdb) p * lpp$23 = {lp_off = 8152, lp_flags = 1, lp_len = 40}

Heapgettup_pagemode- > assigns values to variables in tuple, and ItemPointer is the pointer to the ItemPointerData structure

(gdb) n954 tuple- > t_data = (HeapTupleHeader) PageGetItem ((Page) dp, lpp); (gdb) 955 tuple- > t_len = ItemIdGetLength (lpp); (gdb) 956 ItemPointerSet (& (tuple- > t_self), page, lineoff) (gdb) 961 if (key! = NULL) (gdb) p * tuple- > t_data$26 = {t_choice = {t_heap = {t_xmin = 862, t_xmax = 0, t_field3 = {t_cid = 0, t_xvac = 0}}, t_datum = {datum_len_ = 862, datum_typmod = 0, datum_typeid = 0}}, t_ctid = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1} T_infomask2 = 5, t_infomask = 2306, t_hoff = 24'\ 030mm, t_bits = 0x7efda4b7cbef "} (gdb) p tuple- > t_len$28 = 40 (gdb) p tuple- > t_self$29 = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}

Heapgettup_pagemode- > set scan- > rs_cindex, return

(gdb) n975 scan- > rs_cindex = lineindex; (gdb) n976 return; (gdb) p scan- > rs_cindex $30 = 0

Back to heap_getnext

(gdb) heap_getnext (scan=0x2aadc18, direction=ForwardScanDirection) at heapam.c:18471847 if (scan- > rs_ctup.t_data = = NULL)

Return the obtained tuple

1847 if (scan- > rs_ctup.t_data = = NULL) (gdb) n1859 pgstat_count_heap_getnext (scan- > rs_rd); (gdb) 1861 return & (scan- > rs_ctup); (gdb) p scan- > rs_ctup$31 = {t_len = 40, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}, t_tableOid = 16742, t_data = 0x7efda4b7cbd8}

Finish the first call and enter the function again

(gdb) cContinuing.Breakpoint 1, heap_getnext (scan=0x2aadc18, direction=ForwardScanDirection) at heapam.c:18411841 if (scan- > rs_pageatatime) (gdb) n1842 heapgettup_pagemode (scan, direction, (gdb) stepheapgettup_pagemode (scan=0x2aadc18, dir=ForwardScanDirection, nkeys=0, key=0x0) at heapam.c:794794 HeapTuple tuple = & (scan- > rs_ctup); (gdb) n795 bool backward = ScanDirectionIsBackward (dir) (gdb) 808 if (ScanDirectionIsForward (dir)) (gdb) 810 if (! scan- > rs_inited) (gdb) 844 page = scan- > rs_cblock; / * current page * /

Check the input parameter scan, which is different from the previous one. It stores some information returned by the last call, such as rs_vistuples, etc.

(gdb) p * scan$32 = {rs_rd = 0x7efdb8f2dfd8, rs_snapshot = 0x2a2a6d0, rs_nkeys = 0, rs_key = 0x0, rs_bitmapscan = false, rs_samplescan = false, rs_pageatatime = true, rs_allow_strat = true, rs_allow_sync = true, rs_temp_snap = false, rs_nblocks = 726, rs_startblock = 0, rs_numblocks = 4294967295, rs_strategy = 0x0, rs_syncscan = false, rs_inited = true, rs_ctup = {t_len = 40 T_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}, t_tableOid = 16742, t_data = 0x7efda4b7cbd8}, rs_cblock = 0, rs_cbuf = 346, rs_parallel = 0x0, rs_cindex = 0, rs_ntuples = 158,rs_vistuples = {1,2,3,4,5,7,8,9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151 152, 153, 154, 155, 156, 157, 158, 32639}}

DONE!

IV. Reference materials

Analysis of PostgreSQL Page Page structure (1)-Foundation

PostgreSQL Page page structure parsing (2)-header and row data pointer

PostgreSQL Page page structure parsing (3)-row data

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report