Skip to content

Commit f1e4dc8

Browse files
committed
For performance, switch to a row count estimate for users and devices
1 parent 487c53c commit f1e4dc8

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

crates/syn2mas/src/migration.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,10 @@ pub async fn migrate(
142142

143143
let state = MigrationState {
144144
server_name,
145-
users: HashMap::with_capacity(counts.users),
146-
devices_to_compat_sessions: HashMap::with_capacity(counts.devices),
145+
// We oversize the hashmaps, as the estimates are innaccurate, and we would like to avoid
146+
// reallocations.
147+
users: HashMap::with_capacity(counts.users * 9 / 8),
148+
devices_to_compat_sessions: HashMap::with_capacity(counts.devices * 9 / 8),
147149
provider_id_mapping,
148150
};
149151

crates/syn2mas/src/synapse_reader/mod.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -336,28 +336,31 @@ impl<'conn> SynapseReader<'conn> {
336336
///
337337
/// - An underlying database error
338338
pub async fn count_rows(&mut self) -> Result<SynapseRowCounts, Error> {
339+
// We don't get to filter out application service users by using this estimate,
340+
// which is a shame, but on a large database this is way faster.
341+
// On matrix.org, counting users and devices properly takes around 1m10s,
342+
// which is unnecessary extra downtime during the migration, just to
343+
// show a more accurate progress bar and size a hash map accurately.
339344
let users: usize = sqlx::query_scalar::<_, i64>(
340345
"
341-
SELECT COUNT(1) FROM users
342-
WHERE appservice_id IS NULL
346+
SELECT reltuples::bigint AS estimate FROM pg_class WHERE oid = 'users'::regclass;
343347
",
344348
)
345349
.fetch_one(&mut *self.txn)
346350
.await
347-
.into_database("counting Synapse users")?
351+
.into_database("estimating count of users")?
348352
.max(0)
349353
.try_into()
350354
.unwrap_or(usize::MAX);
351355

352356
let devices = sqlx::query_scalar::<_, i64>(
353357
"
354-
SELECT COUNT(1) FROM devices
355-
WHERE NOT hidden
358+
SELECT reltuples::bigint AS estimate FROM pg_class WHERE oid = 'devices'::regclass;
356359
",
357360
)
358361
.fetch_one(&mut *self.txn)
359362
.await
360-
.into_database("counting Synapse devices")?
363+
.into_database("estimating count of devices")?
361364
.max(0)
362365
.try_into()
363366
.unwrap_or(usize::MAX);

0 commit comments

Comments
 (0)