pg.ddx.io pgsql-hackers@postgresql.org mailing list archive
help / color / mirror / Atom feed From: Maksim.Melnikov <m.melnikov@postgrespro.ru>
To: Потапов Александр <a.potapov@postgrespro.ru>
Cc: Matthias van de Meent <boekewurm+postgres@gmail.com>
Cc: pgsql-hackers@postgresql.org
Subject: Re: Init connection time grows quadratically
Date: Wed, 3 Jun 2026 09:33:41 +0300
Message-ID: <65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru> (raw )
In-Reply-To: <3b7e5e-684fdc80-f-48e15c80@193664207 >
References: <3bdba-68359800-d-249da480@139845401 >
<CAEze2WiHFA43SvV7SdQKjKyMjrSSdW+O6meaV+vk+YuwHr1UQg@mail.gmail.com >
<2ab4be-6847f380-11-1d048f40@125133490 >
<3b7e5e-684fdc80-f-48e15c80@193664207 >
On 6/16/25 11:56, Потапов Александр wrote:
>
> To be more precise I used constant number of threads (128 and 1024) to
> compare with previous results. The quadratic dependency exists
> everywhere, see new graph.
>
> > Q: Did you check that pgbench or the OS does not have
> > O(n_active_connections) or O(n_active_threads) overhead per worker
> > during thread creation or connection establishment, e.g. by varying
> > the number of threads used to manage these N clients? I wouldn't be
> > surprised if there are inefficiencies in e.g. the threading- or
> > synchronization model that cause O(N) per-thread overhead, or O(N^2)
> > overall when you have one thread per connection.
>
Hi, all!
I've investigated slightly different scenario then Alexander and I want
share my thoughts in this thread too.
I found that when we run pgbench scenarios sequantially, without
postgres restart between iterations, initial time degrades from launch
to launch and eventually it stabilizes at the worst values then first
run(ICT_degradation.png attached).
Scenario details:
1. postgres rev 1a51ec16db7, 0001-Fix-fast-connection-rate-issue.patch
was applied
2. numa was disabled, swap was off, ramdisk was used for binaries and
pg_data,Hyperthreading and cpu boost were disabled
3. server was built with -02
4.Add to the postgresql.conf:
huge_pages = off #for the sake of test stability and reproducibility
shared_buffers = 1GB
max_connections = 16384
5. Cycle iteration
psql -U postgres -c 'create database bench'
pgbench -U postgres -i -s100 bench
psql -U postgres -d bench -c "checkpoint"
pgbench -U postgres -c${clients} -t100 -j6 -S bench
psql -U postgres -c "DROP DATABASE bench"
Where ${clients} is one of 512/1024/2048/4096/8192
I paid attention that ICT for the first iteration much better than for
next ones. I investigated this behavior a little bit and found a lot of
minor page fault events in ProcArrayAdd method(perf_without_patch-j6.txt
attached) for code line
allProcs[procno].pgxactoff = index;
So, every proc.pgxactoff access generate page fault, because proc
objects accessed in memory randomly and page replacement can occur. I
have some ideas how to improve this - it seems we can put array
of pgxactoff separately
in shmem to have only few hot pages for them. I've attached appropriate
patch(0001-This-patch-reduce-connection-init-close-time.patch). Perf
with minor faults for updated version also was
attached(perf_with_patch-j6.txt attached),
as we can see, patched version fixes this. I made a series of
measurements for all versions and attached comparison
chart(ICT_degradation_with_patch.png attached). Also I add the table
with results
without_patch_first_iteration, average ICT, ms
without_patch_after_warmup, average ICT, ms with_patch_first_iteration,
average ICT, ms with_patch_after_warmup, average ICT, ms
512 ~480+-15 ~500+-10 ~470+-15 ~215 +-15
1024 ~920+-20 ~1000+-20 ~900+-15 ~920 +-20
2048 ~1780+-30 ~2240+-20 ~1760+-30 ~1800 +-30
4096 ~3570+-50 ~6140+-40 ~3450+-130 ~3740 +-60
8192 ~7440+-90 ~18840+-140 ~7440+-140 ~8100+-80
As we can see from attached charts, from one side there is no
degradation for the first iterations for patched and no patched
versions. From another side patched version is much better for next ones.
I've tried the same tests for different values of pgbench -j parameter
to avoid effects of multithreading pgbench nature and got the same picture.
I hope it will be interesting and helpful.
Best regards,
Maksim Melnikov
# Samples: 1M of event 'minor-faults'
# Event count (approx.): 20314715
#
# Children Self Period Command Shared Object Symbol
# ........ ........ ............ ............... ..................................... ........................................................................
#
99.79% 0.00% 0 postgres postgres [.] _start
|
---_start
__libc_start_main@@GLIBC_2.34
__libc_start_call_main
main
PostmasterMain
|
--99.79%--ServerLoop
|
--99.61%--BackendStartup
|
--99.33%--postmaster_child_launch
|
|--95.12%--BackendInitialize
| |
| --95.08%--PostgresMain
| |
| |--53.39%--InitPostgres
| | |
| | |--35.65%--InitProcessPhase2
| | | |
| | | --35.57%--ProcArrayAdd
Percent | Source code & Disassembly of postgres for minor-faults (103275 samples, percent: local period)
--------------------------------------------------------------------------------------------------------------
:
:
:
: 3 Disassembly of section .text:
:
: 5 00000000006b5720 <ProcArrayAdd>:
: 6 /*
: 7 * Add the specified PGPROC to the shared array.
: 8 */
: 9 void
: 10 ProcArrayAdd(PGPROC *proc)
: 11 {
0.00 : 6b5720: endbr64
0.00 : 6b5724: push %rbp
0.00 : 6b5725: mov %rsp,%rbp
0.00 : 6b5728: sub $0x30,%rsp
0.00 : 6b572c: mov %rdi,-0x28(%rbp)
: 17 int pgprocno = GetNumberFromPGProc(proc);
0.00 : 6b5730: mov 0x686319(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5737: mov (%rax),%rax
0.00 : 6b573a: mov -0x28(%rbp),%rdx
0.00 : 6b573e: sub %rax,%rdx
0.00 : 6b5741: sar $0x7,%rdx
0.00 : 6b5745: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b574f: imul %rdx,%rax
0.00 : 6b5753: mov %eax,-0x18(%rbp)
: 26 ProcArrayStruct *arrayP = procArray;
0.00 : 6b5756: mov 0x684043(%rip),%rax # d397a0 <procArray>
0.00 : 6b575d: mov %rax,-0x8(%rbp)
: 29 int index;
: 30 int movecount;
:
: 32 /* See ProcGlobal comment explaining why both locks are held */
: 33 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
0.00 : 6b5761: mov 0x6854f8(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5768: add $0x200,%rax
0.00 : 6b576e: mov $0x0,%esi
0.00 : 6b5773: mov %rax,%rdi
0.00 : 6b5776: call 6d454c <LWLockAcquire>
: 39 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
0.00 : 6b577b: mov 0x6854de(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5782: add $0x180,%rax
0.00 : 6b5788: mov $0x0,%esi
0.00 : 6b578d: mov %rax,%rdi
0.00 : 6b5790: call 6d454c <LWLockAcquire>
:
: 46 if (arrayP->numProcs >= arrayP->maxProcs)
0.00 : 6b5795: mov -0x8(%rbp),%rax
0.11 : 6b5799: mov (%rax),%edx
0.00 : 6b579b: mov -0x8(%rbp),%rax
0.00 : 6b579f: mov 0x4(%rax),%eax
0.00 : 6b57a2: cmp %eax,%edx
0.00 : 6b57a4: jl 6b57f5 <ProcArrayAdd+0xd5>
: 53 /*
: 54 * Oops, no room. (This really shouldn't happen, since there is a
: 55 * fixed supply of PGPROC structs too, and so we should have failed
: 56 * earlier.)
: 57 */
: 58 ereport(FATAL,
0.00 : 6b57a6: mov $0x0,%esi
0.00 : 6b57ab: mov $0x16,%edi
0.00 : 6b57b0: call 8f9a0f <errstart_cold>
0.00 : 6b57b5: test %al,%al
0.00 : 6b57b7: je 6b57f5 <ProcArrayAdd+0xd5>
0.00 : 6b57b9: mov $0x30c5,%edi
0.00 : 6b57be: call 8fa2a6 <errcode>
0.00 : 6b57c3: lea 0x4496ce(%rip),%rax # afee98 <__func__.0+0x58>
0.00 : 6b57ca: mov %rax,%rdi
0.00 : 6b57cd: mov $0x0,%eax
0.00 : 6b57d2: call 8fa559 <errmsg>
0.00 : 6b57d7: lea 0x449b4a(%rip),%rax # aff328 <__func__.19>
0.00 : 6b57de: mov %rax,%rdx
0.00 : 6b57e1: mov $0x1e2,%esi
0.00 : 6b57e6: lea 0x4496cb(%rip),%rax # afeeb8 <__func__.0+0x78>
0.00 : 6b57ed: mov %rax,%rdi
0.00 : 6b57f0: call 8f9c10 <errfinish>
: 76 * PGPROC structure in the cache.
: 77 *
: 78 * Since the occurrence of adding/removing a proc is much lower than the
: 79 * access to the ProcArray itself, the overhead should be marginal
: 80 */
: 81 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b57f5: movl $0x0,-0x1c(%rbp)
0.00 : 6b57fc: jmp 6b581f <ProcArrayAdd+0xff>
: 84 {
: 85 int this_procno = arrayP->pgprocnos[index];
0.00 : 6b57fe: mov -0x8(%rbp),%rax
0.00 : 6b5802: mov -0x1c(%rbp),%edx
0.00 : 6b5805: movslq %edx,%rdx
0.00 : 6b5808: add $0x8,%rdx
0.07 : 6b580c: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b5810: mov %eax,-0x14(%rbp)
:
: 93 Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 94 Assert(allProcs[this_procno].pgxactoff == index);
:
: 96 /* If we have found our right position in the array, break */
: 97 if (this_procno > pgprocno)
0.00 : 6b5813: mov -0x14(%rbp),%eax
0.00 : 6b5816: cmp -0x18(%rbp),%eax
0.00 : 6b5819: jg 6b582c <ProcArrayAdd+0x10c>
: 101 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b581b: addl $0x1,-0x1c(%rbp)
0.00 : 6b581f: mov -0x8(%rbp),%rax
0.00 : 6b5823: mov (%rax),%eax
0.00 : 6b5825: cmp %eax,-0x1c(%rbp)
0.00 : 6b5828: jl 6b57fe <ProcArrayAdd+0xde>
0.00 : 6b582a: jmp 6b582d <ProcArrayAdd+0x10d>
: 108 break;
0.00 : 6b582c: nop
: 110 }
:
: 112 movecount = arrayP->numProcs - index;
0.00 : 6b582d: mov -0x8(%rbp),%rax
0.00 : 6b5831: mov (%rax),%eax
0.00 : 6b5833: sub -0x1c(%rbp),%eax
0.00 : 6b5836: mov %eax,-0x10(%rbp)
: 117 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b5839: mov -0x10(%rbp),%eax
0.00 : 6b583c: cltq
0.00 : 6b583e: lea 0x0(,%rax,4),%rdx
: 121 &arrayP->pgprocnos[index],
0.00 : 6b5846: mov -0x1c(%rbp),%eax
0.00 : 6b5849: cltq
0.00 : 6b584b: add $0x8,%rax
0.00 : 6b584f: lea 0x0(,%rax,4),%rcx
0.00 : 6b5857: mov -0x8(%rbp),%rax
0.00 : 6b585b: add %rcx,%rax
0.00 : 6b585e: lea 0x4(%rax),%rcx
: 129 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b5862: mov -0x1c(%rbp),%eax
0.00 : 6b5865: add $0x1,%eax
0.00 : 6b5868: cltq
0.00 : 6b586a: add $0x8,%rax
0.00 : 6b586e: lea 0x0(,%rax,4),%rsi
0.00 : 6b5876: mov -0x8(%rbp),%rax
0.00 : 6b587a: add %rsi,%rax
0.00 : 6b587d: add $0x4,%rax
0.00 : 6b5881: mov %rcx,%rsi
0.00 : 6b5884: mov %rax,%rdi
0.00 : 6b5887: call ed240 <memmove@plt>
: 141 movecount * sizeof(*arrayP->pgprocnos));
: 142 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b588c: mov -0x10(%rbp),%eax
0.00 : 6b588f: cltq
0.00 : 6b5891: lea 0x0(,%rax,4),%rdx
: 146 &ProcGlobal->xids[index],
0.00 : 6b5899: mov 0x6861b0(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58a0: mov 0x8(%rax),%rax
0.00 : 6b58a4: mov -0x1c(%rbp),%ecx
0.00 : 6b58a7: movslq %ecx,%rcx
0.00 : 6b58aa: shl $0x2,%rcx
0.00 : 6b58ae: add %rax,%rcx
: 153 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b58b1: mov 0x686198(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58b8: mov 0x8(%rax),%rax
0.00 : 6b58bc: mov -0x1c(%rbp),%esi
0.00 : 6b58bf: add $0x1,%esi
0.00 : 6b58c2: movslq %esi,%rsi
0.00 : 6b58c5: shl $0x2,%rsi
0.00 : 6b58c9: add %rsi,%rax
0.00 : 6b58cc: mov %rcx,%rsi
0.00 : 6b58cf: mov %rax,%rdi
0.00 : 6b58d2: call ed240 <memmove@plt>
: 164 movecount * sizeof(*ProcGlobal->xids));
: 165 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b58d7: mov -0x10(%rbp),%eax
0.00 : 6b58da: cltq
0.00 : 6b58dc: lea (%rax,%rax,1),%rdx
: 169 &ProcGlobal->subxidStates[index],
0.00 : 6b58e0: mov 0x686169(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58e7: mov 0x10(%rax),%rax
0.00 : 6b58eb: mov -0x1c(%rbp),%ecx
0.00 : 6b58ee: movslq %ecx,%rcx
0.00 : 6b58f1: add %rcx,%rcx
0.00 : 6b58f4: add %rax,%rcx
: 176 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b58f7: mov 0x686152(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58fe: mov 0x10(%rax),%rax
0.00 : 6b5902: mov -0x1c(%rbp),%esi
0.00 : 6b5905: add $0x1,%esi
0.00 : 6b5908: movslq %esi,%rsi
0.00 : 6b590b: add %rsi,%rsi
0.00 : 6b590e: add %rsi,%rax
0.00 : 6b5911: mov %rcx,%rsi
0.00 : 6b5914: mov %rax,%rdi
0.00 : 6b5917: call ed240 <memmove@plt>
: 187 movecount * sizeof(*ProcGlobal->subxidStates));
: 188 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b591c: mov -0x10(%rbp),%eax
0.00 : 6b591f: cltq
: 191 &ProcGlobal->statusFlags[index],
0.00 : 6b5921: mov 0x686128(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b5928: mov 0x18(%rdx),%rcx
: 194 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b592c: mov -0x1c(%rbp),%edx
0.00 : 6b592f: movslq %edx,%rdx
: 197 &ProcGlobal->statusFlags[index],
0.00 : 6b5932: lea (%rcx,%rdx,1),%rsi
: 199 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5936: mov 0x686113(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b593d: mov 0x18(%rdx),%rcx
0.00 : 6b5941: mov -0x1c(%rbp),%edx
0.00 : 6b5944: add $0x1,%edx
0.00 : 6b5947: movslq %edx,%rdx
0.00 : 6b594a: add %rdx,%rcx
0.00 : 6b594d: mov %rax,%rdx
0.00 : 6b5950: mov %rcx,%rdi
0.00 : 6b5953: call ed240 <memmove@plt>
: 209 movecount * sizeof(*ProcGlobal->statusFlags));
:
: 211 arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
0.00 : 6b5958: mov 0x6860f1(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b595f: mov (%rax),%rax
0.00 : 6b5962: mov -0x28(%rbp),%rdx
0.00 : 6b5966: sub %rax,%rdx
0.00 : 6b5969: sar $0x7,%rdx
0.00 : 6b596d: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b5977: imul %rdx,%rax
0.00 : 6b597b: mov %eax,%ecx
0.00 : 6b597d: mov -0x8(%rbp),%rax
0.00 : 6b5981: mov -0x1c(%rbp),%edx
0.00 : 6b5984: movslq %edx,%rdx
0.00 : 6b5987: add $0x8,%rdx
0.00 : 6b598b: mov %ecx,0x4(%rax,%rdx,4)
: 225 proc->pgxactoff = index;
0.00 : 6b598f: mov -0x28(%rbp),%rax
0.00 : 6b5993: mov -0x1c(%rbp),%edx
0.00 : 6b5996: mov %edx,0x2c(%rax)
: 229 ProcGlobal->xids[index] = proc->xid;
0.00 : 6b5999: mov 0x6860b0(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b59a0: mov 0x8(%rax),%rax
0.00 : 6b59a4: mov -0x1c(%rbp),%edx
0.00 : 6b59a7: movslq %edx,%rdx
0.00 : 6b59aa: shl $0x2,%rdx
0.00 : 6b59ae: add %rax,%rdx
0.00 : 6b59b1: mov -0x28(%rbp),%rax
0.00 : 6b59b5: mov 0x3c(%rax),%eax
0.00 : 6b59b8: mov %eax,(%rdx)
: 239 ProcGlobal->subxidStates[index] = proc->subxidStatus;
0.00 : 6b59ba: mov 0x68608f(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b59c1: mov 0x10(%rax),%rax
0.00 : 6b59c5: mov -0x1c(%rbp),%edx
0.00 : 6b59c8: movslq %edx,%rdx
0.00 : 6b59cb: add %rdx,%rdx
0.00 : 6b59ce: add %rax,%rdx
0.00 : 6b59d1: mov -0x28(%rbp),%rax
0.00 : 6b59d5: movzwl 0x44(%rax),%eax
0.00 : 6b59d9: mov %ax,(%rdx)
: 249 ProcGlobal->statusFlags[index] = proc->statusFlags;
0.00 : 6b59dc: mov 0x68606d(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b59e3: mov 0x18(%rax),%rdx
0.00 : 6b59e7: mov -0x1c(%rbp),%eax
0.00 : 6b59ea: cltq
0.00 : 6b59ec: add %rax,%rdx
0.00 : 6b59ef: mov -0x28(%rbp),%rax
0.00 : 6b59f3: movzbl 0x30(%rax),%eax
0.00 : 6b59f7: mov %al,(%rdx)
:
: 259 arrayP->numProcs++;
0.00 : 6b59f9: mov -0x8(%rbp),%rax
0.00 : 6b59fd: mov (%rax),%eax
0.00 : 6b59ff: lea 0x1(%rax),%edx
0.00 : 6b5a02: mov -0x8(%rbp),%rax
0.00 : 6b5a06: mov %edx,(%rax)
:
: 266 /* adjust pgxactoff for all following PGPROCs */
: 267 index++;
0.00 : 6b5a08: addl $0x1,-0x1c(%rbp)
: 269 for (; index < arrayP->numProcs; index++)
0.00 : 6b5a0c: jmp 6b5a4c <ProcArrayAdd+0x32c>
: 271 {
: 272 int procno = arrayP->pgprocnos[index];
0.00 : 6b5a0e: mov -0x8(%rbp),%rax
0.00 : 6b5a12: mov -0x1c(%rbp),%edx
0.00 : 6b5a15: movslq %edx,%rdx
0.00 : 6b5a18: add $0x8,%rdx
0.00 : 6b5a1c: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b5a20: mov %eax,-0xc(%rbp)
:
: 280 Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 281 Assert(allProcs[procno].pgxactoff == index - 1);
:
: 283 allProcs[procno].pgxactoff = index;
0.00 : 6b5a23: mov 0x683d7e(%rip),%rcx # d397a8 <allProcs>
0.00 : 6b5a2a: mov -0xc(%rbp),%eax
0.00 : 6b5a2d: movslq %eax,%rdx
0.00 : 6b5a30: mov %rdx,%rax
0.00 : 6b5a33: shl $0x3,%rax
0.00 : 6b5a37: sub %rdx,%rax
0.00 : 6b5a3a: shl $0x7,%rax
0.00 : 6b5a3e: lea (%rcx,%rax,1),%rdx
0.00 : 6b5a42: mov -0x1c(%rbp),%eax
99.82 : 6b5a45: mov %eax,0x2c(%rdx)
: 294 for (; index < arrayP->numProcs; index++)
0.00 : 6b5a48: addl $0x1,-0x1c(%rbp)
0.00 : 6b5a4c: mov -0x8(%rbp),%rax
0.00 : 6b5a50: mov (%rax),%eax
0.00 : 6b5a52: cmp %eax,-0x1c(%rbp)
0.00 : 6b5a55: jl 6b5a0e <ProcArrayAdd+0x2ee>
:
: 301 /*
: 302 * Release in reversed acquisition order, to reduce frequency of having to
: 303 * wait for XidGenLock while holding ProcArrayLock.
: 304 */
: 305 LWLockRelease(XidGenLock);
0.00 : 6b5a57: mov 0x685202(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5a5e: add $0x180,%rax
0.00 : 6b5a64: mov %rax,%rdi
0.00 : 6b5a67: call 6d4da1 <LWLockRelease>
: 310 LWLockRelease(ProcArrayLock);
0.00 : 6b5a6c: mov 0x6851ed(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5a73: add $0x200,%rax
0.00 : 6b5a79: mov %rax,%rdi
0.00 : 6b5a7c: call 6d4da1 <LWLockRelease>
: 315 }
0.00 : 6b5a81: nop
0.00 : 6b5a82: leave
0.00 : 6b5a83: ret
0.13% 0.10% 11727 postgres postgres [.] ProcArrayAdd
Percent | Source code & Disassembly of postgres for minor-faults (445 samples, percent: local period)
-----------------------------------------------------------------------------------------------------------
:
:
:
: 3 Disassembly of section .text:
:
: 5 00000000006b58ba <ProcArrayAdd>:
: 6 /*
: 7 * Add the specified PGPROC to the shared array.
: 8 */
: 9 void
: 10 ProcArrayAdd(PGPROC *proc)
: 11 {
0.00 : 6b58ba: endbr64
0.00 : 6b58be: push %rbp
0.00 : 6b58bf: mov %rsp,%rbp
0.00 : 6b58c2: sub $0x30,%rsp
0.00 : 6b58c6: mov %rdi,-0x28(%rbp)
: 17 int pgprocno = GetNumberFromPGProc(proc);
0.00 : 6b58ca: mov 0x68617f(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58d1: mov (%rax),%rax
0.00 : 6b58d4: mov -0x28(%rbp),%rdx
0.00 : 6b58d8: sub %rax,%rdx
0.00 : 6b58db: sar $0x7,%rdx
0.00 : 6b58df: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b58e9: imul %rdx,%rax
0.00 : 6b58ed: mov %eax,-0x18(%rbp)
: 26 ProcArrayStruct *arrayP = procArray;
0.00 : 6b58f0: mov 0x683ea9(%rip),%rax # d397a0 <procArray>
0.00 : 6b58f7: mov %rax,-0x8(%rbp)
: 29 int index;
: 30 int movecount;
:
: 32 /* See ProcGlobal comment explaining why both locks are held */
: 33 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
0.00 : 6b58fb: mov 0x68535e(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5902: add $0x200,%rax
0.00 : 6b5908: mov $0x0,%esi
0.00 : 6b590d: mov %rax,%rdi
0.00 : 6b5910: call 6d48a7 <LWLockAcquire>
: 39 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
0.00 : 6b5915: mov 0x685344(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b591c: add $0x180,%rax
0.00 : 6b5922: mov $0x0,%esi
0.00 : 6b5927: mov %rax,%rdi
0.00 : 6b592a: call 6d48a7 <LWLockAcquire>
:
: 46 if (arrayP->numProcs >= arrayP->maxProcs)
0.00 : 6b592f: mov -0x8(%rbp),%rax
65.30 : 6b5933: mov (%rax),%edx
0.00 : 6b5935: mov -0x8(%rbp),%rax
0.00 : 6b5939: mov 0x4(%rax),%eax
0.00 : 6b593c: cmp %eax,%edx
0.00 : 6b593e: jl 6b598f <ProcArrayAdd+0xd5>
: 53 /*
: 54 * Oops, no room. (This really shouldn't happen, since there is a
: 55 * fixed supply of PGPROC structs too, and so we should have failed
: 56 * earlier.)
: 57 */
: 58 ereport(FATAL,
0.00 : 6b5940: mov $0x0,%esi
0.00 : 6b5945: mov $0x16,%edi
0.00 : 6b594a: call 8f9e02 <errstart_cold>
0.00 : 6b594f: test %al,%al
0.00 : 6b5951: je 6b598f <ProcArrayAdd+0xd5>
0.00 : 6b5953: mov $0x30c5,%edi
0.00 : 6b5958: call 8fa699 <errcode>
0.00 : 6b595d: lea 0x449534(%rip),%rax # afee98 <__func__.0+0x58>
0.00 : 6b5964: mov %rax,%rdi
0.00 : 6b5967: mov $0x0,%eax
0.00 : 6b596c: call 8fa94c <errmsg>
0.00 : 6b5971: lea 0x4499b0(%rip),%rax # aff328 <__func__.19>
0.00 : 6b5978: mov %rax,%rdx
0.00 : 6b597b: mov $0x1e4,%esi
0.00 : 6b5980: lea 0x449531(%rip),%rax # afeeb8 <__func__.0+0x78>
0.00 : 6b5987: mov %rax,%rdi
0.00 : 6b598a: call 8fa003 <errfinish>
: 76 * PGPROC structure in the cache.
: 77 *
: 78 * Since the occurrence of adding/removing a proc is much lower than the
: 79 * access to the ProcArray itself, the overhead should be marginal
: 80 */
: 81 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b598f: movl $0x0,-0x1c(%rbp)
0.00 : 6b5996: jmp 6b59b9 <ProcArrayAdd+0xff>
: 84 {
: 85 int this_procno = arrayP->pgprocnos[index];
0.00 : 6b5998: mov -0x8(%rbp),%rax
0.00 : 6b599c: mov -0x1c(%rbp),%edx
0.00 : 6b599f: movslq %edx,%rdx
0.00 : 6b59a2: add $0x8,%rdx
34.70 : 6b59a6: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b59aa: mov %eax,-0x14(%rbp)
:
: 93 Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 94 Assert(pgxactoffs[this_procno] == index);
:
: 96 /* If we have found our right position in the array, break */
: 97 if (this_procno > pgprocno)
0.00 : 6b59ad: mov -0x14(%rbp),%eax
0.00 : 6b59b0: cmp -0x18(%rbp),%eax
0.00 : 6b59b3: jg 6b59c6 <ProcArrayAdd+0x10c>
: 101 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b59b5: addl $0x1,-0x1c(%rbp)
0.00 : 6b59b9: mov -0x8(%rbp),%rax
0.00 : 6b59bd: mov (%rax),%eax
0.00 : 6b59bf: cmp %eax,-0x1c(%rbp)
0.00 : 6b59c2: jl 6b5998 <ProcArrayAdd+0xde>
0.00 : 6b59c4: jmp 6b59c7 <ProcArrayAdd+0x10d>
: 108 break;
0.00 : 6b59c6: nop
: 110 }
:
: 112 movecount = arrayP->numProcs - index;
0.00 : 6b59c7: mov -0x8(%rbp),%rax
0.00 : 6b59cb: mov (%rax),%eax
0.00 : 6b59cd: sub -0x1c(%rbp),%eax
0.00 : 6b59d0: mov %eax,-0x10(%rbp)
: 117 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b59d3: mov -0x10(%rbp),%eax
0.00 : 6b59d6: cltq
0.00 : 6b59d8: lea 0x0(,%rax,4),%rdx
: 121 &arrayP->pgprocnos[index],
0.00 : 6b59e0: mov -0x1c(%rbp),%eax
0.00 : 6b59e3: cltq
0.00 : 6b59e5: add $0x8,%rax
0.00 : 6b59e9: lea 0x0(,%rax,4),%rcx
0.00 : 6b59f1: mov -0x8(%rbp),%rax
0.00 : 6b59f5: add %rcx,%rax
0.00 : 6b59f8: lea 0x4(%rax),%rcx
: 129 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b59fc: mov -0x1c(%rbp),%eax
0.00 : 6b59ff: add $0x1,%eax
0.00 : 6b5a02: cltq
0.00 : 6b5a04: add $0x8,%rax
0.00 : 6b5a08: lea 0x0(,%rax,4),%rsi
0.00 : 6b5a10: mov -0x8(%rbp),%rax
0.00 : 6b5a14: add %rsi,%rax
0.00 : 6b5a17: add $0x4,%rax
0.00 : 6b5a1b: mov %rcx,%rsi
0.00 : 6b5a1e: mov %rax,%rdi
0.00 : 6b5a21: call ed240 <memmove@plt>
: 141 movecount * sizeof(*arrayP->pgprocnos));
: 142 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b5a26: mov -0x10(%rbp),%eax
0.00 : 6b5a29: cltq
0.00 : 6b5a2b: lea 0x0(,%rax,4),%rdx
: 146 &ProcGlobal->xids[index],
0.00 : 6b5a33: mov 0x686016(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a3a: mov 0x10(%rax),%rax
0.00 : 6b5a3e: mov -0x1c(%rbp),%ecx
0.00 : 6b5a41: movslq %ecx,%rcx
0.00 : 6b5a44: shl $0x2,%rcx
0.00 : 6b5a48: add %rax,%rcx
: 153 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b5a4b: mov 0x685ffe(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a52: mov 0x10(%rax),%rax
0.00 : 6b5a56: mov -0x1c(%rbp),%esi
0.00 : 6b5a59: add $0x1,%esi
0.00 : 6b5a5c: movslq %esi,%rsi
0.00 : 6b5a5f: shl $0x2,%rsi
0.00 : 6b5a63: add %rsi,%rax
0.00 : 6b5a66: mov %rcx,%rsi
0.00 : 6b5a69: mov %rax,%rdi
0.00 : 6b5a6c: call ed240 <memmove@plt>
: 164 movecount * sizeof(*ProcGlobal->xids));
: 165 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b5a71: mov -0x10(%rbp),%eax
0.00 : 6b5a74: cltq
0.00 : 6b5a76: lea (%rax,%rax,1),%rdx
: 169 &ProcGlobal->subxidStates[index],
0.00 : 6b5a7a: mov 0x685fcf(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a81: mov 0x18(%rax),%rax
0.00 : 6b5a85: mov -0x1c(%rbp),%ecx
0.00 : 6b5a88: movslq %ecx,%rcx
0.00 : 6b5a8b: add %rcx,%rcx
0.00 : 6b5a8e: add %rax,%rcx
: 176 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b5a91: mov 0x685fb8(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a98: mov 0x18(%rax),%rax
0.00 : 6b5a9c: mov -0x1c(%rbp),%esi
0.00 : 6b5a9f: add $0x1,%esi
0.00 : 6b5aa2: movslq %esi,%rsi
0.00 : 6b5aa5: add %rsi,%rsi
0.00 : 6b5aa8: add %rsi,%rax
0.00 : 6b5aab: mov %rcx,%rsi
0.00 : 6b5aae: mov %rax,%rdi
0.00 : 6b5ab1: call ed240 <memmove@plt>
: 187 movecount * sizeof(*ProcGlobal->subxidStates));
: 188 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5ab6: mov -0x10(%rbp),%eax
0.00 : 6b5ab9: cltq
: 191 &ProcGlobal->statusFlags[index],
0.00 : 6b5abb: mov 0x685f8e(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b5ac2: mov 0x20(%rdx),%rcx
: 194 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5ac6: mov -0x1c(%rbp),%edx
0.00 : 6b5ac9: movslq %edx,%rdx
: 197 &ProcGlobal->statusFlags[index],
0.00 : 6b5acc: lea (%rcx,%rdx,1),%rsi
: 199 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5ad0: mov 0x685f79(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b5ad7: mov 0x20(%rdx),%rcx
0.00 : 6b5adb: mov -0x1c(%rbp),%edx
0.00 : 6b5ade: add $0x1,%edx
0.00 : 6b5ae1: movslq %edx,%rdx
0.00 : 6b5ae4: add %rdx,%rcx
0.00 : 6b5ae7: mov %rax,%rdx
0.00 : 6b5aea: mov %rcx,%rdi
0.00 : 6b5aed: call ed240 <memmove@plt>
: 209 movecount * sizeof(*ProcGlobal->statusFlags));
:
: 211 arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
0.00 : 6b5af2: mov 0x685f57(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5af9: mov (%rax),%rax
0.00 : 6b5afc: mov -0x28(%rbp),%rdx
0.00 : 6b5b00: sub %rax,%rdx
0.00 : 6b5b03: sar $0x7,%rdx
0.00 : 6b5b07: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b5b11: imul %rdx,%rax
0.00 : 6b5b15: mov %eax,%ecx
0.00 : 6b5b17: mov -0x8(%rbp),%rax
0.00 : 6b5b1b: mov -0x1c(%rbp),%edx
0.00 : 6b5b1e: movslq %edx,%rdx
0.00 : 6b5b21: add $0x8,%rdx
0.00 : 6b5b25: mov %ecx,0x4(%rax,%rdx,4)
: 225 pgxactoffs[arrayP->pgprocnos[index]] = index;
0.00 : 6b5b29: mov 0x683c80(%rip),%rdx # d397b0 <pgxactoffs>
0.00 : 6b5b30: mov -0x8(%rbp),%rax
0.00 : 6b5b34: mov -0x1c(%rbp),%ecx
0.00 : 6b5b37: movslq %ecx,%rcx
0.00 : 6b5b3a: add $0x8,%rcx
0.00 : 6b5b3e: mov 0x4(%rax,%rcx,4),%eax
0.00 : 6b5b42: cltq
0.00 : 6b5b44: shl $0x2,%rax
0.00 : 6b5b48: add %rax,%rdx
0.00 : 6b5b4b: mov -0x1c(%rbp),%eax
0.00 : 6b5b4e: mov %eax,(%rdx)
: 237 ProcGlobal->xids[index] = proc->xid;
0.00 : 6b5b50: mov 0x685ef9(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5b57: mov 0x10(%rax),%rax
0.00 : 6b5b5b: mov -0x1c(%rbp),%edx
0.00 : 6b5b5e: movslq %edx,%rdx
0.00 : 6b5b61: shl $0x2,%rdx
0.00 : 6b5b65: add %rax,%rdx
0.00 : 6b5b68: mov -0x28(%rbp),%rax
0.00 : 6b5b6c: mov 0x38(%rax),%eax
0.00 : 6b5b6f: mov %eax,(%rdx)
: 247 ProcGlobal->subxidStates[index] = proc->subxidStatus;
0.00 : 6b5b71: mov 0x685ed8(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5b78: mov 0x18(%rax),%rax
0.00 : 6b5b7c: mov -0x1c(%rbp),%edx
0.00 : 6b5b7f: movslq %edx,%rdx
0.00 : 6b5b82: add %rdx,%rdx
0.00 : 6b5b85: add %rax,%rdx
0.00 : 6b5b88: mov -0x28(%rbp),%rax
0.00 : 6b5b8c: movzwl 0x40(%rax),%eax
0.00 : 6b5b90: mov %ax,(%rdx)
: 257 ProcGlobal->statusFlags[index] = proc->statusFlags;
0.00 : 6b5b93: mov 0x685eb6(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5b9a: mov 0x20(%rax),%rdx
0.00 : 6b5b9e: mov -0x1c(%rbp),%eax
0.00 : 6b5ba1: cltq
0.00 : 6b5ba3: add %rax,%rdx
0.00 : 6b5ba6: mov -0x28(%rbp),%rax
0.00 : 6b5baa: movzbl 0x2c(%rax),%eax
0.00 : 6b5bae: mov %al,(%rdx)
:
: 267 arrayP->numProcs++;
0.00 : 6b5bb0: mov -0x8(%rbp),%rax
0.00 : 6b5bb4: mov (%rax),%eax
0.00 : 6b5bb6: lea 0x1(%rax),%edx
0.00 : 6b5bb9: mov -0x8(%rbp),%rax
0.00 : 6b5bbd: mov %edx,(%rax)
:
: 274 /* adjust pgxactoff for all following PGPROCs */
: 275 index++;
0.00 : 6b5bbf: addl $0x1,-0x1c(%rbp)
: 277 for (; index < arrayP->numProcs; index++)
0.00 : 6b5bc3: jmp 6b5bf7 <ProcArrayAdd+0x33d>
: 279 {
: 280 int procno = arrayP->pgprocnos[index];
0.00 : 6b5bc5: mov -0x8(%rbp),%rax
0.00 : 6b5bc9: mov -0x1c(%rbp),%edx
0.00 : 6b5bcc: movslq %edx,%rdx
0.00 : 6b5bcf: add $0x8,%rdx
0.00 : 6b5bd3: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b5bd7: mov %eax,-0xc(%rbp)
:
: 288 Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 289 Assert(pgxactoffs[procno] == index - 1);
:
: 291 pgxactoffs[procno] = index;
0.00 : 6b5bda: mov 0x683bcf(%rip),%rax # d397b0 <pgxactoffs>
0.00 : 6b5be1: mov -0xc(%rbp),%edx
0.00 : 6b5be4: movslq %edx,%rdx
0.00 : 6b5be7: shl $0x2,%rdx
0.00 : 6b5beb: add %rax,%rdx
0.00 : 6b5bee: mov -0x1c(%rbp),%eax
0.00 : 6b5bf1: mov %eax,(%rdx)
: 299 for (; index < arrayP->numProcs; index++)
0.00 : 6b5bf3: addl $0x1,-0x1c(%rbp)
0.00 : 6b5bf7: mov -0x8(%rbp),%rax
0.00 : 6b5bfb: mov (%rax),%eax
0.00 : 6b5bfd: cmp %eax,-0x1c(%rbp)
0.00 : 6b5c00: jl 6b5bc5 <ProcArrayAdd+0x30b>
:
: 306 /*
: 307 * Release in reversed acquisition order, to reduce frequency of having to
: 308 * wait for XidGenLock while holding ProcArrayLock.
: 309 */
: 310 LWLockRelease(XidGenLock);
0.00 : 6b5c02: mov 0x685057(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5c09: add $0x180,%rax
0.00 : 6b5c0f: mov %rax,%rdi
0.00 : 6b5c12: call 6d50fc <LWLockRelease>
: 315 LWLockRelease(ProcArrayLock);
0.00 : 6b5c17: mov 0x685042(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5c1e: add $0x200,%rax
0.00 : 6b5c24: mov %rax,%rdi
0.00 : 6b5c27: call 6d50fc <LWLockRelease>
: 320 }
0.00 : 6b5c2c: nop
0.00 : 6b5c2d: leave
0.00 : 6b5c2e: ret
Attachments:
[image/png] ICT_degradation.png (50.4K, ../65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru/3-ICT_degradation.png)
download | view image
[image/png] ICT_degradation_with_patch.png (63.6K, ../65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru/4-ICT_degradation_with_patch.png)
download | view image
[text/plain] perf_without_patch-j6.txt (16.2K, ../65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru/5-perf_without_patch-j6.txt)
download | inline:
# Samples: 1M of event 'minor-faults'
# Event count (approx.): 20314715
#
# Children Self Period Command Shared Object Symbol
# ........ ........ ............ ............... ..................................... ........................................................................
#
99.79% 0.00% 0 postgres postgres [.] _start
|
---_start
__libc_start_main@@GLIBC_2.34
__libc_start_call_main
main
PostmasterMain
|
--99.79%--ServerLoop
|
--99.61%--BackendStartup
|
--99.33%--postmaster_child_launch
|
|--95.12%--BackendInitialize
| |
| --95.08%--PostgresMain
| |
| |--53.39%--InitPostgres
| | |
| | |--35.65%--InitProcessPhase2
| | | |
| | | --35.57%--ProcArrayAdd
Percent | Source code & Disassembly of postgres for minor-faults (103275 samples, percent: local period)
--------------------------------------------------------------------------------------------------------------
:
:
:
: 3 Disassembly of section .text:
:
: 5 00000000006b5720 <ProcArrayAdd>:
: 6 /*
: 7 * Add the specified PGPROC to the shared array.
: 8 */
: 9 void
: 10 ProcArrayAdd(PGPROC *proc)
: 11 {
0.00 : 6b5720: endbr64
0.00 : 6b5724: push %rbp
0.00 : 6b5725: mov %rsp,%rbp
0.00 : 6b5728: sub $0x30,%rsp
0.00 : 6b572c: mov %rdi,-0x28(%rbp)
: 17 int pgprocno = GetNumberFromPGProc(proc);
0.00 : 6b5730: mov 0x686319(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5737: mov (%rax),%rax
0.00 : 6b573a: mov -0x28(%rbp),%rdx
0.00 : 6b573e: sub %rax,%rdx
0.00 : 6b5741: sar $0x7,%rdx
0.00 : 6b5745: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b574f: imul %rdx,%rax
0.00 : 6b5753: mov %eax,-0x18(%rbp)
: 26 ProcArrayStruct *arrayP = procArray;
0.00 : 6b5756: mov 0x684043(%rip),%rax # d397a0 <procArray>
0.00 : 6b575d: mov %rax,-0x8(%rbp)
: 29 int index;
: 30 int movecount;
:
: 32 /* See ProcGlobal comment explaining why both locks are held */
: 33 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
0.00 : 6b5761: mov 0x6854f8(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5768: add $0x200,%rax
0.00 : 6b576e: mov $0x0,%esi
0.00 : 6b5773: mov %rax,%rdi
0.00 : 6b5776: call 6d454c <LWLockAcquire>
: 39 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
0.00 : 6b577b: mov 0x6854de(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5782: add $0x180,%rax
0.00 : 6b5788: mov $0x0,%esi
0.00 : 6b578d: mov %rax,%rdi
0.00 : 6b5790: call 6d454c <LWLockAcquire>
:
: 46 if (arrayP->numProcs >= arrayP->maxProcs)
0.00 : 6b5795: mov -0x8(%rbp),%rax
0.11 : 6b5799: mov (%rax),%edx
0.00 : 6b579b: mov -0x8(%rbp),%rax
0.00 : 6b579f: mov 0x4(%rax),%eax
0.00 : 6b57a2: cmp %eax,%edx
0.00 : 6b57a4: jl 6b57f5 <ProcArrayAdd+0xd5>
: 53 /*
: 54 * Oops, no room. (This really shouldn't happen, since there is a
: 55 * fixed supply of PGPROC structs too, and so we should have failed
: 56 * earlier.)
: 57 */
: 58 ereport(FATAL,
0.00 : 6b57a6: mov $0x0,%esi
0.00 : 6b57ab: mov $0x16,%edi
0.00 : 6b57b0: call 8f9a0f <errstart_cold>
0.00 : 6b57b5: test %al,%al
0.00 : 6b57b7: je 6b57f5 <ProcArrayAdd+0xd5>
0.00 : 6b57b9: mov $0x30c5,%edi
0.00 : 6b57be: call 8fa2a6 <errcode>
0.00 : 6b57c3: lea 0x4496ce(%rip),%rax # afee98 <__func__.0+0x58>
0.00 : 6b57ca: mov %rax,%rdi
0.00 : 6b57cd: mov $0x0,%eax
0.00 : 6b57d2: call 8fa559 <errmsg>
0.00 : 6b57d7: lea 0x449b4a(%rip),%rax # aff328 <__func__.19>
0.00 : 6b57de: mov %rax,%rdx
0.00 : 6b57e1: mov $0x1e2,%esi
0.00 : 6b57e6: lea 0x4496cb(%rip),%rax # afeeb8 <__func__.0+0x78>
0.00 : 6b57ed: mov %rax,%rdi
0.00 : 6b57f0: call 8f9c10 <errfinish>
: 76 * PGPROC structure in the cache.
: 77 *
: 78 * Since the occurrence of adding/removing a proc is much lower than the
: 79 * access to the ProcArray itself, the overhead should be marginal
: 80 */
: 81 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b57f5: movl $0x0,-0x1c(%rbp)
0.00 : 6b57fc: jmp 6b581f <ProcArrayAdd+0xff>
: 84 {
: 85 int this_procno = arrayP->pgprocnos[index];
0.00 : 6b57fe: mov -0x8(%rbp),%rax
0.00 : 6b5802: mov -0x1c(%rbp),%edx
0.00 : 6b5805: movslq %edx,%rdx
0.00 : 6b5808: add $0x8,%rdx
0.07 : 6b580c: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b5810: mov %eax,-0x14(%rbp)
:
: 93 Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 94 Assert(allProcs[this_procno].pgxactoff == index);
:
: 96 /* If we have found our right position in the array, break */
: 97 if (this_procno > pgprocno)
0.00 : 6b5813: mov -0x14(%rbp),%eax
0.00 : 6b5816: cmp -0x18(%rbp),%eax
0.00 : 6b5819: jg 6b582c <ProcArrayAdd+0x10c>
: 101 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b581b: addl $0x1,-0x1c(%rbp)
0.00 : 6b581f: mov -0x8(%rbp),%rax
0.00 : 6b5823: mov (%rax),%eax
0.00 : 6b5825: cmp %eax,-0x1c(%rbp)
0.00 : 6b5828: jl 6b57fe <ProcArrayAdd+0xde>
0.00 : 6b582a: jmp 6b582d <ProcArrayAdd+0x10d>
: 108 break;
0.00 : 6b582c: nop
: 110 }
:
: 112 movecount = arrayP->numProcs - index;
0.00 : 6b582d: mov -0x8(%rbp),%rax
0.00 : 6b5831: mov (%rax),%eax
0.00 : 6b5833: sub -0x1c(%rbp),%eax
0.00 : 6b5836: mov %eax,-0x10(%rbp)
: 117 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b5839: mov -0x10(%rbp),%eax
0.00 : 6b583c: cltq
0.00 : 6b583e: lea 0x0(,%rax,4),%rdx
: 121 &arrayP->pgprocnos[index],
0.00 : 6b5846: mov -0x1c(%rbp),%eax
0.00 : 6b5849: cltq
0.00 : 6b584b: add $0x8,%rax
0.00 : 6b584f: lea 0x0(,%rax,4),%rcx
0.00 : 6b5857: mov -0x8(%rbp),%rax
0.00 : 6b585b: add %rcx,%rax
0.00 : 6b585e: lea 0x4(%rax),%rcx
: 129 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b5862: mov -0x1c(%rbp),%eax
0.00 : 6b5865: add $0x1,%eax
0.00 : 6b5868: cltq
0.00 : 6b586a: add $0x8,%rax
0.00 : 6b586e: lea 0x0(,%rax,4),%rsi
0.00 : 6b5876: mov -0x8(%rbp),%rax
0.00 : 6b587a: add %rsi,%rax
0.00 : 6b587d: add $0x4,%rax
0.00 : 6b5881: mov %rcx,%rsi
0.00 : 6b5884: mov %rax,%rdi
0.00 : 6b5887: call ed240 <memmove@plt>
: 141 movecount * sizeof(*arrayP->pgprocnos));
: 142 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b588c: mov -0x10(%rbp),%eax
0.00 : 6b588f: cltq
0.00 : 6b5891: lea 0x0(,%rax,4),%rdx
: 146 &ProcGlobal->xids[index],
0.00 : 6b5899: mov 0x6861b0(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58a0: mov 0x8(%rax),%rax
0.00 : 6b58a4: mov -0x1c(%rbp),%ecx
0.00 : 6b58a7: movslq %ecx,%rcx
0.00 : 6b58aa: shl $0x2,%rcx
0.00 : 6b58ae: add %rax,%rcx
: 153 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b58b1: mov 0x686198(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58b8: mov 0x8(%rax),%rax
0.00 : 6b58bc: mov -0x1c(%rbp),%esi
0.00 : 6b58bf: add $0x1,%esi
0.00 : 6b58c2: movslq %esi,%rsi
0.00 : 6b58c5: shl $0x2,%rsi
0.00 : 6b58c9: add %rsi,%rax
0.00 : 6b58cc: mov %rcx,%rsi
0.00 : 6b58cf: mov %rax,%rdi
0.00 : 6b58d2: call ed240 <memmove@plt>
: 164 movecount * sizeof(*ProcGlobal->xids));
: 165 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b58d7: mov -0x10(%rbp),%eax
0.00 : 6b58da: cltq
0.00 : 6b58dc: lea (%rax,%rax,1),%rdx
: 169 &ProcGlobal->subxidStates[index],
0.00 : 6b58e0: mov 0x686169(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58e7: mov 0x10(%rax),%rax
0.00 : 6b58eb: mov -0x1c(%rbp),%ecx
0.00 : 6b58ee: movslq %ecx,%rcx
0.00 : 6b58f1: add %rcx,%rcx
0.00 : 6b58f4: add %rax,%rcx
: 176 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b58f7: mov 0x686152(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58fe: mov 0x10(%rax),%rax
0.00 : 6b5902: mov -0x1c(%rbp),%esi
0.00 : 6b5905: add $0x1,%esi
0.00 : 6b5908: movslq %esi,%rsi
0.00 : 6b590b: add %rsi,%rsi
0.00 : 6b590e: add %rsi,%rax
0.00 : 6b5911: mov %rcx,%rsi
0.00 : 6b5914: mov %rax,%rdi
0.00 : 6b5917: call ed240 <memmove@plt>
: 187 movecount * sizeof(*ProcGlobal->subxidStates));
: 188 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b591c: mov -0x10(%rbp),%eax
0.00 : 6b591f: cltq
: 191 &ProcGlobal->statusFlags[index],
0.00 : 6b5921: mov 0x686128(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b5928: mov 0x18(%rdx),%rcx
: 194 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b592c: mov -0x1c(%rbp),%edx
0.00 : 6b592f: movslq %edx,%rdx
: 197 &ProcGlobal->statusFlags[index],
0.00 : 6b5932: lea (%rcx,%rdx,1),%rsi
: 199 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5936: mov 0x686113(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b593d: mov 0x18(%rdx),%rcx
0.00 : 6b5941: mov -0x1c(%rbp),%edx
0.00 : 6b5944: add $0x1,%edx
0.00 : 6b5947: movslq %edx,%rdx
0.00 : 6b594a: add %rdx,%rcx
0.00 : 6b594d: mov %rax,%rdx
0.00 : 6b5950: mov %rcx,%rdi
0.00 : 6b5953: call ed240 <memmove@plt>
: 209 movecount * sizeof(*ProcGlobal->statusFlags));
:
: 211 arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
0.00 : 6b5958: mov 0x6860f1(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b595f: mov (%rax),%rax
0.00 : 6b5962: mov -0x28(%rbp),%rdx
0.00 : 6b5966: sub %rax,%rdx
0.00 : 6b5969: sar $0x7,%rdx
0.00 : 6b596d: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b5977: imul %rdx,%rax
0.00 : 6b597b: mov %eax,%ecx
0.00 : 6b597d: mov -0x8(%rbp),%rax
0.00 : 6b5981: mov -0x1c(%rbp),%edx
0.00 : 6b5984: movslq %edx,%rdx
0.00 : 6b5987: add $0x8,%rdx
0.00 : 6b598b: mov %ecx,0x4(%rax,%rdx,4)
: 225 proc->pgxactoff = index;
0.00 : 6b598f: mov -0x28(%rbp),%rax
0.00 : 6b5993: mov -0x1c(%rbp),%edx
0.00 : 6b5996: mov %edx,0x2c(%rax)
: 229 ProcGlobal->xids[index] = proc->xid;
0.00 : 6b5999: mov 0x6860b0(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b59a0: mov 0x8(%rax),%rax
0.00 : 6b59a4: mov -0x1c(%rbp),%edx
0.00 : 6b59a7: movslq %edx,%rdx
0.00 : 6b59aa: shl $0x2,%rdx
0.00 : 6b59ae: add %rax,%rdx
0.00 : 6b59b1: mov -0x28(%rbp),%rax
0.00 : 6b59b5: mov 0x3c(%rax),%eax
0.00 : 6b59b8: mov %eax,(%rdx)
: 239 ProcGlobal->subxidStates[index] = proc->subxidStatus;
0.00 : 6b59ba: mov 0x68608f(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b59c1: mov 0x10(%rax),%rax
0.00 : 6b59c5: mov -0x1c(%rbp),%edx
0.00 : 6b59c8: movslq %edx,%rdx
0.00 : 6b59cb: add %rdx,%rdx
0.00 : 6b59ce: add %rax,%rdx
0.00 : 6b59d1: mov -0x28(%rbp),%rax
0.00 : 6b59d5: movzwl 0x44(%rax),%eax
0.00 : 6b59d9: mov %ax,(%rdx)
: 249 ProcGlobal->statusFlags[index] = proc->statusFlags;
0.00 : 6b59dc: mov 0x68606d(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b59e3: mov 0x18(%rax),%rdx
0.00 : 6b59e7: mov -0x1c(%rbp),%eax
0.00 : 6b59ea: cltq
0.00 : 6b59ec: add %rax,%rdx
0.00 : 6b59ef: mov -0x28(%rbp),%rax
0.00 : 6b59f3: movzbl 0x30(%rax),%eax
0.00 : 6b59f7: mov %al,(%rdx)
:
: 259 arrayP->numProcs++;
0.00 : 6b59f9: mov -0x8(%rbp),%rax
0.00 : 6b59fd: mov (%rax),%eax
0.00 : 6b59ff: lea 0x1(%rax),%edx
0.00 : 6b5a02: mov -0x8(%rbp),%rax
0.00 : 6b5a06: mov %edx,(%rax)
:
: 266 /* adjust pgxactoff for all following PGPROCs */
: 267 index++;
0.00 : 6b5a08: addl $0x1,-0x1c(%rbp)
: 269 for (; index < arrayP->numProcs; index++)
0.00 : 6b5a0c: jmp 6b5a4c <ProcArrayAdd+0x32c>
: 271 {
: 272 int procno = arrayP->pgprocnos[index];
0.00 : 6b5a0e: mov -0x8(%rbp),%rax
0.00 : 6b5a12: mov -0x1c(%rbp),%edx
0.00 : 6b5a15: movslq %edx,%rdx
0.00 : 6b5a18: add $0x8,%rdx
0.00 : 6b5a1c: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b5a20: mov %eax,-0xc(%rbp)
:
: 280 Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 281 Assert(allProcs[procno].pgxactoff == index - 1);
:
: 283 allProcs[procno].pgxactoff = index;
0.00 : 6b5a23: mov 0x683d7e(%rip),%rcx # d397a8 <allProcs>
0.00 : 6b5a2a: mov -0xc(%rbp),%eax
0.00 : 6b5a2d: movslq %eax,%rdx
0.00 : 6b5a30: mov %rdx,%rax
0.00 : 6b5a33: shl $0x3,%rax
0.00 : 6b5a37: sub %rdx,%rax
0.00 : 6b5a3a: shl $0x7,%rax
0.00 : 6b5a3e: lea (%rcx,%rax,1),%rdx
0.00 : 6b5a42: mov -0x1c(%rbp),%eax
99.82 : 6b5a45: mov %eax,0x2c(%rdx)
: 294 for (; index < arrayP->numProcs; index++)
0.00 : 6b5a48: addl $0x1,-0x1c(%rbp)
0.00 : 6b5a4c: mov -0x8(%rbp),%rax
0.00 : 6b5a50: mov (%rax),%eax
0.00 : 6b5a52: cmp %eax,-0x1c(%rbp)
0.00 : 6b5a55: jl 6b5a0e <ProcArrayAdd+0x2ee>
:
: 301 /*
: 302 * Release in reversed acquisition order, to reduce frequency of having to
: 303 * wait for XidGenLock while holding ProcArrayLock.
: 304 */
: 305 LWLockRelease(XidGenLock);
0.00 : 6b5a57: mov 0x685202(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5a5e: add $0x180,%rax
0.00 : 6b5a64: mov %rax,%rdi
0.00 : 6b5a67: call 6d4da1 <LWLockRelease>
: 310 LWLockRelease(ProcArrayLock);
0.00 : 6b5a6c: mov 0x6851ed(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5a73: add $0x200,%rax
0.00 : 6b5a79: mov %rax,%rdi
0.00 : 6b5a7c: call 6d4da1 <LWLockRelease>
: 315 }
0.00 : 6b5a81: nop
0.00 : 6b5a82: leave
0.00 : 6b5a83: ret
[text/plain] perf_with_patch-j6.txt (14.7K, ../65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru/6-perf_with_patch-j6.txt)
download | inline:
0.13% 0.10% 11727 postgres postgres [.] ProcArrayAdd
Percent | Source code & Disassembly of postgres for minor-faults (445 samples, percent: local period)
-----------------------------------------------------------------------------------------------------------
:
:
:
: 3 Disassembly of section .text:
:
: 5 00000000006b58ba <ProcArrayAdd>:
: 6 /*
: 7 * Add the specified PGPROC to the shared array.
: 8 */
: 9 void
: 10 ProcArrayAdd(PGPROC *proc)
: 11 {
0.00 : 6b58ba: endbr64
0.00 : 6b58be: push %rbp
0.00 : 6b58bf: mov %rsp,%rbp
0.00 : 6b58c2: sub $0x30,%rsp
0.00 : 6b58c6: mov %rdi,-0x28(%rbp)
: 17 int pgprocno = GetNumberFromPGProc(proc);
0.00 : 6b58ca: mov 0x68617f(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b58d1: mov (%rax),%rax
0.00 : 6b58d4: mov -0x28(%rbp),%rdx
0.00 : 6b58d8: sub %rax,%rdx
0.00 : 6b58db: sar $0x7,%rdx
0.00 : 6b58df: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b58e9: imul %rdx,%rax
0.00 : 6b58ed: mov %eax,-0x18(%rbp)
: 26 ProcArrayStruct *arrayP = procArray;
0.00 : 6b58f0: mov 0x683ea9(%rip),%rax # d397a0 <procArray>
0.00 : 6b58f7: mov %rax,-0x8(%rbp)
: 29 int index;
: 30 int movecount;
:
: 32 /* See ProcGlobal comment explaining why both locks are held */
: 33 LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
0.00 : 6b58fb: mov 0x68535e(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5902: add $0x200,%rax
0.00 : 6b5908: mov $0x0,%esi
0.00 : 6b590d: mov %rax,%rdi
0.00 : 6b5910: call 6d48a7 <LWLockAcquire>
: 39 LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
0.00 : 6b5915: mov 0x685344(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b591c: add $0x180,%rax
0.00 : 6b5922: mov $0x0,%esi
0.00 : 6b5927: mov %rax,%rdi
0.00 : 6b592a: call 6d48a7 <LWLockAcquire>
:
: 46 if (arrayP->numProcs >= arrayP->maxProcs)
0.00 : 6b592f: mov -0x8(%rbp),%rax
65.30 : 6b5933: mov (%rax),%edx
0.00 : 6b5935: mov -0x8(%rbp),%rax
0.00 : 6b5939: mov 0x4(%rax),%eax
0.00 : 6b593c: cmp %eax,%edx
0.00 : 6b593e: jl 6b598f <ProcArrayAdd+0xd5>
: 53 /*
: 54 * Oops, no room. (This really shouldn't happen, since there is a
: 55 * fixed supply of PGPROC structs too, and so we should have failed
: 56 * earlier.)
: 57 */
: 58 ereport(FATAL,
0.00 : 6b5940: mov $0x0,%esi
0.00 : 6b5945: mov $0x16,%edi
0.00 : 6b594a: call 8f9e02 <errstart_cold>
0.00 : 6b594f: test %al,%al
0.00 : 6b5951: je 6b598f <ProcArrayAdd+0xd5>
0.00 : 6b5953: mov $0x30c5,%edi
0.00 : 6b5958: call 8fa699 <errcode>
0.00 : 6b595d: lea 0x449534(%rip),%rax # afee98 <__func__.0+0x58>
0.00 : 6b5964: mov %rax,%rdi
0.00 : 6b5967: mov $0x0,%eax
0.00 : 6b596c: call 8fa94c <errmsg>
0.00 : 6b5971: lea 0x4499b0(%rip),%rax # aff328 <__func__.19>
0.00 : 6b5978: mov %rax,%rdx
0.00 : 6b597b: mov $0x1e4,%esi
0.00 : 6b5980: lea 0x449531(%rip),%rax # afeeb8 <__func__.0+0x78>
0.00 : 6b5987: mov %rax,%rdi
0.00 : 6b598a: call 8fa003 <errfinish>
: 76 * PGPROC structure in the cache.
: 77 *
: 78 * Since the occurrence of adding/removing a proc is much lower than the
: 79 * access to the ProcArray itself, the overhead should be marginal
: 80 */
: 81 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b598f: movl $0x0,-0x1c(%rbp)
0.00 : 6b5996: jmp 6b59b9 <ProcArrayAdd+0xff>
: 84 {
: 85 int this_procno = arrayP->pgprocnos[index];
0.00 : 6b5998: mov -0x8(%rbp),%rax
0.00 : 6b599c: mov -0x1c(%rbp),%edx
0.00 : 6b599f: movslq %edx,%rdx
0.00 : 6b59a2: add $0x8,%rdx
34.70 : 6b59a6: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b59aa: mov %eax,-0x14(%rbp)
:
: 93 Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 94 Assert(pgxactoffs[this_procno] == index);
:
: 96 /* If we have found our right position in the array, break */
: 97 if (this_procno > pgprocno)
0.00 : 6b59ad: mov -0x14(%rbp),%eax
0.00 : 6b59b0: cmp -0x18(%rbp),%eax
0.00 : 6b59b3: jg 6b59c6 <ProcArrayAdd+0x10c>
: 101 for (index = 0; index < arrayP->numProcs; index++)
0.00 : 6b59b5: addl $0x1,-0x1c(%rbp)
0.00 : 6b59b9: mov -0x8(%rbp),%rax
0.00 : 6b59bd: mov (%rax),%eax
0.00 : 6b59bf: cmp %eax,-0x1c(%rbp)
0.00 : 6b59c2: jl 6b5998 <ProcArrayAdd+0xde>
0.00 : 6b59c4: jmp 6b59c7 <ProcArrayAdd+0x10d>
: 108 break;
0.00 : 6b59c6: nop
: 110 }
:
: 112 movecount = arrayP->numProcs - index;
0.00 : 6b59c7: mov -0x8(%rbp),%rax
0.00 : 6b59cb: mov (%rax),%eax
0.00 : 6b59cd: sub -0x1c(%rbp),%eax
0.00 : 6b59d0: mov %eax,-0x10(%rbp)
: 117 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b59d3: mov -0x10(%rbp),%eax
0.00 : 6b59d6: cltq
0.00 : 6b59d8: lea 0x0(,%rax,4),%rdx
: 121 &arrayP->pgprocnos[index],
0.00 : 6b59e0: mov -0x1c(%rbp),%eax
0.00 : 6b59e3: cltq
0.00 : 6b59e5: add $0x8,%rax
0.00 : 6b59e9: lea 0x0(,%rax,4),%rcx
0.00 : 6b59f1: mov -0x8(%rbp),%rax
0.00 : 6b59f5: add %rcx,%rax
0.00 : 6b59f8: lea 0x4(%rax),%rcx
: 129 memmove(&arrayP->pgprocnos[index + 1],
0.00 : 6b59fc: mov -0x1c(%rbp),%eax
0.00 : 6b59ff: add $0x1,%eax
0.00 : 6b5a02: cltq
0.00 : 6b5a04: add $0x8,%rax
0.00 : 6b5a08: lea 0x0(,%rax,4),%rsi
0.00 : 6b5a10: mov -0x8(%rbp),%rax
0.00 : 6b5a14: add %rsi,%rax
0.00 : 6b5a17: add $0x4,%rax
0.00 : 6b5a1b: mov %rcx,%rsi
0.00 : 6b5a1e: mov %rax,%rdi
0.00 : 6b5a21: call ed240 <memmove@plt>
: 141 movecount * sizeof(*arrayP->pgprocnos));
: 142 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b5a26: mov -0x10(%rbp),%eax
0.00 : 6b5a29: cltq
0.00 : 6b5a2b: lea 0x0(,%rax,4),%rdx
: 146 &ProcGlobal->xids[index],
0.00 : 6b5a33: mov 0x686016(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a3a: mov 0x10(%rax),%rax
0.00 : 6b5a3e: mov -0x1c(%rbp),%ecx
0.00 : 6b5a41: movslq %ecx,%rcx
0.00 : 6b5a44: shl $0x2,%rcx
0.00 : 6b5a48: add %rax,%rcx
: 153 memmove(&ProcGlobal->xids[index + 1],
0.00 : 6b5a4b: mov 0x685ffe(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a52: mov 0x10(%rax),%rax
0.00 : 6b5a56: mov -0x1c(%rbp),%esi
0.00 : 6b5a59: add $0x1,%esi
0.00 : 6b5a5c: movslq %esi,%rsi
0.00 : 6b5a5f: shl $0x2,%rsi
0.00 : 6b5a63: add %rsi,%rax
0.00 : 6b5a66: mov %rcx,%rsi
0.00 : 6b5a69: mov %rax,%rdi
0.00 : 6b5a6c: call ed240 <memmove@plt>
: 164 movecount * sizeof(*ProcGlobal->xids));
: 165 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b5a71: mov -0x10(%rbp),%eax
0.00 : 6b5a74: cltq
0.00 : 6b5a76: lea (%rax,%rax,1),%rdx
: 169 &ProcGlobal->subxidStates[index],
0.00 : 6b5a7a: mov 0x685fcf(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a81: mov 0x18(%rax),%rax
0.00 : 6b5a85: mov -0x1c(%rbp),%ecx
0.00 : 6b5a88: movslq %ecx,%rcx
0.00 : 6b5a8b: add %rcx,%rcx
0.00 : 6b5a8e: add %rax,%rcx
: 176 memmove(&ProcGlobal->subxidStates[index + 1],
0.00 : 6b5a91: mov 0x685fb8(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5a98: mov 0x18(%rax),%rax
0.00 : 6b5a9c: mov -0x1c(%rbp),%esi
0.00 : 6b5a9f: add $0x1,%esi
0.00 : 6b5aa2: movslq %esi,%rsi
0.00 : 6b5aa5: add %rsi,%rsi
0.00 : 6b5aa8: add %rsi,%rax
0.00 : 6b5aab: mov %rcx,%rsi
0.00 : 6b5aae: mov %rax,%rdi
0.00 : 6b5ab1: call ed240 <memmove@plt>
: 187 movecount * sizeof(*ProcGlobal->subxidStates));
: 188 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5ab6: mov -0x10(%rbp),%eax
0.00 : 6b5ab9: cltq
: 191 &ProcGlobal->statusFlags[index],
0.00 : 6b5abb: mov 0x685f8e(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b5ac2: mov 0x20(%rdx),%rcx
: 194 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5ac6: mov -0x1c(%rbp),%edx
0.00 : 6b5ac9: movslq %edx,%rdx
: 197 &ProcGlobal->statusFlags[index],
0.00 : 6b5acc: lea (%rcx,%rdx,1),%rsi
: 199 memmove(&ProcGlobal->statusFlags[index + 1],
0.00 : 6b5ad0: mov 0x685f79(%rip),%rdx # d3ba50 <ProcGlobal>
0.00 : 6b5ad7: mov 0x20(%rdx),%rcx
0.00 : 6b5adb: mov -0x1c(%rbp),%edx
0.00 : 6b5ade: add $0x1,%edx
0.00 : 6b5ae1: movslq %edx,%rdx
0.00 : 6b5ae4: add %rdx,%rcx
0.00 : 6b5ae7: mov %rax,%rdx
0.00 : 6b5aea: mov %rcx,%rdi
0.00 : 6b5aed: call ed240 <memmove@plt>
: 209 movecount * sizeof(*ProcGlobal->statusFlags));
:
: 211 arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
0.00 : 6b5af2: mov 0x685f57(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5af9: mov (%rax),%rax
0.00 : 6b5afc: mov -0x28(%rbp),%rdx
0.00 : 6b5b00: sub %rax,%rdx
0.00 : 6b5b03: sar $0x7,%rdx
0.00 : 6b5b07: movabs $0x6db6db6db6db6db7,%rax
0.00 : 6b5b11: imul %rdx,%rax
0.00 : 6b5b15: mov %eax,%ecx
0.00 : 6b5b17: mov -0x8(%rbp),%rax
0.00 : 6b5b1b: mov -0x1c(%rbp),%edx
0.00 : 6b5b1e: movslq %edx,%rdx
0.00 : 6b5b21: add $0x8,%rdx
0.00 : 6b5b25: mov %ecx,0x4(%rax,%rdx,4)
: 225 pgxactoffs[arrayP->pgprocnos[index]] = index;
0.00 : 6b5b29: mov 0x683c80(%rip),%rdx # d397b0 <pgxactoffs>
0.00 : 6b5b30: mov -0x8(%rbp),%rax
0.00 : 6b5b34: mov -0x1c(%rbp),%ecx
0.00 : 6b5b37: movslq %ecx,%rcx
0.00 : 6b5b3a: add $0x8,%rcx
0.00 : 6b5b3e: mov 0x4(%rax,%rcx,4),%eax
0.00 : 6b5b42: cltq
0.00 : 6b5b44: shl $0x2,%rax
0.00 : 6b5b48: add %rax,%rdx
0.00 : 6b5b4b: mov -0x1c(%rbp),%eax
0.00 : 6b5b4e: mov %eax,(%rdx)
: 237 ProcGlobal->xids[index] = proc->xid;
0.00 : 6b5b50: mov 0x685ef9(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5b57: mov 0x10(%rax),%rax
0.00 : 6b5b5b: mov -0x1c(%rbp),%edx
0.00 : 6b5b5e: movslq %edx,%rdx
0.00 : 6b5b61: shl $0x2,%rdx
0.00 : 6b5b65: add %rax,%rdx
0.00 : 6b5b68: mov -0x28(%rbp),%rax
0.00 : 6b5b6c: mov 0x38(%rax),%eax
0.00 : 6b5b6f: mov %eax,(%rdx)
: 247 ProcGlobal->subxidStates[index] = proc->subxidStatus;
0.00 : 6b5b71: mov 0x685ed8(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5b78: mov 0x18(%rax),%rax
0.00 : 6b5b7c: mov -0x1c(%rbp),%edx
0.00 : 6b5b7f: movslq %edx,%rdx
0.00 : 6b5b82: add %rdx,%rdx
0.00 : 6b5b85: add %rax,%rdx
0.00 : 6b5b88: mov -0x28(%rbp),%rax
0.00 : 6b5b8c: movzwl 0x40(%rax),%eax
0.00 : 6b5b90: mov %ax,(%rdx)
: 257 ProcGlobal->statusFlags[index] = proc->statusFlags;
0.00 : 6b5b93: mov 0x685eb6(%rip),%rax # d3ba50 <ProcGlobal>
0.00 : 6b5b9a: mov 0x20(%rax),%rdx
0.00 : 6b5b9e: mov -0x1c(%rbp),%eax
0.00 : 6b5ba1: cltq
0.00 : 6b5ba3: add %rax,%rdx
0.00 : 6b5ba6: mov -0x28(%rbp),%rax
0.00 : 6b5baa: movzbl 0x2c(%rax),%eax
0.00 : 6b5bae: mov %al,(%rdx)
:
: 267 arrayP->numProcs++;
0.00 : 6b5bb0: mov -0x8(%rbp),%rax
0.00 : 6b5bb4: mov (%rax),%eax
0.00 : 6b5bb6: lea 0x1(%rax),%edx
0.00 : 6b5bb9: mov -0x8(%rbp),%rax
0.00 : 6b5bbd: mov %edx,(%rax)
:
: 274 /* adjust pgxactoff for all following PGPROCs */
: 275 index++;
0.00 : 6b5bbf: addl $0x1,-0x1c(%rbp)
: 277 for (; index < arrayP->numProcs; index++)
0.00 : 6b5bc3: jmp 6b5bf7 <ProcArrayAdd+0x33d>
: 279 {
: 280 int procno = arrayP->pgprocnos[index];
0.00 : 6b5bc5: mov -0x8(%rbp),%rax
0.00 : 6b5bc9: mov -0x1c(%rbp),%edx
0.00 : 6b5bcc: movslq %edx,%rdx
0.00 : 6b5bcf: add $0x8,%rdx
0.00 : 6b5bd3: mov 0x4(%rax,%rdx,4),%eax
0.00 : 6b5bd7: mov %eax,-0xc(%rbp)
:
: 288 Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
: 289 Assert(pgxactoffs[procno] == index - 1);
:
: 291 pgxactoffs[procno] = index;
0.00 : 6b5bda: mov 0x683bcf(%rip),%rax # d397b0 <pgxactoffs>
0.00 : 6b5be1: mov -0xc(%rbp),%edx
0.00 : 6b5be4: movslq %edx,%rdx
0.00 : 6b5be7: shl $0x2,%rdx
0.00 : 6b5beb: add %rax,%rdx
0.00 : 6b5bee: mov -0x1c(%rbp),%eax
0.00 : 6b5bf1: mov %eax,(%rdx)
: 299 for (; index < arrayP->numProcs; index++)
0.00 : 6b5bf3: addl $0x1,-0x1c(%rbp)
0.00 : 6b5bf7: mov -0x8(%rbp),%rax
0.00 : 6b5bfb: mov (%rax),%eax
0.00 : 6b5bfd: cmp %eax,-0x1c(%rbp)
0.00 : 6b5c00: jl 6b5bc5 <ProcArrayAdd+0x30b>
:
: 306 /*
: 307 * Release in reversed acquisition order, to reduce frequency of having to
: 308 * wait for XidGenLock while holding ProcArrayLock.
: 309 */
: 310 LWLockRelease(XidGenLock);
0.00 : 6b5c02: mov 0x685057(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5c09: add $0x180,%rax
0.00 : 6b5c0f: mov %rax,%rdi
0.00 : 6b5c12: call 6d50fc <LWLockRelease>
: 315 LWLockRelease(ProcArrayLock);
0.00 : 6b5c17: mov 0x685042(%rip),%rax # d3ac60 <MainLWLockArray>
0.00 : 6b5c1e: add $0x200,%rax
0.00 : 6b5c24: mov %rax,%rdi
0.00 : 6b5c27: call 6d50fc <LWLockRelease>
: 320 }
0.00 : 6b5c2c: nop
0.00 : 6b5c2d: leave
0.00 : 6b5c2e: ret
[text/x-patch] 0001-This-patch-reduce-connection-init-close-time.patch (14.0K, ../65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru/7-0001-This-patch-reduce-connection-init-close-time.patch)
download | inline diff:
From 437b48759126a4d8289fd10eb3a885392cf96a47 Mon Sep 17 00:00:00 2001
From: Maksim Melnikov <m.melnikov@postgrespro.ru>
Date: Tue, 18 Nov 2025 17:20:09 +0300
Subject: [PATCH] This patch reduce connection init/close time.
ProcArrayRemove/ProcArrayAdd are expensive in terms of accessing pgxactoff
field in PGPROC, because its are placed on different pages and it the
reason of page_faults occurence. Now one of the use case with pgxactoff
is iteration with gaps over PGPROCs and read/write pgxactoff, PGPROC
allocate ~1KB and it quite enough to have page_faults in case of such
accessing.
So we placed all pgxactoff in the separate array pgxactoffs to have adjacent
pages for them all. Indexes in allProcs aligned with pgxactoffs array, so
the Nth element in pgxactoffs refer to Nth PGPROC.
Exentually it helps to avoid extra page_faults and reduce connection
init/close time.
Tags: lwlock_scale
---
src/backend/access/transam/varsup.c | 10 +++---
src/backend/commands/indexcmds.c | 2 +-
src/backend/commands/vacuum.c | 2 +-
src/backend/replication/logical/logical.c | 2 +-
src/backend/replication/slot.c | 2 +-
src/backend/replication/walsender.c | 2 +-
src/backend/storage/ipc/procarray.c | 38 ++++++++++++-----------
src/backend/storage/lmgr/proc.c | 8 +++--
src/include/storage/proc.h | 6 ++--
9 files changed, 39 insertions(+), 33 deletions(-)
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index dc5e32d86f3..6c941de5c99 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -85,7 +85,7 @@ GetNewTransactionId(bool isSubXact)
{
Assert(!isSubXact);
MyProc->xid = BootstrapTransactionId;
- ProcGlobal->xids[MyProc->pgxactoff] = BootstrapTransactionId;
+ ProcGlobal->xids[GetMyXactOffPGProc()] = BootstrapTransactionId;
return FullTransactionIdFromEpochAndXid(0, BootstrapTransactionId);
}
@@ -244,18 +244,18 @@ GetNewTransactionId(bool isSubXact)
*/
if (!isSubXact)
{
- Assert(ProcGlobal->subxidStates[MyProc->pgxactoff].count == 0);
- Assert(!ProcGlobal->subxidStates[MyProc->pgxactoff].overflowed);
+ Assert(ProcGlobal->subxidStates[GetMyXactOffPGProc()].count == 0);
+ Assert(!ProcGlobal->subxidStates[GetMyXactOffPGProc()].overflowed);
Assert(MyProc->subxidStatus.count == 0);
Assert(!MyProc->subxidStatus.overflowed);
/* LWLockRelease acts as barrier */
MyProc->xid = xid;
- ProcGlobal->xids[MyProc->pgxactoff] = xid;
+ ProcGlobal->xids[GetMyXactOffPGProc()] = xid;
}
else
{
- XidCacheStatus *substat = &ProcGlobal->subxidStates[MyProc->pgxactoff];
+ XidCacheStatus *substat = &ProcGlobal->subxidStates[GetMyXactOffPGProc()];
int nxids = MyProc->subxidStatus.count;
Assert(substat->count == MyProc->subxidStatus.count);
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9ab74c8df0a..03721601070 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -4654,6 +4654,6 @@ set_indexsafe_procflags(void)
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->statusFlags |= PROC_IN_SAFE_IC;
- ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
+ ProcGlobal->statusFlags[GetMyXactOffPGProc()] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
}
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 99d0db82ed7..10b712c8e78 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -2054,7 +2054,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams params,
MyProc->statusFlags |= PROC_IN_VACUUM;
if (params.is_wraparound)
MyProc->statusFlags |= PROC_VACUUM_FOR_WRAPAROUND;
- ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
+ ProcGlobal->statusFlags[GetMyXactOffPGProc()] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
}
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index a33a685dcc6..91d6d83a5d8 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -188,7 +188,7 @@ StartupDecodingContext(List *output_plugin_options,
{
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->statusFlags |= PROC_IN_LOGICAL_DECODING;
- ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
+ ProcGlobal->statusFlags[GetMyXactOffPGProc()] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
}
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 83fcde74718..180cc800825 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -839,7 +839,7 @@ ReplicationSlotRelease(void)
/* might not have been set when we've been a plain slot */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING;
- ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
+ ProcGlobal->statusFlags[GetMyXactOffPGProc()] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
if (am_walsender)
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 3d4ab929f91..38c935e09a0 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -351,7 +351,7 @@ InitWalSender(void)
Assert(MyProc->xmin == InvalidTransactionId);
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->statusFlags |= PROC_AFFECTS_ALL_HORIZONS;
- ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
+ ProcGlobal->statusFlags[GetMyXactOffPGProc()] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
}
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 9299bcebbda..35578e7222c 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -283,6 +283,7 @@ typedef enum KAXCompressReason
} KAXCompressReason;
static PGPROC *allProcs;
+static int *pgxactoffs;
/*
* Cache to reduce overhead of repeated calls to TransactionIdIsInProgress()
@@ -449,6 +450,7 @@ ProcArrayShmemInit(void *arg)
TransamVariables->xactCompletionCount = 1;
allProcs = ProcGlobal->allProcs;
+ pgxactoffs = ProcGlobal->pgxactoffs;
}
static void
@@ -498,7 +500,7 @@ ProcArrayAdd(PGPROC *proc)
int this_procno = arrayP->pgprocnos[index];
Assert(this_procno >= 0 && this_procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
- Assert(allProcs[this_procno].pgxactoff == index);
+ Assert(pgxactoffs[this_procno] == index);
/* If we have found our right position in the array, break */
if (this_procno > pgprocno)
@@ -520,7 +522,7 @@ ProcArrayAdd(PGPROC *proc)
movecount * sizeof(*ProcGlobal->statusFlags));
arrayP->pgprocnos[index] = GetNumberFromPGProc(proc);
- proc->pgxactoff = index;
+ pgxactoffs[arrayP->pgprocnos[index]] = index;
ProcGlobal->xids[index] = proc->xid;
ProcGlobal->subxidStates[index] = proc->subxidStatus;
ProcGlobal->statusFlags[index] = proc->statusFlags;
@@ -534,9 +536,9 @@ ProcArrayAdd(PGPROC *proc)
int procno = arrayP->pgprocnos[index];
Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
- Assert(allProcs[procno].pgxactoff == index - 1);
+ Assert(pgxactoffs[procno] == index - 1);
- allProcs[procno].pgxactoff = index;
+ pgxactoffs[procno] = index;
}
/*
@@ -574,10 +576,10 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
- myoff = proc->pgxactoff;
+ myoff = GetXactOffPGProc(proc);
Assert(myoff >= 0 && myoff < arrayP->numProcs);
- Assert(ProcGlobal->allProcs[arrayP->pgprocnos[myoff]].pgxactoff == myoff);
+ Assert(ProcGlobal->pgxactoffs[arrayP->pgprocnos[myoff]] == myoff);
if (TransactionIdIsValid(latestXid))
{
@@ -632,9 +634,9 @@ ProcArrayRemove(PGPROC *proc, TransactionId latestXid)
int procno = arrayP->pgprocnos[index];
Assert(procno >= 0 && procno < (arrayP->maxProcs + NUM_AUXILIARY_PROCS));
- Assert(allProcs[procno].pgxactoff - 1 == index);
+ Assert(pgxactoffs[procno] - 1 == index);
- allProcs[procno].pgxactoff = index;
+ pgxactoffs[procno] = index;
}
/*
@@ -708,9 +710,9 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
{
Assert(!LWLockHeldByMe(ProcArrayLock));
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
- Assert(proc->statusFlags == ProcGlobal->statusFlags[proc->pgxactoff]);
+ Assert(proc->statusFlags == ProcGlobal->statusFlags[GetXactOffPGProc(proc)]);
proc->statusFlags &= ~PROC_VACUUM_STATE_MASK;
- ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags;
+ ProcGlobal->statusFlags[GetXactOffPGProc(proc)] = proc->statusFlags;
LWLockRelease(ProcArrayLock);
}
}
@@ -724,7 +726,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
static inline void
ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
{
- int pgxactoff = proc->pgxactoff;
+ int pgxactoff = GetXactOffPGProc(proc);
/*
* Note: we need exclusive lock here because we're going to change other
@@ -747,7 +749,7 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
if (proc->statusFlags & PROC_VACUUM_STATE_MASK)
{
proc->statusFlags &= ~PROC_VACUUM_STATE_MASK;
- ProcGlobal->statusFlags[proc->pgxactoff] = proc->statusFlags;
+ ProcGlobal->statusFlags[GetXactOffPGProc(proc)] = proc->statusFlags;
}
/* Clear the subtransaction-XID cache too while holding the lock */
@@ -916,7 +918,7 @@ ProcArrayClearTransaction(PGPROC *proc)
*/
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
- pgxactoff = proc->pgxactoff;
+ pgxactoff = GetXactOffPGProc(proc);
ProcGlobal->xids[pgxactoff] = InvalidTransactionId;
proc->xid = InvalidTransactionId;
@@ -1475,7 +1477,7 @@ TransactionIdIsInProgress(TransactionId xid)
}
/* No shortcuts, gotta grovel through the array */
- mypgxactoff = MyProc->pgxactoff;
+ mypgxactoff = GetMyXactOffPGProc();
numProcs = arrayP->numProcs;
for (int pgxactoff = 0; pgxactoff < numProcs; pgxactoff++)
{
@@ -2176,7 +2178,7 @@ GetSnapshotData(Snapshot snapshot)
}
latest_completed = TransamVariables->latestCompletedXid;
- mypgxactoff = MyProc->pgxactoff;
+ mypgxactoff = GetMyXactOffPGProc();
myxid = other_xids[mypgxactoff];
Assert(myxid == MyProc->xid);
@@ -2215,7 +2217,7 @@ GetSnapshotData(Snapshot snapshot)
TransactionId xid = UINT32_ACCESS_ONCE(other_xids[pgxactoff]);
uint8 statusFlags;
- Assert(allProcs[arrayP->pgprocnos[pgxactoff]].pgxactoff == pgxactoff);
+ Assert(pgxactoffs[arrayP->pgprocnos[pgxactoff]] == pgxactoff);
/*
* If the transaction has no XID assigned, we can skip it; it
@@ -2583,7 +2585,7 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc)
MyProc->xmin = TransactionXmin = xmin;
MyProc->statusFlags = (MyProc->statusFlags & ~PROC_XMIN_FLAGS) |
(proc->statusFlags & PROC_XMIN_FLAGS);
- ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
+ ProcGlobal->statusFlags[GetMyXactOffPGProc()] = MyProc->statusFlags;
result = true;
}
@@ -4032,7 +4034,7 @@ XidCacheRemoveRunningXids(TransactionId xid,
*/
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
- mysubxidstat = &ProcGlobal->subxidStates[MyProc->pgxactoff];
+ mysubxidstat = &ProcGlobal->subxidStates[GetMyXactOffPGProc()];
/*
* Under normal circumstances xid and xids[] will be in increasing order,
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 1ac25068d62..5ae4922128e 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -165,6 +165,7 @@ ProcGlobalShmemRequest(void *arg)
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->xids)));
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->subxidStates)));
size = add_size(size, mul_size(TotalProcs, sizeof(*ProcGlobal->statusFlags)));
+ size = add_size(size, mul_size(TotalProcs, sizeof(int)));
ProcGlobalAllProcsShmemSize = size;
ShmemRequestStruct(.name = "PGPROC structures",
.size = ProcGlobalAllProcsShmemSize,
@@ -273,7 +274,10 @@ ProcGlobalShmemInit(void *arg)
ProcGlobal->statusFlags = (uint8 *) ptr;
ptr = ptr + (TotalProcs * sizeof(*ProcGlobal->statusFlags));
- /* make sure we didn't overflow */
+ ProcGlobal->pgxactoffs = (int *) ptr;
+ ptr = (char *) ptr + TotalProcs * sizeof(int);
+
+ /* make sure wer didn't overflow */
Assert((ptr > (char *) procs) && (ptr <= (char *) procs + requestSize));
/*
@@ -1498,7 +1502,7 @@ ProcSleep(LOCALLOCK *locallock)
* the lock held, which is much more undesirable.
*/
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
- statusFlags = ProcGlobal->statusFlags[autovac->pgxactoff];
+ statusFlags = ProcGlobal->statusFlags[GetXactOffPGProc(autovac)];
lockmethod_copy = lock->tag.locktag_lockmethodid;
locktag_copy = lock->tag;
LWLockRelease(ProcArrayLock);
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 3e1d1fad5f9..fee9deb8f3a 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -210,9 +210,6 @@ typedef struct PGPROC
Oid tempNamespaceId; /* OID of temp schema this backend is
* using */
- int pgxactoff; /* offset into various ProcGlobal->arrays with
- * data mirrored from this PGPROC */
-
uint8 statusFlags; /* this backend's status flags, see PROC_*
* above. mirrored in
* ProcGlobal->statusFlags[pgxactoff] */
@@ -445,6 +442,7 @@ typedef struct PROC_HDR
{
/* Array of PGPROC structures (not including dummies for prepared txns) */
PGPROC *allProcs;
+ int *pgxactoffs;
/* Array mirroring PGPROC.xid for each PGPROC currently in the procarray */
TransactionId *xids;
@@ -509,6 +507,8 @@ extern PGDLLIMPORT PGPROC *PreparedXactProcs;
*/
#define GetPGProcByNumber(n) (&ProcGlobal->allProcs[(n)])
#define GetNumberFromPGProc(proc) ((proc) - &ProcGlobal->allProcs[0])
+#define GetXactOffPGProc(proc) (ProcGlobal->pgxactoffs[(proc) - &ProcGlobal->allProcs[0]])
+#define GetMyXactOffPGProc() (GetXactOffPGProc(MyProc))
/*
* We set aside some extra PGPROC structures for "special worker" processes,
--
2.43.0
view thread (18+ messages) latest in thread
Message-ID: <65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru>
Permalink: ../65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru/
Also on: postgresql.org/message-id/65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru
copy link · copy postgr.es · copy git am
reply Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: m.melnikov@postgrespro.ru, a.potapov@postgrespro.ru, boekewurm+postgres@gmail.com
Subject: Re: Init connection time grows quadratically
In-Reply-To: <65d0e5b2-2a40-4b12-be04-0804912d2daf@postgrespro.ru>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox