Medir los costos de memoria para los procesos de Postgres

Esta es una traducciΓ³n libre de una publicaciΓ³n de uno de los desarrolladores de Postgres mΓ‘s sΓ³lidos, Andres Freund. AdemΓ‘s del hecho de que el desarrollador es fuerte, el artΓ­culo tambiΓ©n es bastante interesante y revela los detalles de cΓ³mo funciona el sistema operativo Linux.





Es bastante comΓΊn escuchar afirmaciones de que las conexiones posteriores a Grid usan demasiada memoria. Esto se menciona a menudo cuando se compara el modelo de proceso para manejar las conexiones del cliente con otro modelo, donde cada conexiΓ³n se sirve en un hilo separado.





En cuanto a mΓ­, hay mucho que discutir aquΓ­. AdemΓ‘s, puede realizar varias mejoras y reducir el uso de memoria.





Creo que esta preocupaciΓ³n por la sobrecarga de la memoria se debe a una razΓ³n comΓΊn, que es que la forma mΓ‘s sencilla de medir el consumo de memoria a travΓ©s de utilidades como top y ps es bastante engaΓ±osa.





De hecho, es especialmente difΓ­cil medir cΓ³mo aumenta la memoria utilizada con cada nueva conexiΓ³n.





En esta publicaciΓ³n, hablarΓ© sobre la ejecuciΓ³n de Postgres en Linux, porque es en esta direcciΓ³n en la que tengo mΓ‘s experiencia.





Y antes de continuar, quiero enfatizar que con una mediciΓ³n precisa y precisa, una conexiΓ³n tiene una sobrecarga de menos de 2MiB (ver las conclusiones al final del post).





Primera vista

, , ( ). (huge pages), . . , Postgres:





andres@awork3:~$ psql
postgres[2003213][1]=# SELECT pg_backend_pid();
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ pg_backend_pid β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚        2003213 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)

andres@awork3:~/src/postgresql$ ps -q 2003213 -eo pid,rss
    PID   RSS
2003213 16944
      
      



16MiB.





!?! ,

. , pgprewarm, (shared buffers):





postgres[2003213][1]=# SHOW shared_buffers ;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ shared_buffers β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 16GB           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)

postgres[2003213][1]=# SELECT SUM(pg_prewarm(oid, 'buffer')) FROM pg_class WHERE relfilenode <> 0;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  sum   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 383341 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜

andres@awork3:~$ ps -q 2003213 -eo pid,rss
    PID   RSS
2003213 3169144
      
      



3GB. , , . , :





postgres[2003213][1]=# SELECT pg_size_pretty(SUM(pg_relation_size(oid))) FROM pg_class WHERE relfilenode <> 0;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ pg_size_pretty β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 2995 MB        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)
      
      



, , :





postgres[3244960][1]=# SELECT sum(abalance) FROM pgbench_accounts ;
β”Œβ”€β”€β”€β”€β”€β”
β”‚ sum β”‚
β”œβ”€β”€β”€β”€β”€β”€
β”‚   0 β”‚
β””β”€β”€β”€β”€β”€β”˜
(1 row)

andres@awork3:~/src/postgresql$ ps -q 3244960 -eo pid,rss
    PID   RSS
3244960 2700372
      
      



, Postgres 3GB 2.7GB . , huge_pages=off, ps (shred - ) , . .





- 4KiB, , 2MiB.





, , . Debian wiki .





huge_pages=on, . , " ":





andres@awork3:~$ ps -q 3245907 -eo pid,rss
    PID   RSS
3245907  7612
      
      



, 7MiB. (page table) , - , 512 (4KiB * 512 = 2MiB).





:





postgres[3245843][1]=# ;SELECT SUM(pg_prewarm(oid, 'buffer')) FROM pg_class WHERE relfilenode <> 0;
…
postgres[3245851][1]=# SELECT sum(abalance) FROM pgbench_accounts ;
…

andres@awork3:~$ ps -q 3245907,3245974 -eo pid,rss
    PID   RSS
3245907 12260
3245974  8936
      
      



, 12MiB 9MiB , 3GiB 2.7GiB.





.





, Linux , , : RSS ps top.





4.5, /proc/$pid/status :





  • VmRSS . (VmRSS = RssAnon + RssFile + RssShmem)





  • RssAnon .





  • RssFile .





  • RssShmem ( SysV shm, tmpfs )





