Add optional compression to mariabackup
As database backups can grow substantially in size, compressing backups helps to preserve disk space. While the mariabackup utility offers no compression by itself, we can stream the backup into a compression tool to create an archive [1]. The xtrabackup_checkpoints file, which contains metadata on a backup, gets stored alongside the archive, allowing to create incremental backups from non-compressed backups and vice-versa [2]. One thing to note, is that compressed backups cannot be prepared in advance, this step must be manually carried out by the user. Backup compression is disabled by default and different compressors can be chosen (zstd, xz, ...), with gzip being the default. [1] https://mariadb.com/kb/en/using-encryption-and-compression-tools-with-mariabackup/ [2] https://mariadb.com/kb/en/incremental-backup-and-restore-with-mariabackup/#combining-with-stream-output Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/888437 Change-Id: I28c6a0e0b41d4d29c3e79e601de45ea373dee4fb Signed-off-by: Simon Hensel <simon.hensel@inovex.de> (cherry picked from commit 60009ed7cebe9c082592fd564b1577068ef94b6c) (cherry picked from commit 41801ab04d3c64d61b881d410691e05e0312114d)
This commit is contained in:
parent
0f343a8315
commit
03ad7d6ace
@ -319,6 +319,8 @@ galera_mariadb_backups_user: galera_mariadb_backup
|
|||||||
galera_mariadb_backups_suffix: "{{ inventory_hostname }}"
|
galera_mariadb_backups_suffix: "{{ inventory_hostname }}"
|
||||||
galera_mariadb_backups_cnf_file: "/etc/mysql/mariabackup.cnf"
|
galera_mariadb_backups_cnf_file: "/etc/mysql/mariabackup.cnf"
|
||||||
galera_mariadb_backups_nodes: ["{{ galera_cluster_members[0] }}"]
|
galera_mariadb_backups_nodes: ["{{ galera_cluster_members[0] }}"]
|
||||||
|
galera_mariadb_backups_compress: False
|
||||||
|
galera_mariadb_backups_compressor: gzip
|
||||||
|
|
||||||
galera_mariadb_encryption_enabled: false
|
galera_mariadb_encryption_enabled: false
|
||||||
galera_mariadb_encryption_plugin: "file_key_management"
|
galera_mariadb_encryption_plugin: "file_key_management"
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds optional compression for backups created with mariabackup. Adds two
|
||||||
|
new CLI parameters to the mariabackup script that are used to enable
|
||||||
|
compression and to choose a compression tool.
|
||||||
|
|
||||||
|
* ``--compress=True|False``
|
||||||
|
* ``--compressor=<compressor>``
|
||||||
|
|
||||||
|
Also introduces new Ansible variables that control the above mentioned
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
* ``galera_mariadb_backups_compress``
|
||||||
|
* ``galera_mariadb_backups_compressor``
|
||||||
|
|
||||||
|
Each backup archive is stored in a dedicated directory, alongside the
|
||||||
|
backup metadata.
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Backup compression is disabled by default, so no changes need to be made
|
||||||
|
for existing deployments. Should compression be desired, set
|
||||||
|
``galera_mariadb_backups_compress`` to ``True``. Choose a compression tool
|
||||||
|
with ``galera_mariadb_backups_compressor``, default is ``gzip``.
|
||||||
|
others:
|
||||||
|
- |
|
||||||
|
Compressed backups cannot be prepared in advance, this step must be
|
||||||
|
manually carried out by the user before importing it into MariaDB.
|
@ -39,6 +39,7 @@
|
|||||||
- /usr/bin/python3 {{ galera_mariadb_backups_path }}/mariabackup_script.py {{ galera_mariadb_backups_path }}
|
- /usr/bin/python3 {{ galera_mariadb_backups_path }}/mariabackup_script.py {{ galera_mariadb_backups_path }}
|
||||||
--full-backup --copies={{ galera_mariadb_backups_full_copies }} --suffix={{ galera_mariadb_backups_suffix }}
|
--full-backup --copies={{ galera_mariadb_backups_full_copies }} --suffix={{ galera_mariadb_backups_suffix }}
|
||||||
--defaults-file={{ galera_mariadb_backups_cnf_file }}
|
--defaults-file={{ galera_mariadb_backups_cnf_file }}
|
||||||
|
--compress={{ galera_mariadb_backups_compress }} --compressor={{ galera_mariadb_backups_compressor }}
|
||||||
environment:
|
environment:
|
||||||
UMASK: '0640'
|
UMASK: '0640'
|
||||||
UMASK_DIR: '0750'
|
UMASK_DIR: '0750'
|
||||||
@ -66,6 +67,7 @@
|
|||||||
- /usr/bin/python3 {{ galera_mariadb_backups_path }}/mariabackup_script.py {{ galera_mariadb_backups_path }}
|
- /usr/bin/python3 {{ galera_mariadb_backups_path }}/mariabackup_script.py {{ galera_mariadb_backups_path }}
|
||||||
--increment --copies={{ galera_mariadb_backups_full_copies }} --suffix={{ galera_mariadb_backups_suffix }}
|
--increment --copies={{ galera_mariadb_backups_full_copies }} --suffix={{ galera_mariadb_backups_suffix }}
|
||||||
--defaults-file={{ galera_mariadb_backups_cnf_file }}
|
--defaults-file={{ galera_mariadb_backups_cnf_file }}
|
||||||
|
--compress={{ galera_mariadb_backups_compress }} --compressor={{ galera_mariadb_backups_compressor }}
|
||||||
environment:
|
environment:
|
||||||
UMASK: '0640'
|
UMASK: '0640'
|
||||||
UMASK_DIR: '0750'
|
UMASK_DIR: '0750'
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE, check_output, run
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from time import strftime, mktime, sleep
|
from time import strftime, mktime, sleep
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import socket
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def get_opts():
|
def get_opts():
|
||||||
@ -35,6 +34,21 @@ def get_opts():
|
|||||||
default=False,
|
default=False,
|
||||||
help="Flag to make incremental backup, based on the latest backup",
|
help="Flag to make incremental backup, based on the latest backup",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--compress",
|
||||||
|
dest="compress_flag",
|
||||||
|
default=False,
|
||||||
|
type=eval,
|
||||||
|
choices=[True, False],
|
||||||
|
help="Flag to compress created backups",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--compressor",
|
||||||
|
dest="compressor",
|
||||||
|
default="gzip",
|
||||||
|
type=str,
|
||||||
|
help="The compressor to use when compressing backups (default: gzip)",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-c",
|
"-c",
|
||||||
"--copies",
|
"--copies",
|
||||||
@ -102,12 +116,26 @@ def check_backups(dest, warning, critical, full_backup_filename):
|
|||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
|
|
||||||
|
|
||||||
def create_full_backup(dest, curtime, full_backup_filename, extra_mariabackup_args):
|
def create_full_backup(dest, curtime, full_backup_filename, extra_mariabackup_args, compress, compressor):
|
||||||
check_lock_file()
|
check_lock_file()
|
||||||
get_lock_file()
|
get_lock_file()
|
||||||
try:
|
try:
|
||||||
#Creating full backup
|
|
||||||
err = open(os.path.normpath(dest+"/backup.log"), "w")
|
err = open(os.path.normpath(dest+"/backup.log"), "w")
|
||||||
|
if compress:
|
||||||
|
#Creating compressed full backup
|
||||||
|
os.makedirs(dest+"/"+full_backup_filename+curtime, exist_ok=True)
|
||||||
|
mariabackup_run = Popen(
|
||||||
|
["/usr/bin/mariabackup"] + extra_mariabackup_args + ["--backup", "--stream=xbstream", "--extra-lsndir="+os.path.normpath(dest+"/"+full_backup_filename+curtime)], stdout=PIPE, stderr=err
|
||||||
|
)
|
||||||
|
compressed_backup = open(os.path.normpath(dest+"/"+full_backup_filename+curtime+"/"+full_backup_filename+curtime), "wb")
|
||||||
|
run([compressor], stdin=mariabackup_run.stdout, stdout=compressed_backup)
|
||||||
|
mariabackup_run.wait()
|
||||||
|
mariabackup_res = mariabackup_run.communicate()
|
||||||
|
if mariabackup_run.returncode:
|
||||||
|
print(mariabackup_res[1])
|
||||||
|
compressed_backup.close()
|
||||||
|
else:
|
||||||
|
#Creating full backup
|
||||||
mariabackup_run = Popen(
|
mariabackup_run = Popen(
|
||||||
["/usr/bin/mariabackup"] + extra_mariabackup_args + ["--backup", "--target-dir="+os.path.normpath(dest+"/"+full_backup_filename+curtime)], stdout=None, stderr=err
|
["/usr/bin/mariabackup"] + extra_mariabackup_args + ["--backup", "--target-dir="+os.path.normpath(dest+"/"+full_backup_filename+curtime)], stdout=None, stderr=err
|
||||||
)
|
)
|
||||||
@ -115,7 +143,6 @@ def create_full_backup(dest, curtime, full_backup_filename, extra_mariabackup_ar
|
|||||||
mariabackup_res = mariabackup_run.communicate()
|
mariabackup_res = mariabackup_run.communicate()
|
||||||
if mariabackup_run.returncode:
|
if mariabackup_run.returncode:
|
||||||
print(mariabackup_res[1])
|
print(mariabackup_res[1])
|
||||||
err.close()
|
|
||||||
#Preparing full backup
|
#Preparing full backup
|
||||||
err_p = open(os.path.normpath(dest+"/prepare.log"), "w")
|
err_p = open(os.path.normpath(dest+"/prepare.log"), "w")
|
||||||
mariabackup_prep = Popen(
|
mariabackup_prep = Popen(
|
||||||
@ -126,6 +153,7 @@ def create_full_backup(dest, curtime, full_backup_filename, extra_mariabackup_ar
|
|||||||
if mariabackup_prep.returncode:
|
if mariabackup_prep.returncode:
|
||||||
print(mariabackup_prep_res[1])
|
print(mariabackup_prep_res[1])
|
||||||
err_p.close()
|
err_p.close()
|
||||||
|
err.close()
|
||||||
except OSError:
|
except OSError:
|
||||||
print("Please, check that Mariabackup is installed")
|
print("Please, check that Mariabackup is installed")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -134,7 +162,7 @@ def create_full_backup(dest, curtime, full_backup_filename, extra_mariabackup_ar
|
|||||||
os.unlink("/var/run/mariabackup-galera/db_backup.pid")
|
os.unlink("/var/run/mariabackup-galera/db_backup.pid")
|
||||||
|
|
||||||
|
|
||||||
def create_increment_backup(dest, curtime, increment_backup_filename, extra_mariabackup_args):
|
def create_increment_backup(dest, curtime, increment_backup_filename, extra_mariabackup_args, compress, compressor):
|
||||||
check_lock_file()
|
check_lock_file()
|
||||||
get_lock_file()
|
get_lock_file()
|
||||||
try:
|
try:
|
||||||
@ -145,6 +173,20 @@ def create_increment_backup(dest, curtime, increment_backup_filename, extra_mari
|
|||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
try:
|
try:
|
||||||
err = open(os.path.normpath(dest+"/increment.err"), "w")
|
err = open(os.path.normpath(dest+"/increment.err"), "w")
|
||||||
|
if compress:
|
||||||
|
#Creating compressed incremental backup
|
||||||
|
os.makedirs(dest+"/"+increment_backup_filename+curtime, exist_ok=True)
|
||||||
|
mariabackup_run = Popen(
|
||||||
|
["/usr/bin/mariabackup"] + extra_mariabackup_args + ["--backup", "--stream=xbstream", "--incremental-basedir="+basedir, "--extra-lsndir="+os.path.normpath(dest+"/"+increment_backup_filename+curtime)], stdout=PIPE, stderr=err
|
||||||
|
)
|
||||||
|
compressed_backup = open(os.path.normpath(dest+"/"+increment_backup_filename+curtime+"/"+increment_backup_filename+curtime), "wb")
|
||||||
|
run([compressor], stdin=mariabackup_run.stdout, stdout=compressed_backup)
|
||||||
|
mariabackup_run.wait()
|
||||||
|
mariabackup_res = mariabackup_run.communicate()
|
||||||
|
if mariabackup_run.returncode:
|
||||||
|
print(mariabackup_res[1])
|
||||||
|
compressed_backup.close()
|
||||||
|
else:
|
||||||
#Creating incremental backup
|
#Creating incremental backup
|
||||||
mariabackup_run = Popen(
|
mariabackup_run = Popen(
|
||||||
["/usr/bin/mariabackup"] + extra_mariabackup_args + ["--backup", "--target-dir="+os.path.normpath(dest+"/"+increment_backup_filename+curtime), "--incremental-basedir="+basedir], stdout=None, stderr=err
|
["/usr/bin/mariabackup"] + extra_mariabackup_args + ["--backup", "--target-dir="+os.path.normpath(dest+"/"+increment_backup_filename+curtime), "--incremental-basedir="+basedir], stdout=None, stderr=err
|
||||||
@ -227,11 +269,11 @@ def main():
|
|||||||
if opts.fullbackup_flag and opts.increment_flag:
|
if opts.fullbackup_flag and opts.increment_flag:
|
||||||
raise NameError("Only one flag can be specified per operation")
|
raise NameError("Only one flag can be specified per operation")
|
||||||
elif opts.fullbackup_flag:
|
elif opts.fullbackup_flag:
|
||||||
create_full_backup(opts.destdir, curtime, full_backup_filename, extra_mariabackup_args)
|
create_full_backup(opts.destdir, curtime, full_backup_filename, extra_mariabackup_args, opts.compress_flag, opts.compressor)
|
||||||
rotate_backups(opts.destdir, opts.copies_flag, full_backup_filename, increment_backup_filename)
|
rotate_backups(opts.destdir, opts.copies_flag, full_backup_filename, increment_backup_filename)
|
||||||
raise SystemExit()
|
raise SystemExit()
|
||||||
elif opts.increment_flag:
|
elif opts.increment_flag:
|
||||||
create_increment_backup(opts.destdir, curtime, increment_backup_filename, extra_mariabackup_args)
|
create_increment_backup(opts.destdir, curtime, increment_backup_filename, extra_mariabackup_args, opts.compress_flag, opts.compressor)
|
||||||
raise SystemExit()
|
raise SystemExit()
|
||||||
elif opts.check_flag:
|
elif opts.check_flag:
|
||||||
pass
|
pass
|
||||||
|
Loading…
x
Reference in New Issue
Block a user