Skip to content

Commit 5a6ad33

Browse files
committed
* Support multiple databases
* Select compress method: pigz, xz, bzip2, lrzip, brotli, zstd * Ping database before dump
1 parent 96e1ab5 commit 5a6ad33

File tree

4 files changed

+101
-6
lines changed

4 files changed

+101
-6
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
FROM ubuntu:18.04
22

3-
RUN apt update && apt install -y wget gnupg pigz pbzip2 xz-utils \
3+
RUN apt update && apt install -y wget gnupg pigz pbzip2 xz-utils lrzip brotli zstd \
44
&& wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \
55
&& echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" | tee /etc/apt/sources.list.d/postgresql.list \
66
&& apt update && apt install -y postgresql-client \

docker-compose.yml

+2
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ services:
99
- S3_NAME=folder-name/backup-name-prefix
1010
- S3_URI=https://s3-key:[email protected]
1111
- PG_URI=postgres://pg-user:pg-password@postgres-host:5432/db-name
12+
# Available: pigz, xz, bzip2, lrzip, brotli, zstd
13+
- COMPRESS=pigz

entrypoint.sh

+95-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/bin/bash
22
set -e
3+
set -o pipefail
34

45
# Date function
56
get_date () {
@@ -9,6 +10,8 @@ get_date () {
910
# Script
1011
: ${GPG_KEYSERVER:='keyserver.ubuntu.com'}
1112
: ${GPG_KEYID:=''}
13+
: ${COMPRESS:='pigz'}
14+
START_DATE=`date +%Y-%m-%d_%H-%M-%S`
1215

1316
if [ -z "$GPG_KEYID" ]
1417
then
@@ -18,19 +21,106 @@ else
1821
gpg --keyserver ${GPG_KEYSERVER} --recv-keys ${GPG_KEYID}
1922
fi
2023

24+
function uri_parser() {
25+
# uri capture
26+
uri="$@"
27+
28+
# safe escaping
29+
uri="${uri//\`/%60}"
30+
uri="${uri//\"/%22}"
31+
32+
# top level parsing
33+
pattern='^(([a-z]{3,15})://)?((([^:\/]+)(:([^@\/]*))?@)?([^:\/?]+)(:([0-9]+))?)(\/[^?]*)?(\?[^#]*)?(#.*)?$'
34+
[[ "$uri" =~ $pattern ]] || return 1;
35+
36+
# component extraction
37+
uri=${BASH_REMATCH[0]}
38+
uri_schema=${BASH_REMATCH[2]}
39+
uri_address=${BASH_REMATCH[3]}
40+
uri_user=${BASH_REMATCH[5]}
41+
uri_password=${BASH_REMATCH[7]}
42+
uri_host=${BASH_REMATCH[8]}
43+
uri_port=${BASH_REMATCH[10]}
44+
uri_path=${BASH_REMATCH[11]}
45+
}
46+
# uri_parser $PG_URI ; echo $? $uri_host $uri_user $uri_password $uri_port
47+
2148
echo "$(get_date) Postgres backup started"
2249

2350
export MC_HOST_backup=$S3_URI
2451

2552
mc mb backup/${S3_BUCK} --insecure
2653

27-
if [ -z "$GPG_KEYID" ]
54+
55+
case $COMPRESS in
56+
'pigz' )
57+
COMPRESS_CMD='pigz -9'
58+
COMPRESS_POSTFIX='.gz'
59+
;;
60+
'xz' )
61+
COMPRESS_CMD='xz'
62+
COMPRESS_POSTFIX='.xz'
63+
;;
64+
'bzip2' )
65+
COMPRESS_CMD='bzip2 -9'
66+
COMPRESS_POSTFIX='.bz2'
67+
;;
68+
'lrzip' )
69+
COMPRESS_CMD='lrzip -l -L5'
70+
COMPRESS_POSTFIX='.lrz'
71+
;;
72+
'brotli' )
73+
COMPRESS_CMD='brotli -9'
74+
COMPRESS_POSTFIX='.br'
75+
;;
76+
'zstd' )
77+
COMPRESS_CMD='zstd -9'
78+
COMPRESS_POSTFIX='.zst'
79+
;;
80+
* )
81+
echo "$(get_date) Invalid compression method: $COMPRESS. The following are available: pigz, xz, bzip2, lrzip, brotli, zstd"
82+
exit 1
83+
;;
84+
esac
85+
86+
dump_db(){
87+
DATABASE=$1
88+
89+
# Ping databaase
90+
psql --host=${uri_host} --port=${uri_port} --username=${uri_user} --dbname=${DATABASE} -c ''
91+
92+
echo "$(get_date) Dumping database: $DATABASE"
93+
if [ -z "$GPG_KEYID" ]
94+
then
95+
# true
96+
# pg_dump ${PG_URI%/}/${DATABASE} | head -n 10
97+
pg_dump ${PG_URI%/}/${DATABASE} | $COMPRESS_CMD | mc pipe backup/${S3_BUCK}/${S3_NAME}-${START_DATE}-${DATABASE}.pgdump${COMPRESS_POSTFIX} --insecure
98+
else
99+
pg_dump ${PG_URI%/}/${DATABASE} | $COMPRESS_CMD \
100+
| gpg --encrypt -z 0 --recipient ${GPG_KEYID} --trust-model always \
101+
| mc pipe backup/${S3_BUCK}/${S3_NAME}-${START_DATE}-${DATABASE}.pgdump${COMPRESS_POSTFIX}.pgp --insecure
102+
fi
103+
}
104+
105+
DB_NAME=${PG_URI##*/}
106+
if [[ $DB_NAME == *"@"* ]]
107+
then
108+
DB_NAME=""
109+
fi
110+
111+
uri_parser $PG_URI
112+
export PGPASSWORD=${uri_password}
113+
114+
if [ -z "$DB_NAME" ]
28115
then
29-
pg_dump $PG_URI | pigz -9 | mc pipe backup/${S3_BUCK}/${S3_NAME}-`date +%Y-%m-%d_%H-%M-%S`.pgdump --insecure
116+
echo "$(get_date) No specific database selected. Saving each in separate files"
117+
DB_LIST=$(psql --host=${uri_host} --port=${uri_port} --username=${uri_user} -A -c "SELECT datname FROM pg_database WHERE datname NOT LIKE 'template%';" | head -n -1 | tail -n +2)
118+
for db in $DB_LIST; do
119+
dump_db "$db"
120+
done
30121
else
31-
pg_dump $PG_URI | pigz -9 \
32-
| gpg --encrypt -z 0 --recipient ${GPG_KEYID} --trust-model always \
33-
| mc pipe backup/${S3_BUCK}/${S3_NAME}-`date +%Y-%m-%d_%H-%M-%S`.pgdump.pgp --insecure
122+
PG_URI=${PG_URI%$DB_NAME}
123+
dump_db "$DB_NAME"
34124
fi
35125

36126
echo "$(get_date) Postgres backup completed successfully"

kubernetes-cronjob.yml

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ spec:
2020
env:
2121
- name: PG_URI
2222
value: postgres://db-svc-or-hostname:27017/dbname
23+
# Available: pigz, xz, bzip2, lrzip, brotli, zstd
24+
- name: COMPRESS
25+
value: pigz
2326
- name: S3_URI
2427
value: https://your-key:[email protected]
2528
- name: S3_NAME

0 commit comments

Comments
 (0)