Les metriques et les journaux repartaient de zero a chaque reconstruction. setops-copie-a-froid arrete le service le temps de copier et le relance quoi qu il arrive ; les roles remettent la copie avant de demarrer ; les temoins jugent la couverture, pas les fichiers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.3 KiB
Bash
62 lines
2.3 KiB
Bash
#!/bin/bash
|
|
# Géré par Set-OPS (rôle client_backup). Ne pas éditer à la main.
|
|
#
|
|
# setops-copie-a-froid SERVICE SOURCE DESTINATION [--blocs-immuables]
|
|
#
|
|
# Copie COHERENTE d'une base qui ecrit en continu (Prometheus, Loki) : le service est
|
|
# arrete le temps de la copie, puis redemarre — QUOI QU'IL ARRIVE a la copie, et seulement
|
|
# s'il tournait avant. La destination n'est remplacee qu'une fois la copie complete.
|
|
#
|
|
# POURQUOI A FROID (decision de l'exploitant, 2026-10-07 : « on ne prend pas de risque »).
|
|
# Copier a chaud un WAL qu'on ecrit, c'est sauvegarder un fichier a moitie ecrit. L'autre
|
|
# voie — ne garder que les blocs fermes — perdait jusqu'aux deux dernieres heures de
|
|
# metriques a chaque reconstruction. Mesure au site : 2,9 Go de Prometheus se lisent en
|
|
# 4,2 s, son WAL seul en 0,3 s ; Loki entier en 2 s.
|
|
#
|
|
# `--blocs-immuables` : les sous-dossiers nommes par un ULID (26 caracteres, `01…`) sont
|
|
# les blocs de Prometheus, que rien ne reecrit apres leur fermeture. On les recopie par
|
|
# LIENS DURS — instantane, sans place — et le reste (WAL, `chunks_head`) par une vraie
|
|
# copie. Si la destination est sur un autre systeme de fichiers, on copie tout.
|
|
set -euo pipefail
|
|
|
|
service="${1:?service}"
|
|
source="${2:?source}"
|
|
dest="${3:?destination}"
|
|
blocs="${4:-}"
|
|
|
|
[[ -d "${source}" ]] || { echo "copie a froid : ${source} n'existe pas — rien a copier." >&2; exit 0; }
|
|
|
|
tmp="${dest}.en-cours"
|
|
rm -rf "${tmp}"
|
|
mkdir -p "$(dirname "${dest}")"
|
|
|
|
actif=0
|
|
if systemctl is-active --quiet "${service}"; then actif=1; fi
|
|
relancer() { if (( actif )); then systemctl start "${service}"; fi; }
|
|
|
|
debut=$(date +%s%N)
|
|
if (( actif )); then systemctl stop "${service}"; fi
|
|
trap relancer EXIT
|
|
|
|
if [[ "${blocs}" == "--blocs-immuables" ]]; then
|
|
mkdir -p "${tmp}"
|
|
for e in "${source}"/* "${source}"/.[!.]*; do
|
|
[[ -e "${e}" ]] || continue
|
|
n="$(basename "${e}")"
|
|
if [[ -d "${e}" && ${#n} -eq 26 && "${n}" == 01* ]]; then
|
|
cp -al "${e}" "${tmp}/${n}" 2>/dev/null || cp -a "${e}" "${tmp}/${n}"
|
|
else
|
|
cp -a "${e}" "${tmp}/${n}"
|
|
fi
|
|
done
|
|
else
|
|
cp -a "${source}" "${tmp}"
|
|
fi
|
|
|
|
trap - EXIT
|
|
relancer
|
|
fin=$(date +%s%N)
|
|
|
|
rm -rf "${dest}"
|
|
mv "${tmp}" "${dest}"
|
|
echo "copie a froid de ${source} : ${service} $( (( actif )) && echo "arrete (jusqu a la relance, rejeu du WAL non compris) $(( (fin - debut) / 1000000 )) ms" || echo "n'etait pas actif")"
|