Migrate data from PostgreSQL 14 to 16¶
There are two possible ways to migrate data from PostgreSQL 14 to 16 depending on how Roles are managed:
In case of admin roles management, all database objects ownership are handled manually by the user. In this case, see the more general guide Migrate data via pg_dump. Note that you must set extra-user-roles to charmed-admin once a Juju relation is requested the new database.
In the case of charm roles management, all the database objects ownership will be handled by charm automatically. This guide covers how to migrate data from Charmed PostgreSQL 14 to 16 using the new charm roles management setup for client applications managed by Juju. The migrated data from PostgreSQL 14 will be mapped to the corresponding ownership in PostgreSQL 16.
Prepare PostgreSQL 14 data¶
First, in order to make sure the latest data is included, remove the relation between the client app and Charmed PostgreSQL 14.
Then, define the following variables for the old database:
TMP_PATH="~/old-db-dump/"
OLD_DB_NAME="postgresql_test_app_database"
OLD_IP="10.218.34.229"
OLD_USER="operator"
OLD_PASSWORD="fJQYljbthEo2T1gj"
Create a dump of the old PostgreSQL 14 database with pg_dump:
mkdir -p "${TMP_PATH}"
PGPASSWORD="${OLD_PASSWORD}" pg_dump -j 4 -Fd -h "${OLD_IP}" -U "${OLD_USER}" -d "${OLD_DB_NAME}" -f "${TMP_PATH}" --compress 9
Set up new PostgreSQL 16 charm¶
Deploy one unit of Charmed PostgreSQL 16. This will simplify the migration and can be scaled later.
juju deploy postgresql --channel 16/stable
Define the following variables for the new database:
NEW_DB_NAME="postgresql_test_app_database123"
NEW_IP="10.218.34.56"
NEW_USER="operator"
NEW_PASSWORD="RnnijCiotVeW8O5I"
NEW_OWNER="charmed_${NEW_DB_NAME}_owner"
Migrate the following charm features from the old 14 charm to the new 16 charm:
any necessary charm config options
enabled charm extensions/plugins
Note
Config options and extensions must be migrated before restoring the data dump
Create a new database on PostgreSQL 16¶
PGPASSWORD="${NEW_PASSWORD}" psql -h "${NEW_IP}" -U "${NEW_USER}" -d postgres -c "CREATE DATABASE ${NEW_DB_NAME}"
Create new roles by running the function set_up_predefined_catalog_roles() in all databases except postgres and template1. It will create roles like charmed_<database-name>_owner, ..._dml and others:
PGPASSWORD="${NEW_PASSWORD}" psql -h "${NEW_IP}" -U "${NEW_USER}" -d "${NEW_DB_NAME}" -c "SELECT set_up_predefined_catalog_roles();"
PGPASSWORD="${NEW_PASSWORD}" psql -h "${NEW_IP}" -U "${NEW_USER}" -d "${NEW_DB_NAME}" -c "ALTER DATABASE ${NEW_DB_NAME} OWNER TO charmed_databases_owner;"
PGPASSWORD="${NEW_PASSWORD}" psql -h "${NEW_IP}" -U "${NEW_USER}" -d "${NEW_DB_NAME}" -c "ALTER SCHEMA public OWNER TO ${NEW_OWNER};"
Migrate data from PostgreSQL 14 to 16¶
Restore the PostgreSQL 14 database dump into the new 16 database:
PGPASSWORD="${NEW_PASSWORD}" pg_restore -j 4 -h "${NEW_IP}" -U "${NEW_USER}" -d "${NEW_DB_NAME}" -Fd "${TMP_PATH}" --no-owner
Set up new database ownership¶
Verify and modify the ownership for each database object in each schema to be equal to charmed_<database-name>_owner (${NEW_OWNER} above).
For example, to find and fix ownership for all tables, sequences, and views:
PGPASSWORD="${NEW_PASSWORD}" psql -h "${NEW_IP}" -U "${NEW_USER}" -d "${NEW_DB_NAME}"
mydb=> DO $$
DECLARE
r record;
BEGIN
FOR r IN
SELECT format('ALTER %s %I.%I OWNER TO %I;',
CASE c.relkind
WHEN 'r' THEN 'TABLE'
WHEN 'v' THEN 'VIEW'
WHEN 'm' THEN 'MATERIALIZED VIEW'
WHEN 'S' THEN 'SEQUENCE'
WHEN 'p' THEN 'TABLE'
ELSE NULL END,
n.nspname, c.relname, 'charmed_<database-name>_owner')
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public'
LOOP
EXECUTE r.format;
END LOOP;
END$$;
At this stage, the database has been completely imported. The cluster can be scaled, and the client app can be related to the new PostgreSQL 16 database.