Domanda

Ho un database che intendo replicare per motivi di backup (le prestazioni al momento non sono un problema).

Abbiamo impostato la replica correttamente e testata e tutto è andato bene.

Quindi ci siamo resi conto che replica tutte le scritture nelle tabelle temporanee, il che in effetti significava che la replica dei dati di un giorno ha impiegato quasi due ore per lo slave inattivo.

La ragione di ciò è che ricalcoliamo alcuni dei dati nel nostro db tramite cronjob ogni 15 minuti per assicurarci che siano sincronizzati (ci vogliono circa 3 minuti in totale, quindi è inaccettabile fare quelle operazioni durante una richiesta web; invece memorizziamo le modifiche senza tentare di ricalcolare nulla durante la richiesta Web, quindi eseguiamo tutto il lavoro in blocco). Per elaborare i dati in modo efficiente, utilizziamo le tabelle temporanee (poiché esistono molte interdipendenze).

Ora, il primo problema è che le tabelle temporanee non persistono se riavviamo lo slave mentre è nel mezzo dell'elaborazione delle transazioni che utilizzano quella tabella temporanea. Ciò può essere evitato non usando tabelle temporanee, sebbene ciò abbia i suoi problemi.

Il problema più serio è che lo slave potrebbe facilmente recuperare in meno di mezz'ora se non fosse per tutta quella ricalcolo (cosa che fa una dopo l'altra, quindi non c'è alcun vantaggio nel ricostruire i dati ogni 15 minuti ... e puoi letteralmente vederlo bloccato, diciamo 1115, solo per recuperare rapidamente e rimanere bloccato a 1130 ecc.)

Una soluzione che abbiamo trovato è quella di spostare tutta quella ricalcolo dal db replicato, in modo che lo slave non lo replicasse. Ma ha degli svantaggi in quanto dovremmo potare le tabelle che alla fine aggiorna, rendendo in effetti il ??nostro schiavo "castrato", cioè. dovremmo ricalcolare tutto su di esso prima di poterlo effettivamente utilizzare.

Qualcuno ha avuto un problema simile e / o come lo risolveresti? Mi sto perdendo qualcosa di ovvio?

È stato utile?

Soluzione

Ho trovato la soluzione. Fa uso di replicate-do-db menzionato da Nick. Scrivendolo qui nel caso qualcuno avesse un problema simile.

Il problema con l'utilizzo delle opzioni replicate- (wild-) do * in questo caso (come ho detto, usiamo le tabelle temporanee per ripopolare una tabella centrale) è che o ignori le tabelle temporanee e ripopoli quella centrale senza dati (che causa ulteriori problemi in quanto tutte le query che si basano sull'aggiornamento della tabella centrale produrranno risultati diversi) oppure si ignora la tabella centrale, che presenta un problema simile. Per non parlare, devi riavviare mysql dopo aver aggiunto una di queste opzioni a my.cnf. Volevamo qualcosa che coprisse tutti quei casi (e quelli futuri) senza la necessità di ulteriori riavvii.

Quindi, quello che abbiamo deciso di fare è quello di dividere il database in "reale" e una "zona di lavoro" banche dati. Solo il "reale" il database viene replicato (suppongo che potresti decidere una convenzione di nomi di tabelle da utilizzare per la sintassi replicate-wild-do-table).

Tutto il lavoro temporaneo con le tabelle sta avvenendo in " workarea " db, e per evitare il problema di dipendenza sopra menzionato, non popoleremo la tabella centrale (che si trova in "reale") da INSERT ... SELECT o RENAME TABLE, ma piuttosto interrogare le tabelle tmp per generare una sorta di un diff sulla tabella live (es. genera istruzioni INSERT per nuove righe, DELETE per quelle vecchie e aggiorna dove necessario).

In questo modo le uniche query replicate sono esattamente gli aggiornamenti richiesti, nient'altro, cioè. alcune (la maggior parte?) delle query di ricalcolo che si aprono ogni quindici minuti potrebbero non arrivare nemmeno allo schiavo, e quelle che lo faranno saranno minime e non computazionalmente costose, solo semplici INSERTI ed ELENCHI.

Altri suggerimenti

In MySQL, a partire dalla 5.0, credo, puoi fare jolly di tabella per replicare tabelle specifiche. Esistono diverse opzioni da riga di comando che è possibile impostare, ma è anche possibile farlo tramite il file di configurazione MySQL.

[mysqld]
replicate-do-db    = db1
replicate-do-table = db2.mytbl2
replicate-wild-do-table= database_name.%
replicate-wild-do-table= another_db.%

L'idea è che tu gli dica di non replicare tabelle diverse da quelle che hai specificato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top