Ευρετήριο ημερολογίουDockup / σημείωση πεδίου
Note / database-backups-you-have-restored

Ένα backup που δεν έχετε κάνει ποτέ restore δεν είναι backup

Τα database backups που δεν έχουν δοκιμαστεί αποτυγχάνουν με προβλέψιμους τρόπους: άδεια dumps, ρόλοι που λείπουν, λάθος flags, ανύπαρκτο encryption key. Μάθετε πώς να επαληθεύετε ένα restore, ώστε το αρχείο που κρατάτε να είναι ένα αρχείο που λειτουργεί.

Η χειρότερη στιγμή για να ανακαλύψετε ότι ένα backup δεν λειτουργεί είναι η στιγμή που το χρειάζεστε. Κι όμως, αυτό ακριβώς είναι το συνηθέστερο μοτίβο: backups που ρυθμίστηκαν μία φορά, ένα πράσινο tick σε ένα dashboard για δεκαοκτώ μήνες και, στη συνέχεια, ένα restore που δημιουργεί μια άδεια βάση δεδομένων.

Το testing ενός database backup restore δεν είναι best practice με την έννοια ότι οι περισσότερες best practices είναι προαιρετικές. Ένα backup είναι ένας ισχυρισμός και, μέχρι να κάνετε restore έστω και ενός, παραμένει ένας ισχυρισμός που δεν έχει δοκιμαστεί.

Δείτε πώς αποτυγχάνουν και τι πρέπει πραγματικά να ελέγχει μια επαλήθευση.

Οι τέσσερις τρόποι με τους οποίους ένα backup γίνεται αθόρυβα άχρηστο

1. Είναι άδειο και κανείς δεν το έλεγξε

Ένα pg_dump που αποτυγχάνει στη μέση μπορεί και πάλι να δημιουργήσει ένα αρχείο. Ένα dump που εκτελείται στη λάθος database name παράγει ένα έγκυρο, σωστό, άδειο αρχείο. Και τα δύο μοιάζουν επιτυχημένα σε οτιδήποτε ελέγχει αν το exit είναι non-zero ή αν υπάρχει ένα αρχείο.

Ο πιο φθηνός έλεγχος στον κόσμο: δείτε το μέγεθος και συγκρίνετέ το με το χθεσινό. Ένα backup των 400 bytes, όταν το χθεσινό ήταν 40 MB, σας έχει πει τα πάντα. Ένα backup που είναι 400 bytes εδώ και έξι μήνες σάς το λέει όλο αυτό το διάστημα.

2. Περιέχει δεδομένα, αλλά όχι ό,τι τα περιβάλλει

Το pg_dump μίας database δεν περιλαμβάνει roles και δεν περιλαμβάνει άλλες databases. Κάντε restore σε έναν καινούργιο server και οι πίνακες θα εμφανιστούν, ενώ κάθε GRANT θα αναφέρεται σε έναν ρόλο που δεν υπάρχει. Η εφαρμογή σας θα συνδεθεί και θα λαμβάνει permission denied για τα πάντα.

Το ίδιο ισχύει και για τα extensions. Αν το schema σας εξαρτάται από τα pgcrypto ή uuid-ossp και το target δεν τα διαθέτει, το restore αποτυγχάνει στη μέση, αφήνοντάς σας με κάποιους μόνο πίνακες.

3. Τα flags ήταν λάθος για το restore που χρειάζεστε

Το pg_dump παράγει διαφορετικό αποτέλεσμα ανάλογα με το format και το λάθος συνήθως ανακαλύπτεται υπό πίεση:

  • Plain SQL γίνεται restore με psql και είναι ευανάγνωστο. Δεν μπορεί να γίνει selective restore και είναι αργό για μεγάλες databases.
  • Custom format (-Fc) γίνεται restore με pg_restore, υποστηρίζει parallelism και selective restore και είναι αυτό που θέλετε για οτιδήποτε μεγάλου μεγέθους.

Το να παίρνετε backup σε plain format επειδή έτσι έκανε το tutorial και να ανακαλύπτετε, στη διάρκεια ενός incident, ότι δεν μπορείτε να κάνετε restore σε έναν μόνο πίνακα είναι ένας συγκεκριμένος και απολύτως αποφύγιμος τρόπος να έχετε μια κακή μέρα.

4. Δεν μπορείτε να το κάνετε decrypt

Αν τα backups είναι encrypted — και θα έπρεπε να είναι — τότε το key αποτελεί μέρος του backup. Ένα key που βρίσκεται μόνο στο μηχάνημα που χάθηκε ή μόνο σε ένα environment variable της υπηρεσίας που είναι εκτός λειτουργίας είναι ένα key που δεν έχετε όταν το χρειάζεστε.

Πώς μοιάζει μια πραγματική επαλήθευση

Το test δεν είναι «υπάρχει το αρχείο;». Είναι να κάνετε restore κάπου αλλού και να του υποβάλετε μια ερώτηση.

# 1. Restore into a scratch database, not the live one
createdb verify_$(date +%Y%m%d)
pg_restore -d verify_$(date +%Y%m%d) --no-owner --no-privileges latest.dump

# 2. Ask it something only real data can answer
psql -d verify_$(date +%Y%m%d) -c "
  select
    (select count(*) from users)            as users,
    (select count(*) from orders)           as orders,
    (select max(created_at) from orders)    as newest_order;
"

# 3. Drop it
dropdb verify_$(date +%Y%m%d)

Το Step 2 είναι όλη η ουσία. Ένα restore που ολοκληρώνεται χωρίς error εξακολουθεί να μη σας λέει τίποτα για το αν υπάρχουν πραγματικά τα δεδομένα. Αυτό το κάνουν τα row counts και ένας έλεγχος recency.

