Migration from MariaDB to PostgreSQL
While we have tested the migration process thoroughly and found it to work in our scenarios, we cannot guarantee that it will be successful in all possible cases. Please be aware that you use this guide and the pgloader tool at your own risk. You are responsible for verifying that all your data has been successfully migrated.
This guide assumes that you already have a running nevisAdmin 4 instance and a MariaDB database you want to migrate from.
nevisAppliance and RPM-based installations
-
If you haven't done so already, stop the nevisAdmin4 service, so that it doesn't write in the database during migration.
-
Setup the PostgreSQL database. For the setup guide, see PostgreSQL initial setup.
-
Change the
dbproperties in yournevisadmin4.ymlfile to point to the PostgreSQL database. -
Start the nevisAdmin4 service. This will initialize the schema in the new database, preparing it for the data migration.
-
Stop the nevisAdmin4 service.
-
Create the following migration file. Name it
postgres_migration.load.LOAD DATABASEFROM mysql://<mariadb-user>:<mariadb-pw>@<mariadb-host>:<mariadb-port>/nevisadmin4INTO postgresql://<postgres-user>:<postgres-pw>@<postgres-host>:<postgres-port>/nevisadmin4?sslmode=allowalter schema 'nevisadmin4' rename to '<postgres-schema>'SETtimezone to '<inverse-UTC-of-the-admin4-server>'casttype clob to text,type binary to bytea,column analytics_meta.last_confirmation to timestamp,column job_status.end_time to timestamp,column job_status.start_time to timestamp,column job_status.creation_time to timestamp,column job_status.progress to realWITHdata only,truncateexcluding table names matching~<flyway_schema_history>; -
Replace
<mariadb-user>,<mariadb-pw>,<mariadb-host>,<mariadb-port>,<postgres-user>,<postgres-pw>,<postgres-host>,<postgres-port>, and<postgres-schema>with the appropriate values.<postgres-user>needs to be either the schema owner of<postgres-schema>, or a superuser.
-
Replace the timezone value with the timezone of your nevisAdmin4 server, with a negated sign. For example, if your nevisAdmin4 server was in
UTC+1, replace it withUTC-1. If it was inUTC-1, replace it withUTC+1. -
Run this command to run the migration. Replace
<path>/postgres_migration.loadwith the absolute path topostgres_migration.load.docker run --rm -it --network host -v <path>/postgres_migration.load:/postgres_migration.load dimitri/pgloader:latest pgloader --no-ssl-cert-verification /postgres_migration.loadExample output:
2024-08-14T08:06:47.036001Z LOG pgloader version "3.6.7~devel"2024-08-14T08:06:47.250007Z LOG Migrating from #<MYSQL-CONNECTION mysql://mariadb@localhost:3306/nevisadmin4 {1007EAEE53}>2024-08-14T08:06:47.250007Z LOG Migrating into #<PGSQL-CONNECTION pgsql://na4_owner@localhost:5432/nevisadmin4 {1007EAFB93}>2024-08-14T08:06:47.926026Z WARNING PostgreSQL warning: constraint "fk_binary_secret_permission" of relation "binary_secret_permission" does not exist, skipping2024-08-14T08:06:47.928026Z WARNING PostgreSQL warning: constraint "fk_dha_id_dh_id" of relation "deployment_history_action" does not exist, skipping2024-08-14T08:06:47.929026Z WARNING PostgreSQL warning: constraint "fk_dhdt_id_dh_id" of relation "deployment_history_deployment_target" does not exist, skipping2024-08-14T08:06:47.932026Z WARNING PostgreSQL warning: constraint "ptc_id_pt_id" of relation "project_template_categories" does not exist, skipping2024-08-14T08:06:47.933026Z WARNING PostgreSQL warning: constraint "fk_secret_permission" of relation "secret_permission" does not exist, skipping2024-08-14T08:06:47.934026Z WARNING PostgreSQL warning: constraint "fk_gm_user" of relation "group_member" does not exist, skipping2024-08-14T08:06:47.935026Z WARNING PostgreSQL warning: constraint "fk_gm_usergroup" of relation "group_member" does not exist, skipping2024-08-14T08:06:49.210063Z LOG report summary resettable name errors rows bytes total time---------------------------------------------- --------- --------- --------- --------------fetch meta data 0 42 0.258sDrop Foreign Keys 0 14 0.029sTruncate 0 35 0.332s---------------------------------------------- --------- --------- --------- --------------na4_owner.binary_cache 0 2 0.1 kB 0.076sna4_owner.analytics_meta 0 1 0.0 kB 0.051sna4_owner.assigned_group_role 0 1 0.0 kB 0.113sna4_owner.assigned_group_permission 0 1 0.0 kB 0.093sna4_owner.assigned_role 0 1 0.0 kB 0.118sna4_owner.assigned_permission 0 1 0.0 kB 0.131sna4_owner.binary_secret_permission 0 1 0.0 kB 0.163sna4_owner.binary_secret 0 1 0.0 kB 0.158sna4_owner.bundle_entity 0 1 0.0 kB 0.167sna4_owner.blacklisttoken 0 1 0.0 kB 0.226sna4_owner.constant 0 1 0.0 kB 0.251sna4_owner.ca 0 1 5.6 kB 0.281sna4_owner.deployment_history_action 0 1 0.1 kB 0.237sna4_owner.deployment_history 0 1 0.1 kB 0.269sna4_owner.group_member 0 2 0.0 kB 0.285sna4_owner.inventory 0 1 0.1 kB 0.334sna4_owner.deployment_history_deployment_target 0 2 0.0 kB 0.364sna4_owner.head 0 1 0.1 kB 0.351sna4_owner.inventory_modification 0 1 0.1 kB 0.357sna4_owner.inventory_head 0 1 0.1 kB 0.407sna4_owner.modification 0 1 0.1 kB 0.383sna4_owner.job_status 0 1 0.1 kB 0.443sna4_owner.pki_store_content 0 1 0.0 kB 0.438sna4_owner.project_template_categories 0 2 0.0 kB 0.458sna4_owner.pki_store 0 1 0.1 kB 0.463sna4_owner.resource_modification 0 1 0.1 kB 0.505sna4_owner.project_template 0 1 0.2 kB 0.534sna4_owner.secret 0 1 0.0 kB 0.523sna4_owner.resource_head 0 1 0.1 kB 0.539sna4_owner.tenant 0 1 0.0 kB 0.551sna4_owner.role 0 1 0.0 kB 0.591sna4_owner."user" 0 2 0.1 kB 0.572sna4_owner.secret_permission 0 0 0.597sna4_owner.tip 0 1 0.1 kB 0.610sna4_owner.usergroup 0 1 0.0 kB 0.631s---------------------------------------------- --------- --------- --------- --------------COPY Threads Completion 0 4 0.687sReset Sequences 0 0 0.078sCreate Foreign Keys 0 7 0.022sInstall Comments 0 0 0.000s---------------------------------------------- --------- --------- --------- --------------Total import time ✓ 39 7.6 kB 0.787snoteThe warnings for the constraints are false positive.
-
Start the nevisAdmin4 service again.
Kubernetes-based installation
-
Setup a PostgreSQL database. For the setup guide, see PostgreSQL initial setup.
- It might be required to whitelist the IP of the Kubernetes cluster in the PostgreSQL database for the migration to work.
-
Get the current nevisAdmin4 configuration using helm:
RELEASE_NAMESPACE=<release-namespace>helm get values nevisadmin4 -n $RELEASE_NAMESPACE > old-values.yamlThis will download the current helm values to
old-values.yaml. -
Make a copy of
old-values.yamlcallednew-values.yaml. You will have to change the database properties in it to point to the newly created postgres database. Some properties that you have to change might be missing. In that case, add them.-
databaseproperties- Change the
database.typetopostgresql. - Change the values of
database.hostanddatabase.portto point to the service that hosts the PostgreSQL database. - Change the root user credentials to the PostgreSQL root user credentials.
- Example config
-
before modification:
database:host: mariadbroot:password: Generated1!username: root -
after modification:
database:type: postgresqlhost: postgresport: 5432root:password: postgres_passwordusername: postgres
-
- Change the
-
nevisAdmin4.databaseproperties- Change the
nevisAdmin4.database.applicationUserandnevisAdmin4.database.applicationUserPasswordto the PostgreSQL user and user-password. - Change the
nevisAdmin4.database.schemaUserandnevisAdmin4.database.schemaUserPasswordto the PostgreSQL schema owner and schema-owner-password.noteThese users will be created if they don't exist yet.
- Example config
-
before modification:
nevisAdmin4:database:applicationUserPassword: Generated1!enableSSL: falseschemaUserPassword: Generated1! -
after modification:
nevisAdmin4:database:applicationUser: na4_userapplicationUserPassword: user_passwordenableSSL: falseschemaUser: na4_ownerschemaUserPassword: owner_password
-
- Change the
-
-
Use helm to update the nevisAdmin4 deployment:
# For the temporary credentials, click the download button for one of the Docker images at https://portal.nevis.net/portal/secure/releases/rollingCLOUDSMITH_PASSWORD=<cloudsmith-password>helm upgrade nevisadmin4 nevisadmin4 -n $RELEASE_NAMESPACE -f new-values.yaml \--repo https://dl.cloudsmith.io/$CLOUDSMITH_PASSWORD/nevissecurity/rolling/helm/charts/ \--version <version>noteReplace
<version>with the version of the nevisAdmin4 chart you are using. If you don't provide a version, helm will use the latest version.This will also restart the nevisAdmin4 service, this time with the new database configuration, which will initialize the schema in the new database.
-
Stop nevisAdmin4 by scaling the replicas down to zero:
kubectl scale statefulset nevisadmin4 --replicas 0 -n $RELEASE_NAMESPACE -
Create a ConfigMap for the postgres_migration.load file
apiVersion: v1kind: ConfigMapmetadata:name: postgres-migration-configdata:postgres_migration.load: |LOAD DATABASEFROM mysql://<mariadb-user>:<mariadb-pw>@<mariadb-host>:<mariadb-port>/nevisadmin4INTO postgresql://<postgres-user>:<postgres-pw>@<postgres-host>:<postgres-port>/nevisadmin4?sslmode=allowalter schema 'nevisadmin4' rename to '<postgres-schema>'SETtimezone to '<inverse-UTC-of-the-admin4-server>'casttype clob to text,type binary to bytea,column analytics_meta.last_confirmation to timestamp,column job_status.end_time to timestamp,column job_status.start_time to timestamp,column job_status.creation_time to timestamp,column job_status.progress to realWITHdata only,truncateexcluding table names matching~<flyway_schema_history>; -
Replace
<mariadb-user>,<mariadb-pw>,<mariadb-host>,<mariadb-port>,<postgres-user>,<postgres-pw>,<postgres-host>,<postgres-port>, and<postgres-schema>with the appropriate values.<postgres-user>needs to be either the schema owner of<postgres-schema>, or a superuser.- Example:
FROM mysql://admin4schemauser:Generated1!@mariadb:3306/nevisadmin4INTO postgresql://na4_owner:owner_password@postgres:5432/nevisadmin4?sslmode=allowalter schema 'nevisadmin4' rename to 'na4_owner' -
Replace the timezone value with the timezone of your nevisAdmin4 server, with a negated sign. For example, if your nevisAdmin4 server was in
UTC+1, replace it withUTC-1. If it was inUTC-1, replace it withUTC+1. -
Create a Job to run the pgloader container
apiVersion: batch/v1kind: Jobmetadata:name: postgres-migration-jobspec:template:spec:containers:- name: pgloaderimage: dimitri/pgloader:latestcommand: ["pgloader", "--no-ssl-cert-verification", "/config/postgres_migration.load"]volumeMounts:- name: config-volumemountPath: /configrestartPolicy: Nevervolumes:- name: config-volumeconfigMap:name: postgres-migration-configbackoffLimit: 1 -
Apply the ConfigMap and Job
kubectl apply -f postgres-migration-config.yaml -n $RELEASE_NAMESPACE
kubectl apply -f postgres-migration-job.yaml -n $RELEASE_NAMESPACE
- Check the logs of the job
kubectl logs -n $RELEASE_NAMESPACE $(kubectl get pods -n $RELEASE_NAMESPACE --selector=job-name=postgres-migration-job -o=jsonpath='{.items[0].metadata.name}')
You should see an output that is similar to the one in the nevisAppliance and RPM-based installations section. 12. Clean up the Job and ConfigMap
kubectl delete job postgres-migration-job -n $RELEASE_NAMESPACE
kubectl delete configmap postgres-migration-config -n $RELEASE_NAMESPACE
- Start the nevisAdmin4 service again
kubectl scale statefulset nevisadmin4 --replicas 1 -n $RELEASE_NAMESPACE