Stratégie de backup & restore de base postgresql Synapse
Problématique
Comment backuper et restaurer une base postegresql Synapse sur une Freebox avec un watchdog embêtant... Sachant qu'un backup plain SQL n'est pas exploitable sur la VM Freebox parce qu'on ne peut pas importer les tables et les index séparément et donc que ça fait crasher lors de la restauration par le watchdog matériel de la Freebox qui fait rebooter la box.
Créer un backup custom
/etc/systemd/system/synapse-backup.service :
[Unit]
Description=Synapse database backup
After=postgresql.service
[Service]
Type=oneshot
User=postgres
ExecStart=/bin/bash -c '\
echo "Warm-up cache..." && \
psql -d synapse -c "SELECT COUNT() FROM events;" > /dev/null 2>&1 && \
psql -d synapse -c "SELECT COUNT() FROM event_json;" > /dev/null 2>&1 && \
psql -d synapse -c "SELECT COUNT() FROM state_groups_state;" > /dev/null 2>&1 && \
sleep 30 && \
echo "Démarrage backup..." && \
TMPFILE=$(mktemp /home/synapse/backups/synapse_tmp_XXXXXX.dump) && \
pg_dump -Fc --exclude-table-data e2e_one_time_keysjson synapse > $TMPFILE && \
mv $TMPFILE /home/synapse/backups/synapse$(date +%%Y%%m%%d%%H%%M).dump && \
echo "Backup complet."'
ExecStartPost=/bin/bash -c 'find /home/synapse/backups -name "synapse.dump" -mtime +7 -delete && find /home/synapse/backups -name "synapsetmp*.dump" -delete'
[Install]
WantedBy=multi-user.target
/etc/systemd/system/synapse-backup.timer :
[Unit]
Description=Synapse database backup - toutes les nuits à 3h
Requires=synapse-backup.service
[Timer]
OnCalendar=--* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Stratégie de restauration de base pour éviter le watchdog de la Freebox
# 1. Arrêter Synapse
systemctl stop synapse
# 2. Recréer la base avec la bonne collation
sudo -u postgres psql -c "DROP DATABASE IF EXISTS synapse;"
sudo -u postgres psql -c "CREATE DATABASE synapse OWNER synapse_user ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' TEMPLATE template0;"
# 3. Importer le schéma
pg_restore -h localhost -U synapse_user -d synapse \
--no-privileges --no-owner --section=pre-data synapse_XXXXXXXX.dump
# 4. Importer les données table par table (évite le watchdog Freebox)
pg_restore --list synapse_XXXXXXXX.dump | grep "TABLE DATA" > /tmp/tables_list.txt
while IFS= read -r line; do
pg_restore -h localhost -U synapse_user -d synapse \
--no-privileges --no-owner -L <(echo "$line") synapse_XXXXXXXX.dump
sleep 20
done < /tmp/tables_list.txt
# 5. Truncate obligatoire
psql -h localhost -U synapse_user -d synapse -c "TRUNCATE e2e_one_time_keys_json;"
# 6. Index un par un (sauf device_inbox_stream_id_user_id)
pg_restore --list synapse_XXXXXXXX.dump | \
grep -E "^[0-9]+;.*INDEX|^[0-9]+;.*CONSTRAINT|^[0-9]+;.*FK " | \
grep -v "device_inbox_stream_id_user_id" > /tmp/indexes_only.txt
while IFS= read -r line; do
pg_restore -h localhost -U synapse_user -d synapse \
--no-privileges --no-owner -L <(echo "$line") synapse_XXXXXXXX.dump
sleep 30
done < /tmp/indexes_only.txt
# 7. Index problématique manuellement
psql -h localhost -U synapse_user -d synapse -c "
CREATE INDEX IF NOT EXISTS device_inbox_stream_id_user_id ON device_inbox(stream_id, user_id);"
# 8. Démarrer Synapse
systemctl start synapse