Τρία πράγματα που αξίζει να κάνετε assert:

  • Τα row counts είναι της σωστής τάξης μεγέθους. Όχι ακριβή — τα δεδομένα αλλάζουν — αλλά ένας πίνακας που είχε 200.000 rows και τώρα έχει 12 αποτελεί αποτυχία.
  • Η πιο πρόσφατη εγγραφή είναι πρόσφατη. Αν η πιο πρόσφατη παραγγελία στο «nightly» backup σας είναι από τον Μάρτιο, το backup job σταμάτησε τον Μάρτιο.
  • Η εφαρμογή μπορεί πράγματι να συνδεθεί. Δείξτε σε ένα staging instance τη restored database και φορτώστε μία σελίδα.

Κάντε το βάσει προγράμματος, όχι όταν βρείτε χρόνο

Ο ρεαλιστικός ρυθμός είναι μηνιαίος, αυτοματοποιημένος, με το αποτέλεσμα να καταγράφεται κάπου που θα το προσέξετε. Μια υπενθύμιση στο ημερολόγιο για «test backups» είναι μια υπενθύμιση που θα αναβάλετε.

Αυτό που κάνει τη διαδικασία να τηρείται είναι να κάνετε την αποτυχία εμφανή: αν το verification query επιστρέψει λιγότερα rows από ένα threshold, θα πρέπει να ειδοποιηθεί κάποιος με τον ίδιο τρόπο που θα ειδοποιούνταν για ένα production error. Ένα backup system που αποτυγχάνει αθόρυβα δεν διαφέρει από την απουσία backup system, μέχρι ακριβώς τη στιγμή που θα το χρειαστείτε.

Πώς το χειρίζεται αυτό το Dockup

Τρεις αποφάσεις, καθεμία στοχευμένη σε μία συγκεκριμένη από τις παραπάνω αποτυχίες.

Τα backups πηγαίνουν αλλού. Ένα backup στον ίδιο δίσκο με τη database δεν είναι backup — είναι ένα αντίγραφο που πεθαίνει μαζί με τον δίσκο. Το Dockup μεταδίδει τα database backups απευθείας σε object storage καθώς δημιουργούνται, ώστε το αρχείο να μην εξαρτάται ποτέ από το host που το δημιούργησε.

Είναι encrypted και το key δεν βρίσκεται στο box. Τα backups κρυπτογραφούνται με AES-256-GCM καθώς μεταδίδονται. Το σημαντικό για το recovery είναι ότι το key το διαχειρίζεται η πλατφόρμα και δεν βρίσκεται στο environment της υπηρεσίας που γίνεται backup.

Ένα backup που δεν παρήγαγε τίποτα δεν καταγράφεται ως backup. Αυτό αντιμετωπίζει άμεσα την αποτυχία του άδειου αρχείου: αν το dump τερματίσει με non-zero ή παράγει zero bytes, το upload διαγράφεται και το backup καταγράφεται ως failed. Δεν καταλήγετε με μια λίστα από πράσινες εγγραφές, όπου μία από αυτές είναι ένα αρχείο 400 bytes.

dockup db backup my-project/main-db --json     # take one now
dockup db backups my-project/main-db --json    # list them with sizes

Τα μεγέθη σε αυτήν τη λίστα είναι ο πιο φθηνός health check που διαθέτετε. Παρακολουθήστε την τάση τους.

Η άβολη ερώτηση

Αν η production database σας καταστρεφόταν μέσα στα επόμενα δέκα λεπτά, πόσο χρόνο θα χρειαζόσασταν για να την επαναφέρετε και πόσα δεδομένα θα είχατε χάσει;

Αν δεν μπορείτε να απαντήσετε και στους δύο αριθμούς, δεν έχετε στρατηγική backup — έχετε αρχεία backup. Η διαφορά εξαρτάται αποκλειστικά από το αν κάποιος έχει κάνει ποτέ το restore.

Συχνές ερωτήσεις

Πόσο συχνά πρέπει να δοκιμάζω ένα restore; Μηνιαία είναι μια λογική προεπιλογή, αυτοματοποιημένη και όχι χειροκίνητη. Το σημαντικό είναι η αποτυχία να γίνεται αντιληπτή, όχι ο ρυθμός να είναι ιδιαίτερα συχνός.

Γιατί ολοκληρώθηκε το restore μου αλλά δεν παρήγαγε δεδομένα; Συνήθως το dump λήφθηκε από τη λάθος database ή απέτυχε στη μέση ενώ εξακολουθούσε να γράφει ένα αρχείο. Συγκρίνετε τα μεγέθη των backups με την πάροδο του χρόνου — ένα άδειο dump είναι προφανές σε μια τάση μεγέθους και αόρατο σε μια στήλη status.

Πρέπει τα backups να είναι encrypted; Ναι, και το key πρέπει να βρίσκεται κάπου που επιβιώνει από την απώλεια του μηχανήματος. Ένα encrypted backup του οποίου το key βρισκόταν στον server που χάθηκε δεν μπορεί να ανακτηθεί.

Είναι ένα snapshot το ίδιο με ένα backup; Όχι. Ένα volume snapshot αποτυπώνει τον δίσκο, συμπεριλαμβανομένης της κατάστασης στην οποία βρισκόταν η database εκείνη τη στιγμή. Ένα logical dump είναι συνεπές εκ κατασκευής. Οι περισσότερες ομάδες θέλουν και τα δύο, για διαφορετικές αποτυχίες.