Compare commits
17 commits
main
...
pg_backup_
Author | SHA1 | Date | |
---|---|---|---|
Alexey Skobkin | c4ed180592 | ||
Alexey Skobkin | f2dff8632f | ||
Alexey Skobkin | 34c2a222a3 | ||
Alexey Skobkin | a2f25f51a8 | ||
Alexey Skobkin | 198285910a | ||
Alexey Skobkin | f40839b9ae | ||
Alexey Skobkin | e5731a3529 | ||
Alexey Skobkin | 6498a3ab1d | ||
Alexey Skobkin | 89b50cc40f | ||
Alexey Skobkin | 66667dc103 | ||
Alexey Skobkin | 06961c72b5 | ||
Alexey Skobkin | 641ba06898 | ||
Alexey Skobkin | eee9995248 | ||
Alexey Skobkin | aed0c982a8 | ||
Alexey Skobkin | a2b01d0685 | ||
Alexey Skobkin | b26c680e52 | ||
Alexey Skobkin | d1d11c4668 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*/.env.dist
|
10
README.md
10
README.md
|
@ -1,3 +1,13 @@
|
||||||
# scripts
|
# scripts
|
||||||
|
|
||||||
Random scripts for different tasks
|
Random scripts for different tasks
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
If the script provides any configuration, make a copy of `.env.dist` file to `.env` and edit configuration there.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
cd some_script
|
||||||
|
cp .env.dist .env
|
||||||
|
nano .env
|
||||||
|
```
|
22
postgresql_backup/.env.dist
Normal file
22
postgresql_backup/.env.dist
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# Backup path
|
||||||
|
BACKUP_PATH="/path/to/backup/directory"
|
||||||
|
|
||||||
|
# Compression levels
|
||||||
|
ZSTD_LEVEL=5
|
||||||
|
GZIP_LEVEL=7
|
||||||
|
|
||||||
|
# Servers configuration
|
||||||
|
# Add as many as needed
|
||||||
|
|
||||||
|
# Database 1 configuration
|
||||||
|
DB1_HOST="localhost"
|
||||||
|
DB1_PORT="5432"
|
||||||
|
DB1_USER="user1"
|
||||||
|
# "custom" for .dump or "sql" for SQL compressed with Gzip
|
||||||
|
DB1_DUMP_FORMAT="custom"
|
||||||
|
|
||||||
|
# Database 2 configuration
|
||||||
|
#DB2_HOST="remote_host"
|
||||||
|
#DB2_PORT="5432"
|
||||||
|
#DB2_USER="user2"
|
||||||
|
#DB2_DUMP_FORMAT="sql"
|
57
postgresql_backup/README.md
Normal file
57
postgresql_backup/README.md
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
## Authentication
|
||||||
|
|
||||||
|
Do not forget to create and/or edit `~/.pgpass` file providing all needed passwords for each host:
|
||||||
|
|
||||||
|
The format is the following:
|
||||||
|
```properties
|
||||||
|
hostname:port:database:username:password
|
||||||
|
```
|
||||||
|
|
||||||
|
Example
|
||||||
|
|
||||||
|
```properties
|
||||||
|
localhost:5432:*:postgres:pg_password_1
|
||||||
|
localhost:5433:*:postgres:pg_password_2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scheduling
|
||||||
|
|
||||||
|
### Systemd
|
||||||
|
|
||||||
|
#### Service
|
||||||
|
|
||||||
|
`/etc/systemd/system/postgresql_backup.service`
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=PostgreSQL backup Script
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
WorkingDirectory=/root/scripts/postgresql_backup
|
||||||
|
ExecStart=/root/scripts/postgresql_backup/pg_backup.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Timer
|
||||||
|
|
||||||
|
`/etc/systemd/system/postgresql_backup.timer`
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Run Backup Script Every Night
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-* 22:00:00
|
||||||
|
Unit=postgresql_backup.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Then:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
systemctl enable postgresql_backup.timer --now
|
||||||
|
```
|
|
@ -1,38 +1,77 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Configuration
|
# Load environment variables from .env file
|
||||||
HOST="localhost"
|
if [ -f .env ]; then
|
||||||
PORT="5432"
|
export $(grep -v '^#' .env | xargs)
|
||||||
USER="your_postgres_user"
|
else
|
||||||
BACKUP_PATH="/path/to/backup/directory"
|
echo ".env file not found! Please create it with the necessary configuration."
|
||||||
DUMP_FORMAT="custom" # Set to "custom" for .dump or "sql" for plaintext SQL
|
exit 1
|
||||||
EXTENSION="dump" # Default extension
|
|
||||||
|
|
||||||
# Adjust file extension based on dump format
|
|
||||||
if [[ "$DUMP_FORMAT" == "sql" ]]; then
|
|
||||||
EXTENSION="sql.gz"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create backup directory if it doesn't exist
|
# Ensure BACKUP_PATH is set
|
||||||
mkdir -p "$BACKUP_PATH"
|
if [ -z "$BACKUP_PATH" ]; then
|
||||||
|
echo "BACKUP_PATH not set in .env file!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Get a list of all databases, excluding template databases
|
# Extract unique database prefixes (DB1, DB2, ...)
|
||||||
DATABASES=$(psql -h "$HOST" -p "$PORT" -U "$USER" -d postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;")
|
DATABASE_PREFIXES=$(env | grep -o 'DB[0-9]*_' | sort -u)
|
||||||
|
|
||||||
# Loop over each database and create a backup
|
# Loop through each database configuration prefix
|
||||||
for DB in $DATABASES; do
|
for PREFIX in $DATABASE_PREFIXES; do
|
||||||
BACKUP_FILE="$BACKUP_PATH/$DB.$EXTENSION"
|
HOST_VAR="${PREFIX}HOST"
|
||||||
|
PORT_VAR="${PREFIX}PORT"
|
||||||
|
USER_VAR="${PREFIX}USER"
|
||||||
|
FORMAT_VAR="${PREFIX}DUMP_FORMAT"
|
||||||
|
|
||||||
if [[ "$DUMP_FORMAT" == "custom" ]]; then
|
HOST=${!HOST_VAR}
|
||||||
# Create a compressed custom-format backup
|
PORT=${!PORT_VAR}
|
||||||
pg_dump -h "$HOST" -p "$PORT" -U "$USER" -Fc "$DB" -f "$BACKUP_FILE"
|
USER=${!USER_VAR}
|
||||||
elif [[ "$DUMP_FORMAT" == "sql" ]]; then
|
DUMP_FORMAT=${!FORMAT_VAR:-"custom"} # Default to "custom" if not set
|
||||||
# Create a plain-text SQL backup and compress it with gzip
|
|
||||||
pg_dump -h "$HOST" -p "$PORT" -U "$USER" "$DB" | gzip > "$BACKUP_FILE"
|
if [ -z "$HOST" ] || [ -z "$PORT" ] || [ -z "$USER" ]; then
|
||||||
else
|
echo "Incomplete configuration for $PREFIX. Skipping..."
|
||||||
echo "Invalid DUMP_FORMAT specified: $DUMP_FORMAT"
|
continue
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Backup for database '$DB' created at '$BACKUP_FILE'"
|
# Create a directory for each server using host and port, only if it doesn't exist
|
||||||
|
SERVER_DIR="$BACKUP_PATH/${HOST}_${PORT}"
|
||||||
|
if [ ! -d "$SERVER_DIR" ]; then
|
||||||
|
echo "Creating backup directory: $SERVER_DIR"
|
||||||
|
mkdir -p "$SERVER_DIR"
|
||||||
|
else
|
||||||
|
echo "Backup directory $SERVER_DIR already exists, skipping creation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get a list of all databases for this server, excluding template databases
|
||||||
|
echo "Fetching databases for $HOST:$PORT ..."
|
||||||
|
DATABASES=$(psql -h "$HOST" -p "$PORT" -U "$USER" -d postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;")
|
||||||
|
|
||||||
|
# Loop over each database and create a backup
|
||||||
|
for DB_NAME in $DATABASES; do
|
||||||
|
# Set file extension based on DUMP_FORMAT
|
||||||
|
EXTENSION="dump"
|
||||||
|
if [[ "$DUMP_FORMAT" == "sql" ]]; then
|
||||||
|
EXTENSION="sql.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set backup file path within the server-specific directory
|
||||||
|
BACKUP_FILE="$SERVER_DIR/$DB_NAME.$EXTENSION"
|
||||||
|
|
||||||
|
echo "Dumping '$DB_NAME' on $HOST:$PORT to $BACKUP_FILE"
|
||||||
|
|
||||||
|
# Perform the backup based on the specified format
|
||||||
|
if [[ "$DUMP_FORMAT" == "custom" ]]; then
|
||||||
|
pg_dump -h "$HOST" -p "$PORT" -U "$USER" -Fc --compress="zstd:$ZSTD_LEVEL" "$DB_NAME" -f "$BACKUP_FILE"
|
||||||
|
elif [[ "$DUMP_FORMAT" == "sql" ]]; then
|
||||||
|
pg_dump -h "$HOST" -p "$PORT" -U "$USER" "$DB_NAME" | gzip -$GZIP_LEVEL > "$BACKUP_FILE"
|
||||||
|
else
|
||||||
|
echo "Invalid DUMP_FORMAT for $PREFIX: $DUMP_FORMAT. Skipping..."
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
du -sh $BACKUP_FILE
|
||||||
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
echo "Backup process completed."
|
||||||
|
|
Loading…
Reference in a new issue