At Wed, 16 Jun 2021 18:28:28 -0400, Alvaro Herrera <alvhe...@alvh.no-ip.org> 
wrote in 
> On 2021-Jun-16, Ha Ka wrote:
> # Children      Self  Command   Shared Object  Symbol                         
>    
> # ........  ........  ........  .............  
> ..................................
> #
>    100.00%     0.00%  postgres  postgres       [.] exec_replication_command
>             |
>             ---exec_replication_command
>                WalSndLoop
>                XLogSendLogical
>                LogicalDecodingProcessRecord
>                |          
>                 --99.51%--ReorderBufferQueueChange
>                           |          
>                           |--96.06%--hash_seq_search
>                           |          
>                           |--1.78%--ReorderBufferSerializeTXN
>                           |          |          
>                           |           --0.52%--errstart
>                           |          
>                            --0.76%--deregister_seq_scan
> 
> What this tells me is that ReorderBufferQueueChange is spending a lot of
> time doing hash_seq_search, which probably is the one in
> ReorderBufferTXNByXid.

I don't see a call to hash_*seq*_search there. Instead, I see one in
ReorderBufferCheckMemoryLimit().

If added an elog line in hash_seq_search that is visited only when it
is called under ReorderBufferQueueChange, then set
logical_decoding_work_mem to 64kB.

Running the following query calls hash_seq_search (relatively) frequently.

pub=# create table t1 (a int primary key);
pub=# create publication p1 for table t1;
sub=# create table t1 (a int primary key);
sub=# create subscription s1 connection 'host=/tmp port=5432' publication p1;
pub=# insert into t1 (select a from generate_series(0, 9999) a);

The insert above makes 20 calls to ReorderBufferLargestTXN() (via
ReorderBufferCheckmemoryLimit()), which loops over hash_seq_search.

/*
 * Find the largest transaction (toplevel or subxact) to evict (spill to disk).
 *
 * XXX With many subtransactions this might be quite slow, because we'll have
 * to walk through all of them. There are some options how we could improve
 * that: (a) maintain some secondary structure with transactions sorted by
 * amount of changes, (b) not looking for the entirely largest transaction,
 * but e.g. for transaction using at least some fraction of the memory limit,
 * and (c) evicting multiple transactions at once, e.g. to free a given portion
 * of the memory limit (e.g. 50%).
 */
static ReorderBufferTXN *
ReorderBufferLargestTXN(ReorderBuffer *rb)

This looks like a candidate of the culprit. The perf line for
"ReorderBufferSerializeTXN supports this hypothesis.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center


Reply via email to