doc/topics/autodevops/upgrading_postgresql.md
{{< details >}}
{{< /details >}}
When POSTGRES_ENABLED is true, Auto DevOps provides an
in-cluster PostgreSQL database for your application.
The version of the chart used to provision PostgreSQL:
GitLab encourages users to migrate their database to the newer PostgreSQL chart.
This guide provides instructions on how to migrate your PostgreSQL database, which involves:
kubectl.kubectl.
This varies based on Kubernetes providers.POSTGRES_ENABLED to false, as this setting deletes
any existing channel 1 database.[!note] If you have configured Auto DevOps to have staging, consider trying out the backup and restore steps on staging first, or trying this out on a review app.
If required, take your application offline to prevent the database from being modified after the database dump is created.
Get the Kubernetes namespace for the environment. It typically looks like <project-name>-<project-id>-<environment>.
In this example, the namespace is called minimal-ruby-app-4349298-production.
$ kubectl get ns
NAME STATUS AGE
minimal-ruby-app-4349298-production Active 7d14h
For ease of use, export the namespace name:
export APP_NAMESPACE=minimal-ruby-app-4349298-production
Get the deployment name for your application with the following command. In this example, the deployment name is production.
$ kubectl get deployment --namespace "$APP_NAMESPACE"
NAME READY UP-TO-DATE AVAILABLE AGE
production 2/2 2 2 7d21h
production-postgres 1/1 1 1 7d21h
To prevent the database from being modified, set replicas to 0 for the deployment with the following command.
We use the deployment name from the previous step (deployments/<DEPLOYMENT_NAME>).
$ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE"
deployment.extensions/production scaled
You must also set replicas to zero for workers if you have any.
Get the service name for PostgreSQL. The name of the service should end with -postgres. In this example, the service name is production-postgres.
$ kubectl get svc --namespace "$APP_NAMESPACE"
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
production-auto-deploy ClusterIP 10.30.13.90 <none> 5000/TCP 7d14h
production-postgres ClusterIP 10.30.4.57 <none> 5432/TCP 7d14h
Get the pod name for PostgreSQL with the following command. In this example, the pod name is production-postgres-5db86568d7-qxlxv.
$ kubectl get pod --namespace "$APP_NAMESPACE" -l app=production-postgres
NAME READY STATUS RESTARTS AGE
production-postgres-5db86568d7-qxlxv 1/1 Running 0 7d14h
Connect to the pod with:
kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" -- bash
Once, connected, create a dump file with the following command.
SERVICE_NAME is the service name obtained in a previous step.
USERNAME is the username you have configured for PostgreSQL. The default is user.
DATABASE_NAME is usually the environment name.
When prompted for the database password, the default is testing-password.
## Format is:
# pg_dump -h SERVICE_NAME -U USERNAME DATABASE_NAME > /tmp/backup.sql
pg_dump -h production-postgres -U user production > /tmp/backup.sql
Once the backup dump is complete, exit the Kubernetes exec process with <kbd>Control</kbd>-<kbd>D</kbd> or exit.
Download the dump file with the following command:
kubectl cp --namespace "$APP_NAMESPACE" production-postgres-5db86568d7-qxlxv:/tmp/backup.sql backup.sql
By default the persistent volumes
used to store the underlying data for PostgreSQL is marked as Delete
when the pods and pod claims that use the volume is deleted.
This is significant as, when you opt into the newer 8.2.1 PostgreSQL, the older 0.7.1 PostgreSQL is deleted causing the persistent volumes to be deleted as well.
You can verify this by using the following command:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 8Gi RWO Delete Bound minimal-ruby-app-4349298-staging/staging-postgres standard 7d22h
pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 8Gi RWO Delete Bound minimal-ruby-app-4349298-production/production-postgres standard 7d22h
To retain the persistent volume, even when the older 0.7.1 PostgreSQL is deleted, change
the retention policy to Retain. In this example, the persistent volume names are found
by looking at the claims names. To keep the volumes for the staging and production
environments of the minimal-ruby-app-4349298 application, the volume names are
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 and pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096:
$ kubectl patch pv pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
persistentvolume/pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 patched
$ kubectl patch pv pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'
persistentvolume/pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 patched
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-0da80c08-5239-11ea-9c8d-42010a8e0096 8Gi RWO Retain Bound minimal-ruby-app-4349298-staging/staging-postgres standard 7d22h
pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096 8Gi RWO Retain Bound minimal-ruby-app-4349298-production/production-postgres standard 7d22h
[!warning] Using the newer version of PostgreSQL deletes the older 0.7.1 PostgreSQL. To prevent the underlying data from being deleted, you can choose to retain the persistent volume.
You can also modify the steps below to scope
the AUTO_DEVOPS_POSTGRES_CHANNEL, AUTO_DEVOPS_POSTGRES_DELETE_V1 and
POSTGRES_VERSION variables to specific environments, for example, staging.
AUTO_DEVOPS_POSTGRES_CHANNEL to 2. This opts into using the
newer 8.2.1-based PostgreSQL, and removes the older 0.7.1-based
PostgreSQL.AUTO_DEVOPS_POSTGRES_DELETE_V1 to a non-empty value. This flag is a
safeguard to prevent accidental deletion of databases.
<!-- DO NOT REPLACE when upgrading GitLab's supported version. This is NOT related to GitLab's PostgreSQL version support, but the one deployed by Auto DevOps. -->
POSTGRES_VERSION set, make sure it is set to 9.6.16 or later. This is the
minimum PostgreSQL version supported by Auto DevOps. See also the list of
tags available.PRODUCTION_REPLICAS to 0. For other environments, use
REPLICAS with an environment scope.DB_INITIALIZE or DB_MIGRATE variables, either
remove the variables, or rename the variables temporarily to
XDB_INITIALIZE or the XDB_MIGRATE to effectively disable them.main.Get the pod name for the new PostgreSQL, in this example, the pod name is
production-postgresql-0:
$ kubectl get pod --namespace "$APP_NAMESPACE" -l app=postgresql
NAME READY STATUS RESTARTS AGE
production-postgresql-0 1/1 Running 0 19m
Copy the dump file from the backup steps to the pod:
kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql
Connect to the pod:
kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" -- bash
Once connected to the pod, run the following command to restore the database.
testing-password.USERNAME is the username you have configured for PostgreSQL. The default is user.DATABASE_NAME is usually the environment name.## Format is:
# psql -U USERNAME -d DATABASE_NAME < /tmp/backup.sql
psql -U user -d production < /tmp/backup.sql
You can now check that your data restored correctly after the restore
is complete. You can perform spot checks of your data by using the
psql.
Once you are satisfied the database has been restored, run the following steps to reinstate your application:
DB_INITIALIZE and DB_MIGRATE variables, if previously
removed or disabled.PRODUCTION_REPLICAS or REPLICAS variable to its original value.main. After the pipeline is successful, your
application should be serving traffic as before.