HANDLECOLLISIONS | NOHANDLECOLLISIONS
Valido per
Replicat
Descrizione
Utilizzare i parametri HANDLECOLLISIONS e NOHANDLECOLLISIONS per controllare se Replicat tenta di risolvere errori di record duplicati e record mancanti durante l'applicazione di SQL sulla destinazione. Questi errori, denominati collisioni, si verificano durante un caricamento iniziale, quando il caricamento dei dati delle tabelle di origine viene effettuato nelle tabelle di destinazione mentre Oracle GoldenGate replica le modifiche delle transazioni in corso in tali tabelle. Quando Oracle GoldenGate applica le modifiche replicate al termine del caricamento, HANDLECOLLISIONS fornisce a Replicat una logica di gestione degli errori per queste collisioni.
È possibile utilizzare HANDLECOLLISIONS e NOHANDLECOLLISIONS nei modi riportati di seguito.
-
È possibile abilitare
HANDLECOLLISIONSeNOHANDLECOLLISIONSin modo globale specificandoli al livello radice del file dei parametri. Un parametro rimane abilitato per tutte le istruzioniMAPsuccessive nel file dei parametri fino a quando non viene rilevato il parametro opposto. -
È possibile abilitare
HANDLECOLLISIONSoNOHANDLECOLLISIONSall'interno di un parametroMAPspecifico per abilitare o disabilitare la gestione degli errori solo per il mapping origine-destinazione.
I metodi precedenti possono essere combinati. È possibile specificare una regola di gestione delle collisioni globali, quindi sostituire tale regola con regole di gestione delle collisioni diverse nelle istruzioni MAP. Una specifica MAP sostituisce sempre la specifica globale.
Nota: la gestione degli errori di Integrated Replicat non è appropriata con HANDLECOLLISIONS. Oracle consiglia di utilizzare metodi di creazione delle istanze precisi anziché utilizzare HANDLECOLLISIONS.
HowHANDLECOLLISIONSWorks
L'esempio seguente spiega il funzionamento di HANDLECOLLISIONS:
-
Quando Replicat rileva un aggiornamento a una colonna utilizzata da Oracle GoldenGate come chiave, la gestione è la seguente:
-
Se la riga con la vecchia chiave non viene trovata nella destinazione, il record di modifica nel trail viene convertito in un inserimento.
-
Se nella destinazione esiste una riga con la nuova chiave, Replicat elimina la riga con la vecchia chiave (non esisterebbe se l'aggiornamento fosse stato eseguito correttamente), quindi la riga con la nuova chiave viene aggiornata come sovrapposizione in cui i valori di trail sostituiscono i valori correnti.
Questa logica richiede che tutte le colonne della tabella (non solo quelle modificate) vengano registrate nel log delle transazioni, per impostazione predefinita o con forza, ad esempio utilizzando l'opzione
COLSdiADD TRANDATAper un database Oracle. Vedere Possibili soluzioni per evitare valori di colonna mancanti. -
-
Quando Replicat rileva un errore di record duplicati, il record statico applicato dal caricamento iniziale viene sovrascritto dal record di modifica nel trail. Sovrapporre la modifica è più sicuro dal punto di vista operativo che ignorare l'errore di record duplicati.
-
Replicat con
HANDLECOLLISIONSnon elimina il record di modifica nel trail anche se l'operazione di aggiornamento o eliminazione non ha effetto su una colonna chiave nell'origine e Replicat rileva un errore di record mancante nella destinazione. Questi errori si verificano quando un record viene modificato nel sistema di origine e quindi il record viene eliminato prima che i dati della tabella vengano estratti dal processo di caricamento iniziale. Ad esempio:
-
L'applicazione aggiorna il record A nell'origine table1.
-
Estrai l'aggiornamento.
-
L'applicazione elimina il record A nell'origine table1.
-
Estrai l'eliminazione.
-
Oracle GoldenGate estrae i dati del caricamento iniziale dall'origine table1, senza il record A.
-
Oracle GoldenGate applica il caricamento iniziale, senza il record A.
-
Replicat tenta di applicare l'aggiornamento del record A.
-
Il database restituisce un errore "record mancante".
-
Replicat tenta di applicare l'eliminazione del record A.
-
Il database restituisce un errore "record mancante".
Disabilitare HANDLECOLLISIONS dopo l'applicazione alle tabelle di destinazione delle modifiche transazionali acquisite durante il caricamento iniziale, in modo che Replicat non gestisca automaticamente gli errori successivi. Gli errori generati dopo la sincronizzazione iniziale indicano una condizione anomala e devono essere valutati da qualcuno in grado di determinare come risolverli. Ad esempio, un errore di record mancante potrebbe indicare che un record esistente nel sistema di origine è stato inavvertitamente eliminato dal sistema di destinazione.
È possibile disattivare HANDLECOLLISIONS nei modi seguenti:
-
Arrestare Replicat e rimuovere
HANDLECOLLISIONSdal file dei parametri Replicat (può causare latenza di destinazione). In alternativa, è possibile modificare il file dei parametri per aggiungereNOHANDLECOLLISIONSprima delle istruzioniMAPper le quali si desidera disabilitare la gestione degli errori. -
Mentre Replicat è in esecuzione, eseguire GGSCI e quindi utilizzare il comando
SEND REPLICATcon l'opzioneNOHANDLECOLLISIONSper le tabelle che si desidera applicare.Nota: se si utilizza
SEND REPLICAT, assicurarsi di rimuovereHANDLECOLLISIONSdal file dei parametri o di aggiungere un parametroNOHANDLECOLLISIONSprima di avviare un'altra esecuzione Replicat, in modo cheHANDLECOLLISIONSnon venga più attivato.
Possibili soluzioni per evitare valori colonna mancanti
Quando un database non registra tutti i valori di colonna di una tabella di origine per impostazione predefinita, possono verificarsi errori se la tabella di destinazione ha vincoli NOT NULL quando Replicat tenta di convertire un aggiornamento della chiave primaria in un inserimento. È possibile risolvere questo scenario nei modi seguenti:
-
HANDLECOLLISIONSrichiede che la tabella contenga una chiave primaria NOTNULLo un vincolo univoco NOTNULLnella tabella di destinazione. -
Utilizzare il parametro
NOCOMPRESSUPDATESnel file dei parametri Extract per inviare tutte le colonne della tabella al trail e configurare il database per registrare tutti i valori di colonna. Per impostazione predefinita, Extract scrive solo la chiave primaria e le colonne modificate nel trail. Questo è il metodo più sicuro, perché scrive i valori correnti al momento dell'esecuzione dell'operazione ed elimina la necessità di recuperare. -
Utilizzare il parametro
FETCHOPTIONScon l'opzioneFETCHPKUPDATECOLSnel file dei parametri Extract. Questa configurazione induce Extract a recuperare le colonne non disponibili quando una colonna chiave viene aggiornata nell'origine. Un fetch è il valore corrente, non necessariamente il valore al momento di un determinato aggiornamento, quindi possono verificarsi problemi di integrità dei dati. Vedere"[FETCHOPTIONS](fetchoptions.html#GUID-DB7BCF87-E3E8-48CF-868A-A56F6D0B6A07)"per ulteriori informazioni e opzioni di recupero aggiuntive per gestire i recuperi non riusciti.
Se il database include tutte le colonne per impostazione predefinita, è necessario utilizzare NOCOMPRESSUPDATES e NOCOMPRESSDELETES per il corretto funzionamento di HANDLECOLLISIONS. Se il database non supporta NOCOMPRESSDELETES, è necessario utilizzare FETCHOPTIONS MISSINGCOLS.
Per ulteriori informazioni sui metodi di caricamento iniziale di Oracle GoldenGate, vedere Informazioni sulla creazione di istanze con Initial Load Extract.
Predefinito
NOHANDLECOLLISIONS
Sintassi
HANDLECOLLISIONS | NOHANDLECOLLISIONS [_ALLOWPKMISSINGROWCOLLISIONS]
[THREADS (<threadID>[, <threadID>][, ...][, <thread_range>[, <thread_range>][, ...])]
HANDLECOLLISIONS
Abilita la gestione delle collisioni.
_ALLOWPKMISSINGROWCOLLISIONI
Utilizzare HANDLECOLLISIONS con _ALLOWPKMISSINGROWCOLLISIONS per saltare le operazioni UPDATE con chiave primaria se la riga di destinazione corrispondente non esiste.
Nota: le operazioni saltate possono causare il danneggiamento dei dati. Vedere la descrizione in questo argomento.
NOHANDLECOLLISIONS
Disattiva la gestione delle collisioni.
THREADS (<threadID>[, <threadID>][, ...][, <thread_range>[, <thread_range>][, ...])
Abilita HANDLECOLLISIONS per i thread specificati. Se utilizzato in un'istruzione HANDLECOLLISIONS globale a livello radice del file dei parametri, HANDLECOLLISIONS viene abilitato per i thread specificati ovunque si trovino in tutte le istruzioni MAP in cui . Quando viene utilizzato in una clausola HANDLECOLLISIONS di un'istruzione MAP, HANDLECOLLISIONS viene abilitato solo per tale istruzione MAP.
threadID[, threadID][, …]
Specifica un thread ID o una lista separata da virgole di thread nel formato threadID, threadID, threadID.
thread_range[, thread_range][, …]
Specifica un intervallo di thread in formato threadIDlow-threadIDhigh o una lista di intervalli separata da virgole nel formatothreadIDlow-threadIDhigh, threadIDlow-threadIDhigh.
La combinazione di questi formati, ad esempio threadID, threadID, threadIDlow-threadIDhigh, è consentita.
Esempi
Esempio 1
Questo esempio abilita HANDLECOLLISIONS per tutte le istruzioni MAP nel file dei parametri.
HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;
Esempio 2
Questo esempio abilita HANDLECOLLISIONS per alcune istruzioni MAP e le disabilita per altre.
HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
NOHANDLECOLLISIONS
MAP hr.dep, TARGET hr.dep;
MAP hr.country, TARGET hr.country;
Esempio 3
Questo esempio mostra l'uso di base di HANDLECOLLISIONS all'interno di un'istruzione MAP.
MAP dbo.tcust, TARGET dbo.tcust, HANDLECOLLISIONS;
Esempio 4
Questo esempio mostra una combinazione di uso globale e a livello di MAP. La specifica MAP sostituisce la specifica globale per le tabelle specificate.
HANDLECOLLISIONS
MAP hr.emp, TARGET hr.emp;
MAP hr.job_hist, TARGET hr.job_hist;
MAP hr.dep, TARGET hr.dep, NOHANDLECOLLISIONS;
MAP hr.country, TARGET hr.country, NOHANDLECOLLISIONS;
Esempio 5
Nell'esempio seguente, HANDLECOLLISIONS è abilitato a livello globale per tutte le istruzioni MAP, ad eccezione del thread predefinito 0 nella prima istruzione MAP e del thread 3 nella seconda istruzione MAP.
HANDLECOLLISIONS
MAP fin.*, TARGET fin.*;
MAP sales.*, TARGET sales.*;
MAP orders.*, TARGET orders.*;
MAP scott.cust, TARGET scott.cust, NOHANDLECOLLISIONS;
MAP amy.cust, TARGET amy.cust, THREAD(3), NOHANDLECOLLISIONS;
Esempio 6
In questo esempio, HANDLECOLLISIONS è abilitato a livello globale, ma disattivato per il thread 3. I restanti thread 1, 2 e 4 gestiranno le collisioni.
HANDLECOLLISIONS
NOHANDLECOLLISIONS THREAD(3)
MAP scott.emplyees, TARGET scott.employees, THREADRANGE(1,4, OID);
MAP scott.inventory, TARGET scott.inventory, THREADRANGE(1,4, OID);
MAP scott.cust, TARGET scott.cust, THREADRANGE(1,4, OID);
Esempio 7
In questo esempio, HANDLECOLLISIONS viene abilitato a livello globale, quindi disabilitato a livello globale per i thread da 5 a 7. Nella prima istruzione map, tutti i thread gestiranno le collisioni, poiché il parametro HANDLECOLLISIONS non specifica un thread o un intervallo. Nella seconda istruzione mappa, solo i thread 4, 8 e 9 gestiranno le collisioni, poiché NOHANDLECOLLISIONS globale si applica ai thread da 5 a 7.
HANDLECOLLISIONS
NOHANDLECOLLISIONS THREADRANGE(5-7)
MAP scott.cust, TARGET scott.cust, THREADRANGE(4,9,OID), HANDLECOLLISIONS;
MAP scott.offices, TARGET scott.offices, THREADRANGE(4,9,OID);
MAP scott.emp, TARGET scott.emp, THREADRANGE(4,9,OID);
MAP scott.ord, TARGET scott.ord, THREADRANGE(4,9,OID);
MAP acct.*, TARGET acct.*;
MAP admin.*, TARGET admin.*;