Skip to content

Commit acb1f9f

Browse files
committed
Refactor shell scripts
Use a more sensible timestamp for backups Use arrays when possible Lowercase variables More safely process backup retention
1 parent aa688d1 commit acb1f9f

File tree

2 files changed

+86
-65
lines changed

2 files changed

+86
-65
lines changed
Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,82 @@
11
#!/bin/bash
22

3-
PG_VERSION=$(/usr/local/bin/facter -p pe_postgresql_info.installed_server_version)
4-
BACKUPDIR=/opt/puppetlabs/server/data/postgresql/$PG_VERSION/backups
5-
LOGDIR=/var/log/puppetlabs/pe_databases_backup
6-
RETENTION=2
7-
8-
while [[ $# -gt 0 ]]; do
9-
arg="$1"
10-
case $arg in
3+
while [[ $1 ]]; do
4+
case "$1" in
115
-t)
12-
BACKUPDIR="$2"
13-
shift; shift
6+
backup_dir="$2"
7+
shift 2
148
;;
159
-l)
16-
LOGDIR="$2"
17-
shift; shift
10+
log_dir="$2"
11+
shift 2
1812
;;
1913
-r)
20-
RETENTION="$2"
21-
shift; shift
14+
retention="$2"
15+
shift 2
2216
;;
23-
*)
24-
DATABASES="${DATABASES} $1"
17+
# If given the end of options string, shift it out and break
18+
--)
2519
shift
20+
break
21+
;;
22+
# No need to shift if we've processed all options
23+
*)
24+
break
2625
;;
2726
esac
2827
done
2928

30-
if [[ -z "${DATABASES}" ]]; then
31-
echo "Usage: $0 [-t BACKUP_TARGET] [-l LOG_DIRECTORY] [-r RETENTION] <DATABASE> [DATABASE_N ...]"
29+
# The remaining parameters will be the databases to backup
30+
databases=("$@")
31+
[[ $databases ]] || {
32+
echo "Usage: $0 [-t BACKUP_TARGET] [-l LOG_DIRECTORY] [-r retention] <DATABASE> [DATABASE_N ...]"
3233
exit 1
33-
fi
34-
35-
RETENTION_ENFORCE=$((RETENTION-1))
34+
}
3635

37-
for db in $DATABASES; do
38-
echo "Enforcing retention policy of storing only ${RETENTION_ENFORCE} backups for ${db}" >> "${LOGDIR}/${db}.log" 2>&1
36+
[[ $pg_version ]] || pg_version="$(/usr/local/bin/facter -p pe_postgresql_info.installed_server_version)"
37+
backup_dir="${backup_dir:-/opt/puppetlabs/server/data/postgresql/$pg_version/backups}"
38+
log_dir="${log_dir:-/var/log/puppetlabs/pe_databases_backup}"
39+
retention="${retention:-2}"
3940

40-
ls -1tr ${BACKUPDIR}/${db}_* | head -n -${RETENTION_ENFORCE} | xargs -d '\n' rm -f --
41+
for db in "${databases[@]}"; do
42+
# For each db, redirect all output the the log inside the backup dir
43+
exec &>"${log_dir}/${db}.log"
44+
echo "Enforcing retention policy of storing only $retention backups for $db"
4145

42-
echo "Starting dump of database: ${db}" >> "${LOGDIR}/${db}.log" 2>&1
46+
unset backups
47+
# Starting inside <(), use stat to print mtime and the filename and pipe to sort
48+
# Add the filename to the backups array, giving us a sorted list of filenames
49+
while IFS= read -r -d '' line; do
50+
backups+=("${line#* }")
51+
done < <(stat --printf '%Y %n\0' ${backup_dir}/${db}_* 2>/dev/null | sort -nz)
4352

