Utilisation de pgbench
Créer une base pgbench sur laquelle seront effectués
les premiers tests, et l’initialiser avec 13,5 millions de lignes dans
la table pgbench_accounts
:
# en tant qu'utilisateur postgres
createdb pgbench
/usr/pgsql-17/bin/pgbench -i -s 135 pgbench
Noter que le nom de la base (ici en dernier paramètre) ne doit pas
être précédé de -d
.
La base obtenue fait 2 Go.
Simuler l’utilisation de la base pgbench par 3
clients simultanés, chacun effectuant par exemple 1000
transactions :
# en tant que postgres
/usr/pgsql-17/bin/pgbench -c 3 -t 1000 -n -P1 pgbench
…
progress: 1.0 s, 1081.9 tps, lat 2.743 ms stddev 3.450, 0 failed
progress: 2.0 s, 1127.0 tps, lat 2.653 ms stddev 1.112, 0 failed
…
number of transactions per client: 1000
number of transactions actually processed: 3000/3000
number of failed transactions: 0 (0.000%)
latency average = 2.691 ms
latency stddev = 2.933 ms
initial connection time = 8.860 ms
tps = 1111.524022 (without initial connection time)
(Les chiffres peuvent bien sûr varier fortement selon la machine et
la configuration.)
De vrais tests devraient être beaucoup plus longs !
Simuler la même chose, en ajoutant le paramètre -C
pour
forcer une connexion à chaque transaction. Comparer la latence et le
nombre de transactions par seconde.
L’exécution est ici beaucoup plus longue :
/usr/pgsql-17/bin/pgbench -c 3 -t 1000 -n -P1 -C pgbench
…
progress: 7.0 s, 360.8 tps, lat 6.083 ms stddev 1.569, 0 failed
progress: 8.0 s, 342.4 tps, lat 6.392 ms stddev 1.943, 0 failed
…
number of transactions actually processed: 3000/3000
number of failed transactions: 0 (0.000%)
latency average = 6.021 ms
latency stddev = 1.876 ms
average connection time = 1.855 ms
tps = 358.071199 (including reconnection times)
La connexion systématique a diminué les performances des deux tiers.
Ce serait encore pire s’il y avait un réseau entre PostgreSQL et client
pgbench
.
On veut simuler l’utilisation de la base pgbench par
3 utilisateurs effectuant 10 fois la sélection des comptes dont le solde
est positif dans la table pgbench_accounts
.
Créer un fichier query.sql
contenant la requête suivante
:
SELECT aid,bid,abalance
FROM pgbench_accounts
WHERE abalance > 0 ;
Lancer la commande :
/usr/pgsql-17/bin/pgbench -c 3 -t 10 -n -P1 -f query.sql pgbench
…
latency average = 1578.937 ms
latency stddev = 13.462 ms
initial connection time = 5.789 ms
tps = 1.899930 (without initial connection time)
On voit ainsi que pgbench
permet de créer ses propres
requêtes de test.
Influence de fsync
et synchronous_commit
pgbench
peut servir à mesurer l’impact d’un paramètre de
configuration sur les performances du système.
Positionner le paramètre fsync
à off
dans
le fichier postgresql.conf
et redémarrer PostgreSQL.
(Ne jamais faire cela en production, bien sûr.)
Relancer :
systemctl restart postgresql-17
Simuler l’utilisation de la base pgbench par 3
clients simultanés, chacun effectuant par exemple 1000
transactions :
/usr/pgsql-17/bin/pgbench -c 3 -t 1000 -n -P1 pgbench
Comparer avec le premier test précédent.
…
latency average = 0.424 ms
latency stddev = 0.173 ms
initial connection time = 6.861 ms
tps = 6837.809439 (without initial connection time)
On est sur des valeurs beaucoup plus élevés que le premier test. La
synchronisation à chaque COMMIT
est très coûteuse et on l’a
désactivée. Mais fsync
à off
provoquerait une
corruption en cas d’arrêt brutal et ne peut être conservé.
Rétablir fsync
à on
, puis relancer
PostgreSQL.
sudo systemctl restart postgresql-17
Refaire le même test avec synchronous_commit
à
off
dans la session :
PGOPTIONS = '-c synchronous_commit=off' \
/usr/pgsql-17/bin/pgbench -c 3 -t 1000 pgbench
La variable d’environnement est un moyen de changer la configuration
depuis le shell quand on ne peut changer la configuration de la session
avec SET
.
…
latency average = 0.473 ms
initial connection time = 13.312 ms
tps = 6344.453045 (without initial connection time)
Le paramètre synchronous_commit
à off
« regroupe » les synchronisations, et permet de récupérer une bonne
partie des performances perdues avec fsync
à
on
, si l’application le permet : en cas d’arrêt brutal, il
reste le risque de perdre jusqu’à 600 ms de données pourtant committées
(mais sans risque de corruption). Cette perte de données est parfois
acceptable, parfois non. Ce choix peut être opéré transaction par
transaction en changeant synchronous_commit
dans la
session.
Noter à nouveau qu’un test rigoureux devrait durer beaucoup plus
longtemps, sur plus de transactions, et tenir compte des effets de
cache.
Paramétrage de l’overcommit
Ce TP a été testé sur une machine avec 3,5 Go de RAM et pas de swap à
l’origine. Adaptez à votre machine.
Avec free -m
, vérifiez que vous avez du swap. Si ce
n’est pas le cas, créez un fichier de swap de 1 Go.
Si free -m
renvoie ceci, vous n’avez pas de
swap :
total used free shared buff/cache available
Mem: 3647 199 1984 53 1463 3168
Swap: 0 0 0
Comme il est conseillé d’avoir un swap minimal, le créer
ainsi :
sudo fallocate --length 1GiB /swapfile
sudo chmod 0600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon --summary /swapfile
Au final nous obtenons ceci :
$ free -m
total used free shared buff/cache available
Mem: 3647 285 308 148 3053 2982
Swap: 1023 0 1023
Dans une autre session, générer de l’activité avec
pgbench
. (Si elle n’est pas déjà là, créer une base
pgbench de taille 135 ou supérieure.) Laisser tourner
indéfiniment dans cette session.
Pour créer la base pgbench au besoin :
# en tant qu'utilisateur postgres ; durée totale environ 1 minute
createdb --echo pgbench
/usr/pgsql-17/bin/pgbench pgbench -i -s 135
Pour générer de l’activité (ici 3 clients) :
# en tant qu'utilisateur postgres
# (on peut monter au-delà de 3 clients)
/usr/pgsql-17/bin/pgbench pgbench -c3 -T900 -P1 -n
pgbench (17.1)
progress: 1.0 s, 322.0 tps, lat 9.070 ms stddev 5.105, 0 failed
progress: 2.0 s, 315.0 tps, lat 9.511 ms stddev 3.501, 0 failed
progress: 3.0 s, 311.0 tps, lat 9.582 ms stddev 10.133, 0 failed
progress: 4.0 s, 349.0 tps, lat 8.647 ms stddev 3.215, 0 failed
progress: 5.0 s, 325.0 tps, lat 9.199 ms stddev 4.445, 0 failed
Dans une nouvelle session, surveiller en permanence la mémoire :
while true ; do sleep 1 ; free -m ; done
total used free shared buff/cache available
Mem: 3647 263 110 143 3274 3008
Swap: 1023 54 969
En simplifiant :
total
indique les 3,5 Go de RAM ;
used
correspond au système et à ce qu’utilise
PostgreSQL
dont 128 Mo de shared_buffers
(valeur par défaut
ici) ;
available
est la mémoire disponible, donc le
cache.
Noter que la base de données (2 Go) tient dans le cache de Linux mais
pas dans les shared buffers .
Consulter la configuration en place de l’overcommit .
…
vm.overcommit_memory = 0
vm.overcommit_ratio = 50
…
Ces valeurs sont celles par défaut sur les distributions
courantes.
Dans une session psql
, générer un tri en RAM bien plus
gros que la mémoire disponible. Surveiller l’évolution sur la RAM et le
débit des transactions de la session pgbench
(attendre une
minute ou deux suivant la machine).
SET work_mem = '1000GB' ;
-- DANGEREUX ! Tri de 250 Go en RAM !
EXPLAIN (ANALYZE ) SELECT i FROM generate_series (1 ,3e9 ) i
ORDER BY i DESC ;
Quels sont les symptômes dans les différentes sessions et les traces
de PostgreSQL et du système ?
Les symptômes sont nombreux et n’apparaissent pas
systématiquement :
l’ordre SQL précédent tombe généralement en erreur et la session est
perdue :
la connexion au serveur a été coupée de façon inattendue
Le serveur s'est peut-être arrêté anormalement avant ou durant le
traitement de la requête.
La connexion au serveur a été perdue. Tentative de réinitialisation : Échec.
La connexion au serveur a été perdue. Tentative de réinitialisation : Échec.
!?>
la session pgbench
ralentit fortement, et tombe
généralement en erreur aussi :
…
progress: 34.1 s, 1.7 tps, lat 627.322 ms stddev 0.038, 0 failed
progress: 35.1 s, 0.0 tps, lat 0.000 ms stddev 0.000, 0 failed
progress: 36.8 s, 0.0 tps, lat 0.000 ms stddev 0.000, 0 failed
progress: 38.5 s, 0.0 tps, lat 0.000 ms stddev 0.000, 0 failed
progress: 39.0 s, 5.7 tps, lat 5782.505 ms stddev 151.744, 0 failed
progress: 41.5 s, 0.0 tps, lat 0.000 ms stddev 0.000, 0 failed
progress: 42.0 s, 0.0 tps, lat 0.000 ms stddev 0.000, 0 failed
…
WARNING: terminating connection because of crash of another server process
DETAIL: The postmaster has commanded this server process to roll back
the current transaction and exit, because another server process exited
abnormally and possibly corrupted shared memory.
HINT: In a moment you should be able to reconnect to the database
and repeat your command.
pgbench: error: client 0 aborted in command 5 (SQL) of script 0;
perhaps the backend died while processing
…
pgbench: error: client 2 aborted in command 10 (SQL) of script 0;
perhaps the backend died while processing
pgbench: error: client 1 aborted in command 10 (SQL) of script 0;
perhaps the backend died while processing
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 135
query mode: simple
number of clients: 3
number of threads: 1
maximum number of tries: 1
duration: 900 s
number of transactions actually processed: 5432
number of failed transactions: 0 (0.000%)
latency average = 58.651 ms
latency stddev = 1579.195 ms
initial connection time = 17.279 ms
tps = 51.090504 (without initial connection time)
pgbench: error: Run was aborted; the above results are incomplete.
Noter la mention « The postmaster has commanded this server
process to roll back the current transaction and exit, because another
server process exited abnormally and possibly corrupted shared
memory ».
free
indique que la mémoire utilisable
(available
) s’est réduite, ainsi que cache
, ce
qui est normal car used
indique que presque toute la RAM
est utilisée.
total used free shared buff/cache available
Mem: 3647 3331 103 139 213 26
Swap: 1023 960 63
Noter que le swap s’est rempli avec nos données triées,
alors que nous avions demandé un tri en mémoire.
Cette opération d’écriture dans le swap indique que la
mémoire est déjà saturée, et le cache déjà réduit. L’écriture va
également alourdir les entrées-sorties.
Un cache surdimensionné allonge encore la durée du
ralentissement.
Avec des disques mécaniques, c’est encore plus long.
LOG: could not receive data from client: Connection reset by peer
LOG: could not receive data from client: Connection reset by peer
LOG: unexpected EOF on client connection with an open transaction
LOG: unexpected EOF on client connection with an open transaction
LOG: could not send data to client: Broken pipe
FATAL: connection to client lost
LOG: server process (PID 21071) was terminated by signal 9: Killed
DETAIL: Failed process was running: EXPLAIN (ANALYZE) SELECT i
FROM generate_series (1,3e9) i
ORDER BY i DESC ;
LOG: terminating any other active server processes
LOG: all server processes terminated; reinitializing
LOG: database system was interrupted; last known up at 2024-05-06 19:11:52 CEST
FATAL: the database system is in recovery mode
LOG: database system was not properly shut down; automatic recovery in progress
LOG: redo starts at 0/E80042A8
…
LOG: database system is ready to accept connections
On y lit :
sudo dmesg
# alternative :
# sudo journalctl -k -n 130
…
Adding 1048572k swap on /swapfile. Priority:-2 extents:95 across:3491508k FS
postgres invoked oom-killer: gfp_mask=0x6200ca(GFP_HIGHUSER_MOVABLE), order=0,
oom_score_adj=0
…
Mem-Info:
active_anon:60815 inactive_anon:818069 isolated_anon:0
active_file:0 inactive_file:56 isolated_file:0
unevictable:0 dirty:0 writeback:0
slab_reclaimable:7732 slab_unreclaimable:10962
mapped:35416 shmem:35635 pagetables:5149 bounce:0
free:20749 free_pcp:884 free_cma:0
…
…
106213 total pagecache pages
69943 pages in swap cache
Swap cache stats: add 517156, delete 447213, find 7357/9783
Free swap = 0kB
Total swap = 1048572kB
1047069 pages RAM
0 pages HighMem/MovableOnly
113258 pages reserved
0 pages hwpoisoned
Tasks state (memory values in pages):
uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name
0 625 24466 720 237568 236 0 systemd-journal
0 654 24758 380 200704 334 -1000 systemd-udevd
32 728 16814 134 172032 48 0 rpcbind
0 730 32730 102 139264 113 -1000 auditd
0 732 12163 93 147456 2 0 sedispatch
2 771 77274 171 225280 105 0 rngd
81 773 16170 169 147456 60 -900 dbus-daemon
0 774 33817 138 167936 38 0 qemu-ga
0 775 31244 115 143360 47 0 irqbalance
0 776 20886 297 200704 283 0 systemd-logind
992 779 35021 137 176128 66 0 chronyd
0 817 149191 503 401408 232 0 NetworkManager
0 823 192145 2200 442368 2485 0 tuned
0 833 78725 87 192512 79 0 gssproxy
998 879 419423 436 352256 1309 0 polkitd
0 1050 70813 378 204800 2075 0 rsyslogd
0 1076 58908 161 106496 55 0 crond
0 1077 54903 25 65536 4 0 agetty
0 1078 54813 27 73728 3 0 agetty
0 1828 19164 38 184320 196 -1000 sshd
1001 5607 22393 244 212992 98 0 systemd
1001 5610 58736 212 327680 1021 0 (sd-pam)
1001 5650 60090 106 106496 129 0 tmux: server
1001 5651 56270 135 81920 1 0 bash
0 13055 34207 119 307200 210 0 sshd
1001 13058 34207 134 307200 193 0 sshd
1001 13059 56270 3 77824 141 0 bash
0 16555 94770 50 98304 35 0 gpg-agent
0 16593 94770 48 98304 36 0 gpg-agent
0 16632 94770 48 98304 36 0 gpg-agent
0 16671 94770 48 98304 35 0 gpg-agent
0 16710 94770 48 114688 35 0 gpg-agent
0 16749 94770 83 102400 1 0 gpg-agent
26 17768 125350 2076 299008 267 -1000 postgres
26 17769 88301 45 229376 318 0 postgres
26 17770 125484 29199 536576 321 0 postgres
26 17771 125383 32478 528384 300 0 postgres
26 17773 125383 1171 253952 306 0 postgres
26 17774 125752 398 278528 349 0 postgres
26 17775 125747 216 262144 394 0 postgres
1001 18313 83277 41 282624 227 0 sudo
26 18315 56227 138 90112 18 0 bash
0 18739 34207 164 303104 166 0 sshd
1001 18744 34207 162 299008 166 0 sshd
1001 18745 56270 84 86016 61 0 bash
0 20944 34207 306 315392 23 0 sshd
1001 20947 34207 285 307200 42 0 sshd
1001 20948 56270 86 73728 59 0 bash
1001 21015 83277 151 290816 116 0 sudo
26 21017 68623 227 172032 14 0 psql
26 21071 1231817 765295 8413184 245955 0 postgres
1001 21284 55992 151 86016 0 0 watch
26 21303 14128 180 147456 0 0 pgbench
26 21305 125886 15729 544768 412 0 postgres
26 21306 125886 16012 544768 415 0 postgres
26 21307 125886 15635 544768 413 0 postgres
1001 21444 55992 151 73728 0 0 watch
1001 21445 10459 58 114688 0 0 free
26 21450 125383 191 245760 249 0 postgres
0 21459 12214 49 118784 0 0 sshd
oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,
global_oom,task_memcg=/system.slice/postgresql-17.service,task=postgres,
pid=21071,uid=26
Out of memory: Killed process 21071 (postgres) total-vm:4927268kB,
anon-rss:3057476kB, file-rss:4kB, shmem-rss:3700kB, UID:26 pgtables:8216kB
oom_score_adj:0
On trouvera ci-dessus :
le déclenchement de l’OOM killer ;
la mention de la saturation du swap ;
la liste des processus : noter le 21071 (notre requête explosive) et
le 17768 (le processus principal, d’ailleurs encore présent après le
crash) ;
à la fin le choix de Linux de tuer le processes 21071.
La cause première est l’épuisement complet de la mémoire, Linux
n’ayant jamais refusé de réservation mémoire. Une fois RAM et
swap épuisés, il a bien fallu éliminer un processus. Sur une
machine dédiée à PostgreSQL, c’est forcément un de ses processus.
Ici, le processus principal est protégé (noter ci-dessus le score de
-1000, qui provient de la définition du service). Comme le processus
principal était encore là, il a constaté la disparition brutale de son
processus fils, et a tout redémarré par peur d’une corruption de la
mémoire partagée.
L’arrêt des connexions (session psql
et
pgbench
) est la conséquence.
Changer le paramétrage mémoire pour éviter le plantage.
La nouvelle configuration mémoire est à mettre en place ainsi :
sudo vi /etc/sysctl.conf
# alternativement : un fichier /etc/sysctl.d/99-overcommit.conf
Dans ce fichier :
# Protection d'environ 10% de la mémoire
vm.overcommit_memory = 2
vm.overcommit_ratio = 60
# réduction de la propension à swapper
vm.swappiness = 10
Sur des machines mieux dotées en RAM et avec peu de swap,
vm.overcommit_ratio
vaut généralement 80.
# activation de la nouvelle configuration
sudo sysctl --system
…
* Applying /etc/sysctl.conf ...
vm.swappiness = 10
vm.overcommit_memory = 2
vm.overcommit_ratio = 60
Consultation de la nouvelle configuration mémoire :
MemTotal: 3735244 kB
MemFree: 2598780 kB
MemAvailable: 3204396 kB
Buffers: 0 kB
Cached: 967368 kB
SwapCached: 7396 kB
Active: 158296 kB
Inactive: 843860 kB
Active(anon): 24392 kB
Inactive(anon): 190468 kB
Active(file): 133904 kB
Inactive(file): 653392 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 1048572 kB
SwapFree: 996324 kB
Dirty: 4 kB
Writeback: 0 kB
AnonPages: 29708 kB
Mapped: 188868 kB
Shmem: 180072 kB
KReclaimable: 32156 kB
Slab: 74836 kB
SReclaimable: 32156 kB
SUnreclaim: 42680 kB
KernelStack: 2576 kB
PageTables: 9228 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3289716 kB
Committed_AS: 674624 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 17640 kB
VmallocChunk: 0 kB
Percpu: 1888 kB
HardwareCorrupted: 0 kB
AnonHugePages: 2048 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
FileHugePages: 0 kB
FilePmdMapped: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
Hugetlb: 0 kB
DirectMap4k: 156152 kB
DirectMap2M: 4032512 kB
DirectMap1G: 2097152 kB
On y voit notamment :
grep -E '^(Swap|Commit)' /proc/meminfo
SwapCached: 7396 kB
SwapTotal: 1048572 kB
SwapFree: 996324 kB
CommitLimit: 3289716 kB
Committed_AS: 679524 kB
CommitLimit
(l’allocation maximale) est bien le résultat
du calcul :
CommitLimit = RAM × 60 % + swap = 3735244 × 60 % + 1048572 =
3289718
(des écarts de quelques kilooctets sont normaux).
Base inactive, il est normal que la RAM allouée
(CommittedAS
) soit basse.
Relancer la requête consommatrice de RAM en suivant à nouveau la
consommation mémoire et les traces. Ne pas hésiter à tester plusieurs
fois.
Le traçage de la mémoire peut se faire de plusieurs manières :
while true ; do sleep 1 ; free -m ; done
total used free shared buff/cache available
Mem: 3647 134 2536 175 976 3128
Swap: 1023 51 972
while true ; do sleep 1; watch -n 0.5 "grep -E '^(Swap|Commit)' /proc/meminfo" ; done
ou
Le swap est à peu près vide, la moitié de la mémoire
complètement libre.
On relance l’activité pgbench
:
# en tant qu'utilisateur postgres
/usr/pgsql-17/bin/pgbench pgbench -c3 -T900 -P1 -n
Sous psql
:
SET work_mem = '1000GB' ;
EXPLAIN (ANALYZE ) SELECT i FROM generate_series (1 ,3e9 ) i
ORDER BY i DESC ;
Ce dernier ordre tombe avec cette seule erreur :
ERROR: out of memory
DÉTAIL : Failed on request of size 23 in memory context "ExecutorState".
Par contre la session reste utilisable.
pgbench
continue de tourner normalement :
progress: 215.0 s, 242.0 tps, lat 18.192 ms stddev 64.768, 0 failed
progress: 216.0 s, 223.9 tps, lat 13.435 ms stddev 8.988, 0 failed
progress: 217.0 s, 252.1 tps, lat 11.852 ms stddev 4.051, 0 failed
progress: 218.0 s, 251.0 tps, lat 11.960 ms stddev 4.252, 0 failed
Il est difficile de capturer des valeurs juste avant l’erreur avec un
pas d’une seconde, mais par exemple /proc/meminfo
contient
ceci :
SwapCached: 6072 kB
SwapTotal: 1048572 kB
SwapFree: 981316 kB
CommitLimit: 3289716 kB
Committed_AS: 3144000 kB
Committed_AS
(mémoire consommée et swap ) est
alors très proche de CommitLimit
.
Ou encore, free -m
a retourné ceci :
total used free shared buff/cache available
Mem: 3647 2405 159 164 1083 868
Swap: 1023 65 958
ou encore avec sar -rh 1
(sortie modifiée pour
l’affichage) :
kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit…
1,0G 3,0G 2,6G 71,8% 0,0k 2,4G 707,2M 15,1%…
1,0G 3,0G 2,6G 71,9% 0,0k 2,4G 707,2M 15,1%…
…
595,7M 2,9G 3,0G 83,7% 0,0k 2,7G 852,0M 18,2%…
449,5M 2,8G 3,1G 87,7% 0,0k 2,7G 1004,0M 21,5%…
…
kbmemfree kbavail kbmemused %memused kbbuffers kbcached kbcommit %commit…
101,9M 1,8G 3,5G 97,2% 0,0k 2,0G 2,0G 43,1%…
99,8M 1,7G 3,5G 97,3% 0,0k 1,9G 2,1G 45,1%…
105,4M 1,6G 3,5G 97,1% 0,0k 1,8G 2,2G 47,3%…
96,8M 1,4G 3,5G 97,3% 0,0k 1,7G 2,5G 55,1%…
106,0M 1,3G 3,5G 97,1% 0,0k 1,6G 2,6G 57,5%…
103,1M 1,2G 3,5G 97,2% 0,0k 1,4G 2,7G 60,0%…
103,7M 1,1G 3,5G 97,2% 0,0k 1,3G 2,8G 62,4%…
115,2M 1019,1M 3,4G 96,8% 0,0k 1,2G 3,0G 64,8%…
102,9M 925,4M 3,5G 97,2% 0,0k 1,1G 3,0G 66,7%…
Ces outils n’ont pas forcément les mêmes calculs de répartition de la
mémoire, mais on peut constater dans les trois cas :
une consommation mémoire en hausse ;
un swap à peu près inutilisé ;
un cache disque qui n’est pas complètement vidé.
Dans les traces de PostgreSQL apparaît la répartition mémoire du
processus tombé en erreur :
TopPortalContext: 8192 total in 1 blocks; 7664 free (0 chunks); 528 used
PortalHoldContext: 24624 total in 2 blocks; 7400 free (0 chunks); 17224 used
PortalContext: 16384 total in 5 blocks; 5464 free (1 chunks); 10920 used: <unnamed>
ExecutorState: 2553282608 total in 254 blocks; 2224 free (12 chunks); 2553280384 used
SRF multi-call context: 1024 total in 1 blocks; 504 free (1 chunks); 520 used
TupleSort main: 32816 total in 2 blocks; 4928 free (0 chunks); 27888 used
TupleSort sort: 8192 total in 1 blocks; 7928 free (0 chunks); 264 used
Caller tuples: 8192 total in 1 blocks (0 chunks); 7984 free (0 chunks); 208 used
Table function arguments: 8192 total in 1 blocks; 7856 free (0 chunks); 336 used
ExprContext: 8192 total in 1 blocks; 7904 free (0 chunks); 288 used
Relcache by OID: 16384 total in 2 blocks; 3584 free (2 chunks); 12800 used
CacheMemoryContext: 524288 total in 7 blocks; 98664 free (0 chunks); 425624 used
index info: 2048 total in 2 blocks; 584 free (2 chunks); 1464 used: pg_db_role_setting_databaseid_rol_index
…
index info: 2048 total in 2 blocks; 912 free (0 chunks); 1136 used: pg_authid_rolname_index
WAL record construction: 50200 total in 2 blocks; 6376 free (0 chunks); 43824 used
PrivateRefCount: 8192 total in 1 blocks; 2648 free (0 chunks); 5544 used
MdSmgr: 8192 total in 1 blocks; 7688 free (0 chunks); 504 used
LOCALLOCK hash: 8192 total in 1 blocks; 592 free (0 chunks); 7600 used
GUCMemoryContext: 24576 total in 2 blocks; 12240 free (4 chunks); 12336 used
GUC hash table: 32768 total in 3 blocks; 12704 free (5 chunks); 20064 used
Timezones: 104112 total in 2 blocks; 2648 free (0 chunks); 101464 used
ErrorContext: 8192 total in 1 blocks; 7928 free (0 chunks); 264 used
Grand total: 2554573880 bytes in 448 blocks; 346152 free (151 chunks); 2554227728 used
ERROR: out of memory
DETAIL: Failed on request of size 23 in memory context "ExecutorState".
STATEMENT: EXPLAIN (ANALYZE) SELECT i FROM generate_series (1,3e9) i
ORDER BY i DESC ;
Noter à la fin le GrandTotal
à 2,5 Go.
Contrairement à la configuration par défaut, la session s’est vu
refuser par le noyau la réservation de mémoire au moment où
CommittedAS
dépassait CommitLimit
. PostgreSQL
sait gérer ce genre d’erreur et a arrêté la requête, sans tout
redémarrer.