#!/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")"