«Pro, ma non cluster» o come abbiamo effettuato il rimpiazzo delle DB

«Pro, ma non cluster» o come abbiamo effettuato il rimpiazzo delle DB
(c) Yandex.Images

Tutti i personaggi sono frutto di invenzione, i marchi appartengono ai rispettivi proprietari, ogni somiglianza è puramente casuale e, in generale, è la mia "opinione soggettiva, per favore non rompere la porta...".

Abbiamo una notevole esperienza nella traduzione di sistemi informativi con logica nei database da un DBMS a un altro. In base al decreto governativo n.1236 del 16.11.2016, si tratta spesso di un trasferimento da Oracle a Postgresql. Come organizzare il processo in modo massimo ed efficace, possiamo spiegarlo separatamente; oggi parleremo delle peculiarità dell'uso del cluster e delle problematiche che si possono incontrare nella costruzione di sistemi distribuiti ad alta capacità di carico con logica complessa nelle procedure e funzioni.

Spoiler – sì, cap, RAC e pg multimaster sono soluzioni molto diverse.

Supponiamo che tu abbia già trasferito tutta la logica da plsql a pgsql. E i tuoi test di regressione sono abbastanza soddisfacenti; ora, ovviamente, stai pensando alla scalabilità, poiché i test di carico non ti danno molta fiducia, soprattutto sull'hardware che era stato previsto nel progetto inizialmente, per quel altro DBMS. Immagina di aver trovato una soluzione da un fornitore locale, "Postgres Professional", con un'opzione chiamata "multimaster", disponibile solo nella versione "massima" "Postgres Pro Enterprise" e, dalla descrizione, sembra molto simile a ciò di cui hai bisogno, e dopo un primo esame superficiale, ti viene in mente il pensiero: "Oh! Invece di RAC, è perfetto! Inoltre con supporto tecnico in patria!".

Ma non affrettarti a gioire; di seguito descriveremo perché è necessario conoscere queste sfumature, poiché è difficile prevederle, anche leggendo attentamente la documentazione del prodotto. Valuta se sarai pronto a dover aggiornare frequentemente le versioni del DBMS direttamente in produzione, poiché alcuni difetti non sono compatibili con l'esercizio commerciale e sono difficili da rivelare nei test.
Inizia leggendo attentamente la sezione "multimaster" — "limitazioni" sul sito del produttore.

La prima cosa con cui potresti imbatterti sono le peculiarità della gestione delle transazioni in modalità "due fasi" e, a volte, non è possibile correggerle se non riscrivendo completamente la logica della tua procedura. Ecco un semplice esempio:

create table test1 (id integer, id1 integer);
insert into test1 values (1, 1),(1, 2);
 
ALTER TABLE test1 ADD CONSTRAINT test1_uk UNIQUE (id,id1) DEFERRABLE INITIALLY DEFERRED;
 
update test1
           set id1 =
               case id1
                 when 1
                 then 2
                 else id1 - sign(2 - 1)
               end
         where id1 between 1 and 2;

Si verifica un errore:

ERRORE:  [MTM] La transazione MTM-1-2435-10-605783555137701 (10654) è stata annullata nel nodo 3. Controlla il suo log per vedere i dettagli dell'errore.

Poi si può combattere a lungo con dead lock nelle versioni 10.5, 10.6 e l'unico rimedio noto, che annulla tutta l'essenza del cluster, è rimuovere le tabelle "problema" dal cluster, cioè fare make_table_local, ma almeno questo permetterà di continuare a lavorare e non bloccherà tutto a causa di attese per la conferma delle transazioni. Oppure aggiornare alla versione 11.2, che dovrebbe aiutare, o magari no; non dimenticare di verificare.

In alcune versioni potresti incontrare un blocco ancora più misterioso:

username= mtm e backend_type = background worker

In questa situazione, solo l'aggiornamento della versione del DBMS a 11.2 e oltre potrebbe aiutarti, ma potrebbe anche non aiutare.

Alcune operazioni con gli indici possono generare errori in cui viene esplicitamente indicato che il problema è proprio nella replicazione bidirezionale; nei log di MTM vedrai chiaramente BDR. È davvero 2ndQuadrant? No... abbiamo acquistato multimaster, è solo una coincidenza, è il nome della tecnologia.

[MTM] bdr doesn't support index rechecks
[MTM] 12124: REMOTE begin abort transaction 4083
[MTM] 12124: send ABORT notification for transaction  (5467) local xid=4083 to coordinator 3
[MTM] Receive ABORT_PREPARED logical message for transaction MTM-3-25030-83-605694076627780 from node 3
[MTM] Abort prepared transaction MTM-3-25030-83-605694076627780 status InProgress from node 3 originId=3
[MTM] MtmLogAbortLogicalMessage node=3 transaction=MTM-3-25030-83-605694076627780 lsn=9fff448 