44-
if [ "${db}" == "pe-classifier" ]; then
45-
# Save space before backing up by clearing unused node_check_ins table.
46-
/opt/puppetlabs/server/bin/psql -d pe-classifier -c 'TRUNCATE TABLE node_check_ins' >> "${LOGDIR}/${db}.log" 2>&1
53+
# Our array offset will be the number of backups - $retention + 1
54+
# e.g. if we have 2 existing backups and retention=2, offset will be one
55+
# We'll delete from element 0 to 1 of the array, leaving one backup.
56+
# The subsequent backup will leave us with 2 again
57+
offset=$(( ${#backups[@]} - $retention + 1 ))
4758

48-
result=$?
49-
if [ $result != 0 ]; then
50-
echo "Failed to truncate node_check_ins table" >> "${LOGDIR}/${db}.log" 2>&1
51-
fi
59+
if (( offset > 0 )); then
60+
# Continue if we're retaining more copies of the db than currently exist
61+
# This will also be true if no backups currently exist
62+
rm -f -- "${backups[@]:0:$offset}"
5263
fi
5364

54-
DATETIME=$(date +%m_%d_%y_%H_%M)
5565

56-
/opt/puppetlabs/server/bin/pg_dump -Fc "${db}" -f "${BACKUPDIR}/${db}_$DATETIME.bin" >> "${LOGDIR}/${db}.log" 2>&1
66+
echo "Starting dump of database: $db"
5767

58-
result=$?
59-
if [[ $result -eq 0 ]]; then
60-
echo "Completed dump of database: ${db}" >> "${LOGDIR}/${db}.log" 2>&1
61-
else
62-
echo "Failed to dump database ${db}. Exit code is: ${result}" >> "${LOGDIR}/${db}.log" 2>&1
63-
exit 1
68+
if [[ $db == 'pe-classifier' ]]; then
69+
# Save space before backing up by clearing unused node_check_ins table.
70+
/opt/puppetlabs/server/bin/psql -d pe-classifier -c 'TRUNCATE TABLE node_check_ins' || \
71+
echo "Failed to truncate node_check_ins table"
6472
fi
73+
74+
datetime="$(date +%Y%m%d%S)"
75+
76+
/opt/puppetlabs/server/bin/pg_dump -Fc "$db" -f "${backup_dir}/${db}_$datetime.bin" || {
77+
echo "Failed to dump database $db"
78+
exit 1
79+
}
80+
81+
echo "Completed dump of database: ${db}"
6582
done

files/vacuum_full_tables.sh

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
11
#!/bin/bash
22

3-
if [ "$1" = "" ]; then
4-
echo "Usage: $0 <(facts, catalogs, or other) tables to VACUUM FULL> "
5-
exit
6-
fi
3+
usage() {
4+
cat <<EOF
5+
echo "usage: $0 <table>"
6+
where <table> is one of: facts catalogs other
7+
EOF
8+
exit 1
9+
}
10+
# Print usage if given 0 arguments
11+
(( $# == 0 )) && usage
712

8-
if [ "$2" = "" ]; then
9-
SLEEP=300
10-
else
11-
SLEEP=$2
12-
fi
13+
sleep_duration="${2:-300}"
1314

1415
# TODO: Is this used in PE 2018 and newer? RE: fact_values
16+
case "$1" in
17+
'facts')
18+
vacuum_tables=("'facts'" "'factsets'" "'fact_paths'" "'fact_values'")
19+
;;
20+
'catalogs')
21+
vacuum_tables=("'catalogs'" "'catalog_resources'" "'edges'" "'certnames'")
22+
;;
23+
'other')
24+
vacuum_tables=("'producers'" "'resource_params'" "'resource_params_cache'")
25+
;;
26+
*)
27+
usage
28+
esac
1529

16-
if [ "$1" = 'facts' ]; then
17-
WHERE="'facts', 'factsets', 'fact_paths', 'fact_values'"
18-
elif [ "$1" = 'catalogs' ]; then
19-
WHERE="'catalogs', 'catalog_resources', 'edges', 'certnames'"
20-
elif [ "$1" = 'other' ]; then
21-
WHERE="'producers', 'resource_params', 'resource_params_cache'"
22-
else
23-
echo "Must pass facts, catalogs, or other as first argument"
24-
exit 1
25-
fi
2630

2731
SQL="SELECT t.relname::varchar AS table_name
2832
FROM pg_class t
2933
JOIN pg_namespace n
3034
ON n.oid = t.relnamespace
3135
WHERE t.relkind = 'r'
32-
AND t.relname IN ( $WHERE )"
36+
AND t.relname IN ( $(IFS=,; echo "${vacuum_tables[*]}") )"
37+
38+
tables=($(su - pe-postgres -s /bin/bash -c "/opt/puppetlabs/server/bin/psql -d pe-puppetdb -c \"$SQL\" --tuples-only"))
3339

34-
for TABLE in $(su - pe-postgres -s /bin/bash -c "/opt/puppetlabs/server/bin/psql -d pe-puppetdb -c \"$SQL\" --tuples-only")
35-
do
36-
# echo "$TABLE"
37-
su - pe-postgres -s /bin/bash -c "/opt/puppetlabs/server/bin/vacuumdb -d pe-puppetdb -t $TABLE --full --analyze"
38-
sleep "$SLEEP"
40+
for table in "${tables[@]}"; do
41+
su - pe-postgres -s /bin/bash -c "/opt/puppetlabs/server/bin/vacuumdb -d pe-puppetdb -t $table --full --analyze"
42+
sleep "$sleep_duration"
3943
done

0 commit comments

Comments
 (0)