From 8992f162d797bdbc94160df1b560a87c09a6477e Mon Sep 17 00:00:00 2001 From: "Fco. Javier Delgado del Hoyo" Date: Fri, 4 Feb 2022 20:44:11 +0100 Subject: [PATCH 1/2] support saving non-gzipped sql files --- README.md | 1 + backup.sh | 25 +++++++++++++++++-------- restore.sh | 11 +++++++++-- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e2cd2e8..8464811 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ docker container run -d \ - `INIT_RESTORE_LATEST`: If set, restores latest backup. - `TIMEOUT`: Wait a given number of seconds for the database to be ready and make the first backup, `10s` by default. After that time, the initial attempt for backup gives up and only the Cron job will try to make a backup. - `GZIP_LEVEL`: Specify the level of gzip compression from 1 (quickest, least compressed) to 9 (slowest, most compressed), default is 6. +- `USE_PLAIN_SQL`: If set, back up and restore plain SQL files without gzip. - `TZ`: Specify TIMEZONE in Container. E.g. "Europe/Berlin". Default is UTC. If you want to make this image the perfect companion of your MySQL container, use [docker-compose](https://docs.docker.com/compose/). You can add more services that will be able to connect to the MySQL image using the name `my_mariadb`, note that you only expose the port `3306` internally to the servers and not to the host: diff --git a/backup.sh b/backup.sh index 6b75964..76a3d5a 100755 --- a/backup.sh +++ b/backup.sh @@ -20,19 +20,28 @@ do then echo "==> Dumping database: $db" FILENAME=/backup/$DATE.$db.sql - LATEST=/backup/latest.$db.sql.gz - if mysqldump --single-transaction -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASS" "$db" $MYSQLDUMP_OPTS > "$FILENAME" + LATEST=/backup/latest.$db.sql + if mysqldump --single-transaction -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASS" "$db" "$MYSQLDUMP_OPTS" > "$FILENAME" then - gzip "-$GZIP_LEVEL" -f "$FILENAME" - echo "==> Creating symlink to latest backup: $(basename "$FILENAME".gz)" + EXT= + if [ -z "${USE_PLAIN_SQL}" ] + then + echo "==> Compressing $db with LEVEL $GZIP_LEVEL" + gzip "-$GZIP_LEVEL" -f "$FILENAME" + EXT=.gz + FILENAME=$FILENAME$EXT + LATEST=$LATEST$EXT + fi + BASENAME=$(basename "$FILENAME") + echo "==> Creating symlink to latest backup: $BASENAME" rm "$LATEST" 2> /dev/null - cd /backup || exit && ln -s "$(basename "$FILENAME".gz)" "$(basename "$LATEST")" + cd /backup || exit && ln -s "$BASENAME" "$(basename "$LATEST")" if [ -n "$MAX_BACKUPS" ] then - while [ "$(find /backup -maxdepth 1 -name "*.$db.sql.gz" -type f | wc -l)" -gt "$MAX_BACKUPS" ] + while [ "$(find /backup -maxdepth 1 -name "*.$db.sql$EXT" -type f | wc -l)" -gt "$MAX_BACKUPS" ] do - TARGET=$(find /backup -maxdepth 1 -name "*.$db.sql.gz" -type f | sort | head -n 1) - echo "==> Max number of backups ($MAX_BACKUPS) reached. Deleting ${TARGET} ..." + TARGET=$(find /backup -maxdepth 1 -name "*.$db.sql$EXT" -type f | sort | head -n 1) + echo "==> Max number of ($MAX_BACKUPS) backups reached. Deleting ${TARGET} ..." rm -rf "${TARGET}" echo "==> Backup ${TARGET} deleted" done diff --git a/restore.sh b/restore.sh index 07ecbae..536a890 100755 --- a/restore.sh +++ b/restore.sh @@ -13,13 +13,20 @@ fi set -o pipefail -SQL=$(gunzip -c "$1") +if [ -z "${USE_PLAIN_SQL}" ] +then + SQL=$(gunzip -c "$1") +else + SQL=$(cat "$1") +fi + DB_NAME=${MYSQL_DATABASE:-${MYSQL_DB}} if [ -z "${DB_NAME}" ] then + echo "=> Searching database name in $1" DB_NAME=$(echo "$SQL" | grep -oE '(Database: (.+))' | cut -d ' ' -f 2) fi -[ -z "${DB_NAME}" ] && { echo "=> database name cannot be found" && exit 1; } +[ -z "${DB_NAME}" ] && { echo "=> Database name not found" && exit 1; } echo "=> Restore database $DB_NAME from $1" From f7418224036f8c089547918059c148b25d337853 Mon Sep 17 00:00:00 2001 From: "Fco. Javier Delgado del Hoyo" Date: Sat, 5 Feb 2022 13:01:53 +0100 Subject: [PATCH 2/2] fix wrong placement of MYSQLDUMP_OPTS variable --- Dockerfile | 3 ++- README.md | 2 +- backup.sh | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d19d572..a1ee8c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,8 @@ COPY --from=binary /go/bin/dockerize /usr/local/bin ENV CRON_TIME="0 3 * * sun" \ MYSQL_HOST="mysql" \ MYSQL_PORT="3306" \ - TIMEOUT="10s" + TIMEOUT="10s" \ + MYSQLDUMP_OPTS="--quick" COPY ["run.sh", "backup.sh", "restore.sh", "/"] RUN mkdir /backup && \ diff --git a/README.md b/README.md index 8464811..4280622 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ docker container run -d \ - `MYSQL_PASS`: The password of your mysql database. - `MYSQL_PASS_FILE`: The file in container where to find the password of your mysql database (cf. docker secrets). You should use either MYSQL_PASS_FILE or MYSQL_PASS (see examples below). - `MYSQL_DATABASE`: The database name to dump. Default: `--all-databases`. -- `MYSQLDUMP_OPTS`: Command line arguments to pass to mysqldump. Example: `--single-transaction`. +- `MYSQLDUMP_OPTS`: Command line arguments to pass to mysqldump (see [mysqldump documentation](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html)). - `CRON_TIME`: The interval of cron job to run mysqldump. `0 3 * * sun` by default, which is every Sunday at 03:00. It uses UTC timezone. - `MAX_BACKUPS`: The number of backups to keep. When reaching the limit, the old backup will be discarded. No limit by default. - `INIT_BACKUP`: If set, create a backup when the container starts. diff --git a/backup.sh b/backup.sh index 76a3d5a..7082e01 100755 --- a/backup.sh +++ b/backup.sh @@ -21,7 +21,7 @@ do echo "==> Dumping database: $db" FILENAME=/backup/$DATE.$db.sql LATEST=/backup/latest.$db.sql - if mysqldump --single-transaction -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASS" "$db" "$MYSQLDUMP_OPTS" > "$FILENAME" + if mysqldump --single-transaction "$MYSQLDUMP_OPTS" -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASS" "$db" > "$FILENAME" then EXT= if [ -z "${USE_PLAIN_SQL}" ]