Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
# Categories are declared by the <TestCategory> property in each test project. A category can
# span several projects that share infrastructure, so that the container is provisioned once
# and the union of their build closures is compiled once.
test-category: [ DefaultCore, DefaultMonitoring, Raven, SqlServer, PostgreSql, RabbitMQ, AzureServiceBus, AzureStorageQueues, MSMQ, SQS, IBMMQ ]
test-category: [ DefaultCore, DefaultMonitoring, Migration, Raven, SqlServer, PostgreSql, RabbitMQ, AzureServiceBus, AzureStorageQueues, MSMQ, SQS, IBMMQ ]
include:
- os: windows-latest
os-name: Windows
Expand Down Expand Up @@ -87,7 +87,7 @@ jobs:
id: select
run: ./tools/select-test-projects.ps1 -Category ${{ matrix.test-category }}
- name: Download RavenDB Server
if: matrix.test-category == 'DefaultCore'
if: contains(fromJSON('["DefaultCore", "Migration"]'), matrix.test-category)
run: ./tools/download-ravendb-server.ps1
- name: Build
id: build
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ It's also possible to [locally test containers built from PRs in GitHub Containe
If the instance is executed for the first time, it must set up the required infrastructure. To do so, once the instance is configured to use the selected transport and persister, run it in setup mode. This can be done by using the `Setup {instance name}` launch profile that is defined in
the `launchSettings.json` file of each instance. When started in setup mode, the instance will start as usual, execute the setup process, and exit. At this point the instance can be run normally by using the non-setup launch profile.

## Migrating from RavenDB to SQL Server or PostgreSQL

See [Migrating from RavenDB to SQL Server or PostgreSQL](docs/migration/ravendb-to-sql-migration-instructions.md).

## Secrets

Testing using the [CI workflow](/.github/workflows/ci.yml) depends on the following secrets. The Particular values for these secrets are stored in the secure note named **ServiceControl Repo Secrets**.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions docs/migration/ravendb-to-sql-migration-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Migrating from RavenDB to SQL Server or PostgreSQL

This page covers what you can run today. How the migration works, and what is planned, is in the [migration overview](ravendb-to-sql-migration-overview.md) and the [system design diagram](migration-system-design-diagram.png).

> [!NOTE]
> Copying data is not built yet. The one migration command available is the source report. It sends RavenDB only reads, but loading a database lets RavenDB's own expiration, its automatic deletion of documents past their retention date, run against it. If you are keeping the RavenDB database as a fallback, back it up before you run the report, as [Goals](ravendb-to-sql-migration-overview.md#goals) explains.

## Before you start

The source is a ServiceControl error instance on RavenDB. Keep its RavenDB settings in its configuration: the migration reads RavenDB through them, including after `PersistenceType` is switched to SQL Server or PostgreSQL.

| Setting | Environment variable | What it is |
| --- | --- | --- |
| `ServiceControl/RavenDB/ConnectionString` | `SERVICECONTROL_RAVENDB_CONNECTIONSTRING` | An external RavenDB server. Leave unset for an embedded database |
| `ServiceControl/DbPath` | `SERVICECONTROL_DBPATH` | The embedded database's data directory |
| `ServiceControl/RavenDB/DatabaseName` | `SERVICECONTROL_RAVENDB_DATABASENAME` | The primary database, `primary` by default |
| `LicensingComponent/RavenDB/ThroughputDatabaseName` | `LICENSINGCOMPONENT_RAVENDB_THROUGHPUTDATABASENAME` | The throughput database, `throughput` by default |
| `ServiceControl/RavenDB/ClientCertificatePath` or `ServiceControl/RavenDB/ClientCertificateBase64`, with `ServiceControl/RavenDB/ClientCertificatePassword` | `SERVICECONTROL_RAVENDB_CLIENTCERTIFICATEPATH` and so on | A secured external server's client certificate |
| `ServiceControl/ErrorRetentionPeriod` | `SERVICECONTROL_ERRORRETENTIONPERIOD` | Required. Don't change it during the move |
Comment on lines +14 to +19

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So are these exclusively being used for the migration? And if so, should then be something like ServiceControl/Migration\....?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These just list the current settings for raven, which the migration engine uses to set its "Source", but yes, any new setting thats migration specific will be "ServiceControl/Migration/xxxxx"


`ServiceControl/Migration/SourcePersistenceType` defaults to `RavenDB` and needs no setting.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So given the abstractions does this technically allow two way migration? or will that be missing the migrationsource implementation?

If this defaults to the only permissible value should it even be a configuration knob?

@warwickschroeder warwickschroeder Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The abstraction is designed to allow for possible "any direction" migrations, but there will not be an implementation for SQL as the source or Raven as the target for this version.

Yep - I'll remove that setting as it is redundant at the moment. I did think about removing this..


## Report on the source

Run the instance's executable with `--migration-source-report`:

```powershell
# Installed on Windows, from the instance's installation folder
.\ServiceControl.exe --migration-source-report
```

```shell
# Container, against an external RavenDB server
docker run --rm --env-file servicecontrol.env ghcr.io/particular/servicecontrol:<version> --migration-source-report
```

From source, build `src/ServiceControl` and run the same command from its output folder, as in [How to run/debug locally](../../README.md#how-to-rundebug-locally).

The report prints the RavenDB server version, whether the source is embedded or external and where it is, both database names with the setting each came from, and a row count for every collection in both databases.

- **External server:** run it while ServiceControl is running. It sends only reads, and the note above about expiration applies to a server you are keeping as a fallback.
- **Embedded database:** stop the ServiceControl service, run the report, then start the service again. The report starts its own RavenDB process against the data directory, which cannot happen while the instance holds it.
- **Container with an embedded database:** not supported, because the container image does not ship the RavenDB server. Point the instance at an external RavenDB server instead.

## If the report fails

The error names the setting to fix:

- **"has no database named ..."**: the database name setting it quotes is wrong.
- **"refused its client certificate access ..."**: grant that certificate Read access to the database, or supply a certificate that has it.

## Not available yet

Copying the data (`MigrationMode`), the dry run, and the status and verify commands are planned but not built. The planned steps are in [Migration workflow](ravendb-to-sql-migration-overview.md#migration-workflow).
Loading