Merge lp:~barryprice/charms/trusty/postgresql/more_frequent_backups into lp:charms/trusty/postgresql

Proposed by Barry Price
Status: Merged
Merged at revision: 143
Proposed branch: lp:~barryprice/charms/trusty/postgresql/more_frequent_backups
Merge into: lp:charms/trusty/postgresql
Diff against target: 154 lines (+27/-19)
6 files modified
config.yaml (+2/-2)
hooks/postgresql.py (+1/-0)
scripts/pgbackup.py (+4/-5)
templates/pg_backup_job.tmpl (+17/-9)
templates/postgres.cron.tmpl (+2/-2)
tests/test_postgresql.py (+1/-1)
To merge this branch: bzr merge lp:~barryprice/charms/trusty/postgresql/more_frequent_backups
Reviewer Review Type Date Requested Status
Review Queue (community) automated testing Approve
Stuart Bishop (community) Approve
Review via email: mp+283245@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Barry Price (barryprice) wrote :

As stub points out, there will usually be at least two backup files per run, potentially more (basically, $number_of_databases +1 for globals).

So the pruning of old backups needs some work here, I'm setting this to WIP for now.

145. By Barry Price

Another attempt at getting the DB deletions correct

146. By Barry Price

Correct syntax

Revision history for this message
Stuart Bishop (stub) wrote :

Looks good.

review: Approve
Revision history for this message
Review Queue (review-queue) wrote :

This item has failed automated testing! Results available here http://juju-ci.vapour.ws:8080/job/charm-bundle-test-lxc/2273/

review: Needs Fixing (automated testing)
Revision history for this message
Review Queue (review-queue) wrote :

The results (PASS) are in and available here: http://juju-ci.vapour.ws:8080/job/charm-bundle-test-aws/2252/

