WIP postgres

This commit is contained in:
Quentin 2021-07-14 15:51:18 +02:00
parent d10b3d9d7b
commit 34910e376c
6 changed files with 308 additions and 255 deletions

View file

@ -1,9 +1,9 @@
source 'https://rubygems.org' source 'https://rubygems.org'
gem 'github-pages'
gem 'jekyll-sitemap' gem 'jekyll-sitemap'
gem 'jekyll' gem 'jekyll', ">=4.2.0"
gem 'jekyll-paginate' gem 'jekyll-paginate'
gem 'rouge' gem 'rouge'
gem 'redcarpet' gem 'redcarpet'
gem 'jekyll-scholar'
gem 'racc' gem 'racc'
gem "webrick", "~> 1.7"

View file

@ -1,247 +1,50 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
activesupport (6.0.3.7) addressable (2.8.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
bibtex-ruby (4.4.7)
latex-decode (~> 0.0)
citeproc (1.0.10)
namae (~> 1.0)
citeproc-ruby (1.1.13)
citeproc (~> 1.0, >= 1.0.9)
csl (~> 1.5)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
colorator (1.1.0) colorator (1.1.0)
commonmarker (0.17.13) concurrent-ruby (1.1.9)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.8)
csl (1.5.2)
namae (~> 1.0)
csl-styles (1.0.1.11)
csl (~> 1.0)
dnsruby (1.61.5)
simpleidn (~> 0.1)
em-websocket (0.5.2) em-websocket (0.5.2)
eventmachine (>= 0.12.9) eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0) http_parser.rb (~> 0.6.0)
ethon (0.14.0)
ffi (>= 1.15.0)
eventmachine (1.2.7) eventmachine (1.2.7)
execjs (2.8.1) ffi (1.15.3)
faraday (1.4.2)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
multipart-post (>= 1.2, < 3)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.1.0)
ffi (1.15.1)
forwardable-extended (2.6.0) forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (215)
github-pages-health-check (= 1.17.2)
jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.15.1)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-mentions (= 1.6.0)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.16.0)
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.3)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.7.1)
jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.2)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
jekyll-theme-minimal (= 0.1.1)
jekyll-theme-modernist (= 0.1.1)
jekyll-theme-primer (= 0.5.4)
jekyll-theme-slate (= 0.1.1)
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.12.0)
kramdown (= 2.3.1)
kramdown-parser-gfm (= 1.1.0)
liquid (= 4.0.3)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.26.0)
terminal-table (~> 1.4)
github-pages-health-check (1.17.2)
addressable (~> 2.3)
dnsruby (~> 1.60)
octokit (~> 4.0)
public_suffix (>= 2.0.2, < 5.0)
typhoeus (~> 1.3)
html-pipeline (2.14.0)
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.6.0) http_parser.rb (0.6.0)
i18n (0.9.5) i18n (1.8.10)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
jekyll (3.9.0) jekyll (4.2.0)
addressable (~> 2.4) addressable (~> 2.4)
colorator (~> 1.0) colorator (~> 1.0)
em-websocket (~> 0.5) em-websocket (~> 0.5)
i18n (~> 0.7) i18n (~> 1.0)
jekyll-sass-converter (~> 1.0) jekyll-sass-converter (~> 2.0)
jekyll-watch (~> 2.0) jekyll-watch (~> 2.0)
kramdown (>= 1.17, < 3) kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0) liquid (~> 4.0)
mercenary (~> 0.3.3) mercenary (~> 0.4.0)
pathutil (~> 0.9) pathutil (~> 0.9)
rouge (>= 1.7, < 4) rouge (~> 3.0)
safe_yaml (~> 1.0) safe_yaml (~> 1.0)
jekyll-avatar (0.7.0) terminal-table (~> 2.0)
jekyll (>= 3.0, < 5.0)
jekyll-coffeescript (1.1.1)
coffee-script (~> 2.2)
coffee-script-source (~> 1.11.1)
jekyll-commonmark (1.3.1)
commonmarker (~> 0.14)
jekyll (>= 3.7, < 5.0)
jekyll-commonmark-ghpages (0.1.6)
commonmarker (~> 0.17.6)
jekyll-commonmark (~> 1.2)
rouge (>= 2.0, < 4.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
jekyll-feed (0.15.1)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-mentions (1.6.0)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
jekyll-optional-front-matter (0.3.2)
jekyll (>= 3.0, < 5.0)
jekyll-paginate (1.1.0) jekyll-paginate (1.1.0)
jekyll-readme-index (0.3.0) jekyll-sass-converter (2.1.0)
jekyll (>= 3.0, < 5.0) sassc (> 2.0.1, < 3.0)
jekyll-redirect-from (0.16.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.3)
addressable (~> 2.0)
jekyll (>= 3.5, < 5.0)
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-scholar (5.16.0)
bibtex-ruby (~> 4.0, >= 4.0.13)
citeproc-ruby (~> 1.0)
csl-styles (~> 1.0)
jekyll (~> 3.0)
jekyll-seo-tag (2.7.1)
jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0) jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0) jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0)
jekyll-theme-architect (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-cayman (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.2)
jekyll (> 3.5, < 5.0)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-merlot (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-midnight (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.5.4)
jekyll (> 3.5, < 5.0)
jekyll-github-metadata (~> 2.9)
jekyll-seo-tag (~> 2.0)
jekyll-theme-slate (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-tactile (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-time-machine (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-titles-from-headings (0.5.3)
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1) jekyll-watch (2.2.1)
listen (~> 3.0) listen (~> 3.0)
jemoji (0.12.0)
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
kramdown (2.3.1) kramdown (2.3.1)
rexml rexml
kramdown-parser-gfm (1.1.0) kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0) kramdown (~> 2.0)
latex-decode (0.3.2)
liquid (4.0.3) liquid (4.0.3)
listen (3.5.1) listen (3.5.1)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6) mercenary (0.4.0)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.4)
multipart-post (2.1.1)
namae (1.1.1)
nokogiri (1.11.6-x86_64-linux)
racc (~> 1.4)
octokit (4.21.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2) pathutil (0.16.2)
forwardable-extended (~> 2.6) forwardable-extended (~> 2.6)
public_suffix (4.0.6) public_suffix (4.0.6)
@ -252,46 +55,25 @@ GEM
redcarpet (3.5.1) redcarpet (3.5.1)
rexml (3.2.5) rexml (3.2.5)
rouge (3.26.0) rouge (3.26.0)
ruby-enum (0.9.0)
i18n
ruby2_keywords (0.0.4)
rubyzip (2.3.0)
safe_yaml (1.0.5) safe_yaml (1.0.5)
sass (3.7.4) sassc (2.4.0)
sass-listen (~> 4.0.0) ffi (~> 1.9)
sass-listen (4.0.0) terminal-table (2.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
simpleidn (0.2.1)
unf (~> 0.1.4)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1) unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0) unicode-display_width (1.7.0)
zeitwerk (2.4.2) webrick (1.7.0)
PLATFORMS PLATFORMS
x86_64-linux x86_64-linux
DEPENDENCIES DEPENDENCIES
github-pages jekyll (>= 4.2.0)
jekyll
jekyll-paginate jekyll-paginate
jekyll-scholar
jekyll-sitemap jekyll-sitemap
racc racc
redcarpet redcarpet
rouge rouge
webrick (~> 1.7)
BUNDLED WITH BUNDLED WITH
2.2.15 2.2.15

