Monday, July 28, 2025

How to list the postgres processes running on your server and what their jobs are

A neet little trick I learned from the series "Mirage of memory, part 2: PSS"
ps -fu postgres | grep $(pgrep -f postmaster)
postgres    1913       1  0 Jul17 ?        00:02:51 /usr/pgsql-15/bin/postmaster -D /var/lib/pgsql/15/data/
postgres    1982    1913  0 Jul17 ?        00:00:24 postgres: logger
postgres    2063    1913  0 Jul17 ?        00:00:18 postgres: checkpointer
postgres    2064    1913  0 Jul17 ?        00:00:03 postgres: background writer
postgres    2119    1913  0 Jul17 ?        00:00:07 postgres: walwriter
postgres    2120    1913  0 Jul17 ?        00:00:14 postgres: autovacuum launcher
postgres    2121    1913  0 Jul17 ?        00:00:01 postgres: archiver
postgres    2122    1913  0 Jul17 ?        00:00:00 postgres: logical replication launcher
postgres    2657    1913  0 Jul17 ?        00:02:05 postgres: postgres_exporter postgres localhost(48674) idle
The command lists all processes by user "postgres" and and greps for the output of the command "pgrep -f postmaster", which returns a list of process IDs

You could also count the number of processes by user "postgres" by simply typing
pgrep -c postmaster
9

Monday, July 14, 2025

How to find when a PostgreSQL table was last vacuumed

SELECT
schemaname,
relname,
last_vacuum,
last_autovacuum,
last_analyze,
last_autoanalyze
FROM pg_stat_user_tables
WHERE relname = 'documents';
   schemaname   | relname  | last_vacuum |        last_autovacuum        |         last_analyze          |       last_autoanalyze
----------------+----------+-------------+-------------------------------+-------------------------------+-------------------------------
 scott          | documents|             | 2025-06-25 02:05:20.692869+02 | 2025-07-12 22:04:05.119051+02 | 2025-06-17 08:41:12.567351+02
(1 row)
Explanation of columns:

  • last_vacuum: Last manual vacuum.
  • last_autovacuum: Last automatic vacuum.
  • last_analyze: Last manual analyze.
  • last_autoanalyze: Last automatic analyze.

    What does ANALYZE do in PostgreSQL?

    ANALYZE collects statistics about the contents of a table (or all tables), such as:
  • Number of rows
  • Distribution of values
  • Most common values
  • Histogram of value ranges
  • Null fractions These statistics are stored in pg_statistic and are used by the query planner to make decisions (e.g., which index to use, join strategies, etc.).

    Syntax to run ANALYZE

    Analyze the entire database (all tables in all schemas):
    ANALYZE;
    
    Analyze a specific table:
    ANALYZE my_table;
    
    Analyze specific columns only:
    ANALYZE my_table (column1, column2);
    
  • Friday, July 11, 2025

    PostgreSQL: how to tail the alert log of the day with filtering for long-running statements

    I have set the parameter log_min_duration_statement to 2 seconds and reloaded the config:
    postgres=# alter system set log_min_duration_statement='2s';
    ALTER SYSTEM
    
    postgres=# SELECT pg_reload_conf();
     pg_reload_conf
    ----------------
     t
    (1 row)
    
    postgres=# show log_min_duration_statement;
     log_min_duration_statement
    ----------------------------
     2s
    (1 row)
    
    
    I expect every statement that lasts longer than 2 seconds to be logged in the postgreSQL server main log.

    From a different session, I execute the following in any database in the cluster:
    postgres=# SELECT pg_sleep(3);
     pg_sleep
    ----------
    
    (1 row)
    
    From another session, tail the log from today:
    tail -F /var/log/postgres/postgresql-2025-07-11_000000.log | grep --line-buffered "duration:.*statement:"
    
    Output
    2025-07-11 09:45:42 CEST [173349]: [5-1] user=postgres,db=postgres,app=psql,client=[local] LOG:  duration: 3003.698 ms  statement: SELECT pg_sleep(3);
    

    Wednesday, July 9, 2025

    How to list all subdirectories and exclude certain subdirectories in a tree-like fashion

    In this example I want to see all subdirectories that starts with "dir", but also to exclude the directory "dirdat":
    cd $ORACLE_GG
    tree -L 2 --noreport $(ls -d dir* | grep -v '^dirdat$')
    
  • ls -d dir*: lists all dir* entries (only directories if they match)
  • grep -v '^dirdat$': removes dirdat from the list
  • $(...): expands the filtered list as arguments to tree