Rocky Linux update:
[root@rocky ~]# cat /etc/rocky-release
Rocky Linux release 9.8 (Blue Onyx)
[root@rocky ~]# dnf update --assumeyes
[root@rocky ~]# dnf install --assumeyes bash-completion tree lsof git
PostgreSQL installation:
#
# disable Rocky Linux built-in PostgreSQL module streams for version 13:
#
[root@rocky ~]# dnf list available postgresql-server
Last metadata expiration check: 0:01:01 ago on Mon 03 Aug 2026 05:28:45 PM UTC.
Available Packages
[[blue:postgresql-server.x86_64]] 13.23-3.el9_8 appstream
[root@rocky ~]# dnf --quiet --assumeyes module disable postgresql
#
# download and install the official PostgreSQL RIM repo:
#
[root@rocky ~]# cd /tmp
[root@rocky tmp]# curl --location --remote-name https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 12838 100 12838 0 0 266k 0 --:--:-- --:--:-- --:--:-- 272k
[root@rocky tmp]# ls -l pgdg-redhat-repo-latest.noarch.rpm
-rw-r--r--. 1 root root 12838 Aug 3 17:37 pgdg-redhat-repo-latest.noarch.rpm
[root@rocky tmp]# dnf localinstall --assumeyes /tmp/pgdg-redhat-repo-latest.noarch.rpm
DigitalOcean Droplet Agent 87 kB/s | 3.5 kB 00:00
Dependencies resolved.
=================================================================================================================
Package Architecture Version Repository Size
=================================================================================================================
Installing:
pgdg-redhat-repo noarch 42.0-66.rhel9PGDG @commandline 13 k
Transaction Summary
=================================================================================================================
Install 1 Package
Total size: 13 k
Installed size: 16 k
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction
Preparing : 1/1
Installing : pgdg-redhat-repo-42.0-66.rhel9PGDG.noarch 1/1
Verifying : pgdg-redhat-repo-42.0-66.rhel9PGDG.noarch 1/1
Installed:
pgdg-redhat-repo-42.0-66.rhel9PGDG.noarch
Complete!
[root@rocky tmp]# dnf list available --assumeyes postgresql18-server
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 4.4 kB/s | 659 B 00:00
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 4.1 MB/s | 899 kB 00:00
PostgreSQL 18 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 6.9 kB/s | 659 B 00:00
PostgreSQL 18 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
PostgreSQL 18 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.1 MB/s | 717 kB 00:00
PostgreSQL 17 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 9.4 kB/s | 659 B 00:00
PostgreSQL 17 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
PostgreSQL 17 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 7.1 MB/s | 1.2 MB 00:00
PostgreSQL 16 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 8.9 kB/s | 659 B 00:00
PostgreSQL 16 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
PostgreSQL 16 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 5.0 MB/s | 1.5 MB 00:00
PostgreSQL 15 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 7.2 kB/s | 659 B 00:00
PostgreSQL 15 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
PostgreSQL 15 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 6.6 MB/s | 1.7 MB 00:00
PostgreSQL 14 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 3.1 kB/s | 659 B 00:00
PostgreSQL 14 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
PostgreSQL 14 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 5.4 MB/s | 2.0 MB 00:00
Available Packages
postgresql18-server.x86_64 18.4-2PGDG.rhel9.8 pgdg18
[root@rocky tmp]# rm /tmp/pgdg-redhat-repo-latest.noarch.rpm
rm: remove regular file 'pgdg-repo.rpm'? [[yellow:y]]
#
# install PostgreSQL 18:
#
[root@rocky tmp]# dnf install --assumeyes postgresql18-server
Last metadata expiration check: 0:01:31 ago on Sun 02 Aug 2026 07:42:59 PM UTC.
Dependencies resolved.
=================================================================================================================
Package Architecture Version Repository Size
=================================================================================================================
Installing:
[[green:postgresql18-server]] x86_64 18.4-2PGDG.rhel9.8 pgdg18 7.2 M
Installing dependencies:
[[green:libicu]] x86_64 67.1-10.el9_6 baseos 9.6 M
[[green:postgresql18]] x86_64 18.4-2PGDG.rhel9.8 pgdg18 2.0 M
[[green:postgresql18-libs]] x86_64 18.4-2PGDG.rhel9.8 pgdg18 301 k
Transaction Summary
=================================================================================================================
Install 4 Packages
Total download size: 19 M
Installed size: 75 M
Downloading Packages:
(1/4): postgresql18-libs-18.4-2PGDG.rhel9.8.x86_64.rpm 4.0 MB/s | 301 kB 00:00
(2/4): postgresql18-18.4-2PGDG.rhel9.8.x86_64.rpm 21 MB/s | 2.0 MB 00:00
(3/4): libicu-67.1-10.el9_6.x86_64.rpm 23 MB/s | 9.6 MB 00:00
(4/4): postgresql18-server-18.4-2PGDG.rhel9.8.x86_64.rpm 13 MB/s | 7.2 MB 00:00
-----------------------------------------------------------------------------------------------------------------
PostgreSQL 18 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64 2.4 MB/s | 2.4 kB 00:00
Importing GPG key 0x08B40D20:
Userid : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
From : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : libicu-67.1-10.el9_6.x86_64 1/4
Installing : postgresql18-libs-18.4-2PGDG.rhel9.8.x86_64 2/4
Running scriptlet: postgresql18-libs-18.4-2PGDG.rhel9.8.x86_64 2/4
Installing : postgresql18-18.4-2PGDG.rhel9.8.x86_64 3/4
Running scriptlet: postgresql18-18.4-2PGDG.rhel9.8.x86_64 3/4
Running scriptlet: postgresql18-server-18.4-2PGDG.rhel9.8.x86_64 4/4
Creating group 'postgres' with GID 26.
Creating user 'postgres' (PostgreSQL Server) with UID 26 and GID 26.
Installing : postgresql18-server-18.4-2PGDG.rhel9.8.x86_64 4/4
Running scriptlet: postgresql18-server-18.4-2PGDG.rhel9.8.x86_64 4/4
Verifying : postgresql18-18.4-2PGDG.rhel9.8.x86_64 1/4
Verifying : postgresql18-libs-18.4-2PGDG.rhel9.8.x86_64 2/4
Verifying : postgresql18-server-18.4-2PGDG.rhel9.8.x86_64 3/4
Verifying : libicu-67.1-10.el9_6.x86_64 4/4
Installed:
libicu-67.1-10.el9_6.x86_64 postgresql18-18.4-2PGDG.rhel9.8.x86_64
postgresql18-libs-18.4-2PGDG.rhel9.8.x86_64 postgresql18-server-18.4-2PGDG.rhel9.8.x86_64
Complete!
[root@rocky tmp]# dnf list installed postgresql18-server
Installed Packages
[[red:postgresql18.x86_64]] 18.4-2PGDG.rhel9.8 @pgdg18
[root@rocky tmp]# dnf repoquery --installed --list postgresql18-server
/etc/pam.d/postgresql
/etc/sysconfig/pgsql
/run/postgresql
/usr/bin/postgresql-18-setup
/usr/lib/.build-id
::
::
::
::
/var/lib/pgsql
/var/lib/pgsql/18
/var/lib/pgsql/18/backups
/var/lib/pgsql/18/data
[root@rocky tmp]# systemctl status postgresql-18.service
[[red:○]] postgresql-18.service - PostgreSQL 18 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-18.service; disabled; preset: disabled)
Active: [[red:inactive (dead)]]
Docs: https://www.postgresql.org/docs/18/static/
[root@rocky tmp]# grep postgres /etc/group /etc/passwd
/etc/group:postgres:x:26:
/etc/passwd:postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/usr/bin/bash
[root@rocky tmp]# id -a postgres
uid=26(postgres) gid=26(postgres) groups=26(postgres)
PostgreSQL database initilization:
[root@rocky tmp]# su - postgres
Last login: Mon Aug 3 18:04:57 UTC 2026 on pts/0
[postgres@rocky ~]$ whoami
postgres
[postgres@rocky ~]$ tree /var/lib/pgsql/18
/var/lib/pgsql/18
├── backups
└── data
2 directories, 0 files
#
# initdb:
#
[postgres@rocky ~]$ which postgresql-18-setup
/usr/bin/postgresql-18-setup
[postgres@rocky ~]$ file $(which postgresql-18-setup)
/usr/bin/postgresql-18-setup: symbolic link to ../../../../../../../../../../../../../..//usr/pgsql-18/bin/postgresql-18-setup
[postgres@rocky ~]$ export | grep PGDATA
declare -x PGDATA="/var/lib/pgsql/18/data"
[postgres@rocky ~]$ ls -l ${PGDATA}
total 0 ---${PGDATA}
[postgres@rocky ~]$ /usr/pgsql-18/bin/postgresql-18-setup initdb
Initializing database...
[postgres@rocky ~]$ ls -l ${PGDATA}
total 0 ---nothing?
[postgres@rocky ~]$ ls -l /var/lib/pgsql/18
drwx------. 2 postgres postgres 6 May 21 05:59 backups
drwx------. 2 postgres postgres 6 May 21 05:59 data
-rw-------. 1 postgres postgres 86 Aug 3 18:12 initdb.log
[postgres@rocky ~]$ cat /var/lib/pgsql/18/initdb.log
[[red:runuser: may not be used by non-root users]]
[postgres@rocky ~]$ exit
logout
#
# postgresql-18-setup initdb must run by "root":
#
[root@rocky tmp]# postgresql-18-setup initdb
Initializing database ... OK
[root@rocky tmp]# systemctl status postgresql-18.service
○ postgresql-18.service - PostgreSQL 18 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-18.service; disabled; preset: disabled)
Active: [[red:inactive (dead)]]
Docs: https://www.postgresql.org/docs/18/static/
[root@rocky tmp]# systemctl enable --now postgresql-18.service
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql-18.service → /usr/lib/systemd/system/postgresql-18.service.
[root@rocky tmp]# systemctl status postgresql-18.service
[[green:●]] postgresql-18.service - PostgreSQL 18 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-18.service; enabled; preset: disabled)
Active: [[green:active (running)]] since Sun 2026-08-02 20:03:13 UTC; 17s ago
Docs: https://www.postgresql.org/docs/18/static/
Process: 61854 ExecStartPre=/usr/pgsql-18/bin/postgresql-18-check-db-dir ${PGDATA} (code=exited, status=0/SU>
Main PID: 61859 (postgres)
Tasks: 10 (limit: 4303)
Memory: 22.1M (peak: 22.3M)
CPU: 68ms
CGroup: /system.slice/postgresql-18.service
├─61859 /usr/pgsql-18/bin/postgres -D /var/lib/pgsql/18/data/
├─61860 "postgres: logger "
├─61861 "postgres: io worker 2"
├─61862 "postgres: io worker 1"
├─61863 "postgres: io worker 0"
├─61864 "postgres: checkpointer "
├─61865 "postgres: background writer "
├─61867 "postgres: walwriter "
├─61868 "postgres: autovacuum launcher "
└─61869 "postgres: logical replication launcher "
Aug 02 20:03:13 rocky systemd[1]: Starting PostgreSQL 18 database server...
Aug 02 20:03:13 rocky postgres[61859]: 2026-08-02 20:03:13.682 UTC [61859] LOG: redirecting log output to loggi>
Aug 02 20:03:13 rocky postgres[61859]: 2026-08-02 20:03:13.682 UTC [61859] HINT: Future log output will appear >
Aug 02 20:03:13 rocky systemd[1]: Started PostgreSQL 18 database server.
[root@rocky tmp]# ps aux | grep ^postgres
postgres 61859 0.0 4.0 222668 31496 ? Ss 20:03 0:00 /usr/pgsql-18/bin/postgres -D /var/lib/pgsql/18/data/
postgres 61860 0.0 0.9 69272 7152 ? Ss 20:03 0:00 postgres: logger
postgres 61861 0.0 0.9 222668 7464 ? Ss 20:03 0:00 postgres: io worker 2
postgres 61862 0.0 1.0 222800 8180 ? Ss 20:03 0:00 postgres: io worker 1
postgres 61863 0.0 1.2 222800 9492 ? Ss 20:03 0:00 postgres: io worker 0
postgres 61864 0.0 0.9 222800 7384 ? Ss 20:03 0:00 postgres: checkpointer
postgres 61865 0.0 1.0 222824 8484 ? Ss 20:03 0:00 postgres: background writer
postgres 61867 0.0 1.5 222800 11884 ? Ss 20:03 0:00 postgres: walwriter
postgres 61868 0.0 1.3 224248 10956 ? Ss 20:03 0:00 postgres: autovacuum launcher
postgres 61869 0.0 1.3 224248 10204 ? Ss 20:03 0:00 postgres: logical replication launcher
[root@rocky tmp]# lsof -P -i TCP:postgres
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 61859 postgres 7u IPv6 119193 0t0 TCP rocky:5432 (LISTEN)
postgres 61859 postgres 8u IPv4 119194 0t0 TCP rocky:5432 (LISTEN)
[root@rocky tmp]# lsof -n -P -i TCP:postgres
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 63417 postgres 7u IPv6 97296 0t0 TCP [::1]:5432 (LISTEN)
postgres 63417 postgres 8u IPv4 97297 0t0 TCP 127.0.0.1:5432 (LISTEN) ---only listen on localhost
Working with PostgreSQL:
[root@rocky tmp]# su - postgres
Last login: Mon Aug 3 18:05:09 UTC 2026 on pts/0
[postgres@rocky ~]$ whoami
postgres
[postgres@rocky ~]$ export | grep ${PGDATA}
declare -x PGDATA="/var/lib/pgsql/18/data"
[postgres@rocky ~]$ ls -l ${PGDATA}
drwx------. 5 postgres postgres 33 Aug 3 18:16 base
drwx------. 2 postgres postgres 4096 Aug 3 18:16 global
drwx------. 2 postgres postgres 6 Aug 3 18:16 log
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_commit_ts
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_dynshmem
-rw-------. 1 postgres postgres 5509 Aug 3 18:16 pg_hba.conf
-rw-------. 1 postgres postgres 2681 Aug 3 18:16 pg_ident.conf
drwx------. 4 postgres postgres 68 Aug 3 18:16 pg_logical
drwx------. 4 postgres postgres 36 Aug 3 18:16 pg_multixact
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_notify
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_replslot
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_serial
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_snapshots
drwx------. 2 postgres postgres 25 Aug 3 18:16 pg_stat
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_stat_tmp
drwx------. 2 postgres postgres 18 Aug 3 18:16 pg_subtrans
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_tblspc
drwx------. 2 postgres postgres 6 Aug 3 18:16 pg_twophase
-rw-------. 1 postgres postgres 3 Aug 3 18:16 PG_VERSION
drwx------. 4 postgres postgres 77 Aug 3 18:16 pg_wal
drwx------. 2 postgres postgres 18 Aug 3 18:16 pg_xact
-rw-------. 1 postgres postgres 88 Aug 3 18:16 postgresql.auto.conf
-rw-------. 1 postgres postgres 32567 Aug 3 18:16 postgresql.conf
#
# ${PGDATA}/postgresql.conf
#
[postgres@rocky ~]$ ls -l ${PGDATA}/postgresql.conf
-rw-------. 1 postgres postgres 32559 Aug 5 17:44 /var/lib/pgsql/18/data/postgresql.conf
[postgres@rocky ~]$ vi ${PGDATA}/postgresql.conf
::
::
[postgres@rocky ~]$ cat ${PGDATA}/postgresql.conf
[[blue:## -----------------------------]]
[[blue:## PostgreSQL configuration file]]
[[blue:## -----------------------------]]
[[blue:##]]
[[blue:## This file consists of lines of the form:]]
[[blue:::]]
[[blue:::]]
[[blue:::]]
[[blue:]]
[[blue:##------------------------------------------------------------------------------]]
[[blue:## CONNECTIONS AND AUTHENTICATION]]
[[blue:##------------------------------------------------------------------------------]]
[[blue:]]
[[blue:## - Connection Settings -]]
[[blue:]]
[[red:listen_addresses = '*']] [[blue:## what IP address(es) to listen on;]]
[[blue: ## comma-separated list of addresses;]]
[[blue: ## defaults to 'localhost'; use '*' for all]]
[[blue: ## (change requires restart)]]
[[blue:::]]
[[blue:::]]
[[blue:::]]
#
# ${PGDATA}/pg_hba.conf:
#
[postgres@rocky ~]$ ls -l ${PGDATA}/pg_hba.conf
-rw-------. 1 postgres postgres 5588 Aug 5 18:04 /var/lib/pgsql/18/data/pg_hba.conf
[postgres@rocky ~]$ vi ${PGDATA}/pg_hba.conf
::
::
[postgres@rocky ~]$ cat ${PGDATA}/pg_hba.conf
[[blue:::]]
[[blue:::]]
[[blue:::]]
[[blue:::]]
[[blue:host appdb all 0.0.0.0/0 scram-sha-256]]
#
# restart PostgreSQL:
#
[postgres@rocky ~]$ exit
logout
[root@rocky tmp]# systemctl restart postgresql-18.service
[root@rocky tmp]# lsof -n -P -i TCP:postgres
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
postgres 63675 postgres 7u IPv4 99011 0t0 TCP *:5432 (LISTEN) ---listen on all interfaces
postgres 63675 postgres 8u IPv6 99012 0t0 TCP *:5432 (LISTEN)
[root@rocky tmp]# su - postgres
Last login: Thu Aug 6 02:55:46 UTC 2026 on pts/0
#
# prerequisite for liquibase deployment:
#
[postgres@rocky ~]$ psql
psql (18.4)
Type "help" for help.
postgres=# \list
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | Locale | ICU Rules | Access privileges
----------------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------
postgres | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
template0 | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | | =c/postgres +
| | | | | | | | postgres=CTc/postgres
(3 rows)
postgres=# \du+
List of roles
Role name | Attributes | Description
-----------+------------------------------------------------------------+-------------
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS |
postgres=# CREATE DATABASE appdb;
CREATE DATABASE
postgres=# \list+ appdb;
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | Locale | ICU Rules | Access privileges | Size | Tablespace | Description
-------+----------+----------+-----------------+-------------+-------------+--------+-----------+-------------------+---------+------------+-------------
appdb | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | | | 7585 kB | pg_default |
(1 row)
postgres=# CREATE USER liquibase_user WITH PASSWORD 'passw0rd';
CREATE ROLE
postgres=# \du+ liquibase_user;
List of roles
Role name | Attributes | Description
----------------+------------+-------------
liquibase_user | |
postgres=# \connect appdb;
You are now connected to database "appdb" as user "postgres".
appdb=# \dn+;
List of schemas
Name | Owner | Access privileges | Description
--------+-------------------+----------------------------------------+------------------------
public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
| | =U/pg_database_owner |
(1 row)
appdb=# GRANT USAGE ON SCHEMA public TO liquibase_user;
GRANT
appdb=# GRANT CREATE ON SCHEMA public TO liquibase_user;
GRANT
appdb=# \dn+;
List of schemas
Name | Owner | Access privileges | Description
--------+-------------------+----------------------------------------+------------------------
public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
| | =U/pg_database_owner +|
| | liquibase_user=UC/pg_database_owner |
(1 row)
appdb=# \quit
[postgres@rocky ~]$ exit
logout
Create a new GitHub repository:
- Login to https://github.com
- Select [Repositories] tab
- Click [New] to create a new repository
- General
- Owner: kmaau
- Repository name: liquibase
- Description: Liquibase tutorial
- General
- Configuration
- Choose visibility: Private
- Add README: Off
- Add .gitignore: No .gitignore
- Add license: No license
- Click [New] to create a new repository
- Click [Create repository]
Settings for liquibase repositiory:
- Security and quality:
- Secrets and variables:
- Actions:
- DB_URL: jdbc:postgresql://165.245.236.92:5432/appdb
- DB_USERNAME: liquibase_user
- DB_PASSWORD: passw0rd
- Actions:
- Secrets and variables:
GitHub setup:
[root@rocky tmp]# cd ${HOME}
[root@rocky ~]# useradd --home-dir /home/kmaau --create-home --shell /bin/bash kmaau
[root@rocky ~]# id -a kmaau
uid=1001(kmaau) gid=1001(kmaau) groups=1001(kmaau)
[root@rocky ~]# su - kmaau
Last login: Wed Aug 5 05:49:09 UTC 2026 on pts/2
[kmaau@rocky ~]$ whoami
kmaau
[kmaau@rocky ~]$ ls -l ${HOME}/.gitconfig ${HOME}/.git-credentials
[[red:ls: cannot access '/home/kmaau/.gitconfig': No such file or directory]]
[[red:ls: cannot access '/home/kmaau/.git-credentials': No such file or directory]]
[kmaau@rocky ~]$ git config --global user.email "kianming.aau@gmaul.com"
[kmaau@rocky ~]$ git config --global user.name "Kian Ming Aau"
[kmaau@rocky ~]$ git config --global init.defaultBranch main
[kmaau@rocky ~]$ git config --global --get credential.helper
(.....nothing)
[kmaau@rocky ~]$ git config --global credential.helper store
[kmaau@rocky ~]$ ls -l ${HOME}/.gitconfig ${HOME}/.git-credentials
[[red:ls: cannot access '/home/kmaau/.git-credentials': No such file or directory]]
-rw-r--r--. 1 kmaau kmaau 119 Aug 6 03:31 /home/kmaau/.gitconfig
[kmaau@rocky ~]$ cat ${HOME}/.gitconfig
[[blue:[user]]]
[[blue: name = Kian Ming Aau]]
[[blue: email = kianming.aau@gmail.com]]
[[blue:[credential]]]
[[blue: helper = store]]
[[blue:[init]]]
[[blue: defaultBranch = main]]
Working with GitHub repository:
[kmaau@rocky ~]$ mkdir ${HOME}/liquibase
[kmaau@rocky ~]$ ls -ld ${HOME}/liquibase
drwxr-xr-x. 2 kmaau kmaau 6 Aug 5 20:54 /home/kmaau/liquibase
[kmaau@rocky ~]$ cd ${HOME}/liquibase
[kmaau@rocky liquibase]$ git init
Initialized empty Git repository in /home/kmaau/liquibase/.git/
[kmaau@rocky liquibase]$ ls -la
drwxr-xr-x. 3 kmaau kmaau 18 Aug 6 03:35 .
drwx------. 3 kmaau kmaau 144 Aug 6 03:33 ..
drwxr-xr-x. 6 kmaau kmaau 103 Aug 6 03:35 .git
[kmaau@rocky liquibase]$ echo "# Liquibase project" >> README.md
[kmaau@rocky liquibase]$ ls -l
-rw-r--r--. 1 kmaau kmaau 20 Aug 6 03:37 README.md
[kmaau@rocky liquibase]$ git add README.md
[kmaau@rocky liquibase]$ git commit --message "Initial commit"
[main (root-commit) 547a338] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
[kmaau@rocky liquibase]$ git branch
* [[green:main]]
[kmaau@rocky liquibase]$ git remote --verbose
(.....nothing)
[kmaau@rocky liquibase]$ git remote add origin https://github.com/kmaau/liquibase.git
[kmaau@rocky liquibase]$ git remote --verbose
origin https://github.com/kmaau/liquibase.git (fetch)
origin https://github.com/kmaau/liquibase.git (push)
[kmaau@rocky liquibase]$ git push --set-upstream origin main
Username for 'https://github.com': [[yellow:kmaau]]
Password for 'https://kmaau@github.com': [[yellow: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]]
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 237 bytes | 237.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/kmaau/liquibase.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.
[kmaau@rocky liquibase]$ ls -l ${HOME}/.gitconfig ${HOME}/.git-credentials
-rw-r--r--. 1 kmaau kmaau 119 Aug 6 03:31 /home/kmaau/.gitconfig
-rw-------. 1 kmaau kmaau 119 Aug 6 03:43 /home/kmaau/.git-credentials
[kmaau@rocky liquibase]$ cat ${HOME}/.git-credentials
[[blue:https://kmaau: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@github.com]]
GitHub Action:
[kmaau@rocky liquibase]$ vi .github/workflows/database-migration.yml
::
::
[kmaau@rocky liquibase]$ cat .github/workflows/database-migration.yml
[[blue:name: Database Schema Migration]]
[[blue:]]
[[blue:on:]]
[[blue: push:]]
[[blue: branches:]]
[[blue: - main # Triggers automatically when changes are pushed to the main branch]]
[[blue: paths:]]
[[blue: - 'db/**' # Triggers only if changes are inside the db folder]]
[[blue:]]
[[blue:jobs:]]
[[blue: liquibase-update:]]
[[blue: runs-on: ubuntu-latest]]
[[blue:]]
[[blue: steps:]]
[[blue: #1. Pull down the latest code from the repository]]
[[blue: - name: Checkout Code]]
[[blue: uses: actions/checkout@v4]]
[[blue:]]
[[blue: #2. Install liquibase CLI on the automation runner]]
[[blue: - name: Setup Liquibase]]
[[blue: uses: liquibase/setup-liquibase@v3]]
[[blue: with:]]
[[blue: version: '5.0.3']]
[[blue: edition: 'community']]
[[blue:]]
[[blue: #3. Download standard PostgreSQL JDBC driver jar]]
[[blue: - name: Download Postgres Driver]]
[[blue: run: liquibase lpm add postgresql --global]]
[[blue:]]
[[blue: #4. Download and register the required PotgreSQL JDBC driver]]
[[blue: - name: Run Liquibase Update]]
[[blue: run: |]]
[[blue: liquibase \\]]
[[blue: --changelog-file=db/changelogs/db.changelog-root.xml \\]]
[[blue: --url=${{ secrets.DB_URL }} \\]]
[[blue: --username=${{ secrets.DB_USERNAME }} \\]]
[[blue: --password=${{ secrets.DB_PASSWORD }} \\]]
[[blue: update]]
[kmaau@rocky liquibase]$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
[[red:.github/]]
nothing added to commit but untracked files present (use "git add" to track)
[kmaau@rocky liquibase]$ git add .github
[kmaau@rocky liquibase]$ git commit --message "Create GitHub Action"
[main ad78cfe] Create GitHub Action
1 file changed, 38 insertions(+)
create mode 100644 .github/workflows/database-migration.yml
[kmaau@rocky liquibase]$ git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 924 bytes | 924.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/kmaau/liquibase.git
547a338..ad78cfe main -> main
liquibase configuration:
[kmaau@rocky liquibase]$ mkdir -p db/changelogs
[kmaau@rocky liquibase]$ ls -ld db/changelogs
drwxr-xr-x. 2 kmaau kmaau 6 Aug 6 04:07 db/changelogs
#
# Liquibase.properties:
#
[kmaau@rocky liquibase]$ ip -4 --human-readable --family inet address | grep inet
inet 127.0.0.1/8 scope host lo
inet [[red:165.245.236.92]]/20 brd 165.245.239.255 scope global noprefixroute eth0 ---public IP
inet 10.20.0.5/16 brd 10.20.255.255 scope global noprefixroute eth0
inet 10.137.0.3/16 brd 10.137.255.255 scope global noprefixroute eth1
[kmaau@rocky liquibase]$ vi db/liquibase.properties
::
::
[kmaau@rocky liquibase]$ cat db/liquibase.properties
[[blue:changeLogFile=db/changelog-master.xml]]
[[blue:url=jdbc:postgresql://165.245.236.92:5432/appdb]]
[[blue:username=liquibase_user]]
[[blue:password=passw0rd]]
[[blue:driver=org.postgresql.Driver]]
#
# GitHub Action involves db/changelogs/db.changelog-root.xml:
#
[kmaau@rocky liquibase]$ vi db/changelogs/db.changelog-root.xml
::
::
[kmaau@rocky liquibase]$ cat db/changelogs/db.changelog-root.xml
[[blue:<?xml version="1.0" encoding="UTF-8"?>]]
[[blue:<databaseChangeLog]]
[[blue: xmlns="http://www.liquibase.org/xml/ns/dbchangelog"]]
[[blue: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"]]
[[blue: xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog]]
[[blue: http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">]]
[[blue:]]
[[blue: <!-- Include your feature or version migration files here -->]]
[[blue: <include file="db/changelogs/001_create_users_table.sql"/>]]
[[blue:]]
[[blue:</databaseChangeLog>]]
#
# db/changelogs/db.changelog-root.xml calls 001_create_users_table.sql
#
[kmaau@rocky liquibase]$ vi db/changelogs/001_create_users_table.sql
::
::
[kmaau@rocky liquibase]$ cat db/changelogs/001_create_users_table.sql
[[blue:--liquibase formatted sql]]
[[blue: ]]
[[blue:--changeset kmaau:1]]
[[blue:]]
[[blue:CREATE TABLE users (]]
[[blue: id SERIAL PRIMARY KEY,]]
[[blue: username VARCHAR(50) NOT NULL UNIQUE,]]
[[blue: email VARCHAR(100) NOT NULL,]]
[[blue: created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP]]
[[blue:);]]
[kmaau@rocky liquibase]$ tree db
db
├── changelogs
│ ├── 001_create_users_table.sql
│ └── db.changelog-root.xml
└── liquibase.properties
1 directory, 3 files
[kmaau@rocky liquibase]$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
[[red:db/]]
nothing added to commit but untracked files present (use "git add" to track)
[kmaau@rocky liquibase]$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
[[red:db/]]
nothing added to commit but untracked files present (use "git add" to track)
[kmaau@rocky liquibase]$ git add db
[kmaau@rocky liquibase]$ git commit --message "Add liquibase configuration"
[main 13a97f2] Add liquibase configuration
3 files changed, 26 insertions(+)
create mode 100644 db/changelogs/001_create_users_table.sql
create mode 100644 db/changelogs/db.changelog-root.xml
create mode 100644 db/liquibase.properties
[kmaau@rocky liquibase]$ git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Compressing objects: 100% (7/7), done.
Writing objects: 100% (7/7), 1.06 KiB | 1.06 MiB/s, done.
Total 7 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To https://github.com/kmaau/liquibase.git
ad78cfe..13a97f2 main -> main
Create a pull request (PR) between “main” Vs “diff” for GitHub Action:
#
# create a new branch for pull request:
#
[kmaau@rocky liquibase]$ git switch --create diff
Switched to a new branch 'diff'
[kmaau@rocky liquibase]$ git status
On branch diff
nothing to commit, working tree clean
[kmaau@rocky liquibase]$ git push --set-upstream origin diff
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
remote:
remote: Create a pull request for 'diff' on GitHub by visiting:
remote: https://github.com/kmaau/liquibase/pull/new/diff
remote:
To https://github.com/kmaau/liquibase.git
* [new branch] diff -> diff
branch 'diff' set up to track 'origin/diff'.
[kmaau@rocky liquibase]$ echo "VERSION diff" >> db/VERSION
::
::
[kmaau@rocky liquibase]$ git add db/VERSION
[kmaau@rocky liquibase]$ git commit --message "Add db/VERSION"
[diff c695f1f] Add db/VERSION
1 file changed, 1 insertion(+)
create mode 100644 db/VERSION
[kmaau@rocky liquibase]$ git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 402 bytes | 402.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/kmaau/liquibase.git
13a97f2..c695f1f diff -> diff
[kmaau@rocky liquibase]$ git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
[kmaau@rocky liquibase]$ ls -l
drwxr-xr-x. 3 kmaau kmaau 52 Aug 6 04:30 db
-rw-r--r--. 1 kmaau kmaau 20 Aug 6 03:37 README.md
[kmaau@rocky liquibase]$ echo "version 1" >> db/VERSION
[kmaau@rocky liquibase]$ git status
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
[[red:db/VERSION]]
nothing added to commit but untracked files present (use "git add" to track)
[kmaau@rocky liquibase]$ git add db/VERSION
kmaau@rocky liquibase]$ git commit --message "version 1"
[diff f5a45b5] version 1
1 file changed, 1 insertion(+), 1 deletion(-)
[kmaau@rocky liquibase]$ git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 400 bytes | 400.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/kmaau/liquibase.git
13a97f2..2844f21 main -> main ---this push trigger GitHub Action
#
# GitHub Action output:
#
[[yellow:●]] Set up job 2s
Current runner version: '2.336.0'
Runner Image Provisioner
Operating System
Runner Image
GITHUB_TOKEN Permissions
Secret source: Actions
Prepare workflow directory
Prepare all required actions
Getting action download info
Download action repository 'actions/checkout@v4' (SHA:11d5960a326750d5838078e36cf38b85af677262)
Download action repository 'liquibase/setup-liquibase@v3' (SHA:9bd28bc8b31bd5a1651b34c7856569d5392ee869)
Complete job name: liquibase-update
[[yellow:●]] Checkout Code 1s
Node 20 is being deprecated. This workflow is running with Node 24 by default. If you need to temporarily use Node 20,
you can set the ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true environment variable.
For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
Run actions/checkout@v4
Syncing repository: kmaau/liquibase
Getting Git version info
Temporarily overriding HOME='/home/runner/work/_temp/8908d6e3-8f20-41d9-8f46-a7baa53cb268' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
/usr/bin/git config --global --add safe.directory /home/runner/work/liquibase/liquibase
Deleting the contents of '/home/runner/work/liquibase/liquibase'
Initializing the repository
Disabling automatic garbage collection
Setting up auth
Fetching the repository
Determining the checkout info
/usr/bin/git sparse-checkout disable
/usr/bin/git config --local --unset-all extensions.worktreeConfig
Checking out the ref
/usr/bin/git log -1 --format=%H
46e423fbe069ef72e95d1afbd4c78dd96a0805fc
[[yellow:●]] Setup Liquibase 2s
Run liquibase/setup-liquibase@v3
🚀 Setting up Liquibase COMMUNITY 5.0.3
💾 Liquibase not found in cache, proceeding with fresh installation
📥 Downloading from: https://package.liquibase.com/downloads/community/gha/liquibase-5.0.3.tar.gz
📦 Extracting Liquibase archive...
/usr/bin/tar xzf /home/runner/work/_temp/71f13d30-d7a3-4f78-a188-b59f3e1848e9 -C /tmp/liquibase-extract-mof9dcx2we
💾 Caching Liquibase installation for future workflow runs...
✅ Installation completed successfully
🔧 Added Liquibase to system PATH
✅ Liquibase installation validated successfully
🎯 Liquibase configuration
💡 Migration Guidance
✅ setup-liquibase completed successfully!
[[yellow:●]] Download Postges Driver 3s
Run liquibase lpm add postgresql --global
####################################################
## _ _ _ _ ##
## | | (_) (_) | ##
## | | _ __ _ _ _ _| |__ __ _ ___ ___ ##
## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ##
## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ##
## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ##
## | | ##
## |_| ##
## ##
## Get documentation at docs.liquibase.com ##
## Get certified courses at learn.liquibase.com ##
## ##
####################################################
Starting Liquibase at 14:12:51 using Java 17.0.19 (version 5.0.3 #10665 built at 2026-05-13 17:55+0000)
Liquibase Version: 5.0.3
LPM not found at '/opt/hostedtoolcache/liquibase-community/5.0.3/x64/lpm'. Installing LPM automatically...
Downloading LPM version 0.3.6 for linux from https://github.com/liquibase/liquibase-package-manager/releases/download/v0.3.6/lpm-0.3.6-linux.zip
LPM installation completed successfully.
Checksum verified. Installing postgresql-42.7.13.jar to /opt/hostedtoolcache/liquibase-community/5.0.3/x64/lib/
postgresql-42.7.13.jar successfully installed in classpath.
Liquibase command 'lpm' was executed successfully.
[[yellow:●]] Run Liquibase Update 8s
Run liquibase \
####################################################
## _ _ _ _ ##
## | | (_) (_) | ##
## | | _ __ _ _ _ _| |__ __ _ ___ ___ ##
## | | | |/ _` | | | | | '_ \ / _` / __|/ _ \ ##
## | |___| | (_| | |_| | | |_) | (_| \__ \ __/ ##
## \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___| ##
## | | ##
## |_| ##
## ##
## Get documentation at docs.liquibase.com ##
## Get certified courses at learn.liquibase.com ##
## ##
####################################################
Starting Liquibase at 14:12:54 using Java 17.0.19 (version 5.0.3 #10665 built at 2026-05-13 17:55+0000)
Liquibase Version: 5.0.3
Running Changeset: db/changelogs/001_create_users_table.sql::1::kmaau
UPDATE SUMMARY
Run: 1
Previously run: 0
Filtered out: 0
-------------------------------
Total change sets: 1
Liquibase: Update has been successful. Rows affected: 0
Liquibase command 'update' was executed successfully.
[[yellow:●]] Post Checkout Code 0s
Node 20 is being deprecated. This workflow is running with Node 24 by default. If you need to temporarily use Node 20,
you can set the ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true environment variable.
For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
Post job cleanup.
/usr/bin/git version
git version 2.54.0
Temporarily overriding HOME='/home/runner/work/_temp/f167bb6a-a177-4052-9d33-3252bc2fb00c' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
/usr/bin/git config --global --add safe.directory /home/runner/work/liquibase/liquibase
/usr/bin/git config --local --name-only --get-regexp core\.sshCommand
/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' &&
git config --local --unset-all 'core.sshCommand' || :"
/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
http.https://github.com/.extraheader
/usr/bin/git config --local --unset-all http.https://github.com/.extraheader
/usr/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' &&
git config --local --unset-all 'http.https://github.com/.extraheader' || :"
/usr/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
/usr/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
[[blue:●]]Complete job 0s
Cleaning up orphan processes
Warning: Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4.
For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
[kmaau@rocky liquibase]$ exit
logout
Examine appdb:
[root@rocky ~]# su - postgres
Last login: Thu Aug 6 03:05:00 UTC 2026 on pts/0
[postgres@rocky ~]$ psql
psql (18.4)
Type "help" for help.
postgres=# \connect appdb;
You are now connected to database "appdb" as user "postgres".
appdb=# \dt+;
List of tables
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+-----------------------+-------+----------------+-------------+---------------+------------+-------------
public | databasechangelog | table | liquibase_user | permanent | heap | 16 kB |
public | databasechangeloglock | table | liquibase_user | permanent | heap | 8192 bytes |
public | users | table | liquibase_user | permanent | heap | 0 bytes |
(3 rows)
appdb=# \dt+ users;
List of tables
Schema | Name | Type | Owner | Persistence | Access method | Size | Description
--------+-------+-------+----------------+-------------+---------------+---------+-------------
public | users | table | liquibase_user | permanent | heap | 0 bytes |
(1 row)
appdb=# \d users;
Table "public.users"
Column | Type | Collation | Nullable | Default
------------+-----------------------------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('users_id_seq'::regclass)
username | character varying(50) | | not null |
email | character varying(100) | | not null |
created_at | timestamp without time zone | | | CURRENT_TIMESTAMP
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"users_username_key" UNIQUE CONSTRAINT, btree (username)
appdb=# \quit