Skip to content

Commit 2ab39d5

Browse files
authored
Update litestream configuration (#729)
This changeset continues the `litestream` configuration updates following: 1. #719 2. #727
1 parent 43cc609 commit 2ab39d5

File tree

11 files changed

+156
-83
lines changed

11 files changed

+156
-83
lines changed

lib/bencher_json/src/system/config/plus/litestream.rs

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,36 @@ use serde::{Deserialize, Serialize};
1111
pub struct JsonLitestream {
1212
/// Disaster recovery replica
1313
pub replica: JsonReplica,
14-
/// Snapshot interval
14+
/// Snapshot configuration
1515
#[serde(skip_serializing_if = "Option::is_none")]
16-
pub snapshot_interval: Option<String>,
17-
/// Snapshot retention
16+
pub snapshot: Option<JsonSnapshot>,
17+
/// Validation configuration
1818
#[serde(skip_serializing_if = "Option::is_none")]
19-
pub retention: Option<String>,
20-
/// Validation interval
21-
#[serde(skip_serializing_if = "Option::is_none")]
22-
pub validation_interval: Option<String>,
19+
pub validation: Option<JsonValidation>,
2320
/// Checkpoint configuration
2421
#[serde(skip_serializing_if = "Option::is_none")]
2522
pub checkpoint: Option<JsonCheckpoint>,
2623
}
2724

25+
#[derive(Debug, Clone, Serialize, Deserialize)]
26+
#[cfg_attr(feature = "schema", derive(JsonSchema))]
27+
pub struct JsonSnapshot {
28+
/// How often new snapshots are created
29+
#[serde(skip_serializing_if = "Option::is_none")]
30+
pub interval: Option<String>,
31+
/// How long snapshot & WAL files are kept
32+
#[serde(skip_serializing_if = "Option::is_none")]
33+
pub retention: Option<String>,
34+
}
35+
36+
#[derive(Debug, Clone, Serialize, Deserialize)]
37+
#[cfg_attr(feature = "schema", derive(JsonSchema))]
38+
pub struct JsonValidation {
39+
/// How often to restore and validate replica data
40+
#[serde(skip_serializing_if = "Option::is_none")]
41+
pub interval: Option<String>,
42+
}
43+
2844
#[derive(Debug, Clone, Serialize, Deserialize)]
2945
#[cfg_attr(feature = "schema", derive(JsonSchema))]
3046
pub struct JsonCheckpoint {
@@ -113,7 +129,7 @@ mod db {
113129

114130
use crate::system::config::LogLevel;
115131

116-
use super::{JsonCheckpoint, JsonLitestream, JsonReplica};
132+
use super::{JsonCheckpoint, JsonLitestream, JsonReplica, JsonSnapshot, JsonValidation};
117133

118134
impl JsonLitestream {
119135
pub fn into_yaml(
@@ -123,12 +139,13 @@ mod db {
123139
) -> Result<String, serde_yaml::Error> {
124140
let Self {
125141
replica,
126-
snapshot_interval,
127-
retention,
128-
validation_interval,
142+
snapshot,
143+
validation,
129144
checkpoint,
130145
} = self;
131146
let replica = LitestreamReplica::from(replica);
147+
let snapshot = snapshot.map(LitestreamSnapshot::from);
148+
let validation = validation.map(LitestreamValidation::from);
132149
let (min_checkpoint_page_count, checkpoint_interval, truncate_page_n) = checkpoint
133150
.map_or((None, None, JsonCheckpoint::TRUNCATE_DISABLED), |c| {
134151
let JsonCheckpoint {
@@ -149,16 +166,6 @@ mod db {
149166
checkpoint_interval,
150167
truncate_page_n,
151168
}];
152-
let snapshot = match (snapshot_interval, retention) {
153-
(None, None) => None,
154-
(interval, retention) => Some(LitestreamSnapshot {
155-
interval,
156-
retention,
157-
}),
158-
};
159-
let validation = validation_interval.map(|interval| LitestreamValidation {
160-
interval: Some(interval),
161-
});
162169
let logging = Some(LitestreamLogging {
163170
level: Some(log_level.into()),
164171
});
@@ -298,6 +305,26 @@ mod db {
298305
}
299306
}
300307

308+
impl From<JsonSnapshot> for LitestreamSnapshot {
309+
fn from(snapshot: JsonSnapshot) -> Self {
310+
let JsonSnapshot {
311+
interval,
312+
retention,
313+
} = snapshot;
314+
Self {
315+
interval,
316+
retention,
317+
}
318+
}
319+
}
320+
321+
impl From<JsonValidation> for LitestreamValidation {
322+
fn from(validation: JsonValidation) -> Self {
323+
let JsonValidation { interval } = validation;
324+
Self { interval }
325+
}
326+
}
327+
301328
#[derive(Debug, Clone, Serialize)]
302329
#[serde(rename_all = "kebab-case")]
303330
pub struct LitestreamLogging {
@@ -337,9 +364,8 @@ mod db {
337364
secret_access_key: "secret_access_key".parse().unwrap(),
338365
sync_interval: None,
339366
},
340-
snapshot_interval: None,
341-
retention: None,
342-
validation_interval: None,
367+
snapshot: None,
368+
validation: None,
343369
checkpoint: None,
344370
};
345371
let path = PathBuf::from("/path/to/db");
@@ -374,9 +400,13 @@ logging:
374400
secret_access_key: "secret_access_key".parse().unwrap(),
375401
sync_interval: None,
376402
},
377-
snapshot_interval: Some("1h".to_owned()),
378-
retention: Some("24h".to_owned()),
379-
validation_interval: Some("6h".to_owned()),
403+
snapshot: Some(JsonSnapshot {
404+
interval: Some("1h".to_owned()),
405+
retention: Some("24h".to_owned()),
406+
}),
407+
validation: Some(JsonValidation {
408+
interval: Some("6h".to_owned()),
409+
}),
380410
checkpoint: None,
381411
};
382412
let path = PathBuf::from("/path/to/db");
@@ -416,9 +446,8 @@ logging:
416446
secret_access_key: "secret_access_key".parse().unwrap(),
417447
sync_interval: None,
418448
},
419-
snapshot_interval: None,
420-
retention: None,
421-
validation_interval: None,
449+
snapshot: None,
450+
validation: None,
422451
checkpoint: Some(JsonCheckpoint {
423452
interval: Some("5m".to_owned()),
424453
min_page_count: Some(2000),
@@ -454,9 +483,8 @@ logging:
454483
path: PathBuf::from("/path/to/replica"),
455484
sync_interval: Some("5s".to_owned()),
456485
},
457-
snapshot_interval: None,
458-
retention: None,
459-
validation_interval: None,
486+
snapshot: None,
487+
validation: None,
460488
checkpoint: None,
461489
};
462490
let path = PathBuf::from("/path/to/db");
@@ -489,9 +517,8 @@ logging:
489517
key_path: None,
490518
sync_interval: None,
491519
},
492-
snapshot_interval: None,
493-
retention: None,
494-
validation_interval: None,
520+
snapshot: None,
521+
validation: None,
495522
checkpoint: None,
496523
};
497524
let path = PathBuf::from("/path/to/db");

services/api/openapi.json

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11929,20 +11929,23 @@
1192911929
}
1193011930
]
1193111931
},
11932-
"retention": {
11932+
"snapshot": {
1193311933
"nullable": true,
11934-
"description": "Snapshot retention",
11935-
"type": "string"
11936-
},
11937-
"snapshot_interval": {
11938-
"nullable": true,
11939-
"description": "Snapshot interval",
11940-
"type": "string"
11934+
"description": "Snapshot configuration",
11935+
"allOf": [
11936+
{
11937+
"$ref": "#/components/schemas/JsonSnapshot"
11938+
}
11939+
]
1194111940
},
11942-
"validation_interval": {
11941+
"validation": {
1194311942
"nullable": true,
11944-
"description": "Validation interval",
11945-
"type": "string"
11943+
"description": "Validation configuration",
11944+
"allOf": [
11945+
{
11946+
"$ref": "#/components/schemas/JsonValidation"
11947+
}
11948+
]
1194611949
}
1194711950
},
1194811951
"required": [
@@ -15311,6 +15314,21 @@
1531115314
"username"
1531215315
]
1531315316
},
15317+
"JsonSnapshot": {
15318+
"type": "object",
15319+
"properties": {
15320+
"interval": {
15321+
"nullable": true,
15322+
"description": "How often new snapshots are created",
15323+
"type": "string"
15324+
},
15325+
"retention": {
15326+
"nullable": true,
15327+
"description": "How long snapshot & WAL files are kept",
15328+
"type": "string"
15329+
}
15330+
}
15331+
},
1531415332
"JsonSpec": {
1531515333
"description": "A hardware spec",
1531615334
"type": "object",
@@ -16436,6 +16454,16 @@
1643616454
"uuid"
1643716455
]
1643816456
},
16457+
"JsonValidation": {
16458+
"type": "object",
16459+
"properties": {
16460+
"interval": {
16461+
"nullable": true,
16462+
"description": "How often to restore and validate replica data",
16463+
"type": "string"
16464+
}
16465+
}
16466+
},
1643916467
"JsonVersion": {
1644016468
"type": "object",
1644116469
"properties": {

services/console/src/chunks/docs-reference/server-config/de/plus-disaster-recovery.mdx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ Es gibt drei Replikations-`scheme`s:
2424

2525
Alle drei Replikations-`scheme`s haben die folgenden zusätzlichen Optionen:
2626

27-
- `retention`: (Optional) Die Dauer, die Schnappschuss- und WAL-Dateien aufbewahrt werden. Nach dem Ablauf der Aufbewahrungsfrist wird ein neuer Schnappschuss erstellt und der alte entfernt. WAL-Dateien, die vor dem ältesten Schnappschuss existieren, werden ebenfalls entfernt. Standardwert ist `24h`.
28-
- `retention_check_interval`: (Optional) Gibt an, wie oft Bencher überprüft, ob die Aufbewahrung durchgesetzt werden muss. Standardwert ist `1h`.
29-
- `snapshot_interval`: (Optional) Gibt an, wie oft neue Schnappschüsse erstellt werden. Dies wird verwendet, um die Zeit für die Wiederherstellung zu verkürzen, da neuere Schnappschüsse weniger WAL-Frames zum Anwenden haben. Die Aufbewahrung gilt auch für diese Schnappschüsse. Wenn Sie kein Schnappschussintervall festlegen, wird ein neuer Schnappschuss erstellt, wann immer die Aufbewahrung durchgeführt wird. Die Aufbewahrung erfolgt standardmäßig alle 24 Stunden.
30-
- `validation_interval`: (Optional) Wenn angegeben, wird Bencher automatisch wiederherstellen und validieren, dass die Daten auf der Replik mit der lokalen Kopie übereinstimmen. Standardmäßig deaktiviert. Das Aktivieren kann die Kosten für den Betrieb von Bencher erheblich erhöhen, da die meisten Cloud-Services Gebühren für Downloads erheben.
27+
- `snapshot.interval`: (Optional) Gibt an, wie oft neue Schnappschüsse erstellt werden. Dies wird verwendet, um die Zeit für die Wiederherstellung zu verkürzen, da neuere Schnappschüsse weniger WAL-Frames zum Anwenden haben. Die Aufbewahrung gilt auch für diese Schnappschüsse. Wenn Sie kein Schnappschussintervall festlegen, wird ein neuer Schnappschuss erstellt, wann immer die Aufbewahrung durchgeführt wird. Die Aufbewahrung erfolgt standardmäßig alle 24 Stunden.
28+
- `snapshot.retention`: (Optional) Die Dauer, die Schnappschuss- und WAL-Dateien aufbewahrt werden. Nach dem Ablauf der Aufbewahrungsfrist wird ein neuer Schnappschuss erstellt und der alte entfernt. WAL-Dateien, die vor dem ältesten Schnappschuss existieren, werden ebenfalls entfernt. Standardwert ist `24h`.
29+
- `validation.interval`: (Optional) Wenn angegeben, wird Bencher automatisch wiederherstellen und validieren, dass die Daten auf der Replik mit der lokalen Kopie übereinstimmen. Standardmäßig deaktiviert. Das Aktivieren kann die Kosten für den Betrieb von Bencher erheblich erhöhen, da die meisten Cloud-Services Gebühren für Downloads erheben.
3130
- `sync_interval`: (Optional) Häufigkeit, mit der Frames zur Replik übertragen werden. Standardwert ist `1s`. Eine höhere Frequenz kann die Kosten für Cloud-Speicher erheblich erhöhen.
3231
- `checkpoint.interval`: (Optional) Wie häufig Litestream einen nicht-blockierenden PASSIVE-Checkpoint durchführt, unabhängig von der Seitenanzahl. Litestream überspringt den Checkpoint, wenn Leser oder Schreiber aktiv sind. Standardwert ist `1m`.
3332
- `checkpoint.min_page_count`: (Optional) Mindestanzahl an WAL-Seiten, bevor ein nicht-blockierender PASSIVE-Checkpoint ausgelöst wird (~4KB pro Seite). Litestream überspringt den Checkpoint, wenn Leser oder Schreiber aktiv sind. Standardwert ist `1000` (~4MB).
@@ -37,6 +36,9 @@ Alle drei Replikations-`scheme`s haben die folgenden zusätzlichen Optionen:
3736
| :------------------------: | :-------: | :----------: | :----------: | :-----------------------------------------------------------------------------------------: |
3837
| replica | \{ ... \} | --- | Ja | Gibt ein Replikationsobjekt an. |
3938
| replica.scheme | "s3" | --- | Ja | Gibt das Replikationsschema an. Für alle anderen `replica`-Schlüssel siehe die obige Liste. |
39+
| snapshot.interval | "1h" | --- | Nein | Wie oft neue Schnappschüsse erstellt werden. Verkürzt die Wiederherstellungszeit. |
40+
| snapshot.retention | "24h" | 24h | Nein | Wie lange Schnappschuss- und WAL-Dateien aufbewahrt werden, bevor sie ersetzt werden. |
41+
| validation.interval | "6h" | --- | Nein | Wie oft Replikdaten wiederhergestellt und gegen die lokale Kopie validiert werden. Standardmäßig deaktiviert. |
4042
| checkpoint.interval | "1m" | 1m | Nein | Wie oft ein nicht-blockierender PASSIVE-Checkpoint ausgeführt wird. Wird übersprungen, wenn Leser/Schreiber aktiv sind. |
4143
| checkpoint.min_page_count | 1000 | 1000 | Nein | Mindestanzahl WAL-Seiten (~4KB pro Seite) vor einem PASSIVE-Checkpoint. Wird übersprungen, wenn Leser/Schreiber aktiv sind. |
4244
| checkpoint.truncate_page_n | 0 | 0 | Nein | Seitenschwellenwert für einen blockierenden TRUNCATE-Checkpoint. **0 deaktiviert.** Werte ungleich Null können `database is locked`-Fehler unter Last verursachen. |

services/console/src/chunks/docs-reference/server-config/en/plus-disaster-recovery.mdx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ There are three replication `scheme`s:
2424

2525
All three replica `scheme`s have the following additional options:
2626

27-
- `retention`: (Optional) The amount of time that snapshot & WAL files will be kept. After the retention period, a new snapshot will be created and the old one will be removed. WAL files that exist before the oldest snapshot will also be removed. Defaults to `24h`.
28-
- `retention_check_interval`: (Optional) Specifies how often Bencher will check if retention needs to be enforced. Defaults to `1h`.
29-
- `snapshot_interval`: (Optional) Specifies how often new snapshots will be created. This is used to reduce the time to restore since newer snapshots will have fewer WAL frames to apply. Retention still applies to these snapshots. If you do not set a snapshot interval then a new snapshot will be created whenever retention is performed. Retention occurs every 24 hours by default.
30-
- `validation_interval`: (Optional) When specified, Bencher will automatically restore and validate that the data on the replica matches the local copy. Disabled by default. Enabling this may significantly increase the cost of running Bencher as most cloud services charge for downloads.
27+
- `snapshot.interval`: (Optional) Specifies how often new snapshots will be created. This is used to reduce the time to restore since newer snapshots will have fewer WAL frames to apply. Retention still applies to these snapshots. If you do not set a snapshot interval then a new snapshot will be created whenever retention is performed. Retention occurs every 24 hours by default.
28+
- `snapshot.retention`: (Optional) The amount of time that snapshot & WAL files will be kept. After the retention period, a new snapshot will be created and the old one will be removed. WAL files that exist before the oldest snapshot will also be removed. Defaults to `24h`.
29+
- `validation.interval`: (Optional) When specified, Bencher will automatically restore and validate that the data on the replica matches the local copy. Disabled by default. Enabling this may significantly increase the cost of running Bencher as most cloud services charge for downloads.
3130
- `sync_interval`: (Optional) Frequency in which frames are pushed to the replica. Defaults to `1s`. Increasing frequency can increase cloud storage costs significantly.
3231
- `checkpoint.interval`: (Optional) How often Litestream performs a non-blocking PASSIVE checkpoint regardless of page count. Litestream skips the checkpoint if readers or writers are active. Defaults to `1m`.
3332
- `checkpoint.min_page_count`: (Optional) Minimum number of WAL pages before a non-blocking PASSIVE checkpoint is triggered (~4KB per page). Litestream skips the checkpoint if readers or writers are active. Defaults to `1000` (~4MB).
@@ -37,6 +36,9 @@ All three replica `scheme`s have the following additional options:
3736
| :------------------------: | :-------: | :-----: | :------: | :---------------------------------------------------------------------------------: |
3837
| replica | \{ ... \} | --- | Yes | Specifies a replica object. |
3938
| replica.scheme | "s3" | --- | Yes | Specifies the replication scheme. For all other `replica` keys, see the list above. |
39+
| snapshot.interval | "1h" | --- | No | How often new snapshots are created. Reduces restore time. |
40+
| snapshot.retention | "24h" | 24h | No | How long snapshot & WAL files are kept before being replaced. |
41+
| validation.interval | "6h" | --- | No | How often replica data is restored and validated against the local copy. Disabled by default. |
4042
| checkpoint.interval | "1m" | 1m | No | How often a non-blocking PASSIVE checkpoint runs. Skipped if readers/writers are active. |
4143
| checkpoint.min_page_count | 1000 | 1000 | No | Minimum WAL pages (~4KB each) before a PASSIVE checkpoint triggers. Skipped if readers/writers are active. |
4244
| checkpoint.truncate_page_n | 0 | 0 | No | Page threshold for a blocking TRUNCATE checkpoint. **0 disables.** Non-zero values may cause `database is locked` under load. |

0 commit comments

Comments
 (0)