Skip to content

SERVER-130410: Independent Replication Network Compression Control - #1822

Open
y123456yz wants to merge 4 commits into
mongodb:masterfrom
y123456yz:SERVER-130410_replication-compression
Open

SERVER-130410: Independent Replication Network Compression Control#1822
y123456yz wants to merge 4 commits into
mongodb:masterfrom
y123456yz:SERVER-130410_replication-compression

Conversation

@y123456yz

Copy link
Copy Markdown
Contributor

What: Adds a compression policy that applies only to the replication data plane — oplog fetcher, initial sync cloner, and rollback oplog reader — and negotiates independently from the client-facing net.compression.compressors.

Config option: replication.networkCompression.compressors
setParameter: replicationNetworkCompression
"" (default) = inherit net.compression.compressors (no behavior change)
"disabled" = negotiate replication data-plane connections uncompressed
"a,b,c" = use only these algorithms for replication, even when net.compression.compressors is disabled
Why: Replication traffic currently shares the single net.compression.compressors knob with ordinary client traffic. Operators cannot compress replication while keeping clients uncompressed, or use a different compressor for replication than for clients.

Implementation notes / review focus:

Union registry + per-connection candidate sets: MessageCompressorRegistry now distinguishes the net set, the replication set, and their union. The net set is used for ordinary client / non-replication connections; the replication set is used for replication data-plane connections; the union only determines which compressor implementations are registered in the process. This allows replication to use algorithms such as zstd / snappy even when net.compression.compressors is disabled.

Per-connection permit list (_permittedCompressorIds): since the registry is now the net∪repl union, “registered” no longer means “allowed on this connection”, so decompression can no longer rely on the registry alone. We also cannot simply reuse _negotiated[]: _negotiated represents the negotiated result and the default compression preference order, while existing behavior also supports echoing the request’s compression state back in the response (see MessageCompressorManager.SERVER_28008 / SERVER-28008). In that path, decompressMessage() returns the actual compressorId used by the request, and that id is then passed to compressMessage() to explicitly choose the response compressor. Therefore we need a per-connection set of allowed compressor ids, which is what _permittedCompressorIds provides. This makes external connections reject registered replication-only compressors according to the net policy, prevents algorithm smuggling through the union registry, and applies the same rule to explicit echo-back compression. Legacy/direct callers that never negotiated keep the existing permit-all behavior.

Routing via hello marker: replication clients call applyReplicationNetworkCompressionToManager(), which adds replicationCompressionClient: true to hello. The server routes only marked connections through the replication candidate set; heartbeats, shard RPC, and external clients continue to use the net set. This is applied to the three replication data-plane paths: oplog_fetcher.cpp, all_database_cloner.cpp, and bgsync.cpp.

repl.compression observability: adds serverStatus().repl.compression, which reports the replication subset of network.compression. The same bytes are still included in network.compression; replication-marked connections are additionally attributed to repl.compression so replication traffic can be observed separately.

Sticky state: the replicationCompressionClient marker is present only on the initial handshake. Later marker-less hello / awaitable hello commands on the same connection must not reset the connection back to the net policy. The server-side replication candidate set and repl.compression accounting flag are therefore sticky for the lifetime of the connection: they are set once and are not cleared by later marker-less hello commands.

Validation semantics: this option is startup-only; runtime setParameter is rejected. "" means inherit net.compression.compressors. Non-empty values containing only whitespace/separators, such as " " or ",", are rejected. "disabled" cannot be combined with compressor names. Unknown or unregistered compressors fail during startup finalization and do not silently downgrade. Supplying both the config option and the setParameter form is treated as a conflict and startup is rejected.

Compatibility and safety: the default inherits net.compression.compressors, so existing behavior is unchanged. Invalid configuration fails fast. Disjoint replication allow-lists safely fall back to uncompressed replication without breaking replication. Replication-only compressors are never exposed to external clients. MessageCompressorManager is per-session state and is only mutated within that session’s serial SessionWorkflow iteration, so no additional locking is required.

…-less hellos

The replicationCompressionClient hello marker is only present on the initial data-plane handshake. Later hellos on the same connection (topology monitoring / awaitable isMaster) do not carry it, which previously reset the replication state on each renegotiation:

- serverNegotiate() fell back to net.compression.compressors and silently dropped the negotiated replication compressor when net.compression was disabled.

- The repl.compression accounting flag was cleared, so the sync source stopped attributing oplog-response compression to serverStatus().repl.compression.

Make both the server-side replication candidate set and the accounting flag sticky for the connection's lifetime (only ever set, never clear), and prefer the sticky candidate set over the per-hello argument during renegotiation. Update tests and docs accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant