Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Analyse des backups Postgres de production

scripts/backups-analysis.livemd

Analyse des backups Postgres de production

Mix.install([
  {:kino, "~> 0.16.0"},
  {:kino_vega_lite, "~> 0.1.11"}
])

Pré-requis : installation du client S3 MinIO (mc)

Ce livebook s’appuie sur MinIO Client (mc).

Sur Mac, l’installation se fait avec brew install minio/stable/mc (pour les autres plateformes voir le README).

Sous ~/.mc/config.json, intégrer la configuration suivante (et la modifier avec les credentials de l’addon Backups sur Clever Cloud) :

{
    "version": "10",
    "aliases": {
        "transport-backups": {
            "url": "https://cellar-c2.services.clever-cloud.com",
            "accessKey": "REDACTED",
            "secretKey": "REDACTED",
            "api": "S3v4",
            "path": "dns"
        }
    }
}

Puis faire le test suivant: mc ls transport-backups pour vérifier la connectivité.

Lister les backups de production avec la commande suivante:

❯ mc ls transport-backups/ccbackups-postgresql-4a305f24-8a31-4815-b2bb-23f4711303ee
[2024-12-21 02:40:53 CET] 2.0GiB STANDARD postgresql_4a305f24-8a31-4815-b2bb-23f4711303ee-20241221013239.dump
[2024-12-22 03:20:02 CET] 2.0GiB STANDARD postgresql_4a305f24-8a31-4815-b2bb-23f4711303ee-20241222021306.dump
# SNIP

Analyse des backups de production

Pour une analyse automatisée, on peut passer le flag --json à mc, qui retourne alors un output structuré.

minio_config = "transport-backups"
bucket = "ccbackups-postgresql-4a305f24-8a31-4815-b2bb-23f4711303ee"

{output, 0} = System.cmd("mc", ["ls","--json","#{minio_config}/#{bucket}"])

entries = output
  |> String.trim()
  |> String.split("\n") 
  |> Enum.map(&JSON.decode!/1)

:ok

Pour illustrer le problème des backups qui échouent, je compte le nombre de backups par jour.

Je soustrais 1 pour calculer un “estimatif” du nombre d’incidents de backups par jour:

estimated_backup_incidents = entries
  |> Enum.map(fn(x) -> x["lastModified"] |> String.slice(0..9) end)
  |> Enum.frequencies()
  |> Enum.sort(:desc)
  |> Enum.map(fn({date, count}) -> %{date: date, count: count - 1} end)

:ok

Puis je fais un rendu graphique :

VegaLite.new(width: 800, height: 400, title: "Incidents (estimatifs) au moment du backup")
|> VegaLite.data_from_values(estimated_backup_incidents, only: ["date", "count"])
|> VegaLite.mark(:bar)
|> VegaLite.encode_field(:x, "date", type: :temporal)
|> VegaLite.encode_field(:y, "count", type: :quantitative)

Conclusion

Le nombre d’incidents de backups est important et croissant depuis mai.

Il va falloir demander à notre hébergeur ce qui se passe et voir comment traiter ça.

Travailler sur la taille de la base de données serait aussi une bonne idée.