(table: &Table)
| 417 | } |
| 418 | |
| 419 | async fn optimize_compaction_with_fallback(table: &Table) -> Result<OptimizePath, String> { |
| 420 | let options = maintenance_compaction_options(table).await?; |
| 421 | match table |
| 422 | .optimize(OptimizeAction::Compact { |
| 423 | options: options.clone(), |
| 424 | remap_options: None, |
| 425 | }) |
| 426 | .await |
| 427 | { |
| 428 | Ok(_) => Ok(OptimizePath::Maintenance), |
| 429 | Err(err) => { |
| 430 | if !is_offset_overflow_error(&err) { |
| 431 | return Err(format!("compact failed: {err:#}")); |
| 432 | } |
| 433 | |
| 434 | let options = CompactionOptions { |
| 435 | num_threads: Some(MAINTENANCE_COMPACTION_THREADS), |
| 436 | batch_size: Some(SAFE_COMPACTION_BATCH_SIZE), |
| 437 | max_rows_per_group: SAFE_COMPACTION_MAX_ROWS_PER_GROUP, |
| 438 | max_bytes_per_file: Some(SAFE_COMPACTION_MAX_BYTES_PER_FILE), |
| 439 | defer_index_remap: options.defer_index_remap, |
| 440 | ..CompactionOptions::default() |
| 441 | }; |
| 442 | |
| 443 | if let Err(fallback_err) = table |
| 444 | .optimize(OptimizeAction::Compact { |
| 445 | options, |
| 446 | remap_options: None, |
| 447 | }) |
| 448 | .await |
| 449 | { |
| 450 | return Err(format!( |
| 451 | "compact failed: {err:#}; safe compact fallback failed: {fallback_err:#}" |
| 452 | )); |
| 453 | } |
| 454 | |
| 455 | Ok(OptimizePath::SafeFallback) |
| 456 | }, |
| 457 | } |
| 458 | } |
| 459 | |
| 460 | fn is_offset_overflow_error(err: &dyn std::error::Error) -> bool { |
| 461 | err.to_string().contains("Offset overflow error") |
no test coverage detected