|
| 1 | +# PostgreSQL Version Migration Script |
| 2 | + |
| 3 | +This script facilitates the migration of a PostgreSQL database between different versions within a Kubernetes environment. It addresses a specific limitation of the a8s framework components, which cannot perform backup and restore operations between different PostgreSQL instances. |
| 4 | + |
| 5 | +The following provides a workaround for this limitation, allowing for migration between different PostgreSQL versions. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +- Kubernetes cluster with kubectl configured |
| 10 | +- Source and destination PostgreSQL instances (of different versions) running as pods in the cluster |
| 11 | +- Sufficient permissions to execute kubectl commands and access PostgreSQL instances |
| 12 | + |
| 13 | +## Usage |
| 14 | + |
| 15 | +```bash |
| 16 | +./migrate_postgresql_versions.sh.sh <SOURCE_INSTANCE> <DESTINATION_INSTANCE> [DB_NAME] [DB_USER] |
| 17 | +``` |
| 18 | + |
| 19 | +### Parameters |
| 20 | + |
| 21 | +- `<SOURCE_INSTANCE>`: The name of the source PostgreSQL pod (older version) |
| 22 | +- `<DESTINATION_INSTANCE>`: The name of the destination PostgreSQL pod (newer version) |
| 23 | +- `[DB_NAME]`: The name of the database to migrate (optional, defaults to 'a9s_apps_default_db') |
| 24 | +- `[DB_USER]`: The PostgreSQL user to use for operations (optional, defaults to 'postgres') |
| 25 | + |
| 26 | +## Script Workflow |
| 27 | + |
| 28 | +1. Validates input parameters and checks for the existence of source and destination instances. |
| 29 | +2. Creates a backup of the specified database on the source instance (older version). |
| 30 | +3. Copies the backup file to the local machine. |
| 31 | +4. Checks if the destination database exists in the newer version instance, creates it if necessary. |
| 32 | +5. Copies the backup file to the destination instance. |
| 33 | +6. Restores the backup on the destination instance (newer version). |
| 34 | +7. Verifies the data restoration by listing tables in the destination database. |
| 35 | + |
| 36 | +## Error Handling |
| 37 | + |
| 38 | +The script includes error handling to catch and report issues during the migration process. If an error occurs, the script will display an error message and exit. |
| 39 | + |
| 40 | +## Cleanup |
| 41 | + |
| 42 | +The script automatically removes the temporary backup file from the local machine upon completion or in case of an error. |
| 43 | + |
| 44 | +## Example |
| 45 | + |
| 46 | +To migrate the 'myapp' database from PostgreSQL 12 to PostgreSQL 14: |
| 47 | + |
| 48 | +```bash |
| 49 | +./migrate_postgres_version.sh postgres-12-pod postgres-14-pod a9s_apps_default_db postgres |
| 50 | +``` |
| 51 | + |
| 52 | +## Important Notes |
| 53 | + |
| 54 | +- This script is specifically designed to work around the limitations of the a8s framework components in migrating data between different PostgreSQL versions. |
| 55 | +- Ensure that you have tested the migration process in a non-production environment before applying it to production databases. |
| 56 | +- Always have a backup of your data before performing any migration. |
| 57 | +- The script assumes that the PostgreSQL instances are running in containers named 'postgres' within their respective pods. |
| 58 | + |
| 59 | +migrate_postgresql_versions.sh |
| 60 | + |
| 61 | +```bash |
| 62 | +#!/bin/bash |
| 63 | + |
| 64 | +set -e # Exit immediately if a command exits with a non-zero status |
| 65 | + |
| 66 | +# Check if required arguments are provided |
| 67 | +if [ "$#" -lt 2 ]; then |
| 68 | + echo "Usage: $0 <SOURCE_INSTANCE> <DESTINATION_INSTANCE> [DB_NAME] [DB_USER]" |
| 69 | + exit 1 |
| 70 | +fi |
| 71 | + |
| 72 | +SOURCE_INSTANCE="$1" |
| 73 | +DESTINATION_INSTANCE="$2" |
| 74 | +DB_NAME="${3:-a9s_apps_default_db}" # Default to 'a9s_apps_default_db' if not provided |
| 75 | +DB_USER="${4:-postgres}" # Default to 'postgres' if not provided |
| 76 | +BACKUP_FILE="pg_backup_$(date +%Y%m%d_%H%M%S).sql" |
| 77 | + |
| 78 | +# Function to execute PostgreSQL commands |
| 79 | +exec_psql() { |
| 80 | + local instance="$1" |
| 81 | + local command="$2" |
| 82 | + kubectl exec "$instance" --container postgres -- psql -U "$DB_USER" -d "$DB_NAME" -c "$command" |
| 83 | +} |
| 84 | + |
| 85 | +# Function to handle errors |
| 86 | +handle_error() { |
| 87 | + echo "Error: $1" >&2 |
| 88 | + exit 1 |
| 89 | +} |
| 90 | + |
| 91 | +# Trap to clean up on script exit |
| 92 | +trap 'rm -f ./"$BACKUP_FILE"' EXIT |
| 93 | + |
| 94 | +# Check if source instance exists and is accessible |
| 95 | +echo "Checking source instance $SOURCE_INSTANCE..." |
| 96 | +kubectl get pod "$SOURCE_INSTANCE" &>/dev/null || handle_error "Source instance $SOURCE_INSTANCE not found" |
| 97 | + |
| 98 | +# Check if destination instance exists and is accessible |
| 99 | +echo "Checking destination instance $DESTINATION_INSTANCE..." |
| 100 | +kubectl get pod "$DESTINATION_INSTANCE" &>/dev/null || handle_error "Destination instance $DESTINATION_INSTANCE not found" |
| 101 | + |
| 102 | +# Check if the database exists in the source instance |
| 103 | +echo "Checking if database $DB_NAME exists in $SOURCE_INSTANCE..." |
| 104 | +exec_psql "$SOURCE_INSTANCE" "\l" | grep -q "$DB_NAME" || handle_error "Database $DB_NAME not found in source instance" |
| 105 | + |
| 106 | +# Create backup on source instance |
| 107 | +echo "Creating backup of $DB_NAME from $SOURCE_INSTANCE..." |
| 108 | +kubectl exec "$SOURCE_INSTANCE" --container postgres -- pg_dump -U "$DB_USER" -d "$DB_NAME" -f "/tmp/$BACKUP_FILE" || handle_error "Failed to create backup" |
| 109 | + |
| 110 | +# Copy backup file to local machine |
| 111 | +echo "Copying backup file to local machine..." |
| 112 | +kubectl cp "$SOURCE_INSTANCE:/tmp/$BACKUP_FILE" "./$BACKUP_FILE" -c postgres || handle_error "Failed to copy backup to local machine" |
| 113 | + |
| 114 | +# Check if the database exists in the destination instance, create if not |
| 115 | +echo "Checking if database $DB_NAME exists in $DESTINATION_INSTANCE..." |
| 116 | +if ! exec_psql "$DESTINATION_INSTANCE" "\l" | grep -q "$DB_NAME"; then |
| 117 | + echo "Creating database $DB_NAME in $DESTINATION_INSTANCE..." |
| 118 | + exec_psql "$DESTINATION_INSTANCE" "CREATE DATABASE $DB_NAME;" || handle_error "Failed to create database in destination instance" |
| 119 | +fi |
| 120 | + |
| 121 | +# Copy backup file to destination instance |
| 122 | +echo "Copying backup file to $DESTINATION_INSTANCE..." |
| 123 | +kubectl cp "./$BACKUP_FILE" "$DESTINATION_INSTANCE:/tmp/$BACKUP_FILE" -c postgres || handle_error "Failed to copy backup to destination instance" |
| 124 | + |
| 125 | +# Restore from backup on destination instance |
| 126 | +echo "Restoring backup on $DESTINATION_INSTANCE..." |
| 127 | +kubectl exec "$DESTINATION_INSTANCE" --container postgres -- psql -U "$DB_USER" -d "$DB_NAME" -f "/tmp/$BACKUP_FILE" || handle_error "Failed to restore backup" |
| 128 | + |
| 129 | +# Verify data restoration |
| 130 | +echo "Verifying data restoration in $DESTINATION_INSTANCE..." |
| 131 | +exec_psql "$DESTINATION_INSTANCE" "\dt" || handle_error "Failed to verify data restoration" |
| 132 | + |
| 133 | +echo "Migration completed successfully!" |
| 134 | +``` |
0 commit comments