Robin Thoni 7 лет назад
Сommit
e4e57cb375
5 измененных файлов: 270 добавлений и 0 удалений
  1. 15
    0
      Dockerfile
  2. 45
    0
      backup/pg_backup.config
  3. 3
    0
      backup/pg_backup_rotated.cron.sh
  4. 202
    0
      backup/pg_backup_rotated.sh
  5. 5
    0
      run.sh

+ 15
- 0
Dockerfile Просмотреть файл

@@ -0,0 +1,15 @@
1
+FROM postgres:9.6
2
+
3
+COPY ./backup/pg_backup.config /etc/pg_backup.config
4
+
5
+COPY ./backup/pg_backup_rotated.sh /usr/local/bin/pg_backup_rotated.sh
6
+
7
+COPY ./backup/pg_backup_rotated.cron.sh /etc/cron.daily/pg_backup_rotated.cron.sh
8
+
9
+COPY ./run.sh /run.sh
10
+
11
+VOLUME "/var/lib/postgresql/backup"
12
+
13
+ENTRYPOINT ["/run.sh"]
14
+
15
+CMD ["postgres"]

+ 45
- 0
backup/pg_backup.config Просмотреть файл

@@ -0,0 +1,45 @@
1
+##############################
2
+## POSTGRESQL BACKUP CONFIG ##
3
+##############################
4
+ 
5
+# Optional system user to run backups as.  If the user the script is running as doesn't match this
6
+# the script terminates.  Leave blank to skip check.
7
+BACKUP_USER=
8
+ 
9
+# Optional hostname to adhere to pg_hba policies.  Will default to "localhost" if none specified.
10
+HOSTNAME=
11
+ 
12
+# Optional username to connect to database as.  Will default to "postgres" if none specified.
13
+USERNAME=
14
+ 
15
+# This dir will be created if it doesn't exist.  This must be writable by the user the script is
16
+# running as.
17
+BACKUP_DIR=/var/lib/postgresql/backup/
18
+ 
19
+# List of strings to match against in database name, separated by space or comma, for which we only
20
+# wish to keep a backup of the schema, not the data. Any database names which contain any of these
21
+# values will be considered candidates. (e.g. "system_log" will match "dev_system_log_2010-01")
22
+SCHEMA_ONLY_LIST=""
23
+ 
24
+# Will produce a custom-format backup if set to "yes"
25
+ENABLE_CUSTOM_BACKUPS=yes
26
+ 
27
+# Will produce a gzipped plain-format backup if set to "yes"
28
+ENABLE_PLAIN_BACKUPS=yes
29
+ 
30
+# Will produce gzipped sql file containing the cluster globals, like users and passwords, if set to "yes"
31
+ENABLE_GLOBALS_BACKUPS=yes
32
+ 
33
+ 
34
+#### SETTINGS FOR ROTATED BACKUPS ####
35
+ 
36
+# Which day to take the weekly backup from (1-7 = Monday-Sunday)
37
+DAY_OF_WEEK_TO_KEEP=1-7
38
+ 
39
+# Number of days to keep daily backups
40
+DAYS_TO_KEEP=7
41
+ 
42
+# How many weeks to keep weekly backups
43
+WEEKS_TO_KEEP=10
44
+ 
45
+######################################

+ 3
- 0
backup/pg_backup_rotated.cron.sh Просмотреть файл

@@ -0,0 +1,3 @@
1
+#! /usr/bin/env bash
2
+
3
+pg_backup_rotated.sh -c /etc/pg_backup.config

+ 202
- 0
backup/pg_backup_rotated.sh Просмотреть файл

