IO attendere causando così tanto rallentamento (EXT4 JDB2 al 99% di IO) durante il commit di Mysql


14

Sto scrivendo un indicizzatore, usando Python, che indicizza i documenti e li inserisce nel Database, Prima era un processo singolo ma ora sono passato al multiprocessore con 4 processi paralleli in esecuzione. Dopo ogni estrazione di testo, si inserisce nel database e fa un commit.

Ora sta colpendo il problema IO, il principale problema IO non è il mio processo ma il sistema di journaling jdb2 di EXT4. È al 99,99% e incassa la CPU in attesa di IO in ogni MySQL Commit.

Ho visto molti avere quel problema su Internet e la loro soluzione è montare usando barrier = 0. Disabiliterebbe totalmente il journaling? I miei server hanno UPS e sono tentato di farlo, dovrei?


Tutti i tuoi dati sono InnoDB ???
RolandoMySQLDBA

Risposte:


4

Inserire il database in un file system senza journaling. Almeno i server più grandi (oracle, sql server) hanno la loro funzione journal (registro delle transazioni) e ottimizzano il loro IO di conseguenza. Disponi di log e database su file system e dischi separati e fai affidamento sulla funzionalità interna del database per la gestione di IO errati. Normalmente non ci sono modifiche al file system (configurazione più grande) tranne la data di scrittura comunque perché i file non si espandono - verrebbero generati con la loro dimensione "finale" (ok, gli amministratori possono cambiarlo), e le modifiche sono come ho detto tracciate dal database registro delle transazioni a livello.

Potresti anche dirci qual è il tuo livello hardware. La maggior parte delle persone sottovaluta che IOPS è il fattore limitante per un database e pensa che un set di piccoli dischi sia un ambiente adeguato per un database di grandi dimensioni. Mentre alcuni di noi lavorano su database utilizzando un numero maggiore di dischi, potenzialmente supportando un numero maggiore di IOPS.


Modificherei questo per usare un filesystem non usando il journal per i dati ma solo i metadati. Ext4 può essere configurato anche in questo modo.
the-wabbit,

Sì. Alla fine il jouirnal raddoppia l'IO - e il registro del database farà di nuovo lo stesso, quindi ti ritroverai con un numero di IOPS maggiore di quello che devi. E ridondanza che sostanzialmente non è necessaria. Il sistema jouirnalling è NICE per proteggere il file .... ma inutile quando l'applicazione lo fa già, quali database fanno.
TomTom,

Quale offre le migliori prestazioni nel non journaling? Grazie!
Phyo Arkar Lwin,

4

Ci sarà sempre un compromesso tra resilienza e prestazioni.

Con MySQL su ext4 le barriere = 1 di default causano effettivamente un rallentamento, tuttavia la prima azione non dovrebbe essere quella di disabilitare il journaling o attivare data = writeback.

In primo luogo, se la resilienza è di grande importanza, vale sicuramente la pena un RAID con batteria.

Le opzioni di montaggio che ho scelto, in particolare su RAID senza batteria, sono:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

Questo non sta usando intenzionalmente data = writeback perché non voglio rischiare la corruzione del filesystem con conseguente "visualizzazione di vecchi dati nei file dopo un arresto anomalo e il ripristino del journal" (la citazione proviene da man mount).

La configurazione ideale in my.cnf per la piena resilienza attorno alle impostazioni relative agli I / O sono:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

Ho optato per la seguente sequenza di compromessi per aumentare le prestazioni:

  1. sync_binlog = 0: questa è la prima configurazione di MySQL che cambio lontano dalla piena resilienza. La ragione di ciò è che offre un significativo miglioramento delle prestazioni, soprattutto dove binlog_format=row(purtroppo richiesto per Jira). Sto usando abbastanza repliche MySQL nel cluster che se il binlog venisse danneggiato da uno scenario di perdita di potenza, farei una copia binaria da un'altra replica.
  2. innodb_flush_log_at_trx_commit = 2: Mentre è richiesto un valore 1 per la piena conformità ACID, con un valore di 2 "il buffer del registro viene scritto nel file ad ogni commit, ma l'operazione flush to disk non viene eseguita su di esso. Tuttavia, il flushing sul il file di registro ha luogo una volta al secondo anche quando il valore è 2. Notare che il flushing una volta al secondo non è garantito al 100% ogni secondo, a causa di problemi di pianificazione del processo. " (citazione dai documenti MySQL)
  3. Aggiorna le opzioni di montaggio da utilizzare data=writeback. Nota che se questo è il tuo filesystem di root dovrai anche passare un'opzione della riga di comando del kernel. Ho messo insieme alcuni passaggi su quello al coderwall .
  4. Prova vari valori di innodb_flush_method. O_DIRECT ha dimostrato di migliorare le prestazioni in alcuni carichi di lavoro, ma non è un dato di fatto che funzionerà nel tuo ambiente.
  5. L'aggiornamento a SSD, nel qual caso si potrà anche aumentare innodb_io_capacity, e regolare le impostazioni, come innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, e altre impostazioni possibili.

