2020-10-30 17:08:52 -04:00
---
2020-11-16 13:09:15 -05:00
stage: Configure
group: Configure
2020-11-26 01:09:20 -05:00
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
2020-10-30 17:08:52 -04:00
---
2021-02-08 13:09:49 -05:00
# Upgrading PostgreSQL for Auto DevOps **(FREE)**
2020-03-19 23:09:12 -04:00
2020-04-07 23:09:31 -04:00
Auto DevOps provides an [in-cluster PostgreSQL database ](customize.md#postgresql-database-support )
2020-03-19 23:09:12 -04:00
for your application.
The version of the chart used to provision PostgreSQL:
- Is 0.7.1 in GitLab 12.8 and earlier.
- Can be set to from 0.7.1 to 8.2.1 in GitLab 12.9 and later.
2020-04-01 02:07:50 -04:00
GitLab encourages users to migrate their database to the newer PostgreSQL chart.
2020-03-19 23:09:12 -04:00
This guide provides instructions on how to migrate your PostgreSQL database, which
involves:
1. Taking a database dump of your data.
1. Installing a new PostgreSQL database using the newer version 8.2.1 of the chart
and removing the old PostgreSQL installation.
1. Restoring the database dump into the new PostgreSQL.
## Prerequisites
1. Install
2021-03-09 13:09:41 -05:00
[`kubectl` ](https://kubernetes.io/docs/tasks/tools/ ).
2020-03-19 23:09:12 -04:00
1. Ensure that you can access your Kubernetes cluster using `kubectl` .
This varies based on Kubernetes providers.
1. Prepare for downtime. The steps below include taking the application offline
so that the in-cluster database does not get modified after the database dump is created.
2020-06-22 23:09:26 -04:00
1. Ensure you have not set `POSTGRES_ENABLED` to `false` , as this setting deletes
any existing channel 1 database. For more information, see
2021-02-19 13:10:51 -05:00
[Detected an existing PostgreSQL database ](troubleshooting.md#detected-an-existing-postgresql-database ).
2020-03-19 23:09:12 -04:00
2020-12-07 22:09:37 -05:00
NOTE:
2020-07-16 02:09:33 -04:00
If you have configured Auto DevOps to have staging,
2020-03-19 23:09:12 -04:00
consider trying out the backup and restore steps on staging first, or
trying this out on a review app.
## Take your application offline
If required, take your application offline to prevent the database from
being modified after the database dump is created.
1. Get the Kubernetes namespace for the environment. It typically looks like `<project-name>-<project-id>-<environment>` .
In our example, the namespace is called `minimal-ruby-app-4349298-production` .
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ kubectl get ns
NAME STATUS AGE
minimal-ruby-app-4349298-production Active 7d14h
```
1. For ease of use, export the namespace name:
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
export APP_NAMESPACE=minimal-ruby-app-4349298-production
```
1. Get the deployment name for your application with the following command. In our example, the deployment name is `production` .
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ 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
```
1. 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 > `).
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ kubectl scale --replicas=0 deployments/production --namespace "$APP_NAMESPACE"
deployment.extensions/production scaled
```
2020-11-18 19:09:41 -05:00
1. You must also set replicas to zero for workers if you have any.
2020-03-19 23:09:12 -04:00
## Backup
1. Get the service name for PostgreSQL. The name of the service should end with `-postgres` . In our example the service name is `production-postgres` .
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ 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
```
1. Get the pod name for PostgreSQL with the following command. In our example, the pod name is `production-postgres-5db86568d7-qxlxv` .
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ kubectl get pod --namespace "$APP_NAMESPACE" -l app=production-postgres
NAME READY STATUS RESTARTS AGE
production-postgres-5db86568d7-qxlxv 1/1 Running 0 7d14h
```
1. Connect to the pod with:
2020-05-19 14:08:11 -04:00
```shell
2021-07-30 08:10:12 -04:00
kubectl exec -it production-postgres-5db86568d7-qxlxv --namespace "$APP_NAMESPACE" -- bash
2020-03-19 23:09:12 -04:00
```
1. 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.
2020-11-18 19:09:41 -05:00
- When prompted for the database password, the default is `testing-password` .
2020-03-19 23:09:12 -04:00
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
## 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
```
1. Once the backup dump is complete, exit the Kubernetes exec process with `Control-D` or `exit` .
1. Download the dump file with the following command:
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
kubectl cp --namespace "$APP_NAMESPACE" production-postgres-5db86568d7-qxlxv:/tmp/backup.sql backup.sql
```
## Retain persistent volumes
By default the [persistent
volumes](https://kubernetes.io/docs/concepts/storage/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.
2020-05-13 14:08:47 -04:00
This is significant as, when you opt into the newer 8.2.1 PostgreSQL, the older 0.7.1 PostgreSQL is
2020-03-19 23:09:12 -04:00
deleted causing the persistent volumes to be deleted as well.
You can verify this by using the following command:
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ 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, we can change the retention policy to `Retain` . In this example, we find
the persistent volume names by looking at the claims names. As we are
interested in keeping the volumes for the staging and production of the
`minimal-ruby-app-4349298` application, the volume names here are
`pvc-0da80c08-5239-11ea-9c8d-42010a8e0096` and `pvc-9085e3d3-5239-11ea-9c8d-42010a8e0096` :
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ 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
```
## Install new PostgreSQL
2020-12-04 16:09:29 -05:00
WARNING:
2020-11-18 19:09:41 -05:00
Using the newer version of PostgreSQL deletes
2020-03-19 23:09:12 -04:00
the older 0.7.1 PostgreSQL. To prevent the underlying data from being
2020-06-22 23:09:26 -04:00
deleted, you can choose to retain the [persistent volume ](#retain-persistent-volumes ).
2020-03-19 23:09:12 -04:00
2020-12-07 22:09:37 -05:00
NOTE:
2020-07-16 02:09:33 -04:00
You can also
2021-08-11 05:10:00 -04:00
[scope ](../../ci/environments/index.md#scope-environments-with-specs ) the
2020-05-13 14:08:47 -04:00
`AUTO_DEVOPS_POSTGRES_CHANNEL` , `AUTO_DEVOPS_POSTGRES_DELETE_V1` and
2021-12-03 07:10:23 -05:00
`POSTGRES_VERSION` variables to specific environments, for example, `staging` .
2020-03-19 23:09:12 -04:00
1. Set `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.
2020-05-13 14:08:47 -04:00
1. Set `AUTO_DEVOPS_POSTGRES_DELETE_V1` to a non-empty value. This flag is a
safeguard to prevent accidental deletion of databases.
2020-10-06 08:08:38 -04:00
<!-- 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. -->
1. If you have a `POSTGRES_VERSION` set, make sure it is set to `9.6.16` *or
higher*. This is the
minimum PostgreSQL version supported by Auto DevOps. See also the list of
[tags available ](https://hub.docker.com/r/bitnami/postgresql/tags ).
2020-03-19 23:09:12 -04:00
1. Set `PRODUCTION_REPLICAS` to `0` . For other environments, use
2021-08-11 05:10:00 -04:00
`REPLICAS` with an [environment scope ](../../ci/environments/index.md#scope-environments-with-specs ).
2020-03-19 23:09:12 -04:00
1. If you have set the `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.
1. Run a new CI pipeline for the branch. In this case, we run a new CI
2021-06-16 23:09:59 -04:00
pipeline for `main` .
2020-11-18 19:09:41 -05:00
1. After the pipeline is successful, your application is upgraded
with the new PostgreSQL installed. Zero replicas exist at this time, so
no traffic is served for your application (to prevent
2020-03-19 23:09:12 -04:00
new data from coming in).
## Restore
1. Get the pod name for the new PostgreSQL, in our example, the pod name is
`production-postgresql-0` :
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
$ kubectl get pod --namespace "$APP_NAMESPACE" -l app=postgresql
NAME READY STATUS RESTARTS AGE
production-postgresql-0 1/1 Running 0 19m
````
1. Copy the dump file from the backup steps to the pod:
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
kubectl cp --namespace "$APP_NAMESPACE" backup.sql production-postgresql-0:/tmp/backup.sql
```
1. Connect to the pod:
2020-05-19 14:08:11 -04:00
```shell
2021-07-30 08:10:12 -04:00
kubectl exec -it production-postgresql-0 --namespace "$APP_NAMESPACE" -- bash
2020-03-19 23:09:12 -04:00
```
1. Once connected to the pod, run the following command to restore the database.
2020-11-18 19:09:41 -05:00
- When asked for the database password, the default is `testing-password` .
2020-03-23 23:09:28 -04:00
- `USERNAME` is the username you have configured for PostgreSQL. The default is `user` .
2020-03-19 23:09:12 -04:00
- `DATABASE_NAME` is usually the environment name.
2020-05-19 14:08:11 -04:00
```shell
2020-03-19 23:09:12 -04:00
## Format is:
# psql -U USERNAME -d DATABASE_NAME < /tmp/backup.sql
psql -U user -d production < /tmp/backup.sql
```
1. 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` .
## Reinstate your application
Once you are satisfied the database has been restored, run the following
steps to reinstate your application:
1. Restore the `DB_INITIALIZE` and `DB_MIGRATE` variables, if previously
removed or disabled.
1. Restore the `PRODUCTION_REPLICAS` or `REPLICAS` variable to its original value.
1. Run a new CI pipeline for the branch. In this case, we run a new CI
2021-06-16 23:09:59 -04:00
pipeline for `main` . After the pipeline is successful, your
2020-03-19 23:09:12 -04:00
application should be serving traffic as before.