Skip to content

Commit cfd87ec

Browse files
authored
Avoid leaking sitrep rows during deletion (#10143)
Fixes #10131 In an attempt to avoid using transactions during the INSERT pathway (see: #10133) this PR instead tries to alter how DELETE works for sitreps. Rather than using a two-step GC process (listing orphaned sitreps and deleting them - even while concurrent INSERT operations could be underway) this PR also enables the deletion of "rows within a sitrep, for which the sitrep metadata record no longer exists". This allows us to delete rows that were previously leaked, and is also now the primary mechanism by which rows are removed: we delete the high-level sitrep first, then remove all these newly-orphaned rows. This is still performed within a transaction on the DELETE pathway to avoid reading torn sitreps during the loading phase (as originally appeared in #9594).
1 parent a32ad4b commit cfd87ec

9 files changed

Lines changed: 1153 additions & 442 deletions

File tree

dev-tools/omdb/src/bin/omdb/nexus.rs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3459,8 +3459,10 @@ fn print_task_fm_sitrep_loader(details: &serde_json::Value) {
34593459

34603460
fn print_task_fm_sitrep_gc(details: &serde_json::Value) {
34613461
let SitrepGcStatus {
3462-
orphaned_sitreps_found,
34633462
orphaned_sitreps_deleted,
3463+
sitrep_metadata_batches,
3464+
batch_size,
3465+
child_tables,
34643466
errors,
34653467
} = match serde_json::from_value::<SitrepGcStatus>(details.clone()) {
34663468
Err(error) => {
@@ -3473,23 +3475,51 @@ fn print_task_fm_sitrep_gc(details: &serde_json::Value) {
34733475
Ok(status) => status,
34743476
};
34753477

3476-
pub const ORPHANS_FOUND: &str = "orphaned sitreps found:";
3477-
pub const ORPHANS_DELETED: &str = "orphaned sitreps deleted:";
3478-
pub const ERRORS: &str = "errors:";
3479-
pub const WIDTH: usize =
3480-
const_max_len(&[ERRORS, ORPHANS_FOUND, ORPHANS_DELETED]) + 1;
3481-
pub const NUM_WIDTH: usize = 4;
3478+
const BASE_WIDTH: usize = 40;
3479+
const NUM_WIDTH: usize = 4;
3480+
3481+
// Ensure columns stay aligned even if a child table name is long.
3482+
let width = child_tables
3483+
.keys()
3484+
// We're using two spaces here to match the
3485+
// "orphaned {name} rows deleted" format string.
3486+
// Removing "{name}" leaves a space on either side.
3487+
.map(|name| "orphaned rows deleted:".len() + name.len() + 1)
3488+
.fold(BASE_WIDTH, |w, l| w.max(l));
3489+
34823490
if !errors.is_empty() {
3483-
println!("{ERRICON} {ERRORS:<WIDTH$}{:>NUM_WIDTH$}", errors.len());
3491+
println!(
3492+
"{ERRICON} {:<width$}{:>NUM_WIDTH$}",
3493+
"errors:",
3494+
errors.len()
3495+
);
34843496
for error in errors {
34853497
println!(" > {error}")
34863498
}
34873499
}
34883500

3489-
println!(" {ORPHANS_FOUND:<WIDTH$}{orphaned_sitreps_found:>NUM_WIDTH$}");
3501+
println!(" {:<width$}{batch_size:>NUM_WIDTH$}", "batch size:");
3502+
println!(
3503+
" {:<width$}{orphaned_sitreps_deleted:>NUM_WIDTH$}",
3504+
"orphaned sitreps deleted:"
3505+
);
34903506
println!(
3491-
" {ORPHANS_DELETED:<WIDTH$}{orphaned_sitreps_deleted:>NUM_WIDTH$}"
3507+
" {:<width$}{sitrep_metadata_batches:>NUM_WIDTH$}",
3508+
" batches:"
34923509
);
3510+
3511+
if child_tables.is_empty() {
3512+
eprintln!("(!) warning: no child tables reported (likely a bug)");
3513+
}
3514+
3515+
for (table_name, stats) in &child_tables {
3516+
println!(
3517+
" {:<width$}{:>NUM_WIDTH$}",
3518+
format!("orphaned {table_name} rows deleted:"),
3519+
stats.rows_deleted,
3520+
);
3521+
println!(" {:<width$}{:>NUM_WIDTH$}", " batches:", stats.batches,);
3522+
}
34933523
}
34943524

34953525
fn print_task_fm_rendezvous(details: &serde_json::Value) {

dev-tools/omdb/tests/successes.out

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,15 @@ task: "fm_sitrep_gc"
713713
configured period: every <REDACTED_DURATION>s
714714
last completed activation: <REDACTED ITERATIONS>, triggered by <TRIGGERED_BY_REDACTED>
715715
started at <REDACTED_TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
716-
orphaned sitreps found: 0
717-
orphaned sitreps deleted: 0
716+
batch size: 1000
717+
orphaned sitreps deleted: 0
718+
batches: 1
719+
orphaned fm_alert_request rows deleted: 0
720+
batches: 1
721+
orphaned fm_case rows deleted: 0
722+
batches: 1
723+
orphaned fm_ereport_in_case rows deleted: 0
724+
batches: 1
718725

719726
task: "fm_sitrep_loader"
720727
configured period: every <REDACTED_DURATION>s
@@ -1346,8 +1353,15 @@ task: "fm_sitrep_gc"
13461353
configured period: every <REDACTED_DURATION>s
13471354
last completed activation: <REDACTED ITERATIONS>, triggered by <TRIGGERED_BY_REDACTED>
13481355
started at <REDACTED_TIMESTAMP> (<REDACTED DURATION>s ago) and ran for <REDACTED DURATION>ms
1349-
orphaned sitreps found: 0
1350-
orphaned sitreps deleted: 0
1356+
batch size: 1000
1357+
orphaned sitreps deleted: 0
1358+
batches: 1
1359+
orphaned fm_alert_request rows deleted: 0
1360+
batches: 1
1361+
orphaned fm_case rows deleted: 0
1362+
batches: 1
1363+
orphaned fm_ereport_in_case rows deleted: 0
1364+
batches: 1
13511365

13521366
task: "fm_sitrep_loader"
13531367
configured period: every <REDACTED_DURATION>s

0 commit comments

Comments
 (0)