MariaDB Sauvegarde Restauration
Voici le pack complet simplifié pour un MariaDB où le root système peut se connecter sans mot de passe via socket local. MariaDB documente bien que l’authentification unix_socket permet au root système de se connecter à root@localhost sans mot de passe. mariadb
Configuration locale du serveur MariaDB pôur une utilisation sans mot de passe. ibug
Script de sauvegarde
Créez /usr/local/sbin/mariadb-backup.sh :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| #!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="/var/backups/mariadb"
LOG_FILE="/var/log/mariadb-backup.log"
LOCK_FILE="/run/mariadb-backup.lock"
RETENTION_DAYS=14
log() { echo "[$(date '+%F %T')] $1" | tee -a "$LOG_FILE"; }
fail() { log "ERREUR: $1"; exit 1; }
mkdir -p "$BACKUP_DIR" "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
command -v mariadb >/dev/null 2>&1 || fail "mariadb introuvable"
command -v mariadb-dump >/dev/null 2>&1 || fail "mariadb-dump introuvable"
command -v gzip >/dev/null 2>&1 || fail "gzip introuvable"
sudo mariadb -e "SELECT 1;" >/dev/null 2>&1 || fail "Connexion MariaDB impossible sans mot de passe"
exec 9>"$LOCK_FILE"
flock -n 9 || fail "Une autre sauvegarde est déjà en cours"
DATE="$(date +%F_%H-%M-%S)"
HOSTNAME="$(hostname -s)"
databases=$(sudo mariadb -Nse "SHOW DATABASES;" | grep -Ev '^(information_schema|performance_schema|mysql|sys)$')
[[ -n "$databases" ]] || fail "Aucune base à sauvegarder"
for db in $databases; do
log "Sauvegarde de $db"
tmp_file="$BACKUP_DIR/${HOSTNAME}_${db}_${DATE}.sql.gz.tmp"
out_file="$BACKUP_DIR/${HOSTNAME}_${db}_${DATE}.sql.gz"
sudo mariadb-dump --single-transaction --routines --events --triggers --hex-blob --databases "$db" \
| gzip -9 > "$tmp_file"
mv "$tmp_file" "$out_file"
log "OK: $out_file"
done
find "$BACKUP_DIR" -type f -name '*.sql.gz' -mtime +"$RETENTION_DAYS" -delete
log "Rotation terminée"
log "Sauvegarde terminée"
# Message ntfy
curl \
-H "X-Email: ntfy@cinay.eu" \
-H "Title: ⛁ CWWK - Sauvegarde Bases MariaDB" \
-H "Authorization: Bearer tk_xxxxxxxxxxxxxxxxxxxxxxxx5x" \
-H prio:low \
-d "CWWK Debian 13
`hostname -I`
✔️ Fin Sauvegarde Bases MariaDB `date +%d/%m/%Y-%Hh%M`" \
https://ntfy.rnmkcy.eu/yan_infos
|
mariadb-dump est l’outil adapté pour créer des dumps logiques, et la restauration se fait ensuite avec le client mariadb. mariadb
Script de restauration
Créez /usr/local/sbin/mariadb-restore-fzf.sh :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
| #!/usr/bin/env bash
set -euo pipefail
LOG_FILE="/var/log/mariadb-restore.log"
LOCK_FILE="/run/mariadb-restore.lock"
BACKUP_BEFORE_RESTORE="/var/backups/mariadb/pre-restore"
FILE=""
DRY_RUN=false
RESTORE_ALL=false
RED=$'\033[0;31m'
GREEN=$'\033[0;32m'
YELLOW=$'\033[1;33m'
BLUE=$'\033[0;34m'
RESET=$'\033[0m'
log() { printf '%s[%s] %s%s\n' "$BLUE" "$(date '+%F %T')" "$1" "$RESET" | tee -a "$LOG_FILE"; }
ok() { printf '%s[%s] %s%s\n' "$GREEN" "$(date '+%F %T')" "$1" "$RESET" | tee -a "$LOG_FILE"; }
warn() { printf '%s[%s] %s%s\n' "$YELLOW" "$(date '+%F %T')" "$1" "$RESET" | tee -a "$LOG_FILE"; }
fail() { printf '%s[%s] %s%s\n' "$RED" "$(date '+%F %T')" "$1" "$RESET" | tee -a "$LOG_FILE" >&2; exit 1; }
usage() {
cat <<EOF
Usage:
$0 /chemin/vers/dump.sql.gz [--dry-run] [--all]
EOF
}
extract_sql() {
if [[ "$FILE" == *.gz ]]; then
gunzip -c "$FILE"
else
cat "$FILE"
fi
}
list_databases() {
extract_sql | awk '
/^(CREATE DATABASE|USE) / {
gsub(/`/, "", $0)
if ($1 == "USE") print $2
else if ($1 == "CREATE" && $2 == "DATABASE") print $4
}
' | sed 's/;$//' | sort -u
}
list_tables_for_db() {
local db="$1"
extract_sql | awk -v target="$db" '
BEGIN {p=0}
/^CREATE DATABASE / {p=($0 ~ target)}
/^USE / {p=($0 ~ target)}
p==1 && /^CREATE TABLE / {
gsub(/`/, "", $0)
print $3
}
' | sed 's/;$//' | sort -u
}
verify_env() {
[[ -n "$FILE" ]] || fail "Fichier manquant"
[[ -f "$FILE" ]] || fail "Fichier introuvable: $FILE"
command -v mariadb >/dev/null 2>&1 || fail "mariadb introuvable"
command -v mariadb-dump >/dev/null 2>&1 || fail "mariadb-dump introuvable"
command -v gunzip >/dev/null 2>&1 || fail "gunzip introuvable"
command -v fzf >/dev/null 2>&1 || warn "fzf absent: sélection interactive désactivée"
if [[ "$FILE" == *.gz ]]; then
gunzip -t "$FILE" || fail "Archive gzip invalide"
fi
sudo mariadb -e "SELECT 1;" >/dev/null 2>&1 || fail "Connexion MariaDB impossible sans mot de passe"
extract_sql | head -n 30 | grep -qiE 'CREATE|INSERT|USE|DROP|LOCK TABLES' || fail "Aucun SQL détecté"
ok "Vérifications OK"
}
backup_current_db() {
local db="$1"
mkdir -p "$BACKUP_BEFORE_RESTORE"
local out="$BACKUP_BEFORE_RESTORE/${db}_$(date +%F_%H-%M-%S).sql.gz"
warn "Sauvegarde de sécurité: $db -> $out"
sudo mariadb-dump --single-transaction --routines --events --triggers --hex-blob --databases "$db" | gzip -9 > "$out"
ok "Sauvegarde créée: $out"
}
restore_db() {
local db="$1"
log "Restauration de $db"
if [[ "$DRY_RUN" == true ]]; then
warn "[DRY-RUN] $db serait restaurée"
warn "[DRY-RUN] Tables détectées:"
list_tables_for_db "$db" | sed 's/^/ - /'
return 0
fi
backup_current_db "$db"
if [[ "$FILE" == *.gz ]]; then
gunzip -c "$FILE" | awk -v target="$db" '
BEGIN {p=0}
/^-- Current Database: / {p=0}
/^CREATE DATABASE / {if ($0 ~ target) p=1}
/^USE / {if ($0 ~ target) p=1}
{if (p==1) print}
' | sudo mariadb "$db"
else
awk -v target="$db" '
BEGIN {p=0}
/^-- Current Database: / {p=0}
/^CREATE DATABASE / {if ($0 ~ target) p=1}
/^USE / {if ($0 ~ target) p=1}
{if (p==1) print}
' "$FILE" | sudo mariadb "$db"
fi
ok "Restauration terminée: $db"
}
mkdir -p "$(dirname "$LOG_FILE")"
touch "$LOG_FILE"
exec 9>"$LOCK_FILE"
flock -n 9 || fail "Une autre restauration est déjà en cours"
[[ $# -ge 1 ]] || { usage; exit 1; }
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run) DRY_RUN=true; shift ;;
--all) RESTORE_ALL=true; shift ;;
-h|--help) usage; exit 0 ;;
*)
if [[ -z "$FILE" ]]; then
FILE="$1"
shift
else
fail "Argument inattendu: $1"
fi
;;
esac
done
verify_env
mapfile -t DBS < <(list_databases)
[[ "${#DBS[@]}" -gt 0 ]] || fail "Aucune base détectée"
printf '\n%sBases détectées:%s\n' "$BLUE" "$RESET"
printf ' - %s\n' "${DBS[@]}"
SELECTED=()
if [[ "$RESTORE_ALL" == true ]]; then
SELECTED=("${DBS[@]}")
else
if command -v fzf >/dev/null 2>&1; then
warn "Sélectionnez les bases avec Tab puis Entrée"
CHOICES="$(printf '%s\n' "${DBS[@]}" | fzf -m --prompt='Bases > ')"
[[ -n "$CHOICES" ]] || fail "Aucune base sélectionnée"
mapfile -t SELECTED <<< "$CHOICES"
else
warn "fzf indisponible, saisie manuelle requise"
read -r -p "Entrez les bases séparées par des espaces: " -a SELECTED
fi
fi
printf '\n%sBases retenues:%s\n' "$BLUE" "$RESET"
printf ' - %s\n' "${SELECTED[@]}"
if [[ "$DRY_RUN" == true ]]; then
warn "Mode dry-run activé"
for db in "${SELECTED[@]}"; do
warn "[DRY-RUN] $db"
list_tables_for_db "$db" | sed 's/^/ table: /'
done
exit 0
fi
read -r -p "Confirmez la restauration ? (o/n): " confirm
[[ "$confirm" == "o" || "$confirm" == "O" ]] || fail "Restauration annulée"
for db in "${SELECTED[@]}"; do
restore_db "$db"
done
ok "Toutes les restaurations sont terminées"
|
fzf reste pratique pour la sélection multiple et le mode --dry-run permet de valider avant import. thevaluable
Systemd service mariadb-backup
/etc/systemd/system/mariadb-backup.service
1
2
3
4
5
6
7
8
9
10
11
12
13
| [Unit]
Description=MariaDB backup
After=network.target mariadb.service
Requires=mariadb.service
[Service]
Type=oneshot
User=root
Group=root
ExecStart=/usr/local/sbin/mariadb-backup.sh
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
|
Systemd timer mariadb-backup
/etc/systemd/system/mariadb-backup.timer
1
2
3
4
5
6
7
8
9
10
| [Unit]
Description=Daily MariaDB backup timer
[Timer]
OnCalendar=*-*-* 01:00:00
Persistent=true
Unit=mariadb-backup.service
[Install]
WantedBy=timers.target
|
oneshot avec OnCalendar est la combinaison appropriée pour une sauvegarde planifiée par systemd. dailystuff
README d’installation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Pack sauvegarde / restauration MariaDB
Ce pack permet :
- des sauvegardes automatiques via systemd timer,
- une restauration interactive avec `fzf`,
- un mode `--dry-run`,
- une sauvegarde de sécurité avant restauration.
## Prérequis
- MariaDB installé.
- `mariadb`, `mariadb-dump`, `gzip`.
- `fzf` pour la sélection interactive.
## Hypothèse
Le compte système `root` peut utiliser `mariadb` sans mot de passe via socket local.
Test :
```bash
sudo mariadb -e "SELECT 1;"
|
Installation Pack
1. Copier les scripts
1
2
| sudo install -m 750 mariadb-backup.sh /usr/local/sbin/mariadb-backup.sh
sudo install -m 750 mariadb-restore-fzf.sh /usr/local/sbin/mariadb-restore-fzf.sh
|
2. Créer les dossiers
1
2
3
| sudo mkdir -p /var/backups/mariadb/pre-restore
sudo mkdir -p /var/backups/mariadb
sudo touch /var/log/mariadb-backup.log /var/log/mariadb-restore.log
|
3. Installer systemd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| sudo tee /etc/systemd/system/mariadb-backup.service >/dev/null <<'EOF'
[Unit]
Description=MariaDB backup
After=network.target mariadb.service
Requires=mariadb.service
[Service]
Type=oneshot
User=root
Group=root
ExecStart=/usr/local/sbin/mariadb-backup.sh
Nice=19
IOSchedulingClass=best-effort
IOSchedulingPriority=7
EOF
|
1
2
3
4
5
6
7
8
9
10
11
12
| sudo tee /etc/systemd/system/mariadb-backup.timer >/dev/null <<'EOF'
[Unit]
Description=Daily MariaDB backup timer
[Timer]
OnCalendar=*-*-* 01:00:00
Persistent=true
Unit=mariadb-backup.service
[Install]
WantedBy=timers.target
EOF
|
4. Activer le timer
1
2
| sudo systemctl daemon-reload
sudo systemctl enable --now mariadb-backup.timer
|
5. Vérification
1
2
| systemctl list-timers --all | grep mariadb-backup
journalctl -u mariadb-backup.service -n 100 --no-pager
|
6. Sauvegarde manuelle
1
| sudo /usr/local/sbin/mariadb-backup.sh
|
Sortie
1
2
3
4
5
6
7
8
| [2026-06-10 22:24:55] Sauvegarde de authelia
[2026-06-10 22:24:55] OK: /var/backups/mariadb/alder_authelia_2026-06-10_22-24-55.sql.gz
[2026-06-10 22:24:55] Sauvegarde de git
[2026-06-10 22:24:55] OK: /var/backups/mariadb/alder_git_2026-06-10_22-24-55.sql.gz
[2026-06-10 22:24:55] Sauvegarde de nextcloud
[2026-06-10 22:24:56] OK: /var/backups/mariadb/alder_nextcloud_2026-06-10_22-24-55.sql.gz
[2026-06-10 22:24:56] Rotation terminée
[2026-06-10 22:24:56] Sauvegarde terminée
|
Restauration
Dry-run :
1
| sudo /usr/local/sbin/mariadb-restore-fzf.sh /var/backups/mariadb/full.sql.gz --dry-run
|
Sélection interactive :
1
| sudo /usr/local/sbin/mariadb-restore-fzf.sh /var/backups/mariadb/full.sql.gz
|
Tout restaurer :
1
| sudo /usr/local/sbin/mariadb-restore-fzf.sh /var/backups/mariadb/full.sql.gz --all
|
Rotation
Les sauvegardes de plus de 14 jours sont supprimées automatiquement.
Sécurité
Chaque restauration crée une sauvegarde de sécurité dans :
1
| /var/backups/mariadb/pre-restore/
|