Tema
Runbook: rehash di una dimensione storicizzata
Il rehash ricalcola l'hash di riga delle versioni correnti di una dimensione caricata in modalità SCD2, senza aprire versioni.
Sintesi
- Cosa fa: riesegue la pipeline con
scd2Rehash: true; ogni sink SCD2 aggiorna solo la colonna hash della versione corrente di ogni chiave naturale in arrivo. - Owner: chi possiede la pipeline della dimensione.
- Schedulazione: on-demand, mai schedulato.
- Criticità: alta. Saltarlo, o farlo nel momento sbagliato, apre una versione per ogni riga della dimensione.
1. Quando serve
| Situazione | Il sink si ferma da solo? |
|---|---|
| Errore «versione dell'hash di riga diversa» dal sink | Sì: nessuna versione è stata aperta |
Cambio pianificato di version in hashRow | Sì, alla prima run, con l'errore qui sopra |
Una colonna tracciata aggiunta, tolta o rinominata in hashRow | No. Senza rehash la run successiva apre una versione per ogni riga |
Nel terzo caso il prefisso dell'hash non cambia, quindi il sink non può accorgersene: l'hash è opaco. Il rehash va pianificato insieme al cambio, non dopo.
2. Prima
Sospendere le run schedulate dell'intera pipeline. Una run normale partita fra il cambio e il rehash è esattamente l'incidente da evitare.
Eseguire un'ultima run normale con la configurazione vecchia, così la dimensione è allineata alla sorgente:
bashpnpm run etl run <pipeline> --params '{"referenceDate":"<YYYY-MM-DD>"}'Annotare
nodes[].versionsdel sink dal report, e la data di riferimento usata.Fare un backup della tabella della dimensione. È l'unico modo di tornare indietro se al posto del rehash parte una run normale (punto 8).
3. Cambio
- Aggiornare
hashRow:version, oppurecolumns. - Aggiornare
columnsdel sink, se è cambiato ciò che si scrive. - Se c'è una colonna nuova, aggiungerla alla tabella (
ALTER TABLE ... ADD). Nelle versioni chiuse restaNULL: va quindi dichiarata annullabile, o con un default. - Rilasciare il codice. Le run schedulate restano sospese.
4. Rehash
Subito dopo, e sulla stessa estrazione dell'ultima run normale: ogni entità cambiata nel frattempo verrebbe assorbita senza versione.
bash
pnpm run etl run <pipeline> --params '{"scd2Rehash":true}'referenceDatenon serve e non viene letta.scd2Rehashdeve essere un booleano:"true"fra virgolette è un errore, non un rehash.- Vale per tutti i sink SCD2 della pipeline: con più dimensioni vengono ricalcolate tutte. Gli altri sink caricano normalmente.
- Il sink tocca solo l'hash e l'
executionIddelle versioni correnti. Validità, chiavi e colonne di business restano come sono. - La stessa chiave naturale due volte con valori diversi è un errore, come in un carico normale: serve una
dedupa monte.
Nel report, written del sink è il numero delle versioni ricalcolate; versions è assente. In metrics e nel log sink.scd2.rehash ci sono tre contatori:
| Contatore | Significato |
|---|---|
<sink>:scd2.rehashed | Versioni correnti ricalcolate |
<sink>:scd2.rehash.unchanged | Versioni correnti che avevano già l'hash in arrivo: non riscritte. È ciò che si vede rieseguendo il rehash |
<sink>:scd2.rehash.missing | Chiavi in arrivo senza una versione corrente: non scritte. Sono entità nuove, le aprirà la prossima run normale |
5. Verifica
Nessuna versione corrente col prefisso vecchio. Dopo un cambio di
versiondav1av2:sql-- Postgres SELECT count(*) FROM dwh.dim_cliente WHERE valid_to IS NULL AND riga_hash NOT LIKE 'v2:%'; -- SQL Server SELECT COUNT(*) FROM dbo.dim_cliente WHERE valid_to IS NULL AND riga_hash NOT LIKE 'v2:%';Atteso:
0, a meno delle entità che la sorgente non manda più. Dopo un cambio di sole colonne il prefisso è lo stesso, e questa query non dice niente: vale il passo seguente.Una run normale sulla stessa data di riferimento del punto 2 riporta tutto invariato:
written: 0eversions: { opened: 0, closed: 0, corrected: 0, unchanged: N }, conNuguale al numero dei record in arrivo. Unopenedo uncorrecteddiverso da zero va capito prima di riprendere lo scheduling.
6. Dopo
Riprendere le run schedulate.
7. Cosa non fa
- Non ricalcola le versioni chiuse, che tengono l'hash vecchio. Il sink confronta solo le versioni correnti, quindi prefissi misti nella storia sono attesi.
- Non rileva i cambi avvenuti fra l'ultima run e il rehash. Dichiara «i dati di oggi corrispondono alla versione corrente»: per questo i punti 2 e 4 stanno vicini.
- Non ripara una
entityo un ordine dinaturalKeycambiati. Quelli riscrivono le chiavi di versione, e non sono un rehash. - Non apre versioni per le chiavi che non ne hanno una corrente.
8. Se va storto
| Sintomo | Azione |
|---|---|
| Il rehash fallisce a metà | È idempotente: si riesegue, e le versioni già ricalcolate risultano unchanged. Ogni load è una transazione, quindi non resta niente a metà dentro un blocco |
| «Un altro caricamento sta scrivendo su …» | Una run è ancora in corso sulla stessa tabella: aspettare che finisca, poi rieseguire |
| Una run normale è partita al posto del rehash | Ha aperto una versione per riga. Ripristinare la tabella dal backup del punto 2, poi rifare il rehash |
Dopo il rehash la verifica riporta opened diverso da zero | Le colonne di hashRow non corrispondono a quelle scritte dal sink: vedi i due avvisi nella scheda del connettore |
Escalation
- Primo livello: owner della pipeline.
- Secondo livello: team BI/ETL, con il report delle run dei punti 2, 4 e 5.