View file

@ -14,10 +14,6 @@ paginate: 20
domain_name: 'https://quentin.dufour.io' domain_name: 'https://quentin.dufour.io'
url: 'https://quentin.dufour.io' url: 'https://quentin.dufour.io'
scholar:
style: './_bibliography/ieee-with-url.csl'
bibliography: '**/*.bib{,tex}'
# Details for the RSS feed generator # Details for the RSS feed generator
url: 'https://quentin.dufour.io' url: 'https://quentin.dufour.io'
author: 'Quentin Dufour' author: 'Quentin Dufour'
@ -42,4 +38,3 @@ defaults:
plugins: plugins:
- jekyll-sitemap - jekyll-sitemap
- jekyll-paginate - jekyll-paginate
- jekyll-scholar

View file

@ -1,9 +1 @@
<a class="twitter" href="https://twitter.com/intent/tweet?text={{page.title}} by Quentin Dufour - {{ site.shareurl }}{{ page.url }}"><span class="icon-twitter"> Tweet</span></a>
<a class="facebook" href="#" onclick="
window.open(
'https://www.facebook.com/sharer/sharer.php?u='+encodeURIComponent(location.href),
'facebook-share-dialog',
'width=626,height=436');
return false;"><span class="icon-facebook-rect"> Share</span>
</a>