andres@awork3:~$ grep -E '^(Rss|HugetlbPages)' /proc/3247901/status
RssAnon:	    2476 kB
RssFile:	    5072 kB
RssShmem:	    8520 kB
HugetlbPages:	       0 kB

postgres[3247901][1]=# SELECT SUM(pg_prewarm(oid, 'buffer')) FROM pg_class WHERE relfilenode <> 0;

andres@awork3:~$ ps -q 3247901 -eo pid,rss
    PID   RSS
3247901 3167164

andres@awork3:~$ grep -E '^(Rss|HugetlbPages)' /proc/3247901/status
RssAnon:	    3148 kB
RssFile:	    9212 kB
RssShmem:	 3154804 kB
HugetlbPages:	       0 kB
      
      



RssAnon "" , .. . RssFile , postgres. RssShmem .





ps - - .





, huge_pages=on:





andres@awork3:~$ grep -E '^(Rss|HugetlbPages)' /proc/3248101/status
RssAnon:	    2476 kB
RssFile:	    4664 kB
RssShmem:	       0 kB
HugetlbPages:	  778240 kB

postgres[3248101][1]=# SELECT SUM(pg_prewarm(oid, 'buffer')) FROM pg_class WHERE relfilenode <> 0;

andres@awork3:~$ grep -E '^(Rss|HugetlbPages)' /proc/3248101/status
RssAnon:	    3136 kB
RssFile:	    8756 kB
RssShmem:	       0 kB
HugetlbPages:    3846144 kB
      
      



, . :





, RssFile - (Postgres mmap() - ). .





, RssAnon . ps , postgres ( postmaster). Linux ( fork()), Copy-on-Write , .





, . , 4.14 ( ) /proc/$pid/smaps_rollup . Pss " " ( smaps_rollups Pss ). , .





postgres[2004042][1]=# SELECT SUM(pg_prewarm(oid, 'buffer')) FROM pg_class WHERE relfilenode <> 0;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  sum   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 383341 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)

postgres[2004042][1]=# SHOW huge_pages ;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ huge_pages β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ off        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)

andres@awork3:~$ grep ^Pss /proc/2004042/smaps_rollup
Pss:             3113967 kB
Pss_Anon:           2153 kB
Pss_File:           3128 kB
Pss_Shmem:       3108684 kB
      
      



Pss_Anon , Pss_File , Pss_Shmem ( ) .





, . pgbench (scale 1000, -S -M prepared -c 1024) :





postgres[2004042][1]=# SELECT count(*) FROM pg_stat_activity ;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”
β”‚ count β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1030 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)

postgres[2004042][1]=# SELECT pid FROM pg_stat_activity WHERE application_name = 'pgbench' ORDER BY random() LIMIT 1;
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   pid   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 3249913 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
(1 row)

andres@awork3:~$ grep ^Pss /proc/3249913/smaps_rollup
Pss:                4055 kB
Pss_Anon:           1185 kB
Pss_File:              6 kB
Pss_Shmem:          2863 kB
      
      



huge_pages=on:





andres@awork3:~$ grep ^Pss /proc/2007379/smaps_rollup
Pss:                1179 kB
Pss_Anon:           1173 kB
Pss_File:              6 kB
Pss_Shmem:             0 kB
      
      



Pss , . , . `/proc/$pid/status`.





, , VmPTE ( ) , Vm* , VmStk copy-on-write.





, huge_pages=off:





andres@awork3:~$ grep ^VmPTE /proc/2004042/status
VmPTE:      6480 kB
      
      



huge_pages=on:





VmPTE:	     132 kB
      
      



- , , .





Con base en estas mediciones, podemos imaginar que un proceso que realiza una carga OLTP de solo lectura bastante simple tiene una sobrecarga de aproximadamente 7.6MiB con huge_pages = off y aproximadamente 1.3MiB con huge_pages = on incluyendo Pss_Anon en VmPTE.





Incluso si imaginamos que hay algΓΊn tipo de sobrecarga "invisible" y una gran cantidad de datos en el bΓΊfer, etc., creo que volveremos a mi declaraciΓ³n anterior de que la sobrecarga de conexiΓ³n es inferior a 2MiB.





Suplemento del traductor. Postgres 14 presenta una nueva vista pg_backend_memory_contexts que muestra la utilizaciΓ³n de memoria detallada por el proceso actual desde la perspectiva del propio Postgres.








All Articles