Skip to content

IO-READ-001: Erro de leitura de SSTable não isola arquivo — falha contínua na mesma leitura #359

@ElioNeto

Description

@ElioNeto

🟡 Médio | Resiliência | SSTable

Problema

Se um SSTable retorna erro de I/O na leitura (setor defeituoso, corrupção), o erro propaga para o cliente como 500, mas o arquivo permanece no VersionSet. Leituras subsequentes continuam tentando ler o mesmo arquivo e falhando repetidamente.

Impacto

  • Uma única corrupção de setor causa falha em TODAS as leituras subsequentes daquela chave
  • Sem quarantine mechanism: arquivo corrompido nunca é isolado
  • Amplificação de erro: 1 setor defeituoso → milhares de requisições com 500

Evidência

src/storage/reader.rs: erro de I/O no bloco propaga via ? sem remover arquivo do rotation.

Correção recomendada

// No reader.rs, após N falhas consecutivas:
const MAX_CONSECUTIVE_READ_ERRORS: u8 = 3;

struct SstableReader {
    path: PathBuf,
    consecutive_errors: AtomicU8,
    // ...
}

fn read_block(&self, block_idx: usize) -> Result<Vec<u8>> {
    // ... tenta ler ...
    if let Err(e) = result {
        let errors = self.consecutive_errors.fetch_add(1, Ordering::Relaxed);
        if errors >= MAX_CONSECUTIVE_READ_ERRORS {
            // Isolar arquivo: mover para quarentena
            let quarantine_dir = self.path.parent().unwrap().join("quarantine");
            std::fs::create_dir_all(&quarantine_dir)?;
            let quarantined = quarantine_dir.join(self.path.file_name().unwrap());
            std::fs::rename(&self.path, &quarantined)?;

            tracing::error!(
                "SSTable {} quarantined after {} consecutive read errors",
                self.path.display(), errors + 1
            );
            // Notificar engine para remover do VersionSet
            return Err(LsmError::CorruptedData(format!(
                "SSTable quarantined after {} read errors", errors + 1
            )));
        }
    } else {
        self.consecutive_errors.store(0, Ordering::Relaxed);
    }
    result
}

Esforço: Médio (8h)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions