Comprendre la BDD Etherpad
Se connecter à la base de données
Sur `pica01-test`
docker exec -it etherpad-db bash mysql -u etherpad etherpad-lite -sN --default-character-set=utf8 -p
Le mot de passe est normalement password2
, il est défini ici (MYSQL_PASSWORD)
Sur la prod
À ne faire que si c’est absolument nécessaire
pad.picasoft.net (`pica02`)
Mêmes étapes que précédemment, mais le mot de passe est dans /DATA/docker/services/etherpad/secrets
week.pad.picasoft.net (`pica01`)
docker exec -it weekpad-db bash psql -U weekpad -d weekpad
Sur ce conteneur, vous êtes connecté direct en tant que root, donc psql
vous demandera pas de mot de passe
Structure de la BDD
La structure est hyper simple. Dans la BDD etherpad-lite
, il y a juste une table store
avec 2 colonnes: key
et value
.
mysql> show databases; +--------------------+ | Database | +--------------------+ | etherpad-lite | | information_schema | +--------------------+ 2 rows in set (0.01 sec) mysql> show tables; +-------------------------+ | Tables_in_etherpad-lite | +-------------------------+ | store | +-------------------------+ 1 row in set (0.00 sec) mysql> describe store; +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | key | varchar(100) | NO | PRI | NULL | | | value | longtext | NO | | NULL | | +-------+--------------+------+-----+---------+-------+ 2 rows in set (0.07 sec)
Structure des clés
Les clés concernant les pads commencent par pad:
. Vous pouvez avoir un aperçu avec
- snippet.sql
SELECT s.key FROM store s WHERE s.key LIKE "pad:%" LIMIT 20;
Le %
désigne n’importe quelle suite de caractères. N’utilisez pas plusieurs %
dans une même requête ! Cela serait à l’origine d’un nombre astronomique de possibilités, vu la taille de la BDD Etherpad, et donc un temps de calcul astronomique lui aussi.
Pour un pad nommé monpad
, il y a normalement:
- une clé
pad:monpad
- une ou plusieurs clés
pad:monpad:revs:i
oùi
est compris entre 0 et le nombre de révisions
pad:monpad
contient la dernière version
Si le pad vient d’être crée, il y a juste pad:monpad
et pad:monpad:revs:0
Comprendre le format des révisions
J’ai crée un nouveau pad sur l’instance de test, nommé newpad
, puis j’ai ajouté le texte de test
(Ctrl-V) juste après Bienvenue sur Picapad
. Ceci a généré la révision suivante (et mis à jour pad:newpad
)
mysql> select s.value from store s where s.key="pad:newpad:revs:1"; value {"changeset":"Z:18h>8=l*0+8$ de test","meta":{"author":"a.jkPhNoJhljvlAjjq","timestamp":1585588719641}}
Mais qu’est ce signifie Z:18h>8=l*0+8$ de test
?
Documentation officielle: Changeset Library
Pour comprendre que contient cette mystérieuse chaine de caractères, on va sur pad.test.picasoft.net et on ouvre une console web.
La chaine Z:18h>8=l*0+8$ de test
signifie donc quelque chose comme
Pour passer de la révision 0 à la révision 1, on agrandit le document de 1601 à 1609 caractères. On se place au début. On parcours 21 caractères qui restent inchangés. Puis on ajoute les 8 caractères suivants: " de test"
Quelques tests pour simuler une BDD corrompue
Ces tests pourraient aider à comprendre pourquoi des pads en production ne fonctionnent pas
Test 1: révision manquante
Sur l’instance de test, on crée un pad nommé newpad2
, puis on fait quelques modifications. Depuis la console mysql, on devrait avoir quelque chose comme:
- snippet.sql
mysql> SELECT s.key FROM store s WHERE s.key LIKE "pad:newpad2%" LIMIT 15; pad2readonly:newpad2 pad:newpad2 pad:newpad2:revs:0 pad:newpad2:revs:1 pad:newpad2:revs:2
On vérifie que tout fonctionne bien, puis on efface la révision 1:
- snippet.sql
DELETE FROM store s WHERE s.key="pad:newpad2:revs:1";
On retourne sur le pad. Résultat: tout fonctionne toujours bien. On éteint puis on lance à nouveau etherpad_app
. Résultat: le pad s’affiche toujours correctement, mais l’historique ne fonctionne plus
Test 2: JSON corrompu
Sur l’instance de test, on crée un pad nommé newpad3
, puis on fait quelques modifications. On affiche le contenu de pad:newpad3
:
- snippet.sql
mysql> SELECT s.value FROM store s WHERE s.key="pad:newpad3"; {"atext":{"text":"Bienvenue sur Picapad de test, ... "savedRevisions":[]}
On va mettre à jour la valeur de cette clé avec du JSON invalide. Pour cela, on copie-colle le retour de la commande précédente sur un éditeur de texte, on remplace les '
par \'
puis on efface la première {
.
On met à jour le champ:
- snippet.sql
mysql> UPDATE store SET VALUE='<nouvelle_valeur>' WHERE store.key='pad:newpad3';
On redémarre etherpad-app
. Résultat: le pad semble prendre du temps à charger, mais après quelques minutes, on tombe sur un Bad Gateway
.
Si on regarde les logs récents (docker logs --since="5m" etherpad-app
), on retrouve une erreur du type
[2020-03-30 23:11:31.773] [ERROR] console - JSON-PROBLEM:
Faire un dump manuel de la BDD
Le script nécessaire est préparé par le conteneur db-backup
(plus d'infos). Il suffit de l’exécuter:
- snippet.bash
amaldona@pica02:/DATA/BACKUP/etherpad$ docker exec -it db-backup bash root@08cbba05d797:/# ./etherpad-backup.sh
Réparer la base de données suite à un incident
2020-03-23: Les backups de la BDD Etherpad cessent de fonctionner 2020-03-30: On s’en rend compte suite à l'incident. Le dump de la BDD échoue:
root@08cbba05d797:/# ./etherpad-backup.sh => etherpad: Backup started: 2020.03.30.140224.sql mysqldump: Error 1194: Table 'store' is marked as crashed and should be repaired when dumping table `store` at row: 8147475 etherpad: Backup failed
On a réparé la table avec:
- snippet.sql
REPAIR TABLE store;