Files
website/dist/articles/synapse-revitalization-script/index.html
2025-08-23 04:17:24 +03:00

79 lines
6.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<!--<link rel="icon" type="image/svg+xml" href="/favicon.svg" />-->
<meta name="generator" content="Astro v2.10.7">
<meta name="description" content="Restoration of Synapse after losing 1 year of database history">
<meta name="keywords" content="nothing.run nothing privacy free libre software floss self host">
<meta name="keywords" content="matrix synapse conduit postgres">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/nothingrun-favicon-whiteonblack.png" type="image/png">
<title>Restoration of Synapse after losing 1 year of database history</title>
<link rel="stylesheet" href="/_astro/contact.8ef370d5.css" /></head>
<body>
<div class="header astro-HPNW4VWY">
<a href="/" class="astro-HPNW4VWY">~/</a>
<a href="/contact" class="astro-HPNW4VWY">Contact</a>
<a href="https://uptime.nothing.run" class="astro-HPNW4VWY">Uptime</a>
<a href="/news" class="astro-HPNW4VWY">News</a>
<a href="/notes" class="astro-HPNW4VWY">Notes</a>
<a href="/donate" class="astro-HPNW4VWY">Donate :3</a>
</div>
<h1>Restoration of Synapse after losing 1 year of database history</h1>
<div class="article"><h2 id="introduction">Introduction</h2><p>In July 2025, my Synapse PostgreSQL had broken, so I needed to restore it from my 1-y.o. backup. I was thinking about what to do, and my friend sent me <a href="https://blog.erethon.com/blog/2023/06/21/what-happens-when-a-matrix-server-disappears/">this</a> article, so we understood what to do!</p><p>For example, there is a room called #example:example.org (roomid !example:example.org), whose member was @user:example.net.
The problem is that every server knows @user:example.net is in the room #example:example.org. But our server doesnt! So that is what we should aim at solving the problem.</p><h2 id="architecture">Architecture</h2><p>We get 2 types of error messages:</p><ul>
<li><code>synapse.handlers.receipts: [PUT-...] Ignoring receipt for room &#39;!example:example.org&#39; from server example.org as we&#39;re not in the room</code> (there is the same error message, but when you get a typing event from an unknown room)</li>
<li><code>synapse.federation.federation_server: [PUT-...] Ignoring PDU for unknown room_id: !example:example.org</code></li>
</ul><p>We can read the journal and parse the error message (I use a bash script to do that).
Okay, we have a room id! In the given article, the author is the only user of their server, so they can just send <a href="https://spec.matrix.org/v1.15/client-server-api/#post_matrixclientv3joinroomidoralias">POST /_matrix/client/v3/join/!example:example.org</a> request, and everything will be good.
But my server has multiple users, so I cant use the easiest way. We need to get information about membership (so we need to get state).</p><p>As we are admins of our servers, we have their signing keys.
We will need them because we are going to get state via Federation API requests.
How? There are different ways to do that.
However, all of them require at least 1 event id, so firstly we need to do <a href="https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1timestamp_to_eventroomid">GET /_matrix/federation/v1/timestamp_to_event</a>.
Determining request parameters (?dir as direction (b[ackward] or f[orward]) and &amp;ts as timestamp in Unix time format in milliseconds), we have just got either the last or the first event id! In my case, I chose the way of getting the last event, so then Ill have to make <a href="https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1stateroomid">GET /_matrix/federation/v1/state/!example:example.org?event_id=$event_id</a>, and I will get the actual state.
Of course, both of the requests, as I said, should be signed using your servers key (<a href="https://spec.matrix.org/v1.15/server-server-api/#signing-events">how to sign events</a>).</p><br/><p>(There is no support of timestamp_to_event in Conduit, so it would be a good idea to make support of requesting different servers)</p><p>After we receive the state, we need to parse it, but I think this cant make a difficulty.
As a result, we have a list of our users that were in the given room, like [“@user:example.net”, “@anotheruser:example.net”, “@exampleuser:example.net”].
Then, the simplest way is to get temporary users auth token via <a href="https://github.com/matrix-org/synapse/blob/develop/docs/admin_api/user_admin_api.md#login-as-a-user">POST /_synapse/admin/v1/users/user_id/login</a> and make <a href="https://spec.matrix.org/v1.15/client-server-api/#post_matrixclientv3joinroomidoralias">POST /_matrix/client/v3/join/!example:example.org</a> from the name of the user using their token.
The problem is solved!</p><h2 id="external-links">External links</h2><ul>
<li><a href="https://blog.erethon.com/blog/2023/06/21/what-happens-when-a-matrix-server-disappears/">Article that gave me the idea</a></li>
<li><a href="https://spec.matrix.org/v1.15/server-server-api/">Matrix Federation API docs</a>
<ul>
<li><a href="https://spec.matrix.org/v1.15/server-server-api/#signing-events">How to sign Federation API requests</a></li>
<li><a href="https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1stateroomid">GET /_matrix/federation/v1/state/!example:example.org?event_id=$event_id</a></li>
<li><a href="https://spec.matrix.org/v1.15/server-server-api/#get_matrixfederationv1timestamp_to_eventroomid">GET /_matrix/federation/v1/timestamp_to_event</a></li>
</ul>
</li>
<li><a href="https://spec.matrix.org/v1.15/server-server-api/">Matrix Client API docs</a>
<ul>
<li><a href="https://spec.matrix.org/v1.15/client-server-api/#post_matrixclientv3joinroomidoralias">POST /_matrix/client/v3/join/!example:example.org</a></li>
</ul>
</li>
<li><a href="https://github.com/matrix-org/synapse/blob/develop/docs/admin_api/user_admin_api.md#login-as-a-user">Admin API POST /_synapse/admin/v1/users/user_id/login</a></li>
</ul></div>
<div id="footer">
<main>
<pre> .--.
." o \__
_.-" ,( `
_.-" ,;;|
_.-=" _," ,,;;;'
.-"`_.-"``-..,,;;;;:'
`"'` `\`\
/^\\\
</pre>
</main>
<aside>
<b>Made with ♥</b> by Thary<br>
<!-- Website sources are available on <a href="https://git.vector1.dev/thary/website">Gitea</a>!<br> -->
<!-- All content is in Public domain and licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a><br> -->
Logo is created by <a href="https://houl.floof.company/">Houl</a><br>
ASCII arts are taken from <a href="https://web.archive.org/web/20010420182629/http://www.geocities.com/spunk1111/indexjava.htm">this website</a>
</aside>
</div>
</body></html>