Se stai utilizzando tabelle temporanee, nonostante le affermazioni: "L'estensione multimaster esegue la replicazione dei dati in modo completamente automatico. Puoi eseguire transazioni di scrittura e lavorare con tabelle temporanee su qualsiasi nodo del cluster."

Allora, di fatto, scoprirai che non funziona la replicazione su tutte le tabelle utilizzate nella procedura se nel codice è presente la creazione di una tabella temporanea, e persino l'uso di multimaster.remote_functions non aiuterà; dovrai aggiornare o riscrivere la tua logica nella procedura. Se hai bisogno di utilizzare contemporaneamente due estensioni multimaster e pg_pathman all'interno di "Postgres Pro Enterprise" v 10.5, assicurati che in questo semplice esempio:

CREA UNA TABELLA measurement (
    city_id         int not null,
    logdate         date not null,
    peaktemp        int,
    unitsales       int
) PARTIZIONATA PER INTERVALLO (logdate);

CREA TABELLA measurement_y2019m06 PARTIZIONE DI measurement PER VALORI DA ('2019-06-01') A ('2019-07-01');
inserisci nella measurement valori (1, to_date('27.06.2019', 'dd.mm.yyyy'), 1, 1);
inserisci nella measurement valori (2, to_date('28.06.2019', 'dd.mm.yyyy'), 1, 1);
inserisci nella measurement valori (3, to_date('29.06.2019', 'dd.mm.yyyy'), 1, 1);
inserisci nella measurement valori (4, to_date('30.06.2019', 'dd.mm.yyyy'), 1, 1);

Nei log dei nodi del DBMS iniziano a verificarsi errori del tipo:

…
 PATHMAN_CONFIG non contiene la relazione 23245
> find_in_dynamic_libpath: tentando "/opt/…/ent-10/lib/pg_pathman"
> find_in_dynamic_libpath: tentando "/opt//…/ent-10/lib/pg_pathman.so"
> DEBUG:  find_in_dynamic_libpath: tentando "/opt/…/ent-10/lib/pg_pathman"
> find_in_dynamic_libpath: tentando "/opt/…/ent-10/lib/pg_pathman.so"
> PrepareTransaction(1) nome: unnamed; blockState: PREPARE; stato: INPROGR, xid/subid/cid: 6919/1/40
> StartTransaction(1) nome: unnamed; blockState: DEFAULT; stato: INPROGR, xid/subid/cid: 0/1/0
> passato alla timeline 1 valida fino a 0/0
…
La transazione MTM-1-13604-7-612438856339841 (6919) è abortita sul nodo 2. Controlla il suo log per dettagli sull'errore.
...
[MTM] 28295: REMOTE inizio abortimento transazione 7017
…
[MTM] 28295: invia notifica di ABORT per transazione (6919) xid locale=7017 al coordinatore 1

Di che errori si tratta, lo potrai scoprire nel supporto tecnico, non l'hai acquistato invano.

Cosa fare? Giusto! Aggiornare a «Postgres Pro Enterprise» alla versione 11.2

È importante sapere che la sequenza, essendo un oggetto di un DB replicabile, non ha un valore continuo per l'intero cluster, ogni sequenza è locale per ogni nodo. Se hai campi con vincoli di unicità che utilizzano sequenze, puoi solo incrementare il valore equivalente al numero del nodo nel cluster, poiché più nodi hai nel cluster, più velocemente crescerà la sequenza, e il tipo int finirà più rapidamente di quanto pensassi. Per semplificare il lavoro con le sequenze, nel prodotto troverai anche la funzione alter_sequences, che eseguirà i necessari incrementi su ogni sequenza in tutti i nodi, ma preparati, poiché la funzione potrebbe non funzionare in tutte le versioni. Certamente, puoi scriverla tu stesso, prendendo come base il codice da github o modificandolo direttamente nel DBMS. Inoltre, i campi di tipo serialbigserial funzioneranno in modo più corretto, ma per il loro utilizzo probabilmente dovrai riscrivere il codice delle tue procedure e funzioni. Potrebbe essere utile la funzione monotonic_sequences.

Fino alla versione 11.2 di «Postgres Pro Enterprise», la replicazione funzionerà solo in presenza di chiavi primarie uniche, tienilo a mente durante lo sviluppo.

Un'altra nota riguarda le peculiarità del funzionamento di npgsql nelle soluzioni cluster, questi problemi non si presentano su nodi singoli, ma in un multi-master sono effettivamente presenti.
In alcune versioni potresti imbattersi nell'errore:

