Skip to content

Commit 35f6f11

Browse files
author
Matthew Fisher
committed
fix(database): run backups in the background
Instead of running the backup in the publish loop, we can schedule the backups on a timed interval. I tried to do this with cron, but I was having trouble sending the output of the forked processes to /dev/stdout, so instead I just forked a for loop in the background :)
1 parent 4de2c90 commit 35f6f11

3 files changed

Lines changed: 24 additions & 26 deletions

File tree

database/bin/backup

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
export BACKUP_FREQUENCY=${BACKUP_FREQUENCY:-3h}
4+
export BACKUPS_TO_RETAIN=${BACKUPS_TO_RETAIN:-5}
5+
6+
while true; do
7+
sleep "$BACKUP_FREQUENCY"
8+
echo "database: performing a backup..."
9+
if [[ -f /var/lib/postgresql/9.3/main/recovery.conf ]] ; then
10+
echo "database: database is currently recovering from a backup. Will try again next loop..."
11+
else
12+
# perform a backup
13+
envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
14+
# only retain the latest BACKUPS_TO_RETAIN backups
15+
envdir /etc/wal-e.d/env wal-e delete --confirm retain $BACKUPS_TO_RETAIN
16+
echo "database: backup has been completed."
17+
fi
18+
done

database/bin/boot

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ export ETCD_PATH=${ETCD_PATH:-/deis/database}
1616
export ETCD_TTL=${ETCD_TTL:-20}
1717

1818
export BUCKET_NAME=${BUCKET_NAME:-db_wal}
19-
export BACKUPS_TO_RETAIN=${BACKUPS_TO_RETAIN:-5}
20-
21-
# how many TTL/2 sleeps between backups -- 2160 is 3 hours
22-
export BACKUP_FREQUENCY=${BACKUP_FREQUENCY:-2160}
2319

2420
# wait for etcd to be available
2521
until etcdctl --no-sync -C $ETCD ls >/dev/null 2>&1; do
@@ -125,9 +121,10 @@ if [[ "${initial_backup}" == "1" ]] ; then
125121
sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
126122
fi
127123

124+
sudo -Eu postgres /app/bin/backup &
125+
128126
echo "database: postgres is running..."
129127

130-
count=1
131128
# publish the service to etcd using the injected HOST and EXTERNAL_PORT
132129
if [[ ! -z $EXTERNAL_PORT ]]; then
133130
# configure service discovery
@@ -143,23 +140,6 @@ if [[ ! -z $EXTERNAL_PORT ]]; then
143140
while [[ ! -z $(netstat -lnt | awk "\$6 == \"LISTEN\" && \$4 ~ \".$PORT\" && \$1 ~ \"$PROTO.?\"") ]] ; do
144141
etcdctl --no-sync -C $ETCD set $ETCD_PATH/host $HOST --ttl $ETCD_TTL >/dev/null
145142
etcdctl --no-sync -C $ETCD set $ETCD_PATH/port $EXTERNAL_PORT --ttl $ETCD_TTL >/dev/null
146-
147-
# perform a backup whenever we hit BACKUP_FREQUENCY
148-
# we really need cron :(
149-
if [[ "${count}" -ge "${BACKUP_FREQUENCY}" ]] ; then
150-
echo "database: performing a backup..."
151-
if [[ -f /var/lib/postgresql/9.3/main/recovery.conf ]] ; then
152-
echo "database: database is currently recovering from a backup. Will try again next loop..."
153-
else
154-
# perform a backup
155-
sudo -u postgres envdir /etc/wal-e.d/env wal-e backup-push /var/lib/postgresql/9.3/main
156-
# only retain the latest BACKUPS_TO_RETAIN backups
157-
sudo -u postgres envdir /etc/wal-e.d/env wal-e delete --confirm retain ${BACKUPS_TO_RETAIN}
158-
count=0
159-
echo "database: backup has been completed."
160-
fi
161-
fi
162-
((count++))
163143
sleep $(($ETCD_TTL/2)) # sleep for half the TTL
164144
done
165145

database/tests/recovery_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@ func TestDatabaseRecovery(t *testing.T) {
107107
"-e", "HOST="+host,
108108
"-e", "ETCD_PORT="+etcdPort,
109109
"-e", "ETCD_TTL=2",
110-
"-e", "BACKUP_FREQUENCY=0",
110+
"-e", "BACKUP_FREQUENCY=1s",
111111
"-e", "BACKUPS_TO_RETAIN=100",
112112
imageName)
113113
}
114114

115115
stopDatabase := func() {
116-
fmt.Print("--- Stopping data-database... ")
116+
fmt.Println("--- Stopping data-database... ")
117117
if err = stdout.Close(); err != nil {
118118
t.Fatal("Failed to closeStdout")
119119
}
@@ -124,7 +124,7 @@ func TestDatabaseRecovery(t *testing.T) {
124124
//ACTION
125125

126126
//STEP 1: start db with volume A and wait for init to complete
127-
fmt.Print("--- Starting database with Volume A... ")
127+
fmt.Println("--- Starting database with Volume A... ")
128128
go startDatabase(databaseVolumeA)
129129
dockercli.WaitForLine(t, stdout, "database: postgres is running...", true)
130130
fmt.Println("Done")
@@ -148,7 +148,7 @@ func TestDatabaseRecovery(t *testing.T) {
148148
execSql(t, db, "create table api_foo(t text)")
149149

150150
//STEP 2b: make sure we observed full backup cycle after forced checkpoint
151-
fmt.Print("--- Waiting for the change to be backed up... ")
151+
fmt.Println("--- Waiting for the change to be backed up... ")
152152
dockercli.WaitForLine(t, stdout, "database: performing a backup...", true)
153153
dockercli.WaitForLine(t, stdout, "database: backup has been completed.", true)
154154
fmt.Println("Done")

0 commit comments

Comments
 (0)