3

È molto probabile che il tuo back-end I / O non riesca a gestire bene il carico. Dovresti assicurarti che il tuo filesystem non contenga dati di journaling. Suggerirei di utilizzare i data=writeback,relatime,nobarrierparametri da montare per la partizione dati del database come prima ottimizzazione rapida e sporca.

Inoltre, deducendo dai sintomi, apparentemente non si utilizza la cache in scrittura con il controller. Dovresti assicurarti di utilizzare una cache di scrittura supportata da batteria o supportata da flash sul controller e abilitarla; questo dovrebbe darti un significativo aumento delle prestazioni senza aumentare notevolmente il rischio di perdita o danneggiamento dei dati. Si noti che l'utilizzo della cache di scrittura senza batteria o backup flash aumenta in modo significativo il rischio di perdita o danneggiamento dei dati , quindi farlo solo a scopo di test e / o se si può subire la perdita.


che ne dite di: data = writeback, relatime, nobarrier e quindi disabilitare totalmente la registrazione mysql? Penso che questo accelererebbe molto le cose?
Phyo Arkar Lwin,

hdpram -i mostra che sto usando la cache di scrittura. così hmm ??
Phyo Arkar Lwin,

@ V3ss0n non puoi disabilitare la registrazione per un motore transazionale - è il vero cuore di esso. È possibile scegliere di spostare il registro delle transazioni in un diverso set di dischi in quanto ha un modello di accesso totalmente diverso (principalmente scritture lineari) rispetto ai dati del database principale (lettura / scrittura casuali): si tratta di una configurazione comunemente consigliata. Per quanto riguarda la configurazione della memoria: non stai utilizzando un controller RAID, ma semplicemente singoli dischi con cache di scrittura attiva? Questo non aiuterebbe nessuna delle tue scritture sincrone in quanto arrivano con richieste esplicite di flush della cache.
the-wabbit il

È nobarrierlo stesso di barrier=0?
Nic Cottrell,

@NicCottrell sì, sono uguali.
Kouton,

3

Questa è una vecchia domanda, ma abbiamo affrontato gli stessi problemi (High IO Waits e terribili velocità di inserimento / aggiornamento) la settimana scorsa su un nuovo server dedicato e questa soluzione risolve direttamente questo problema.

La disabilitazione del journaling con è tune2fs -O "^has_journal" /dev/<drive>stata la soluzione più rapida in quanto elimina l'attesa di IO a causa del processo JDB2. Ma questo non è raccomandato a meno che non si disponga di un'unità a batteria perché si perderanno i dati in caso di crash. Le tabelle InnoDB sono sicure se è stato doublewriteabilitato in MySQL. Ma file come .frm, log, ecc. Non sono sicuri. Abbiamo provato a spostare questi file su un'altra unità (in particolare i registri bin) ma l'attesa IO jdb2 è ancora persistente. Quindi non ci ha lasciato molto a nostro agio.

data=writeback,relatime,nobarriernon ha aiutato a velocizzare le scritture / letture tanto quanto disabilitare il journaling sull'intera partizione. Altre opzioni per ext4 sono nel documento EXT4 .

Il vero colpevole nel nostro caso è stato sync_binlog. Avevamo impostato come 1in /etc/mysql/my.cnfe stava uccidendo le prestazioni.

Percona lo conferma qui . Lo impostiamo sul valore predefinito 0e le prestazioni aumentano di oltre il 500%.


0

In quale motore di database stai utilizzando per inserire questi dati?

Se è MyISAM: questo deve bloccare l'intera tabella durante una scrittura, quindi l'esecuzione di thread di inserimento simultanei ucciderà QUALUNQUE sistema, non importa quanto potente.

Assicurati di utilizzare InnoDB per queste tabelle.


Dal momento che sta eseguendo transazioni, il motore non sarebbe MyISAM poiché MyISAM non supporta le transazioni.
the-wabbit,

Arr, brainfart.
adattamento

Sto usando innodb, per impostazione predefinita mysql5.5 su innodb.
Phyo Arkar Lwin,

0

Inoltre, non direttamente correlato a mysql, ma alcuni HD hanno problemi con ext4 a causa della gestione aggressiva dell'alimentazione ... quando ciò accade, il carico della macchina aumenta senza alcuna attività apparente.

Prova a disabilitarlo. controlla prima di tutto il valore che hai (se devi ripristinarlo senza riavviare) e poi disabilitalo.

Verifica il valore corrente:

    hdparm -B /dev/sda

Disabilitalo

   hdparm -B 255 /dev/sda

(o qualunque sia il tuo HD) e prova. Probabilmente non aiuterà per la maggior parte dei problemi, ma potrebbe aiutare alcuni utenti là fuori. Il riavvio ripristinerà il valore o sostituirà manualmente il 255 per il valore precedente.

Se aiuta, controlla /etc/default/hdparmo /etc/hdparm.confper una configurazione più permanente, impostandola all'avvio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.