mirror of
https://github.com/prodrigestivill/docker-postgres-backup-local.git
synced 2026-07-05 01:38:05 +00:00
Rewritten to breakdown the script into specific functions
Added monthly backups that are only taken once a month Added weekly backups that are only taken once a week Added backup deletion protection when backups are failing to be taken Added flags so that tasks can be run separately from each other Added the ability to choose whether backups are actually deleted or a dry run is performed Removed last backup folder and latest backup symbolic links
This commit is contained in:
committed by
Pau Rodriguez-Estivill
parent
af916da211
commit
d1793740b3
@@ -1,4 +1,39 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Environmental variables
|
||||||
|
#POSTGRES_DB_FILE="**None**"
|
||||||
|
#POSTGRES_USER_FILE="**None**"
|
||||||
|
#POSTGRES_PASSWORD_FILE="**None**"
|
||||||
|
#POSTGRES_PASSFILE_STORE="**None**"
|
||||||
|
#BACKUP_DIR="/matrix/postgres-backup"
|
||||||
|
#POSTGRES_USER=matrix
|
||||||
|
#POSTGRES_PASSWORD=3wI9iPlxuMnv2xT3Ozk1rCYOOfF192GlK6rCcwkQD7KlMkTKgsjG9umPQQNAINJ9
|
||||||
|
#POSTGRES_HOST=matrix-postgres
|
||||||
|
#POSTGRES_DB=( synapse matrix_registration matrix_mautrix_telegram matrix_prometheus_postgres_exporter )
|
||||||
|
#POSTGRES_EXTRA_OPTS="-Z9 --schema=public --blobs"
|
||||||
|
#SCHEDULE=@daily
|
||||||
|
#HEALTHCHECK_PORT=8080
|
||||||
|
#POSTGRES_PORT=5432
|
||||||
|
|
||||||
|
BACKUP_KEEP_DAYS="2"
|
||||||
|
BACKUP_DELETE_DAYS=false
|
||||||
|
BACKUP_KEEP_WEEKS="0"
|
||||||
|
BACKUP_DELETE_WEEKS=false
|
||||||
|
BACKUP_KEEP_MONTHS="0"
|
||||||
|
BACKUP_DELETE_MONTHS=false
|
||||||
|
BACKUP_MONTH_DAY="01"
|
||||||
|
BACKUP_WEEK_DAY="Sunday"
|
||||||
|
|
||||||
|
# Import variables from environment
|
||||||
|
export PGHOST="${POSTGRES_HOST}"
|
||||||
|
export PGPORT="${POSTGRES_PORT}"
|
||||||
|
KEEP_MINS=${BACKUP_KEEP_MINS}
|
||||||
|
KEEP_DAYS=${BACKUP_KEEP_DAYS}
|
||||||
|
KEEP_WEEKS=`expr $((${BACKUP_KEEP_WEEKS} * 7))`
|
||||||
|
KEEP_MONTHS=`expr $((${BACKUP_KEEP_MONTHS} * 31))`
|
||||||
|
|
||||||
|
setup () {
|
||||||
|
|
||||||
set -Eeo pipefail
|
set -Eeo pipefail
|
||||||
|
|
||||||
if [ "${POSTGRES_DB}" = "**None**" -a "${POSTGRES_DB_FILE}" = "**None**" ]; then
|
if [ "${POSTGRES_DB}" = "**None**" -a "${POSTGRES_DB_FILE}" = "**None**" ]; then
|
||||||
@@ -53,28 +88,52 @@ else
|
|||||||
echo "Missing POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE file."
|
echo "Missing POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE file."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
export PGHOST="${POSTGRES_HOST}"
|
|
||||||
export PGPORT="${POSTGRES_PORT}"
|
|
||||||
KEEP_MINS=${BACKUP_KEEP_MINS}
|
|
||||||
KEEP_DAYS=${BACKUP_KEEP_DAYS}
|
|
||||||
KEEP_WEEKS=`expr $(((${BACKUP_KEEP_WEEKS} * 7) + 1))`
|
|
||||||
KEEP_MONTHS=`expr $(((${BACKUP_KEEP_MONTHS} * 31) + 1))`
|
|
||||||
|
|
||||||
#Initialize dirs
|
FREQUENCY=( daily weekly monthly )
|
||||||
mkdir -p "${BACKUP_DIR}/last/" "${BACKUP_DIR}/daily/" "${BACKUP_DIR}/weekly/" "${BACKUP_DIR}/monthly/"
|
|
||||||
|
for f in ${FREQUENCY[@]}
|
||||||
|
do
|
||||||
|
|
||||||
|
mkdir -p "${BACKUP_DIR}/${f}/"
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
MONTH_DAY=`date +%d`
|
||||||
|
WEEK_DAY=`date +%A`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#Create Backups
|
||||||
|
create_backups () {
|
||||||
|
|
||||||
|
for DB in ${POSTGRES_DBS}
|
||||||
|
do
|
||||||
|
|
||||||
|
FILE="${BACKUP_DIR}/daily/${DB}-`date +%Y%m%d`${BACKUP_SUFFIX}"
|
||||||
|
|
||||||
|
create_dump
|
||||||
|
|
||||||
|
if [ "${BACKUP_MONTH_DAY}" = "${MONTH_DAY}" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
create_hardlinks "${FILE}" "monthly"
|
||||||
|
|
||||||
|
elif [ "${BACKUP_WEEK_DAY}" = "${WEEK_DAY}" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
create_hardlinks "${FILE}" "weekly"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "SQL backup created successfully"
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create dump of postgres database
|
||||||
|
create_dump () {
|
||||||
|
|
||||||
#Loop all databases
|
|
||||||
for DB in ${POSTGRES_DBS}; do
|
|
||||||
#Initialize filename vers
|
|
||||||
LAST_FILENAME="${DB}-`date +%Y%m%d-%H%M%S`${BACKUP_SUFFIX}"
|
|
||||||
DAILY_FILENAME="${DB}-`date +%Y%m%d`${BACKUP_SUFFIX}"
|
|
||||||
WEEKLY_FILENAME="${DB}-`date +%G%V`${BACKUP_SUFFIX}"
|
|
||||||
MONTHY_FILENAME="${DB}-`date +%Y%m`${BACKUP_SUFFIX}"
|
|
||||||
FILE="${BACKUP_DIR}/last/${LAST_FILENAME}"
|
|
||||||
DFILE="${BACKUP_DIR}/daily/${DAILY_FILENAME}"
|
|
||||||
WFILE="${BACKUP_DIR}/weekly/${WEEKLY_FILENAME}"
|
|
||||||
MFILE="${BACKUP_DIR}/monthly/${MONTHY_FILENAME}"
|
|
||||||
#Create dump
|
|
||||||
if [ "${POSTGRES_CLUSTER}" = "TRUE" ]; then
|
if [ "${POSTGRES_CLUSTER}" = "TRUE" ]; then
|
||||||
echo "Creating cluster dump of ${DB} database from ${POSTGRES_HOST}..."
|
echo "Creating cluster dump of ${DB} database from ${POSTGRES_HOST}..."
|
||||||
pg_dumpall -l "${DB}" ${POSTGRES_EXTRA_OPTS} | gzip > "${FILE}"
|
pg_dumpall -l "${DB}" ${POSTGRES_EXTRA_OPTS} | gzip > "${FILE}"
|
||||||
@@ -82,36 +141,137 @@ for DB in ${POSTGRES_DBS}; do
|
|||||||
echo "Creating dump of ${DB} database from ${POSTGRES_HOST}..."
|
echo "Creating dump of ${DB} database from ${POSTGRES_HOST}..."
|
||||||
pg_dump -d "${DB}" -f "${FILE}" ${POSTGRES_EXTRA_OPTS}
|
pg_dump -d "${DB}" -f "${FILE}" ${POSTGRES_EXTRA_OPTS}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create hardlinks from daily backup to monthly and weekly backups
|
||||||
|
create_hardlinks () {
|
||||||
|
|
||||||
|
SRC=$1
|
||||||
|
INCREMENT=$2
|
||||||
|
|
||||||
|
if [ "${INCREMENT}" = "weekly" ]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "Creating Weekly Backup of ${DB} database from ${POSTGRES_HOST}..."
|
||||||
|
FILENAME="${DB}-`date +%G%V`${BACKUP_SUFFIX}"
|
||||||
|
|
||||||
|
elif [ "${INCREMENT}" = "monthly"]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "Creating Monthly Backup of ${DB} database from ${POSTGRES_HOST}..."
|
||||||
|
FILENAME="${DB}-`date +%Y%m`${BACKUP_SUFFIX}"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
DEST="${BACKUP_DIR}/${INCREMENT}/${FILENAME}"
|
||||||
|
|
||||||
#Copy (hardlink) for each entry
|
#Copy (hardlink) for each entry
|
||||||
if [ -d "${FILE}" ]; then
|
if [ -d "${SRC}" ]
|
||||||
DFILENEW="${DFILE}-new"
|
then
|
||||||
WFILENEW="${WFILE}-new"
|
ln -f "${SRC}/"* "${DEST}/"
|
||||||
MFILENEW="${MFILE}-new"
|
|
||||||
rm -rf "${DFILENEW}" "${WFILENEW}" "${MFILENEW}"
|
|
||||||
mkdir "${DFILENEW}" "${WFILENEW}" "${MFILENEW}"
|
|
||||||
ln -f "${FILE}/"* "${DFILENEW}/"
|
|
||||||
ln -f "${FILE}/"* "${WFILENEW}/"
|
|
||||||
ln -f "${FILE}/"* "${MFILENEW}/"
|
|
||||||
rm -rf "${DFILE}" "${WFILE}" "${MFILE}"
|
|
||||||
mv -v "${DFILENEW}" "${DFILE}"
|
|
||||||
mv -v "${WFILENEW}" "${WFILE}"
|
|
||||||
mv -v "${MFILENEW}" "${MFILE}"
|
|
||||||
else
|
else
|
||||||
ln -vf "${FILE}" "${DFILE}"
|
ln -vf "${SRC}" "${DEST}"
|
||||||
ln -vf "${FILE}" "${WFILE}"
|
|
||||||
ln -vf "${FILE}" "${MFILE}"
|
|
||||||
fi
|
fi
|
||||||
# Update latest symlinks
|
# Update latest symlinks
|
||||||
ln -svf "${LAST_FILENAME}" "${BACKUP_DIR}/last/${DB}-latest${BACKUP_SUFFIX}"
|
ln -svf "${DEST}" "${BACKUP_DIR}/${INCREMENT}/${DB}-latest"
|
||||||
ln -svf "${DAILY_FILENAME}" "${BACKUP_DIR}/daily/${DB}-latest${BACKUP_SUFFIX}"
|
|
||||||
ln -svf "${WEEKLY_FILENAME}" "${BACKUP_DIR}/weekly/${DB}-latest${BACKUP_SUFFIX}"
|
}
|
||||||
ln -svf "${MONTHY_FILENAME}" "${BACKUP_DIR}/monthly/${DB}-latest${BACKUP_SUFFIX}"
|
|
||||||
|
#Clean up old backups
|
||||||
|
cleanup_backups () {
|
||||||
|
|
||||||
|
for folder in "${FREQUENCY[@]}"
|
||||||
|
do
|
||||||
|
if [ $folder == "weekly" ]
|
||||||
|
then
|
||||||
|
KEEP=$KEEP_WEEKS
|
||||||
|
DELETE=$BACKUP_DELETE_WEEKS
|
||||||
|
elif [ $folder == 'monthly' ]
|
||||||
|
then
|
||||||
|
KEEP=$KEEP_MONTHS
|
||||||
|
DELETE=$BACKUP_DELETE_MONTHS
|
||||||
|
elif [ $folder == 'daily' ]
|
||||||
|
then
|
||||||
|
KEEP=$KEEP_DAYS
|
||||||
|
DELETE=$BACKUP_DELETE_DAYS
|
||||||
|
fi
|
||||||
|
|
||||||
|
for DB in ${POSTGRES_DBS}
|
||||||
|
do
|
||||||
|
|
||||||
#Clean old files
|
#Clean old files
|
||||||
echo "Cleaning older files for ${DB} database from ${POSTGRES_HOST}..."
|
echo "Cleaning older files in ${folder} for ${DB} database from ${POSTGRES_HOST}..."
|
||||||
find "${BACKUP_DIR}/last" -maxdepth 1 -mmin "+${KEEP_MINS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rf '{}' ';'
|
|
||||||
find "${BACKUP_DIR}/daily" -maxdepth 1 -mtime "+${KEEP_DAYS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rf '{}' ';'
|
local all=( `find "${BACKUP_DIR}/${folder}" -maxdepth 1 -name "${DB}-*"` )
|
||||||
find "${BACKUP_DIR}/weekly" -maxdepth 1 -mtime "+${KEEP_WEEKS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rf '{}' ';'
|
|
||||||
find "${BACKUP_DIR}/monthly" -maxdepth 1 -mtime "+${KEEP_MONTHS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rf '{}' ';'
|
if [ $KEEP -gt 0 ]
|
||||||
|
then
|
||||||
|
|
||||||
|
local files=( `find "${BACKUP_DIR}/${folder}" -maxdepth 1 -mtime "+$((${KEEP}-1))" -name "${DB}-*"` )
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $((${#all[@]}-${#files[@]})) -lt ${KEEP} ]
|
||||||
|
then
|
||||||
|
|
||||||
|
echo "Only ${#all[@]} Backups exist for ${DB} and you want to keep $KEEP."
|
||||||
|
echo "If you have just started taking backups you may ignore this"
|
||||||
|
echo "Otherwise you may want to investigate why backups are not being taken"
|
||||||
|
|
||||||
|
elif $DELETE
|
||||||
|
then
|
||||||
|
for file in "${files[@]}"
|
||||||
|
do
|
||||||
|
|
||||||
|
echo "Deleting $file"
|
||||||
|
rm $file
|
||||||
|
|
||||||
|
done
|
||||||
|
else
|
||||||
|
for file in "${files[@]}"
|
||||||
|
do
|
||||||
|
|
||||||
|
echo "Dry Run: Delete $file"
|
||||||
|
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "SQL backup created successfully"
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
listCommands () {
|
||||||
|
|
||||||
|
echo "--create-backup -b Create Daily, Weekly and Monthly backups"
|
||||||
|
echo "--cleanup -c Cleanup old backups"
|
||||||
|
echo "--help -h List commands"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
|
||||||
|
"--create-backup" | "-b")
|
||||||
|
|
||||||
|
setup
|
||||||
|
create_backups
|
||||||
|
;;
|
||||||
|
|
||||||
|
"--cleanup" | "-c")
|
||||||
|
|
||||||
|
setup
|
||||||
|
cleanup_backups
|
||||||
|
;;
|
||||||
|
|
||||||
|
"--help" | "-h")
|
||||||
|
|
||||||
|
listCommands
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
|
||||||
|
echo "No command found."
|
||||||
|
listCommands
|
||||||
|
|
||||||
|
esac
|
||||||
|
|||||||
Reference in New Issue
Block a user