Dettagli dell'eccezione: Npgsql.PostgresException: 25001: comando SET TRANSACTION ISOLATION LEVEL 
Descrizione: si è verificata un'eccezione non gestita durante l'esecuzione della richiesta web corrente. Ti preghiamo di controllare lo stack trace per ulteriori informazioni sull'errore e su dove è originato nel codice. 

Cosa si può fare? Basta non utilizzare alcune versioni. È fondamentale conoscerle, poiché l'errore non si verifica in una sola versione e, anche dopo il suo primo fix, potresti incontrarlo nuovamente più tardi. È bene essere pronti e meglio coprire tutti i difetti del DBMS identificati e corretti dal produttore con test regressivi separati. Così, fidati, ma controlla.

Se l'applicazione utilizza npgsql e si sposta tra i nodi credendo che siano tutti identici, potresti ricevere l'errore:

ECCEZIONE:Npgsql.PostgresException (0x80004005): XX000: la ricerca della cache è fallita per il tipo ...

Questo errore si verificherà a causa della mappatura

(NpgsqlConnection.GlobalTypeMapper.MapComposite<SomeType>("some_composite_type");) 

dei tipi compositi all'avvio dell'applicazione per tutte le connessioni. Di conseguenza, otteniamo un identificatore da un nodo solo, e quando facciamo una richiesta a un altro nodo, non coincide, portando a un errore. Quindi, lavorare in modo trasparente con tipi compositi in un cluster sarà impossibile per alcune applicazioni senza ulteriori riscritture sul lato dell'applicazione (se riesci a farlo).

Come tutti sappiamo, una valutazione complessiva dello stato del cluster è molto importante per la diagnosi e le misure operative durante il funzionamento. Nel prodotto troverai alcune funzioni che dovrebbero semplificarti la vita, ma a volte potrebbero dare risultanze diverse da quelle che ti aspetti e anche da quelle attese dal produttore.

Ad esempio:

select mtm.collect_cluster_info();
su ogni nodo restituisce lo stesso risultato:
(1,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06")
(2,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:06")
(3,Online,0,0,0,2,3,0,0,0,1,0,0,1,1,3,7,0,0,0,"2018-10-31 05:33:09")

Ma perché nel campo LiveNodes c'è sempre il numero 2, mentre secondo la descrizione del funzionamento del multi-master dovrebbe corrispondere al numero AllNodes=3? Risposta: è necessario aggiornare la versione del DBMS.

E siate pronti a raccogliere i log da tutti i nodi, poiché di solito vedrete "l'errore si trova nel log di un altro nodo". Il supporto tecnico accetterà tutti i difetti che avete riscontrato e vi informerà quando sarà disponibile una nuova versione, che dovrete installare a volte interrompendo il servizio, altre volte richiedendo più tempo (a seconda del volume del vostro DBMS). Non aspettatevi che i problemi operativi preoccupino molto il fornitore, e che l'aggiornamento a causa dei difetti riscontrati venga effettuato con l'assistenza dei rappresentanti del fornitore; in effetti, non è necessario coinvolgere i rappresentanti del fornitore, poiché alla fine potreste trovarvi con un cluster in produzione smontato e senza backup.

In effetti, nella licenza del prodotto commerciale il produttore avverte onestamente: "Questo software è fornito sulla base del principio 'così com'è' e la società a responsabilità limitata 'Postgres Professionale' non è obbligata a fornire assistenza, supporto, aggiornamenti, estensioni o modifiche."

Se non avete ancora capito di quale prodotto si tratta, tutta questa esperienza è stata acquisita in seguito a un anno di utilizzo di Postgres Pro Enterprise. Potete trarre le vostre conclusioni, un tale livello di instabilità che i funghi crescono.

Ma sarebbe già qualcosa se si risolvessero tempestivamente e rapidamente i problemi che si presentano.

Ma proprio questo non accade. Evidentemente, le risorse del produttore non sono sufficienti per risolvere rapidamente i bug riscontrati.

Solo gli utenti registrati possono partecipare al sondaggio. Accedi, per favore.

Avete esperienza di transizione da un DBMS straniero/proprietario a uno libero/locale?

  • 21,3%Sì, positiva10

  • 10,6%Sì, negativa5

  • 21,3%No, non abbiamo cambiato DBMS10

  • 4,3%Abbiamo cambiato DBMS, ma nulla è cambiato2

  • 42,6%Guarda i risultati20

Hanno votato 47 utenti. 12 utenti si sono astenuti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS 🔥 Acquista hosting affidabile per siti web con protezione DDoS, server VPS VDS | ProHoster