@@ -0,0 +1,202 @@
1
+#!/bin/bash
2
+ 
3
+###########################
4
+####### LOAD CONFIG #######
5
+###########################
6
+ 
7
+while [ $# -gt 0 ]; do
8
+        case $1 in
9
+                -c)
10
+                        CONFIG_FILE_PATH="$2"
11
+                        shift 2
12
+                        ;;
13
+                *)
14
+                        ${ECHO} "Unknown Option \"$1\"" 1>&2
15
+                        exit 2
16
+                        ;;
17
+        esac
18
+done
19
+ 
20
+if [ -z $CONFIG_FILE_PATH ] ; then
21
+        SCRIPTPATH=$(cd ${0%/*} && pwd -P)
22
+        CONFIG_FILE_PATH="${SCRIPTPATH}/pg_backup.config"
23
+fi
24
+ 
25
+if [ ! -r ${CONFIG_FILE_PATH} ] ; then
26
+        echo "Could not load config file from ${CONFIG_FILE_PATH}" 1>&2
27
+        exit 1
28
+fi
29
+ 
30
+source "${CONFIG_FILE_PATH}"
31
+ 
32
+###########################
33
+#### PRE-BACKUP CHECKS ####
34
+###########################
35
+ 
36
+# Make sure we're running as the required backup user
37
+if [ "$BACKUP_USER" != "" -a "$(id -un)" != "$BACKUP_USER" ] ; then
38
+  echo "This script must be run as $BACKUP_USER. Exiting." 1>&2
39
+  exit 1
40
+fi
41
+ 
42
+ 
43
+###########################
44
+### INITIALISE DEFAULTS ###
45
+###########################
46
+ 
47
+if [ ! $HOSTNAME ]; then
48
+  HOSTNAME="localhost"
49
+fi;
50
+ 
51
+if [ ! $USERNAME ]; then
52
+  USERNAME="postgres"
53
+fi;
54
+ 
55
+ 
56
+###########################
57
+#### START THE BACKUPS ####
58
+###########################
59
+ 
60
+function perform_backups()
61
+{
62
+  SUFFIX=$1
63
+  FINAL_BACKUP_DIR=$BACKUP_DIR"`date +\%Y-\%m-\%d`$SUFFIX/"
64
+ 
65
+  echo "Making backup directory in $FINAL_BACKUP_DIR"
66
+ 
67
+  if ! mkdir -p $FINAL_BACKUP_DIR; then
68
+    echo "Cannot create backup directory in $FINAL_BACKUP_DIR. Go and fix it!" 1>&2
69
+    exit 1;
70
+  fi;
71
+ 
72
+  #######################
73
+  ### GLOBALS BACKUPS ###
74
+  #######################
75
+ 
76
+  echo -e "\n\nPerforming globals backup"
77
+  echo -e "--------------------------------------------\n"
78
+ 
79
+  if [ $ENABLE_GLOBALS_BACKUPS = "yes" ]
80
+  then
81
+        echo "Globals backup"
82
+ 
83
+        if ! pg_dumpall -g -h "$HOSTNAME" -U "$USERNAME" | gzip > $FINAL_BACKUP_DIR"globals".sql.gz.in_progress; then
84
+                echo "[!!ERROR!!] Failed to produce globals backup" 1>&2
85
+        else
86
+                mv $FINAL_BACKUP_DIR"globals".sql.gz.in_progress $FINAL_BACKUP_DIR"globals".sql.gz
87
+        fi
88
+  else
89
+    echo "None"
90
+  fi
91
+ 
92
+ 
93
+  ###########################
94
+  ### SCHEMA-ONLY BACKUPS ###
95
+  ###########################
96
+ 
97
+  for SCHEMA_ONLY_DB in ${SCHEMA_ONLY_LIST//,/ }
98
+  do
99
+          SCHEMA_ONLY_CLAUSE="$SCHEMA_ONLY_CLAUSE or datname ~ '$SCHEMA_ONLY_DB'"
100
+  done
101
+ 
102
+  SCHEMA_ONLY_QUERY="select datname from pg_database where false $SCHEMA_ONLY_CLAUSE order by datname;"
103
+ 
104
+  echo -e "\n\nPerforming schema-only backups"
105
+  echo -e "--------------------------------------------\n"
106
+ 
107
+  SCHEMA_ONLY_DB_LIST=`psql -h "$HOSTNAME" -U "$USERNAME" -At -c "$SCHEMA_ONLY_QUERY" postgres`
108
+ 
109
+  echo -e "The following databases were matched for schema-only backup:\n${SCHEMA_ONLY_DB_LIST}\n"
110
+ 
111
+  for DATABASE in $SCHEMA_ONLY_DB_LIST
112
+  do
113
+          echo "Schema-only backup of $DATABASE"
114
+ 
115
+          if ! pg_dump -Fp -s -h "$HOSTNAME" -U "$USERNAME" "$DATABASE" | gzip > $FINAL_BACKUP_DIR"$DATABASE"_SCHEMA.sql.gz.in_progress; then
116
+                  echo "[!!ERROR!!] Failed to backup database schema of $DATABASE" 1>&2
117
+          else
118
+                  mv $FINAL_BACKUP_DIR"$DATABASE"_SCHEMA.sql.gz.in_progress $FINAL_BACKUP_DIR"$DATABASE"_SCHEMA.sql.gz
119
+          fi
120
+  done
121
+ 
122
+ 
123
+  ###########################
124
+  ###### FULL BACKUPS #######
125
+  ###########################
126
+ 
127
+  for SCHEMA_ONLY_DB in ${SCHEMA_ONLY_LIST//,/ }
128
+  do
129
+    EXCLUDE_SCHEMA_ONLY_CLAUSE="$EXCLUDE_SCHEMA_ONLY_CLAUSE and datname !~ '$SCHEMA_ONLY_DB'"
130
+  done
131
+ 
132
+  FULL_BACKUP_QUERY="select datname from pg_database where not datistemplate and datallowconn $EXCLUDE_SCHEMA_ONLY_CLAUSE order by datname;"
133
+ 
134
+  echo -e "\n\nPerforming full backups"
135
+  echo -e "--------------------------------------------\n"
136
+ 
137
+  for DATABASE in `psql -h "$HOSTNAME" -U "$USERNAME" -At -c "$FULL_BACKUP_QUERY" postgres`
138
+  do
139
+    if [ $ENABLE_PLAIN_BACKUPS = "yes" ]
140
+    then
141
+      echo "Plain backup of $DATABASE"
142
+ 
143
+      if ! pg_dump -Fp -h "$HOSTNAME" -U "$USERNAME" "$DATABASE" | gzip > $FINAL_BACKUP_DIR"$DATABASE".sql.gz.in_progress; then
144
+        echo "[!!ERROR!!] Failed to produce plain backup database $DATABASE" 1>&2
145
+      else
146
+        mv $FINAL_BACKUP_DIR"$DATABASE".sql.gz.in_progress $FINAL_BACKUP_DIR"$DATABASE".sql.gz
147
+      fi
148
+    fi
149
+ 
150
+    if [ $ENABLE_CUSTOM_BACKUPS = "yes" ]
151
+    then
152
+      echo "Custom backup of $DATABASE"
153
+ 
154
+      if ! pg_dump -Fc -h "$HOSTNAME" -U "$USERNAME" "$DATABASE" -f $FINAL_BACKUP_DIR"$DATABASE".custom.in_progress; then
155
+        echo "[!!ERROR!!] Failed to produce custom backup database $DATABASE"
156
+      else
157
+        mv $FINAL_BACKUP_DIR"$DATABASE".custom.in_progress $FINAL_BACKUP_DIR"$DATABASE".custom
158
+      fi
159
+    fi
160
+ 
161
+  done
162
+ 
163
+  date > $FINAL_BACKUP_DIR/complete
164
+  echo -e "\nAll database backups complete!"
165
+}
166
+ 
167
+# MONTHLY BACKUPS
168
+ 
169
+DAY_OF_MONTH=`date +%d`
170
+ 
171
+if [ $DAY_OF_MONTH -eq 1 ];
172
+then
173
+  # Delete all expired monthly directories
174
+  find $BACKUP_DIR -maxdepth 1 -name "*-monthly" -exec rm -rf '{}' ';'
175
+ 
176
+  perform_backups "-monthly"
177
+ 
178
+  exit 0;
179
+fi
180
+ 
181
+# WEEKLY BACKUPS
182
+ 
183
+DAY_OF_WEEK=`date +%u` #1-7 (Monday-Sunday)
184
+EXPIRED_DAYS=`expr $((($WEEKS_TO_KEEP * 7) + 1))`
185
+ 
186
+if [ $DAY_OF_WEEK = $DAY_OF_WEEK_TO_KEEP ];
187
+then
188
+  # Delete all expired weekly directories
189
+  find $BACKUP_DIR -maxdepth 1 -mtime +$EXPIRED_DAYS -name "*-weekly" -exec rm -rf '{}' ';'
190
+ 
191
+  perform_backups "-weekly"
192
+ 
193
+  exit 0;
194
+fi
195
+ 
196
+# DAILY BACKUPS
197
+ 
198
+# Delete daily backups 7 days old or more
199
+find $BACKUP_DIR -maxdepth 1 -mtime +$DAYS_TO_KEEP -name "*-daily" -exec rm -rf '{}' ';'
200
+ 
201
+perform_backups "-daily"
202
+

+ 5
- 0
run.sh Просмотреть файл

@@ -0,0 +1,5 @@
1
+#! /usr/bin/env bash
2
+
3
+cron -f &
4
+
5
+/docker-entrypoint.sh $*

Загрузка…
Отмена
Сохранить