Remove upload.pending files from WAL segment directories in parallel,
unblocking WalPurgeJob so it can reap old WAL segments.
When repointing a QuestDB instance to a new empty object store, the
replication startup path (process_startup_table) iterates every WAL
segment directory to delete upload.pending files. On large tables with
millions of accumulated WAL segments, this single-threaded filesystem
walk can block server startup indefinitely.
This tool performs the same cleanup in parallel while the database is
running in standalone (non-replicated) mode, allowing WalPurgeJob to
reap old segments before the next replicated startup.
Requires a Rust toolchain (1.85+).
cargo build --releaseThe binary will be at target/release/rm_wal_segments_pending.
rm_wal_segments_pending <db_root> [--dry-run] [--threads=N]
<db_root>— Path to the QuestDB database root directory (e.g./var/lib/questdb/db).--dry-run— Countupload.pendingfiles without deleting them.--threads=N— Number of parallel threads (default: 12).
Count pending files across all tables:
./rm_wal_segments_pending /var/lib/questdb/db --dry-runRemove pending files with 24 threads:
./rm_wal_segments_pending /var/lib/questdb/db --threads=24-
The database must be running in standalone (non-replicated) mode. The replication uploader must not be active — otherwise there is a race between this tool deleting
upload.pendingfiles and the uploader creating new ones. -
After running this tool, wait for
WalPurgeJobto reap the old WAL segments before restarting with replication enabled.
The tool walks the database directory structure:
db_root/
my_table/
wal1/ # WAL directory (walN where N is a u32)
0/ # Segment directory (u32 name)
.pending/
upload.pending <-- this file is deleted
1/
.pending/
upload.pending <-- this file is deleted
wal2/
...
other_table/
...
- Iterates all table directories under the database root.
- For each table, enumerates
walNdirectories (tables without WAL directories are skipped silently). - Uses a rayon thread pool to process WAL directories in parallel.
- Within each WAL directory, iterates segment directories and deletes
.pending/upload.pendingif present. - Logs progress every second per table (files removed and rate).
The tool is safe to run against a live database in standalone mode:
WalPurgeJobmay concurrently remove directories that this tool is scanning.NotFounderrors from such races are silently ignored.- New WAL and segment directories created by ongoing writes will not
have
upload.pendingfiles (the uploader is not running), so they are harmless.
0— Success (or no WAL directories found).1— Completed with errors.2— Invalid usage (bad arguments, unknown flags).