View file

@ -0,0 +1,284 @@
---
layout: post
slug: chroniques-administration-synapse
status: draft
sitemap: false
title: Chroniques d'administration de Synapse
description: Pour l'instant tout va bien, pour l'instant tout...
categories:
tags:
---
Tout a commencé le mercredi 30 juin par un message parfaitement innocent de Max qui nous dit que les disques sont presque pleins :
![Capture d'écran d'un message de Max alertant sur les disques presque pleins](/assets/images/posts/synapse-explo.png)
Pour éviter la catastrophe annoncée, je décide de trouver le coupable.
Après une rapide recherche, il apparait que PostgreSQL occupe plus de 50Go.
Ayant des SSD de 120 Go, c'est donc majoritairement PostgreSQL qui occupe de la place.
En creusant plus profondément, c'est la base de donnée de Synapse (le serveur Matrix) qui prend tout cet espace, les autres bases ne comptant que pour quelques kilo-octets.
À ce même moment, nous ne le savions pas encore, mais le réseau Matrix faisait face à [une vague de spam](https://matrix.org/blog/2021/06/30/security-update-synapse-1-37-1-released).
Sans être responsable de l'indisponibilité qui va suivre, elle plante le décor et participe à expliquer pourquoi nous avons été pris de court.
En effet, la croissance rapide de notre base de donnée n'est pas seulement due à des usages normaux, mais aussi au spam qui a généré beaucoup d'activité sur les autres serveurs, et via la fédération, participé à remplir notre base.
Pour finir de planter le décor, notre instance Matrix a 4 ans mais n'a jamais nécessité de nettoyage ou maintenance de quelque sorte que ce soit jusqu'ici, bien que jusqu'à récemment, nous nous fédérerions avec des salons bruyants comme [Matrix HQ](https://view.matrix.org/room/!OGEhHVWSdvArJzumhm:matrix.org/). Nous avons donc aucune expérience dans ce domaine.
Sûr de moi, je vise une petite maintenance de deux heures où je compte supprimer les salons de discussions vides et réduire l'historique distant des salons très bruyants. La documentation sur le sujet est quasi inexistante mais je me dis que c'est parce que la tâche ne doit pas être si complexe. En réalité, la maintenance durera 4 jours et ne se sera pas passée du tout comme prévu. Je vous propose de revenir ici sur tous les points qui ont bloqué !
Avant d'aller plus loin, je souhaite souligner l'existence de deux guides sur le sujet qui m'ont aidé et qui sont de très bons compléments à cet article :
- [Compressing Synapse database](https://levans.fr/shrink-synapse-database.html) par Levans
- [Administration Synapse > Nettoyage du serveur](https://www.tedomum.net/dev/service/matrix/administration/#nettoyage-du-serveur) par Tedomum
## L'API d'administration de Synapse
Replaçons le contexte : Matrix est un protocole, et spécifie entre autre des API de communications clients à serveurs et serveurs à serveurs.
Cependant, à ce jour, les API de Matrix ne permettent pas à des communautés de se gérer totalement en autonomie.
La preuve, nous étions en train d'épuiser les ressources du serveur mais nous pouvions rien faire en tant qu'utilisateur pour les libérer.
Au delà de la gestion des ressources, il manque aussi des outils pour la gestion du spam et la modération.
En suivant l'actualité de Matrix, on peut voir qu'ils travaillent déjà sur ces fonctionnalités.
Pour la gestion de l'espace disque, ils ont une option pour définir la durée de rétention de l'historique d'un salon de discussion mais l'option n'est pas encore disponible dans l'interface.
On sait aussi qu'ils ont échangé avec la Quadrature du Net sur les questions de modération.
En attendant la publication de ces fonctionnalités, les développeurs de Synapse ont déplacé ces responsabilités depuis les utilisateurs vers les administrateurs.
Ils fournissent aux administrateurs des fonctionnalités manuelles et naives via une API ne faisant pas partie de la norme Matrix.
J'ai commencé par explorer cette API via l'interface web synapse-admin réalisée par la communauté.
Elle m'a permis de supprimer presque un millier de comptes invités et quelques salons de discussions vides.
Cependant, cette interface montre vite ses limites : elle est très vite ralentie quand il y a beaucoup de contenu et gèrent très mal les opérations en lot (suppression de 40 salons d'un coup par exemple). Enfin, en affichant par défaut tout le contenu qu'elle a à disposition, elle expose inutilement des données personnelles aux administrateurs.
Très vite, je suis passé en ligne de commande avec `curl` (pour les requêtes HTTP) et `jq` (pour intéragir avec le JSON), ce qui semble être une pratique qui fait consensus parmi les administrateurs de serveurs Synapse.
La mise en route est rapide : il faut commencer par passer un compte Synapse en administrateur dans la base de données
```sql
UPDATE users SET admin = 1 WHERE name = '@foo:bar.com';
```
Ensuite, il faut récupérer un *bearer* pour ce compte.
Pour ma part, je me suis simplement connecté sur Element avec puis j'ai utilisé l'inspecteur réseau de mon navigateur, regardé les détails d'une requête partant vers l'API et extrait l'entête *Authorization* qui contient le *bearer*.
Enfin, pour ne pas retaper le bearer à chaque fois, je définis un alias pour ma session (il faut remplacer les points d'interogation avec le *bearer* que vous avez récupéré précédemment !) :
```bash
alias mctl='curl --header "Authorization: Bearer ???"'
```
Vous pouvez commencer par récupérer quelques informations simples comme le nombre de salons et le nombres de comptes sur votre serveur :
```bash
mctl 'https://synapse.tld/_synapse/admin/v1/rooms?limit=0'
mctl 'https://synapse.tld/_synapse/admin/v2/users?from=0&limit=0&guests=true'
```
Maintenant qu'on a le nombre, on va vouloir récupérer la liste.
À vous de choisir si vous voulez écrire un script utilisant le système de pagination de l'API
ou tout récupérer d'un coup au risque de mettre une pression importante sur votre serveur.
Ayant moins de 10 000 entrées, j'ai tout récupéré d'un coup :
```bash
mctl 'https://synapse.tld/_synapse/admin/v1/rooms?limit=10000' > rooms.json
mctl 'https://synapse.tld/_synapse/admin/v2/users?from=0&limit=10000&guests=true' > users.json
```
J'ai procédé à chaque fois en deux étapes : référencement des objets à supprimer dans un fichier puis appels à l'API.
J'ai commencé par les comptes, et plus particulièrement les comptes invités, qui étaient souvent utilisés quelques minutes avant d'être définitivement perdus :
```bash
cat users.json \
# requête jq manquante
>> users_to_delete.txt
```
Ensuite, [LX](https://adnab.me) avait développé un bridge entre Synapse et plusieurs autres protocols de communication comme Mattermost, Facebook ou IRC.
Ne nous donnant pas entière satisfaction, nous avons décidé de le décomissioner.
Le bridge devant répliqué un grand nombre de données, il était intéressant de supprimer ses données également.
Étant donné son évolution et ses différents protocoles, nous avons du réaliser plusieurs requetes via `jq` :
```bash
cat users.json \
| jq -r '.users[] | select(.name) | select(.name|test("_ezbr_:deuxfleurs.fr$")) | .name' \
>> users_to_delete.txt
cat users.json \
| jq -r '.users[] | select(.name) | select(.name|test("^@_ezbr_")) | .name' \
>> users_to_delete.txt
```
Il ne reste plus alors qu'à appeler l'API de Synapse :
```bash
cat users_to_delete.txt \
| while read u; do
echo "delete $u"
mctl \
-w "\n%{http_code}\n" \
-X POST \
-H "Content-Type: application/json" \
-d '{"erase": true}' \
https://synapse.tld/_synapse/admin/v1/deactivate/$u
echo -e "done $u\n"
done
```
Après que mon nettoyage utilisateur soit terminé, je suis passé du côté des salons.
J'ai commencé par référencer les salons vides :
```bash
cat rooms.json \
| jq -r '.rooms[] | select(.joined_local_members == 0) | .room_id' \
>> rooms_to_delete.txt
```
Ensuite je me suis occupé de Easybridge : en effet, il ne créait pas seulement des comptes mais aussi des salons.
Là aussi, il m'a fallu chercher différents motifs pour repérer les salons, ce qui a nécessité plusieurs requêtes :
```bash
cat rooms.json \
| jq -r '.rooms[] | select(.canonical_alias) | select(.canonical_alias|test("_ezbr_:deuxfleurs.fr$")) | .room_id' \
>> rooms_to_delete.txt
cat rooms.json \
| jq -r '.rooms[] | select(.creator) | select(.creator|test("_ezbr_:deuxfleurs.fr$")) | .room_id' \
>> rooms_to_delete.txt
cat rooms.json \
| jq -r '.rooms[] | select(.creator) | select(.creator|test("^@_ezbr_")) | .room_id' \
>> rooms_to_delete.txt
```
Enfin, bien que nous n'avions pas prévu à l'origine de supprimer des salons auxquelles nous participions encore,
il est apparu que certains étaient particulièrement couteux à suivre. Cette information n'est pas disponible via l'API,
cependant à l'aide de requêtes SQL plus loin, nous avons déterminé que les 6 salons suivants étaient trop couteux à suivre pour nous (Matrix HQ, Matrix HQ (old), Arch Linux (old), tor, openwrt et fedora-devel) :
```bash
cat >> rooms_to_delete.txt <<EOF
!OGEhHVWSdvArJzumhm:matrix.org
!mpvDHdMSZHzhzEDirR:matrix.org
!QtykxKocfZaZOUrTwp:matrix.org
!gVMacPcvhtqaEfaANo:matrix.org
!SEgsRQLScqPxYtucHl:archlinux.org
!MqVoatBTzkpWvekEvo:matrix.org
EOF
```
Maintenant que notre liste est complète, on peut supprimer les salons (l'API est synchrone) :
```bash
cat rooms_to_delete.txt \
| while read r; do
echo -e "delete $r\n"
mctl \
-w "\n%{http_code}\n" \
-X DELETE \
-H "Content-Type: application/json" \
-d '{"purge": true}' \
https://synapse.tld/_synapse/admin/v1/rooms/$r
done
```
Pour les salons qui restent, nous voulons limiter l'historique des contenus distants (c'est à dire des messages postés par les internautes ayant un compte rattaché à un autre serveur que le notre) à seulement deux mois. Si on veut remonter plus loin, on peut simplement redemander leur historique à leur serveur d'accueil.
Cette fois-ci l'API est asynchrone et on ne veut pas surcharger le serveur : on va surveiller la suppression courante avant d'en lancer une autre.
On veut aussi retélécharger la liste des salons avant de commencer car elle a bien changé : on en a supprimé beaucoup juste avant !
```bash
mctl 'https://synapse.tld/_synapse/admin/v1/rooms?limit=10000' > rooms.json
# c'est ici qu'on définit le deux mois VVVVVVVVVVVV
export MX_UNIX_TIMESTAMP=$(date +%s%3N --date='TZ="UTC+2" 2 months ago')
cat rooms.json \
| jq -r '.rooms[] | .room_id' \
| while read room; do
JOB_ID=$(mctl -s -X POST -H "Content-Type: application/json" -d "{\"delete_local_events\": false, \"purge_up_to_ts\": $MX_UNIX_TIMESTAMP}" "https://synapse.tld/_synapse/admin/v1/purge_history/$room" | jq -r '.purge_id')
echo Purge $room, job $JOB_ID
while true; do
STATUS=$(mctl -s "https://synapse.tld/_synapse/admin/v1/purge_history_status/$JOB_ID" | jq -r ".status")
echo Purge $room, job $JOB_ID, status $STATUS
if [ "$STATUS" = "complete" ]; then break; fi
if [ "$STATUS" = "null" ]; then break; fi
sleep 10
done
done
```
## Finir par mettre les mains dans le SQL
```bash
export PGPASSWORD="???"
alias mpsql='psql -h 127.0.0.1 -U matrix synapse'
```
Pour avoir une idée de ce "coût", nous avons du passer par SQL (attention les commandes mettent beaucoup de temps à s'exécuter).
Cette première commande permet d'avoir le nombre ???
Vous pouvez adapter la limite pour afficher plus de
```sql
SELECT room_id, count(*) AS count
FROM state_groups_state
GROUP BY room_id
ORDER BY count DESC
LIMIT 6;
-- Result (the last column has been added by me):
-- !OGEhHVWSdvArJzumhm:matrix.org | 51203310 | matrix HQ
-- !mpvDHdMSZHzhzEDirR:matrix.org | 19954563 | tor
-- !QtykxKocfZaZOUrTwp:matrix.org | 14727741 | Matrix HQ
-- !gVMacPcvhtqaEfaANo:matrix.org | 11356723 | fedora-devel
-- !SEgsRQLScqPxYtucHl:archlinux.org | 5326554 | Arch Linux (old)
-- !MqVoatBTzkpWvekEvo:matrix.org | 2961032 | #openwrt
```
Cette commande est plus rapide, c'est elle aussi qui est utilisée en interne pour calculer une complexité arbitraire pour les salons :
```sql
SELECT r.name, s.room_id, s.current_state_events
FROM room_stats_current s
LEFT JOIN room_stats_state r USING (room_id)
ORDER BY current_state_events DESC
LIMIT 6;
; Result:
; Matrix HQ | !OGEhHVWSdvArJzumhm:matrix.org | 57475
; #openwrt | !MqVoatBTzkpWvekEvo:matrix.org | 16083
; Arch Linux (old) | !SEgsRQLScqPxYtucHl:archlinux.org | 15718
; Yggdrasil | !DwmKuvGvRKciqyFcxv:matrix.org | 3462
; Synapse Announcements | !qBFNwucQebGPQldAnq:matrix.org | 2755
; Synapse Announcements | !iyIlInqJyxXrRmRHFx:matrix.org | 2544
```
## Quelques changements de configuration
```yaml
presence:
enabled: false
limit_remote_rooms:
enabled: true
complexity: 3.0
complexity_error: "Ce salon de discussion a trop d'activité, le serveur n'est pas assez puissant pour le rejoindre. N'hésitez pas à remonter l'information à l'équipe technique, nous pourrons ajuster la limitation au besoin."
admins_can_join: false
retention:
enabled: true
# no default policy for now, this is intended.
# DO NOT ADD ONE BECAUSE THIS IS DANGEROUS AND WILL DELETE CONTENT WE WANT TO KEEP!
purge_jobs:
- interval: 1d
```
## VACUUM FULL et Tablespace, un duo de choc
## Quand le WAL te met au pied du mur
## Stolon : initialisation, mise à jour et subtilités
keeper a besoin de la libc
très facile de flush totalement le cluster : reinit le cluster
import/export sql, le trick de pv :P
## D'autres outils

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB