Skip to content

Update RavenDB to 7.2.7 - #6049

Draft
danielmarbach wants to merge 9 commits into
masterfrom
ravendb-7.2-upgrade
Draft

danielmarbach wants to merge 9 commits into
masterfrom
ravendb-7.2-upgrade

Conversation

@danielmarbach

@danielmarbach danielmarbach commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

This moves RavenDB.Embedded from 6.2.18 to 7.2.7. The upgrade changes the on-disk data format and raises the minimum server version for external databases, so we should ship it as ServiceControl 7.

Why now

RavenDB 6.2 support ends in 2027. The RavenDB policy page says June 30 and the support page says December 31. ServiceControl 6 remains supported for one year after ServiceControl 7 ships, so the earlier we ship, the more of that year RavenDB still covers. 7.2 is the only supported 7.x line, because 7.0 and 7.1 were short-term releases. 7.2.7 includes the compaction fix for migrated databases from 7.2.5, the storage fixes from 7.2.7, and a fix for excessive memory use in sorted queries.

What changes

We squash-merge, so here are the individual steps:

  1. Retry database load timeouts for external RavenDB servers. Until now, only the embedded lifecycle retried DatabaseLoadTimeoutException. An instance that connects to an external server or the container now waits for the server to finish loading a large database instead of failing to start. Like the embedded loop, it retries until host startup is cancelled.

  2. Publish the shared embedded RavenDB test server only after its setup completes. Tests that started together could reach the server before it was ready.

  3. Add characterization tests for the RavenDB contracts we depend on. These tests change no production code. They cover:

    • the client-generated definition of every primary, throughput, and audit index
    • the JSON fields we read from /admin/debug/memory/stats and /license/status
    • deploying each index on its own
    • @expires set by patches and bulk inserts, and the JavaScript patch semantics
    • throughput time series, audit queries on Lucene and Corax, and server log output

    The approvals were created on 6.2.18 and pass unchanged on 7.2.7.

  4. Update RavenDB to 7.2.7.

    • RavenDB 7 refuses to start with --Logs.Mode, so we pass --Logs.MinLevel.
    • RavenDBLogLevel accepts NLog level names as they are and translates the legacy names the same way RavenDB does: None to Off, Operations to Info, Information to Debug.
    • The default stays Warn, and Storage.LogLevel in the usage report now says Warn instead of Operations.
    • The client-side Raven.Embedded log is gone, because RavenDB 7 removed the Sparrow logging API it relied on.
    • OptimisticConcurrencyMode.Writes replaces the obsolete UseOptimisticConcurrency and keeps the same behavior.
    • SingleNodeBatchCommand no longer takes the session context.
    • The container is now based on ubuntu.24.04, because ravendb/ravendb publishes only those tags from 7.2.4 on.
  5. Escape control characters in throughput endpoint document IDs. Databases created by RavenDB 7.2.5 or later reject them. Every other ID stays byte-for-byte the same, so existing documents still resolve. A name that already contains a literal %01 maps to the same ID as one with the control character. We accept that, because we don't expect endpoint names like that.

  6. Save enums as integers in RavenDB patches. SaveEnumsAsIntegersForPatching is now set wherever SaveEnumsAsIntegers is, so a future typed patch cannot write enums as strings.

  7. Leave unused RavenDB server libraries out of the package. The ONNX runtime libraries and the local embeddings model no longer ship in RavenDBServer.zip, which saves about 19 MB. The managed AI assemblies stay, because the server does not start without them.

  8. Reject RavenDB 7.2 servers that corrupt migrated databases on compaction. The check keeps RavenDB's compatibility rule, which ignores the patch: the server's major.minor must be at least the client's. On top of that, it rejects 7.2.0 to 7.2.4, because those versions corrupt the attachments index when an operator compacts a database migrated from 6.2 or 7.1. 7.2.5 fixed this and repairs the schema when the database loads, so refusing to start moves operators to a server that repairs their database. The 7.2.5 floor is fixed, so a later client patch does not raise the server requirement. The check handles suffixes such as -nightly.

  9. Require the latest 6.x before upgrading to 7. The installer requires 6.21.0 before an upgrade to 7.0, the same way 5.11.0 gated the move to 6.0.

What operators need to know

  • External RavenDB servers and the servicecontrol-ravendb container must run 7.2.5 or later before the instances are upgraded. We recommend 7.2.7, the version ServiceControl 7 ships with. A 6.x instance still starts against a 7.2 server, because its check only rejects servers with a lower major.minor version. We have not smoke-tested that order yet.
  • The data upgrade is one-way. Rolling back requires a backup taken before the first start on 7.2.7.
  • Particular.PlatformSample.ServiceControl needs the .NET 10 runtime 10.0.12 or later, because the RavenDB 7.2.7 server is framework-dependent.
  • On Corax databases, results that share a sort key, for example in a message_type sort, can come back in a different order than on 6.2.18. Totals and result sets stay the same.

Alternatives we did not take

  • Rebasing draft Ravendb upgrade #5978. I picked its changes one by one after checking each of them. Its logging mapping (Operations to Warn) differs from RavenDB's own translation, so I did not use it.
  • Upgrading through 7.0 or 7.1. Both are out of support.
  • Routing RavenDB client logs into ServiceControl logging. RavenLogManager.Set would need an adapter for an interface with about 52 members, and it has to run before any RavenDB type loads. That is a lot of code for a log that was only written at the most verbose level.
  • Turning off bulk insert compression for the embedded server. With NoCompression, inserts were not faster and used more CPU overall.

Related pull requests

How this was verified

Tests ran on macOS arm64 in Release, after the rebase on master:

Project Result
ServiceControl.Persistence.Tests.RavenDB 436 passed
ServiceControl.Audit.Persistence.Tests.RavenDB 104 passed
ServiceControl.AcceptanceTests.RavenDB 228 passed, 2 skipped (before the rebase)
ServiceControl.Audit.AcceptanceTests.RavenDB 74 passed (before the rebase)
ServiceControl.MultiInstance.AcceptanceTests 23 passed (before the rebase)
Unit tests, ServiceControlInstaller.Packaging.UnitTests All passed

Beyond the test suites:

  • The servicecontrol-ravendb image built locally from the 24.04 base, started, reported 7.2.7, and accepted the license.
  • Against real servers, an earlier version of the external version check rejected 7.2.4 and 6.2.20 and accepted 7.2.7. The current check gives the same results for those versions in its unit tests, but I have not re-run it against the containers.
  • A server with the excluded files removed started on Linux, Studio loaded, and creating and querying an index worked.
  • I simulated the in-place upgrade in Docker:
    • Master instances ran against a 6.2.18 container with RabbitMQ and seeded data: failed messages, failure groups, retries, archives, audit messages with bodies, and saga snapshots.
    • I then moved the container to 7.2.7 on the same volume and started the instances from this branch against it.
    • On Lucene and on Corax databases, no index was reset or rebuilt. CreatedTimestamp, search engine, and entry counts stayed the same, and polling found no ReplacementOf/ index.
    • On Corax, 234 REST queries returned the same totals and result sets before and after the upgrade. Only the order of equal message_type sort keys changed.

Still to verify:

  • ServiceControlInstaller.Engine.UnitTests targets net10.0-windows, so it needs CI. That covers PackagedRavenDBTests against the trimmed zip and the new upgrade gate tests. The gate logic already passed in a net10.0 copy.
  • How long the upgrade takes on large databases, especially the attachment migration on the first start of 7.2, and how the installer's 120-second wait for the service to start behaves in the meantime.
  • A consumer project running Particular.PlatformSample.ServiceControl.

Before this is ready for review

  • Confirm the final 6.x version for the upgrade gate. The gate requires 6.21.0, but master builds as 6.22.0-alpha.
  • Decide how the version becomes 7.0.0.
  • Draft the release notes and the upgrade guide for the docs repository, covering the upgrade order, backup and rollback, and free disk space on external hosts.

Only the embedded lifecycle retried DatabaseLoadTimeoutException. An
instance connected to an external server or container failed to start
while the server was still loading the database. Both external lifecycles
now retry until the host cancels startup, using a shared helper.
…letes

GetInstance assigned the static field before the server was reachable and before the database setup finished, while the fast path returned it without taking the semaphore. A test running in parallel could use the server too early and fail with a connection refused error in its setup.
Pin the persister behavior that a RavenDB upgrade can change without a
compile error.

Approve the client-generated definition of every primary, throughput, and
audit index, including the search engine setting that IndexDeployment
applies, so a change that would start a side-by-side rebuild shows up as a
diff. Deploy each index on its own to an empty database. Check the JSON
shape of /admin/debug/memory/stats and /license/status that both
persisters read into hand-written types. Check where the JavaScript
patches and bulk inserts set @expires, how ingestion orders and
de-duplicates attempts by AttemptedAt, and how a retry confirmation
compares times. Read throughput time series back through
LicensingDataStore. Run audit queries against Lucene and Corax databases.
Check that the embedded server writes log files into the log path.
RavenDB 7.2 is the only supported 7.x line, and RavenDB 6.2 support ends
in 2027. 7.2.7 contains the compaction, storage, and sorted-query memory
fixes that earlier 7.2 patches lack.

RavenDB 7 replaced Logs.Mode with Logs.MinLevel and rejects the old
option at startup. RavenDBLogLevel now accepts NLog level names as is and
translates the legacy mode names the way RavenDB does: None to Off,
Operations to Info, Information to Debug. The default stays Warn, which
Storage.LogLevel now reports as Warn instead of Operations.

The client-side Sparrow.Logging setup no longer exists in RavenDB 7, so
the embedded Raven.Embedded log is gone. UseOptimisticConcurrency is
obsolete; OptimisticConcurrencyMode.Writes keeps the previous behavior.
The ravendb/ravendb images exist only for Ubuntu 24.04 from 7.2.4 on.
Databases created by RavenDB 7.2.5 or later reject document IDs that
contain control characters. Throughput document IDs embed the endpoint
name, so such a name could not be stored in a new database. IDs without
control characters are unchanged, so existing documents still resolve.
SaveEnumsAsIntegers does not apply to patch scripts built from typed patches. Set SaveEnumsAsIntegersForPatching wherever SaveEnumsAsIntegers is set, so a future typed patch cannot write enums as strings.
RavenDB 7.2.7 ships the native ONNX runtime libraries and a local
embeddings model that ServiceControl does not use. The server starts and
serves Studio without them, which saves about 19 MB in RavenDBServer.zip.
The managed AI assemblies stay because Raven.Server loads them at startup.
RavenDB 7.2.0 to 7.2.4 corrupt the attachments index when an operator
compacts a database migrated from 6.2 or 7.1. 7.2.5 fixed it and repairs
the stale schema when the database loads, so refusing to start on those
patches moves operators to a server that repairs their database before a
compaction can damage it.

The check keeps RavenDB's compatibility rule, which ignores the patch:
the server's major.minor must be at least the client's. The 7.2.5 floor is
fixed, so a later client patch does not raise the server requirement.
The RavenDB 6.2 to 7.2 data upgrade is one-way, and the 6.x data
migrations must finish on RavenDB 6.2 first. Add 6.21.0 as the last
version of major 6 to the upgrade path, as 5.11.0 was added for the move
to 6. Instances on an older version are told to upgrade to 6.21.0 first.
@danielmarbach

Copy link
Copy Markdown
Contributor Author

Left it in draft since we haven't made a decision to roll this out. We first want to make tests and then decide

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