]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-scripts: Add support for backing up persistent TDBs
authorMartin Schwenke <mschwenke@ddn.com>
Fri, 5 Apr 2024 06:12:40 +0000 (17:12 +1100)
committerMartin Schwenke <martins@samba.org>
Thu, 29 Aug 2024 22:48:33 +0000 (22:48 +0000)
Signed-off-by: Vinit Agnihotri <vagnihotri@ddn.com>
Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/config/ctdb-backup-persistent-tdbs.sh [new file with mode: 0755]
ctdb/config/events/legacy/95.database.script
ctdb/doc/ctdb-script.options.5.xml
ctdb/doc/examples/ctdb.spec.in
ctdb/wscript

diff --git a/ctdb/config/ctdb-backup-persistent-tdbs.sh b/ctdb/config/ctdb-backup-persistent-tdbs.sh
new file mode 100755 (executable)
index 0000000..9610eef
--- /dev/null
@@ -0,0 +1,123 @@
+#!/bin/sh
+
+# Backup persistent CTDB TDBs into the given directory.
+
+# Copyright: DataDirect Networks, 2024
+# Authors: Vinit Agnihotri <vagnihotri@ddn.com>
+#          Martin Schwenke <mschwenke@ddn.com>
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Options:
+#
+# -l: Only do the backup if this node is the leader node, otherwise
+#     exit with 0.
+#
+# -L <rc>: Only do the backup if this node is the leader node, otherwise
+#     exit with <rc>.
+
+#
+# Option/argument handling
+#
+
+die()
+{
+       echo "ERROR: $1"
+       exit 1
+}
+
+usage()
+{
+       die "usage: $0 [-l | -L <rc> ] <dir>"
+}
+
+leader_only=false
+leader_only_rc=0
+dir=""
+
+while getopts "L:lh?" opt; do
+       case "$opt" in
+       L)
+               leader_only=true
+               leader_only_rc="$OPTARG"
+               ;;
+       l)
+               leader_only=true
+               ;;
+       \? | h)
+               usage
+               ;;
+       esac
+done
+shift $((OPTIND - 1))
+
+if [ $# -ne 1 ]; then
+       usage
+fi
+
+dir="$1"
+
+if [ ! -d "$dir" ]; then
+       die "No such directory ${dir}"
+fi
+
+if $leader_only; then
+       this_node=$(ctdb pnn)
+       leader_node=$(ctdb leader)
+       if [ "$this_node" != "$leader_node" ]; then
+               exit "$leader_only_rc"
+       fi
+fi
+
+#
+# Backups TDBs in timestamped subdirectory
+#
+
+dt=$(date "+%Y%m%d%H%M%S")
+prefix="ctdb-persistent-db-backup-${dt}"
+outdir="${dir}/${prefix}"
+
+# Clean up temporary directory on failure"
+trap 'rm -rf ${outdir}' 0
+
+mkdir -p "$outdir"
+
+if ! db_map=$(ctdb getdbmap -X); then
+       die "Failed to list databases"
+fi
+db_list=$(echo "$db_map" | awk -F '|' '$5 == "1" { print $3 }')
+
+cd "$outdir" || die "Failed to change directory to ${dir}"
+
+for db in $db_list; do
+       if ! ctdb backupdb "$db" "${db}.backup"; then
+               die "Failed to backup ${db}"
+       fi
+done
+
+#
+# Create tarball
+#
+
+cd "$dir" || die "Failed to change directory to ${dir}"
+
+tarball="${prefix}.tgz"
+
+if ! tar -c -z -f "$tarball" "$prefix"; then
+       die "Failed to create tarball"
+fi
+
+echo "Created backup tarball ${dir}/${tarball}"
+
+exit 0
index dab4125806d0c443a8c78ad0a2d7867a7c741e88..e2627c6c1d04ff49ba91da5659463d67aa555d75 100755 (executable)
@@ -101,6 +101,38 @@ EOF
        done
 }
 
+maybe_backup_persistent_tdbs()
+{
+       _dir="${CTDB_PERSISTENT_DB_BACKUP_DIR:-}"
+       if [ -z "$_dir" ]; then
+               return 0
+       fi
+
+       if [ ! -d "$_dir" ]; then
+               echo "Creating CTDB_PERSISTENT_DB_BACKUP_DIR=${_dir}"
+               if ! mkdir -p "$_dir"; then
+                       die "ERROR: unable to create ${_dir}"
+               fi
+       fi
+
+       # Don't backup if there are backup files from within the past day
+       _out=$(find "$_dir" -type f -mtime -1)
+       if [ -n "$_out" ]; then
+               return 0
+       fi
+
+       # Script will ignore if this isn't leader node, so don't
+       # double-check that here...
+       "${CTDB_BASE}/ctdb-backup-persistent-tdbs.sh" -l "$_dir"
+
+       # Remove backups beyond the limit (default 14)
+       _limit="${CTDB_PERSISTENT_DB_BACKUP_LIMIT:-14}"
+       _offset=$((_limit + 1))
+       # Can't sort by time using find instead of ls
+       # shellcheck disable=SC2012
+       ls -t "$_dir"/* 2>/dev/null | tail -n "+${_offset}" | xargs rm -f
+}
+
 ############################################################
 
 ctdb_check_args "$@"
@@ -115,6 +147,9 @@ init)
                check_non_persistent_databases
        fi
        ;;
+monitor)
+       maybe_backup_persistent_tdbs
+       ;;
 esac
 
 # all OK
index 1fcf9c4722813d03bbd565f46eaf6f519faf8ea9..11597097a0437cd715cb346564d5fb96fe18f84c 100644 (file)
@@ -1000,7 +1000,8 @@ CTDB_PER_IP_ROUTING_TABLE_ID_HIGH=9000
       </title>
 
       <para>
-       CTDB checks the consistency of databases during startup.
+       CTDB checks the consistency of databases during startup and
+       provides a facility to backup persistent databases.
       </para>
 
       <refsect2>
@@ -1024,6 +1025,56 @@ CTDB_PER_IP_ROUTING_TABLE_ID_HIGH=9000
            </listitem>
          </varlistentry>
 
+         <varlistentry>
+           <term>CTDB_PERSISTENT_DB_BACKUP_DIR=<parameter>DIRECTORY</parameter></term>
+           <listitem>
+             <para>
+               Create a daily backup tarball for all persistent TDBs
+               in DIRECTORY.  Note that DIRECTORY must exist or no
+               backups will be created.
+             </para>
+             <para>
+               Given that persistent databases are fully replicated,
+               duplication is avoid by only creating backups on the
+               current leader node.  To maintain a complete, single
+               set of backups, it makes sense for DIRECTORY to be in
+               a cluster filesystem.
+             </para>
+             <para>
+               This creates the backup from the
+               <command>monitor</command> event, which should be fine
+               because backing up persistent databases is a local
+               operation.  Users who do not wish do create backups
+               during the <command>monitor</command> event can choose
+               not to use this option and instead run
+               <command>/usr/local/etc/ctdb/ctdb-backup-persistent-tdbs.sh
+               -l <parameter>DIRECTORY</parameter></command> on all
+               nodes using a
+               <citerefentry><refentrytitle>cron</refentrytitle>
+               <manvolnum>8</manvolnum></citerefentry> job, which
+               will also need to manually manage backup pruning.
+             </para>
+             <para>
+               No default.  No daily backups are created.
+             </para>
+           </listitem>
+         </varlistentry>
+
+         <varlistentry>
+           <term>CTDB_PERSISTENT_DB_BACKUP_LIMIT=<parameter>COUNT</parameter></term>
+           <listitem>
+             <para>
+               Keep at most COUNT backups in
+               CTDB_PERSISTENT_DB_BACKUP_DIR.  Note that if
+               additional manual backups are created in this
+               directory then these will count towards the limit.
+             </para>
+             <para>
+               Default is 14.
+             </para>
+           </listitem>
+         </varlistentry>
+
        </variablelist>
       </refsect2>
 
index 83c28b495594cd0fa852c0cd74bc4e9bcf7e6315..23b0008d83b202b77cfd687e6dd2dda875136169 100644 (file)
@@ -199,6 +199,7 @@ fi
 %doc doc/examples
 %dir %{_sysconfdir}/ctdb
 %{_sysconfdir}/ctdb/functions
+%{_sysconfdir}/ctdb/ctdb-backup-persistent-tdbs.sh
 %dir %{_sysconfdir}/ctdb/events
 %{_sysconfdir}/ctdb/events/*
 %dir %{_sysconfdir}/ctdb/nfs-checks.d
index 34a7a212de1364678538097fc2037737c92ec08d..e89f6548af3514817e55963a536fc3c9c19b09f7 100644 (file)
@@ -877,6 +877,7 @@ def build(bld):
     bld.INSTALL_FILES(bld.env.CTDB_ETCDIR, 'functions', destname='functions')
 
     etc_scripts = [
+        'ctdb-backup-persistent-tdbs.sh',
         'ctdb-crash-cleanup.sh',
         'debug-hung-script.sh',
         'debug_locks.sh',