Migration: copy in two passes, and time the second one
Taken from the cutover page, where the reasoning is worked out: with no filesystem snapshot to take, a single copy inside the window makes every byte downtime. A first pass while the server still serves moves the bulk and is deliberately inconsistent; a delta pass after the process has exited makes it consistent and moves little, because a RocksDB store is mostly immutable SST files. That is the difference between a window proportional to the store and one proportional to the delta, which is the number this tool exists to advertise. Also carried over: hand the copy to the user the fork runs as, and make the original unwritable before the fork starts, since the old server's store lock was the only thing holding that line until it stopped.
This commit is contained in:
+17
-3
@@ -110,7 +110,19 @@ store is copied, never moved, never opened for writing.
|
|||||||
2. **Stop**: the mail server, then the webmail container. The unit is
|
2. **Stop**: the mail server, then the webmail container. The unit is
|
||||||
disabled as well as stopped, so a reboot can't put two servers on one set
|
disabled as well as stopped, so a reboot can't put two servers on one set
|
||||||
of ports with two diverging stores.
|
of ports with two diverging stores.
|
||||||
3. **Copy** the store to the fork's path.
|
3. **Copy** the store to the fork's path, in two passes where the
|
||||||
|
filesystem has no snapshot to offer (`cutover.md`): a first pass with
|
||||||
|
the server still running, deliberately inconsistent, which moves the
|
||||||
|
bulk outside the window; then, inside the window and after the process
|
||||||
|
has fully exited, a delta pass that makes the copy consistent. A RocksDB
|
||||||
|
store is mostly immutable SST files, so the delta is small and the
|
||||||
|
window is the delta, not the store. The tool times both and reports the
|
||||||
|
second as the downtime.
|
||||||
|
|
||||||
|
Then hand the copy to the user the fork runs as, and make the original
|
||||||
|
unwritable before the fork starts: until the old server stopped, its own
|
||||||
|
store lock was the only thing preventing a second process from opening
|
||||||
|
it.
|
||||||
4. **Configure**: the fork's config and unit, pointing at the copy.
|
4. **Configure**: the fork's config and unit, pointing at the copy.
|
||||||
5. **Start** the fork, and wait for it to answer.
|
5. **Start** the fork, and wait for it to answer.
|
||||||
6. **Front ends**: INBUXA Admin and the webmail, against the same store's
|
6. **Front ends**: INBUXA Admin and the webmail, against the same store's
|
||||||
@@ -119,8 +131,10 @@ store is copied, never moved, never opened for writing.
|
|||||||
8. **Report**.
|
8. **Report**.
|
||||||
|
|
||||||
**Downtime is phases 2 to 7**, and it is the number worth advertising — not
|
**Downtime is phases 2 to 7**, and it is the number worth advertising — not
|
||||||
the total, which preflight and the copy dominate and which nobody
|
the total, which preflight and the first copy pass dominate and which
|
||||||
experiences. The report gives both, per phase, and writes them as JSON
|
nobody experiences. The first pass happens with the server still serving,
|
||||||
|
which is what keeps the window proportional to the delta rather than to the
|
||||||
|
store. The report gives both, per phase, and writes them as JSON
|
||||||
beside the human-readable summary so a release note can quote them
|
beside the human-readable summary so a release note can quote them
|
||||||
honestly. A migration of a small server should be minutes; the number that
|
honestly. A migration of a small server should be minutes; the number that
|
||||||
gets published should be one this tool measured, on a stated store size and
|
gets published should be one this tool measured, on a stated store size and
|
||||||
|
|||||||
Reference in New Issue
Block a user