How to use the tuplesort_performsort function of PostgreSQL
SortKeys + I; (gdb) 852 AssertArg (attNums [I]! = 0); (gdb) p * state- > sortKeys$10 = {ssup_cxt = 0x0, ssup_collation = 0, ssup_reverse = false, ssup_nulls_first = false, ssup_attno = 0, ssup_extra = 0x0, comparator = 0x0, abbreviate = false, abbrev_converter = 0x0, abbrev_abort = 0x0, abbrev_full_comparator = 0x0} (gdb) n853 AssertArg (sortoperators [I]! = 0) (gdb) 855 sortKey- > ssup_cxt = CurrentMemoryContext; (gdb) 856 sortKey- > ssup_collation = sortCollations [I]; (gdb) 857 sortKey- > ssup_nulls_first = nullsFirstFlags [I]; (gdb) 858 sortKey- > ssup_attno = attNums [I]; (gdb) 860 sortKey- > abbreviate = (I = 0); (gdb) 862 PrepareSortSupportFromOrderingOp (sortOperators [I], sortKey); (gdb) 848 for (I = 0; I; I)
< nkeys; i++)(gdb) 850 SortSupport sortKey = state->SortKeys + I; (gdb) 852 AssertArg (attNums [I]! = 0); (gdb) 853 AssertArg (sortoperators [I]! = 0); (gdb) 855 sortKey- > ssup_cxt = CurrentMemoryContext; (gdb) 856 sortKey- > ssup_collation = sortCollations [I]; (gdb) 857 sortKey- > ssup_nulls_first = nullsFirstFlags [I]; (gdb) 858 sortKey- > ssup_attno = attNums [I] (gdb) 860 sortKey- > abbreviate = (I = = 0); (gdb) 862 PrepareSortSupportFromOrderingOp (sortOperators [I], sortKey); (gdb) 848 for (I = 0; I)
< nkeys; i++)(gdb) 完成初始化,返回state (gdb) 871 if (nkeys == 1 && !state->SortKeys- > abbrev_converter) (gdb) n874 MemoryContextSwitchTo (oldcontext); (gdb) 876 return state (gdb) p * state$11 = {status = TSS_INITIAL, nKeys = 2, randomAccess = false, bounded = false, boundUsed = false, bound = 0, tuples = true, availMem = 4169704, allowedMem = 4194304, maxTapes = 0, tapeRange = 0, sortcontext = 0x2093290, tuplecontext = 0x20992c0, tapeset = 0x0, comparetup = 0xa7525b, copytup = 0xa76247, writetup = 0xa76de1, readtup = 0xa76ec6, memtuples = 0x209b310, memtupcount = 0, memtupsize = 1024, memtupsize = growmemtuples, growmemtuples = true, true =, =, = 0, = CurrentRun = 0, mergeactive = 0x0, Level = 0, destTape = 0, tp_fib = 0x0, tp_runs = 0x0, tp_dummy = 0x0, tp_tapenum = 0x0, activeTapes = 0, result_tape =-1, current = 0, eof_reached = false, markpos_block = 0, markpos_offset = 0, markpos_eof = false, worker =-1, shared = 0x0, nParticipants =-1, tupDesc = 0x208fa40, sortKeys = 0x20937c0, onlyKey = 0x0, abbrevNext = 10, indexInfo = 0x0, estate = estate, 0x0 = 0x0, 0x0 = 0x0 EnforceUnique = false, high_mask = 0, low_mask = 0, max_buckets = 0, datumType = 0, datumTypeLen = 0, ru_start = {tv = {tv_sec = 0, tv_usec = 0}, ru = {ru_utime = {tv_sec = 0, tv_usec = 0}, ru_stime = {tv_sec = 0, tv_usec = 0}, {ru_maxrss = 0, _ ru_maxrss_word = 0}, {ru_ixrss = 0 _ _ ru_ixrss_word = 0}, {ru_idrss = 0, _ _ ru_idrss_word = 0}, {ru_isrss = 0, _ _ ru_isrss_word = 0}, {ru_minflt = 0, _ _ ru_minflt_word = 0}, {ru_majflt = 0, _ _ ru_majflt_word = 0}, {ru_nswap = 0, _ _ ru_nswap_word = 0}, {ru_inblock = 0 _ _ ru_inblock_word = 0}, {ru_oublock = 0, _ _ ru_oublock_word = 0}, {ru_msgsnd = 0, _ _ ru_msgsnd_word = 0}, {ru_msgrcv = 0, _ _ ru_msgrcv_word = 0}, {ru_nsignals = 0, _ _ ru_nsignals_word = 0}, {ru_nvcsw = 0, _ _ ru_nvcsw_word = 0}, {ru_nivcsw = 0 _ _ ru_nivcsw_word = 0} (gdb)
Tuplesort_puttupleslot
Appear in a loop
For (;;) {/ / get tuples slot = ExecProcNode (outerNode) from outer plan; if (TupIsNull (slot)) break;// until all are acquired / / sort tuplesort_puttupleslot (tuplesortstate, slot);}
Take one of the slot as an example
(gdb) cContinuing.Breakpoint 2, tuplesort_puttupleslot (state=0x20933a8, slot=0x208f8c8) at tuplesort.c:14361436 MemoryContext oldcontext = MemoryContextSwitchTo (state- > sortcontext)
Input parameter, state is the tuple slot returned by the state,slot returned by the previous call to begin_heap, and returned by outer node
(gdb) p * slot$12 = {type = T_TupleTableSlot, tts_isempty = false, tts_shouldFree = false, tts_shouldFreeMin = false, tts_slow = false, tts_tuple = 0x2090678, tts_tupleDescriptor = 0x7f061a300380, tts_mcxt = 0x208f270, tts_buffer = 103, tts_nvalid = 0, tts_values = 0x208f928, tts_isnull = 0x208f960, tts_mintuple = 0x0, tts_minhdr = {t_len = 0, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0} Ip_posid = 0}, t_tableOid = 0, t_data = 0x0}, tts_off = 0, tts_fixedTupleDescriptor = true} (gdb)
Tuple data in slot
(gdb) p * slot- > tts_values$13 = 0 (gdb) p * slot- > tts_tuple$14 = {t_len = 56, t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}, t_tableOid = 286759, t_data = 0x7f05ee0c4648} (gdb) p * slot- > tts_tuple- > t_data$15 = {t_choice = {t_heap = {t_xmin = 839, t_xmax = 0, t_field3 = {t_cid = 0, t_xvac = 0}} T_datum = {datum_len_ = 839, datum_typmod = 0, datum_typeid = 0}}, t_ctid = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 1}, t_infomask2 = 7, t_infomask = 2306, t_hoff = 24'\ 030' T_bits = 0x7f05ee0c465f ""} (gdb) p * slot- > tts_tuple- > tdatea-> t_bits$16 = 0'\ 000' (gdb) x/16ux * slot- > tts_tuple- > tweedata-> t_bits0x0: Cannot access memory at address 0x0 (gdb) x/16ux slot- > tts_tuple- > tweedata-> t_bits0x7f05ee0c465f: 0x5a470b00 0x00003130 0x00000100 0x000001000x7f05ee0c466f: 0x00000100 0x00000100 0x00000100 0x000001000x7f05ee0c467f: 0x00000000 0x8f282800 0x000000da 0x400238000x7f05ee0c468f: 0x04200002 0x00000020 0x709fc800 0x709f9000 (gdb) x/16bx slot- > tts_tuple- > tweedata-> t_bits0x7f05ee0c465f: 0x00 0x0b 0x47 0x5a 0x30 0x31 0x00 0x000x7f05ee0c4667: 0x00 0x01 0x00 0x00 0x00 0x01 0x000x 00 (gdb) x/16bc slot- > tts_tuple- > tweedata-> t_bits0x7f05ee0c465f: 0'\ 00011'\ v'71'G' 90 'Z48' 0' 49'1' 0'\ 000' 0'\ 000'0x7f05ee0c4667: 0'\ 0001'\ 0010'\ 000000'\ 000000'\ 0001' (gdb) p * slot- > tts_tupleDescriptor$17 = {natts = 7 Tdtypeid = 286761, tdtypmod =-1, tdhasoid = false, tdrefcount = 2, constr = 0x0, attrs = 0x7f061a3003a0} (gdb) p * slot$18 = {type = T_TupleTableSlot, tts_isempty = false, tts_shouldFree = false, tts_shouldFreeMin = false, tts_slow = false, tts_tuple = 0x2090678, tts_tupleDescriptor = 0x7f061a300380, tts_mcxt = 0x208f270, tts_buffer = 103, tts_nvalid = 0, tts_values = 0x208f928, tts_isnull = 0x208f960, tts_mintuple = 0x0, tts_minhdr = {tts_minhdr = 0 T_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 0}, t_tableOid = 0, t_data = 0x0}, tts_off = 0 Tts_fixedTupleDescriptor = true} (gdb) p * slot- > tts_values [0] Cannot access memory at address 0x0 (gdb) p slot- > tts_values [0] $19 = 0 (gdb) x/32bc slot- > tts_tuple- > tdatea-> t_bits0x7f05ee0c465f: 0'\ 00011'\ v'71'G' 90'Z' 48 '049' 1' 0'\ 000\ 000'0x7f05ee0c4667: 0'\ 000 '1'\ 001' 0'\ 000000'\ 000000'\ 001' 0'\ 000000'\ 000'0x7f05ee0c466f: 0'\ 0001'\ 0010'\ 000000'\ 0001'\ 001' 0'\ 000000'\ 000'0x7f05ee0c4677: 0'\ 0001' 1 '\ 001' 0'\ 0000'\ 0001'\ 001' 0'\ 0000' (gdb) x/32bx slot- > tts_tuple- > tdatea-> t_bits0x7f05ee0c465f: 0x00 0x0b 0x47 0x5a 0x30 0x31 0x00 0x000x7f05ee0c4667: 0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x000x7f05ee0c466f: 0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x000x7f05ee0c4677: 0x00 0x01 0x00 0x00 0x00 0x01 0x00 0x00
Copy the tuple and put it in state- > memtuples
(gdb) n1443 COPYTUP (state, & stup, (void *) slot); (gdb) 1445 puttuple_common (state, & stup); (gdb) stepputtuple_common (state=0x20933a8, tuple=0x7ffe890e0b00) at tuplesort.c:16391639 Assert (! LEADER (state)) (gdb) n1641 switch (state- > status) (gdb) p state- > status$20 = TSS_INITIAL (gdb) n1652 if (state- > memtupcount > = state- > memtupsize-1) (gdb) p state- > memtupcount$21 = 0 (gdb) p state- > memtupsize-1 $22 = 1023 (gdb) n1657 state- > memtups [state-> memtupcount++] = * tuple (gdb) 1671 if (state- > bounded & & (gdb) p state- > bounded$23 = false (gdb) n1688 if (state- > memtupcount)
< state->Memtupsize & &! LACKMEM (state) (gdb) 1689 return; (gdb) 1743} (gdb) tuplesort_puttupleslot (state=0x20933a8, slot=0x208f8c8) at tuplesort.c:14471447 MemoryContextSwitchTo (oldcontext); (gdb) 1448} (gdb) (gdb) p state- > memtuples [0] $25 = {tuple = 0x20993d8, datum1 = 1, isnull1 = false, tupindex = 0}
Tuplesort_performsort
(gdb) info bNum Type Disp Enb Address What1 breakpoint keep y 0x0000000000a6ffa1 in tuplesort_begin_heap at tuplesort.c:812 breakpoint already hit 1 time2 breakpoint keep y 0x0000000000a7119d in tuplesort_puttupleslot at tuplesort.c:1436 breakpoint already hit 1 time3 breakpoint keep y 0x0000000000a71f45 in tuplesort_performsort at tuplesort.c:1792 (gdb) del 2 (gdb) cContinuing.Breakpoint 3 Tuplesort_performsort (state=0x20933a8) at tuplesort.c:17921792 MemoryContext oldcontext = MemoryContextSwitchTo (state- > sortcontext) (gdb)
Input parameters
(gdb) p * state$27 = {status = TSS_BUILDRUNS, nKeys = 2, randomAccess = false, bounded = false, boundUsed = false, bound = 0, tuples = true, availMem = 824360, allowedMem = 4194304, maxTapes = 16, tapeRange = 15, sortcontext = 0x2093290, tuplecontext = 0x20992c0, tapeset = 0x2093a00, comparetup = 0xa7525b, copytup = 0xa76247, writetup = 0xa76de1, readtup = 0xa76ec6, memtuples = 0x2611570, memtupcount = 26592, memtupsize = 37448, memtupsize = growmemtuples, growmemtuples = growmemtuples, growmemtuples = false, false = 0, =, = CurrentRun = 2, mergeactive = 0x2093878, Level = 1, destTape = 2, tp_fib = 0x20938a0, tp_runs = 0x20938f8, tp_dummy = 0x2093950, tp_tapenum = 0x20939a8, activeTapes = 0, result_tape =-1, current = 0, eof_reached = false, markpos_block = 0, markpos_offset = 0, markpos_eof = false, worker =-1, shared = 0x0, nParticipants =-1, tupDesc = 0x208fa40, sortKeys = 0x20937c0, onlyKey = 0x0, abbrevNext = 10, indexInfo = 0x0, estate = estate, 0x0 = 0x0, 0x0 = 0x0 EnforceUnique = false, high_mask = 0, low_mask = 0, max_buckets = 0, datumType = 0, datumTypeLen = 0, ru_start = {tv = {tv_sec = 0, tv_usec = 0}, ru = {ru_utime = {tv_sec = 0, tv_usec = 0}, ru_stime = {tv_sec = 0, tv_usec = 0}, {ru_maxrss = 0, _ ru_maxrss_word = 0}, {ru_ixrss = 0 _ _ ru_ixrss_word = 0}, {ru_idrss = 0, _ _ ru_idrss_word = 0}, {ru_isrss = 0, _ _ ru_isrss_word = 0}, {ru_minflt = 0, _ _ ru_minflt_word = 0}, {ru_majflt = 0, _ _ ru_majflt_word = 0}, {ru_nswap = 0, _ _ ru_nswap_word = 0}, {ru_inblock = 0 _ _ ru_inblock_word = 0}, {ru_oublock = 0, _ _ ru_oublock_word = 0}, {ru_msgsnd = 0, _ _ ru_msgsnd_word = 0}, {ru_msgrcv = 0, _ _ ru_msgrcv_word = 0}, {ru_nsignals = 0, _ _ ru_nsignals_word = 0}, {ru_nvcsw = 0, _ _ ru_nvcsw_word = 0}, {ru_nivcsw = 0 _ _ ru_nivcsw_word = 0} (gdb) p state- > memtupsize$28 = 37448 (gdb)
State- > status status has been switched to TSS_BUILDRUNS
(gdb) n1795 if (trace_sort) (gdb) 1800 switch (state- > status) (gdb) p state- > status$29 = TSS_BUILDRUNS (gdb)
All are brushed to disk and merged and sorted
(gdb) n1864 dumptuples (state, true); (gdb) 1865 mergeruns (state); (gdb) 1866 state- > eof_reached = false; (gdb) 1867 state- > markpos_block = 0L; (gdb) 1868 state- > markpos_offset = 0; (gdb) 1869 state- > markpos_eof = false; (gdb) 1870 break (gdb) 1878 if (trace_sort) (gdb) 1890 MemoryContextSwitchTo (oldcontext); (gdb) 1891} (gdb) so far, I believe you have a better understanding of "how to use PostgreSQL's tuplesort_performsort function". You might as well do it in practice! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!