Add storage command for triggering RocksDB compaction#4385
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
I have read the CLA Document and I hereby sign the CLA |
|
recheck |
|
@tillrohrmann |
|
Hi @david-wagih, thanks a lot for this contribution. I'll get to review your PR this week. Sorry for the slow response. |
|
@tillrohrmann Hi Till, I am just rechecking with you about the state of this PR |
|
Hi @david-wagih, sorry for the delay. I haven't forgotten it. Will get to it swiftly. |
tillrohrmann
left a comment
There was a problem hiding this comment.
Thanks a lot for creating this PR @david-wagih. I think it looks good. I left a few comments for how we could improve it. Let me know what you think.
| } else if name == "db" || name.starts_with("db-") { | ||
| DatabaseKind::PartitionStore | ||
| } else { | ||
| DatabaseKind::Unknown |
There was a problem hiding this comment.
What is this variant being used for? It looks as if all unknown dbs map to this variant. Since we are translating the existing db names to variants it could then happen that a request for "foobar" triggers a compaction on a newly introduced db for which we forgot to add the translation to DatabaseKind.
There was a problem hiding this comment.
Differently asked, why not ignoring requested db to compact which are not known?
| } | ||
|
|
||
| let cf_count = db.cfs().len() as u32; | ||
| db.compact_all().await; |
There was a problem hiding this comment.
I assume it was intentional to run compactions sequentially to avoid overloading the system with I/O operations. Maybe add a comment to make this explicit (why we are only running a single compaction at a time).
| } | ||
|
|
||
| let cf_count = db.cfs().len() as u32; | ||
| db.compact_all().await; |
There was a problem hiding this comment.
Maybe we can extend compact_all to return whether the compaction was successful. Right now, independent of whether the compaction succeeded, we are returning success: true.
| if name == "log-server" { | ||
| DatabaseKind::LogServer | ||
| } else if name == "replicated-metadata-server" { | ||
| DatabaseKind::MetadataServer | ||
| } else if name == "local-loglet" { | ||
| DatabaseKind::LocalLoglet | ||
| } else if name == "db" || name.starts_with("db-") { |
There was a problem hiding this comment.
There is a chance that this will silently break if the db names should be changed where we open the RocksDB databases.
| let requested_kinds: Vec<DatabaseKind> = if request.databases.is_empty() { | ||
| vec![DatabaseKind::All] |
There was a problem hiding this comment.
If an empty request.databases translates into all databases, do we need an explicit DatabaseKind::All variant? It seems that we are mixing the database kinds with more general filter conditions by having a DatabaseKind::All.
| /// Database type(s) to compact: all, partition-store, log-server, | ||
| /// metadata-server, local-loglet. Defaults to all. | ||
| #[arg(long, short = 'd', value_delimiter = ',')] | ||
| database: Vec<String>, |
There was a problem hiding this comment.
Could the Vec type be DatabaseKind? That way we might get automatic type safety and prevent user typos from going unnoticed.
| /// Target specific node addresses (default: all nodes from cluster) | ||
| #[arg(long, short = 'n', value_delimiter = ',')] | ||
| node: Vec<AdvertisedAddress<FabricPort>>, |
There was a problem hiding this comment.
Wondering whether we want to rather specify NodeId instead of addresses. We can obtain the addresses from the NodesConfiguration. A bit similar to restatectl nodes rm --nodes N1,N2.
| let mut client = new_node_ctl_client(channel, &CliContext::get().network); | ||
|
|
||
| let request = TriggerCompactionRequest { databases }; | ||
| let response = tokio::time::timeout(COMPACTION_TIMEOUT, client.trigger_compaction(request)) |
There was a problem hiding this comment.
The compaction timeout is hardcoded which can be a problem for very long running compaction calls. Could we use CliContext::get().request_timeout() instead?
| } else { | ||
| opts.database | ||
| .iter() | ||
| .filter_map(|s| parse_database_kind(s)) |
There was a problem hiding this comment.
Here we are silently dropping dbs with typos.
|
@tillrohrmann |
|
@tillrohrmann |
|
Will do later today. |
|
@tillrohrmann |
tillrohrmann
left a comment
There was a problem hiding this comment.
Great work @david-wagih. The changes look good to me. I will try your changes out and if everything works, then I will merge your PR. Will also address the only comment I had left. Thanks a lot for your contribution ❤️
thanks till for your feedback, excited to get my first contribution in restate merged ❤️ |
2eb9c2d to
30d7bb1
Compare
Address review feedback on storage compact command - Remove DatabaseKind::All from proto; empty databases list now means compact all, keeping DB kind semantics clean - Rename DATABASE_KIND_UNKNOWN to DATABASE_KIND_UNSPECIFIED (proto3 convention) - db_name_to_kind returns Option<DatabaseKind> so unrecognized DB names are skipped rather than risking accidental compaction of future DBs - compact_all now returns Result<(), RocksError> so failures are propagated into the per-DB success/error fields in the response instead of always reporting success: true - Add comment explaining sequential compaction is intentional to avoid I/O overload - CLI --database field is now Vec<DatabaseKind> with a value_parser so clap rejects invalid values at parse time instead of silently dropping them - CLI --node now accepts PlainNodeId (e.g. N1,N2) instead of raw addresses; addresses are resolved from NodesConfiguration, matching the nodes rm pattern - Replace hardcoded 300s compaction timeout with CliContext::get().request_timeout() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Update server/src/signal.rs Co-authored-by: Till Rohrmann <till.rohrmann@gmail.com>
Move DatabaseKind from node_ctl_svc.proto to common.proto so it is available in restate-types. Add DatabaseKind::db_name() as the canonical mapping from kind to RocksDB database name, and store the kind on DbSpec so that RocksDb::kind() can be queried directly without reverse- engineering the kind from the name string. This eliminates the scattered DB_NAME constants from individual crates and removes the fragile db_name_to_kind() function that could silently go out of sync if a database was renamed.
30d7bb1 to
aa1749d
Compare
What is Added
TriggerCompactionRPC in the NodeCtlSvc protocol.trigger_compactionmethod in NodeCtlSvcHandler to handle compaction requests.Compactcommand in the Restate CLI for initiating compaction on specified nodes.compact.rsto define compaction options and logic.