review: Approve (automated testing)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'config.yaml'
2--- config.yaml 2015-12-30 09:05:19 +0000
3+++ config.yaml 2016-01-26 10:45:35 +0000
4@@ -124,11 +124,11 @@
5 backup_schedule:
6 default: "13 4 * * *"
7 type: string
8- description: Cron-formatted schedule for daily database backups.
9+ description: Cron-formatted schedule for regular database backups.
10 backup_retention_count:
11 default: 7
12 type: int
13- description: Number of daily backups to retain.
14+ description: Number of backups to retain.
15 nagios_context:
16 default: "juju"
17 type: string
18
19=== modified file 'hooks/postgresql.py'
20--- hooks/postgresql.py 2015-10-01 01:36:42 +0000
21+++ hooks/postgresql.py 2016-01-26 10:45:35 +0000
22@@ -132,6 +132,7 @@
23 ver = version()
24 return set(['postgresql-{}'.format(ver),
25 'postgresql-common', 'postgresql-client-common',
26+ 'run-one',
27 'postgresql-contrib-{}'.format(ver),
28 'postgresql-client-{}'.format(ver)])
29
30
31=== modified file 'scripts/pgbackup.py'
32--- scripts/pgbackup.py 2014-03-11 13:37:56 +0000
33+++ scripts/pgbackup.py 2016-01-26 10:45:35 +0000
34@@ -1,11 +1,11 @@
35 #!/usr/bin/python
36
37-# Copyright 2008-2014 Canonical Ltd. All rights reserved.
38+# Copyright 2008-2016 Canonical Ltd. All rights reserved.
39
40 """
41 Backup one or more PostgreSQL databases.
42
43-Suitable for use in crontab for daily backups.
44+Suitable for use in crontab for regular backups.
45 """
46
47 __metaclass__ = type
48@@ -24,9 +24,7 @@
49
50
51 def main(options, databases):
52- #Need longer file names if this is used more than daily
53- #today = datetime.now().strftime('%Y%m%d_%H:%M:%S')
54- today = datetime.now().strftime('%Y%m%d')
55+ today = datetime.now().strftime('%Y%m%d_%H%M%S')
56
57 backup_dir = options.backup_dir
58 rv = 0
59@@ -80,6 +78,7 @@
60 # If the file already exists, it is from an older dump today.
61 # We don't know if it was successful or not, so abort on this
62 # dump. Leave for operator intervention
63+ # n.b. this is extremely unlikely with %H%M%S in the filename
64 if os.path.exists(dest):
65 log.error("%s already exists. Skipping." % dest)
66 continue
67
68=== modified file 'templates/pg_backup_job.tmpl'
69--- templates/pg_backup_job.tmpl 2015-08-11 10:36:28 +0000
70+++ templates/pg_backup_job.tmpl 2016-01-26 10:45:35 +0000
71@@ -6,12 +6,12 @@
72 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
73
74 usage () {
75- echo "usage: $0 <retain_days>"
76+ echo "usage: $0 <retain_files>"
77 }
78
79-typeset -i DAYS=$1
80+typeset -i FILES=$1
81 shift
82-if [ $DAYS -le 0 ]; then
83+if [ $FILES -le 0 ]; then
84 usage
85 exit 1
86 fi
87@@ -27,14 +27,14 @@
88 # Set umask so backups are automatically created without group and other
89 umask 0077
90
91-echo backups started `date`
92+echo backups started $(date)
93
94 export PGPORT=5432
95 export PGUSER=postgres
96
97 DUMP_DIR={{backups_dir}}
98 SCRIPTS={{scripts_dir}}
99-TODAY=`date +'%Y%m%d'`
100+TODAY=$(date +'%Y%m%d_%H%M%S')
101
102 # Dump globals, which we often need to restore a database dump.
103 pg_dumpall --globals-only --quote-all-identifiers \
104@@ -81,9 +81,17 @@
105 nice -n 19 ${SCRIPTS}/dump-pg-db --dir=${DUMP_DIR} --compression=postgres ${DATABASES}
106
107 # Prune old backups:
108-# - Delete anything older than $DAYS days
109-find ${DUMP_DIR}/ -mtime +${DAYS} -delete
110-
111-echo backups completed `date`
112+# - Delete anything beyond $FILES count of each backup
113+
114+# get name/size of the globals dump from $FILES runs ago
115+THRESHOLD_GLOBALS_DUMP=$(find ${DUMP_DIR} -type f -name 'globals.*.sql' | sort | tail -${FILES}| head -1)
116+TIME_NOW=$(date +%s)
117+TIME_DUMP=$(date +%s -r $THRESHOLD_GLOBALS_DUMP)
118+THRESHOLD_AGE=$(($TIME_NOW - $TIME_DUMP))
119+THRESHOLD_MINS=$(($THRESHOLD_AGE / 60))
120+THRESHOLD_MINS=$(($THRESHOLD_MINS + 1)) # always round up
121+find ${DUMP_DIR} -type f -mmin +${THRESHOLD_MINS} -delete
122+
123+echo backups completed $(date)
124
125 backup_success
126
127=== modified file 'templates/postgres.cron.tmpl'
128--- templates/postgres.cron.tmpl 2015-08-10 11:44:18 +0000
129+++ templates/postgres.cron.tmpl 2016-01-26 10:45:35 +0000
130@@ -4,10 +4,10 @@
131 # Scheduled logical dump of the primary using pg_dump. We don't dump hot
132 # standbys, as operations performed on the primary can cause queries on
133 # the standby to be aborted.
134-{{backup_schedule}} postgres {{scripts_dir}}/pg_backup_job {{backup_retention_count}}
135+{{backup_schedule}} postgres run-one {{scripts_dir}}/pg_backup_job {{backup_retention_count}}
136 {% endif -%}
137
138 {% if is_master and wal_e_enabled and wal_e_backup_schedule -%}
139 # Scheduled filesystem backup of the primary using wal-e.
140-{{wal_e_backup_schedule}} postgres {{wal_e_backup_command}} && {{wal_e_prune_command}}
141+{{wal_e_backup_schedule}} postgres run-one {{wal_e_backup_command}} && {{wal_e_prune_command}}
142 {% endif -%}
143
144=== modified file 'tests/test_postgresql.py'
145--- tests/test_postgresql.py 2015-08-25 13:50:07 +0000
146+++ tests/test_postgresql.py 2016-01-26 10:45:35 +0000
147@@ -137,7 +137,7 @@
148 def test_packages(self, version):
149 version.return_value = '9.9'
150 expected = set(['postgresql-9.9', 'postgresql-common',
151- 'postgresql-client-common',
152+ 'postgresql-client-common', 'run-one',
153 'postgresql-contrib-9.9', 'postgresql-client-9.9'])
154 self.assertSetEqual(postgresql.packages(), expected)
155

Subscribers

People subscribed via source and target branches

to all changes: