Stallo dell'istanza MySQL "facendo indice SYNC"


12

Problema

Un'istanza di MySQL 5.6.20 che esegue (principalmente solo) un database con tabelle InnoDB mostra bancarelle occasionali per tutte le operazioni di aggiornamento per la durata di 1-4 minuti con tutte le query INSERT, UPDATE e DELETE che rimangono nello stato "Fine query". Questo ovviamente è molto sfortunato. Il log delle query lente di MySQL registra anche le query più banali con tempi di query folli, centinaia di loro con lo stesso timestamp corrispondente al punto nel tempo in cui lo stallo è stato risolto:

# Query_time: 101.743589  Lock_time: 0.000437 Rows_sent: 0  Rows_examined: 0
SET timestamp=1409573952;
INSERT INTO sessions (redirect_login2, data, hostname, fk_users_primary, fk_users, id_sessions, timestamp) VALUES (NULL, NULL, '192.168.10.151', NULL, 'anonymous', '64ef367018099de4d4183ffa3bc0848a', '1409573850');

E le statistiche del dispositivo stanno mostrando un aumento, anche se non un carico I / O eccessivo in questo intervallo di tempo (in questo caso gli aggiornamenti erano in stallo 14:17:30 - 14:19:12 secondo i timestamp della dichiarazione sopra):

# sar -d
[...]
02:15:01 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
02:16:01 PM    dev8-0     41.53    207.43   1227.51     34.55      0.34      8.28      3.89     16.15
02:17:01 PM    dev8-0     59.41    137.71   2240.32     40.02      0.39      6.53      4.04     24.00
02:18:01 PM    dev8-0    122.08   2816.99   1633.44     36.45      3.84     31.46      1.21      2.88
02:19:01 PM    dev8-0    253.29   5559.84   3888.03     37.30      6.61     26.08      1.85      6.73
02:20:01 PM    dev8-0    101.74   1391.92   2786.41     41.07      1.69     16.57      3.55     36.17
[...]
# sar
[...]
02:15:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
02:16:01 PM     all     15.99      0.00     12.49      2.08      0.00     69.44
02:17:01 PM     all     13.67      0.00      9.45      3.15      0.00     73.73
02:18:01 PM     all     10.64      0.00      6.26     11.65      0.00     71.45
02:19:01 PM     all      3.83      0.00      2.42     24.84      0.00     68.91
02:20:01 PM     all     20.95      0.00     15.14      6.83      0.00     57.07

Più spesso, noto nel registro lento mysql che lo stallo della query più vecchio è un INSERT in una tabella di grandi dimensioni (~ 10 M righe) con una chiave primaria VARCHAR e un indice di ricerca full-text:

CREATE TABLE `files` (
  `id_files` varchar(32) NOT NULL DEFAULT '',
  `filename` varchar(100) NOT NULL DEFAULT '',
  `content` text,
  PRIMARY KEY (`id_files`),
  KEY `filename` (`filename`),
  FULLTEXT KEY `content` (`content`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Ulteriori ricerche (es. SHOW ENGINE INNODB STATUS) hanno dimostrato che si tratta sempre di un aggiornamento di una tabella che utilizza indici full-text che causano lo stallo. La rispettiva sezione TRANSAZIONI di "SHOW ENGINE INNODB STATUS" contiene voci come queste due per le transazioni in esecuzione più vecchie:

---TRANSACTION 162269409, ACTIVE 122 sec doing SYNC index
6 lock struct(s), heap size 1184, 0 row lock(s), undo log entries 19942
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_1" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_2" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_3" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_4" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_5" trx id 162269409 lock mode IX
TABLE LOCK table "vw"."FTS_000000000000224a_00000000000036b9_INDEX_6" trx id 162269409 lock mode IX
---TRANSACTION 162269408, ACTIVE (PREPARED) 122 sec committing
mysql tables in use 1, locked 1
1 lock struct(s), heap size 360, 0 row lock(s), undo log entries 1
MySQL thread id 165998, OS thread handle 0x7fe0e239c700, query id 91208956 192.168.10.153 root query end
INSERT INTO files (id_files, filename, content) VALUES ('f19e63340fad44841580c0371bc51434', '1237716_File_70380a686effd6b66592bb5eeb3d9b06.doc', '[...]
TABLE LOCK table `vw`.`files` trx id 162269408 lock mode IX

Quindi c'è qualche pesante azione sull'indice full-text in corso lì ( doing SYNC index) che ferma TUTTI gli aggiornamenti SUCCESSIVI a QUALSIASI tabella.

Dai registri sembra un po 'come se il undo log entriesnumero doing SYNC indexavanzi a ~ 150 / s fino a raggiungere i 20.000, a quel punto l'operazione viene eseguita.

La dimensione FTS di questa tabella specifica è piuttosto impressionante:

# du -c FTS_000000000000224a_00000000000036b9_*
614404  FTS_000000000000224a_00000000000036b9_INDEX_1.ibd
2478084 FTS_000000000000224a_00000000000036b9_INDEX_2.ibd
1576964 FTS_000000000000224a_00000000000036b9_INDEX_3.ibd
1630212 FTS_000000000000224a_00000000000036b9_INDEX_4.ibd
1978372 FTS_000000000000224a_00000000000036b9_INDEX_5.ibd
1159172 FTS_000000000000224a_00000000000036b9_INDEX_6.ibd
9437208 total

sebbene il problema sia anche innescato da tabelle con dimensioni di dati FTS significativamente meno massicce come questa:

# du -c FTS_0000000000002467_0000000000003a21_INDEX*
49156   FTS_0000000000002467_0000000000003a21_INDEX_1.ibd
225284  FTS_0000000000002467_0000000000003a21_INDEX_2.ibd
147460  FTS_0000000000002467_0000000000003a21_INDEX_3.ibd
135172  FTS_0000000000002467_0000000000003a21_INDEX_4.ibd
155652  FTS_0000000000002467_0000000000003a21_INDEX_5.ibd
106500  FTS_0000000000002467_0000000000003a21_INDEX_6.ibd
819224  total

Anche in questi casi il tempo della stalla è più o meno lo stesso. Ho aperto un bug su bugs.mysql.com in modo che gli sviluppatori possano esaminarlo.

La natura delle bancarelle mi ha inizialmente fatto sospettare che l'attività di lavaggio del registro sia il colpevole e questo articolo di Percona su problemi di prestazioni di lavaggio del registro con MySQL 5.5 descrive sintomi molto simili, ma ulteriori occorrenze hanno dimostrato che le operazioni INSERT nella singola tabella MyISAM in questo database sono interessati anche dallo stallo, quindi questo non sembra un problema solo di InnoDB.

Tuttavia, ho deciso di tenere traccia dei valori di Log sequence numbere Pages flushed up todalla sezione "LOG" delle uscite SHOW ENGINE INNODB STATUSogni 10 secondi. Sembra infatti che durante lo stallo sia in corso l'attività di lavaggio mentre la diffusione tra i due valori sta diminuendo:

Mon Sep 1 14:17:08 CEST 2014 LSN: 263992263703, Pages flushed: 263973405075, Difference: 18416 K
Mon Sep 1 14:17:19 CEST 2014 LSN: 263992826715, Pages flushed: 263973811282, Difference: 18569 K
Mon Sep 1 14:17:29 CEST 2014 LSN: 263993160647, Pages flushed: 263974544320, Difference: 18180 K
Mon Sep 1 14:17:39 CEST 2014 LSN: 263993539171, Pages flushed: 263974784191, Difference: 18315 K
Mon Sep 1 14:17:49 CEST 2014 LSN: 263993785507, Pages flushed: 263975990474, Difference: 17377 K
Mon Sep 1 14:17:59 CEST 2014 LSN: 263994298172, Pages flushed: 263976855227, Difference: 17034 K
Mon Sep 1 14:18:09 CEST 2014 LSN: 263994670794, Pages flushed: 263978062309, Difference: 16219 K
Mon Sep 1 14:18:19 CEST 2014 LSN: 263995014722, Pages flushed: 263983319652, Difference: 11420 K
Mon Sep 1 14:18:30 CEST 2014 LSN: 263995404674, Pages flushed: 263986138726, Difference: 9048 K
Mon Sep 1 14:18:40 CEST 2014 LSN: 263995718244, Pages flushed: 263988558036, Difference: 6992 K
Mon Sep 1 14:18:50 CEST 2014 LSN: 263996129424, Pages flushed: 263988808179, Difference: 7149 K
Mon Sep 1 14:19:00 CEST 2014 LSN: 263996517064, Pages flushed: 263992009344, Difference: 4402 K
Mon Sep 1 14:19:11 CEST 2014 LSN: 263996979188, Pages flushed: 263993364509, Difference: 3529 K
Mon Sep 1 14:19:21 CEST 2014 LSN: 263998880477, Pages flushed: 263993558842, Difference: 5196 K
Mon Sep 1 14:19:31 CEST 2014 LSN: 264001013381, Pages flushed: 263993568285, Difference: 7270 K
Mon Sep 1 14:19:41 CEST 2014 LSN: 264001933489, Pages flushed: 263993578961, Difference: 8158 K
Mon Sep 1 14:19:51 CEST 2014 LSN: 264004225438, Pages flushed: 263993585459, Difference: 10390 K

E alle 14:19:11 la diffusione ha raggiunto il suo minimo, quindi l'attività di irrigazione sembra essere cessata qui, proprio in coincidenza con la fine della bancarella. Ma questi punti mi hanno fatto respingere il flush del log di InnoDB come causa:

  • affinché l'operazione di scaricamento blocchi tutti gli aggiornamenti del database, deve essere "sincrono", il che significa che è necessario occupare 7/8 dello spazio del registro
  • sarebbe preceduto da una fase di lavaggio "asincrona" a partire dal innodb_max_dirty_pages_pctlivello di riempimento - che non vedo
  • gli LSN continuano ad aumentare anche durante lo stallo, quindi l'attività di registro non si interrompe completamente
  • Anche gli INSERT della tabella MyISAM sono interessati
  • il thread page_cleaner per il flushing adattivo sembra fare il suo lavoro e svuotare i log senza causare l'interruzione delle query DML:

LSN - PagesFlushed

(i numeri provengono ([Log Sequence Number] - [Pages flushed up to]) / 1024da SHOW ENGINE INNODB STATUS)

Il problema sembra in qualche modo alleviato dall'impostazione innodb_adaptive_flushing_lwm=1, costringendo il pulitore della pagina a fare più lavoro di prima.

Non error.logci sono voci che coincidono con le bancarelle. SHOW INNODB STATUSgli estratti dopo circa 24 ore di funzionamento si presentano così:

SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 789330
OS WAIT ARRAY INFO: signal count 1424848
Mutex spin waits 269678, rounds 3114657, OS waits 65965
RW-shared spins 941620, rounds 20437223, OS waits 442474
RW-excl spins 451007, rounds 13254440, OS waits 215151
Spin rounds per wait: 11.55 mutex, 21.70 RW-shared, 29.39 RW-excl
------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-09-03 10:33:55 7fe0e2e44700
[...]
--------
FILE I/O
--------
[...]
932635 OS file reads, 2117126 OS file writes, 1193633 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 17.00 writes/s, 1.20 fsyncs/s
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
0 read views open inside InnoDB
Main thread process no. 54745, id 140604272338688, state: sleeping
Number of rows inserted 528904, updated 1596758, deleted 99860, read 3325217158
5.40 inserts/s, 10.40 updates/s, 0.00 deletes/s, 122969.21 reads/s

Quindi, sì, il database ha deadlock, ma sono molto rari (l'ultimo è stato gestito circa 11 ore prima della lettura delle statistiche).

Ho provato a tracciare i valori della sezione "SEMAPHORES" per un periodo di tempo, specialmente in una situazione di normale funzionamento e durante uno stallo (ho scritto un piccolo script che controllava l'elenco dei processi del server MySQL ed eseguiva un paio di comandi diagnostici in un output del registro nel caso in cui di una stalla ovvia). Dato che i numeri sono stati rilevati in diversi intervalli di tempo, ho normalizzato i risultati in eventi / secondo:

                          normal   stall
                          1h avg  1m avg
OS WAIT ARRAY INFO: 
    reservation count      5,74    1,00
    signal count          24,43    3,17
Mutex spin waits           1,32    5,67
    rounds                 8,33   25,85
    OS waits               0,16    0,43
RW-shared spins            9,52    0,76
    rounds               140,73    13,39
    OS waits               2,60    0,27
RW-excl spins              6,36    1,08
    rounds               178,42   16,51
    OS waits               2,38    0,20

Non sono del tutto sicuro di quello che vedo qui. La maggior parte dei numeri è diminuita di un ordine di grandezza - probabilmente a causa di cessate operazioni di aggiornamento, "Mutex spin wait" e "Mutex spin rounds" sono entrambi aumentati del fattore 4.

Analizzando ulteriormente questo, l'elenco dei mutex ( SHOW ENGINE INNODB MUTEX) ha ~ 480 voci mutex elencate sia durante il normale funzionamento che durante uno stallo. Ho abilitato innodb_status_output_locksa vedere se mi darà maggiori dettagli.

Variabili di configurazione

(Ho armeggiato con la maggior parte di loro senza un successo definito):

mysql> show global variables where variable_name like 'innodb_adaptive_flush%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| innodb_adaptive_flushing     | ON    |
| innodb_adaptive_flushing_lwm | 1     |
+------------------------------+-------+
mysql> show global variables where variable_name like 'innodb_max_dirty_pages_pct%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_max_dirty_pages_pct     | 50    |
| innodb_max_dirty_pages_pct_lwm | 10    |
+--------------------------------+-------+
mysql> show global variables where variable_name like 'innodb_log_%';
+-----------------------------+-----------+
| Variable_name               | Value     |
+-----------------------------+-----------+
| innodb_log_buffer_size      | 8388608   |
| innodb_log_compressed_pages | ON        |
| innodb_log_file_size        | 268435456 |
| innodb_log_files_in_group   | 2         |
| innodb_log_group_home_dir   | ./        |
+-----------------------------+-----------+
mysql> show global variables where variable_name like 'innodb_double%';
+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| innodb_doublewrite | ON    |
+--------------------+-------+
mysql> show global variables where variable_name like 'innodb_buffer_pool%';
+-------------------------------------+----------------+
| Variable_name                       | Value          |
+-------------------------------------+----------------+
| innodb_buffer_pool_dump_at_shutdown | OFF            |
| innodb_buffer_pool_dump_now         | OFF            |
| innodb_buffer_pool_filename         | ib_buffer_pool |
| innodb_buffer_pool_instances        | 8              |
| innodb_buffer_pool_load_abort       | OFF            |
| innodb_buffer_pool_load_at_startup  | OFF            |
| innodb_buffer_pool_load_now         | OFF            |
| innodb_buffer_pool_size             | 29360128000    |
+-------------------------------------+----------------+
mysql> show global variables where variable_name like 'innodb_io_capacity%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| innodb_io_capacity     | 200   |
| innodb_io_capacity_max | 2000  |
+------------------------+-------+
mysql> show global variables where variable_name like 'innodb_lru_scan_depth%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_lru_scan_depth | 1024  |
+-----------------------+-------+

Le cose hanno già provato

  • disabilitando la cache delle query di SET GLOBAL query_cache_size=0
  • aumentando innodb_log_buffer_sizea 128M
  • giocare con innodb_adaptive_flushing, innodb_max_dirty_pages_pcte le rispettive _lwmvalori (che sono stati fissati per default prima del mio modifiche)
  • crescente innodb_io_capacity(2000) e innodb_io_capacity_max(4000)
  • ambientazione innodb_flush_log_at_trx_commit = 2
  • in esecuzione con innodb_flush_method = O_DIRECT (sì, usiamo una SAN con una cache di scrittura persistente)
  • impostando / sys / block / sda / queue / scheduler su noopodeadline

Quali sono i valori di innodb_io_capacity, innodb_io_capacity_max e innodb_lru_scan_depth? L'impostazione su valori più alti (più appropriati) consente di mantenere libero lo spazio del registro.
Morgan Tocker,

valori predefiniti: 200, 2000 e 1024. Ora li ho cambiati in 2000, 4000 e 2000 e la diffusione tra i valori LSN e Pages Flushed è nuovamente diminuita a <1.000 K. Ma non sono sicuro che si tratti di un log spazio in primo luogo.
syneticon-dj,

In effetti sembra non esserlo. Vedo ancora bancarelle: non sono cambiate molto in termini di durata o frequenza di eventi. Il mio registro LSN / checkpoint sta mostrando numeri di spread assoluti significativamente più bassi che stanno aumentando in qualche modo durante lo stallo a circa 3 M in 1-2 minuti (probabilmente le transazioni non finite con conseguente utilizzo del log non infiammabile) e il successivo flushing riuscito a spread quasi zero tra LSN e checkpoint a partire dal momento in cui lo stallo è stato risolto.
syneticon-dj,

Non sono sicuro che dovresti avere innodb_adaptive_flushing_lwm impostato su 1: è una percentuale di spazio di log, in cui entra in funzione il flushing adattivo (default: 10).
Morgan Tocker,

@MorganTocker Ho impostato questo per assicurarsi che il flushing adattivo svuotasse qualsiasi cosa per la maggior parte del tempo poiché sospettavo che l'utilizzo dello spazio di log fosse parte del problema. Il problema si è verificato anche con il valore predefinito 10, l'ho modificato a scopo di risoluzione dei problemi.
syneticon-dj,

Risposte:


6

Stavamo riscontrando lo stesso problema su due server nelle versioni 5.6.12 e 5.6.16 in esecuzione su Windows, con una coppia di slave ciascuno. Siamo rimasti perplessi, come te, per quasi due mesi.

Soluzione :

set global binlog_order_commits = 0;

Vedi https://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html#sysvar_binlog_order_commits per i dettagli della variabile.

Spiegazione :

InnoDB full-text utilizza una cache (per impostazione predefinita 8M di dimensioni) contenente le modifiche che devono essere applicate all'indice full-text effettivo sul disco.

Una volta che la cache si riempie, vengono create un paio di transazioni per eseguire il lavoro di unione dei dati contenuti nella cache - questo tende ad essere una grande quantità di IO casuali, quindi a meno che l'intero indice full-text non possa essere caricato in il pool di buffer, è una transazione lunga e lenta.

Con binlog_order_commits impostato su true, tutte le transazioni contenenti inserimenti e aggiornamenti, avviate dopo la transazione fts_sync_index di lunga durata, devono attendere il completamento prima di poter eseguire il commit.

Questo è solo un problema se la registrazione binaria è abilitata


Sembra proprio che potrebbe essere la risoluzione del problema che stavo vedendo. Come ti è venuta questa soluzione? Inoltre, nel mio caso l'indice di testo completo si sarebbe adattato al pool di buffer (che ha una dimensione di ~ 30 G) ma l'operazione sembrava essere fortemente legata alla latenza. Ho l'impressione che lo stack I / O di MySQL sia estremamente inefficiente quando si ha a che fare con la latenza di archiviazione , quindi questo problema probabilmente è una combinazione di entrambi: l'inefficienza e un difetto di default per le configurazioni di registrazione binaria.
syneticon-dj,

Mi chiedo come possa passare inosservato per così tanto tempo. Sicuramente, ci sono più persone che eseguono InnoDB con FTS e binlog abilitati su storage non SSD?
syneticon-dj,

Fortuna. Ero arrivato allo stesso punto di te, dove ero riuscito a catturare lo "stato di innodb del motore di show" durante i blocchi. Ho scritto un piccolo programma che inserisce molte righe in una tabella con un indice FTS e un altro che aggiorna una seconda tabella e registra i tempi di aggiornamento. Non sono stato in grado di ottenere le pause di flush della cache FTS per bloccare gli aggiornamenti per un po ', fino a quando non ho esaminato le differenze nell'installazione, una per una, tra la mia macchina locale e i server live. L'attivazione del binlog ha ricreato il problema, quindi ho appena letto le opzioni del binlog.
Daniel Golding,

1
Vale la pena notare che il team di sviluppo di MySQL finalmente (dopo 15 mesi in coda!) Ha impostato lo stato del bug segnalato su "verificato" e almeno qualcuno del team di sviluppo sembra pensare a soluzioni. Inutile dire che ho finito con MySQL. Per sempre, spero.
syneticon-dj,

4

Vorrei forse provare a descrivere il problema storico con lo scarico dei log e come funziona lo scarico adattivo:

  • I registri di ripetizione sono un progetto di buffer ad anello . Vengono sempre e solo scritti (mai letti durante il normale funzionamento) e forniscono il ripristino di emergenza. Mi piace descrivere un ring buffer simile al battistrada di un serbatoio.

  • InnoDB non sarà in grado di sovrascrivere lo spazio del file di registro se contiene modifiche che non sono state ancora modificate sul disco. Quindi, storicamente, ciò che accadrebbe è che InnoDB tenterebbe una certa quantità di lavoro al secondo (configurato da innodb_io_capacity) e se ciò non bastasse, si raggiungerebbe lo spazio di log completo. Si verificherebbe uno stallo in quanto il risciacquo sincrono doveva verificarsi per liberare improvvisamente spazio, rendendo improvvisamente in primo piano quello che di solito è un'attività in background.

  • Per risolvere questo problema, è stato introdotto il lavaggio adattivo. Laddove il 10% dello spazio di log (predefinito) viene consumato, il lavoro in background inizia a diventare progressivamente più aggressivo. L'obiettivo di questo è piuttosto che uno stallo improvviso, hai più di un "breve calo" delle prestazioni.

  • Indipendente di vampate di calore adattivo, è importante disporre di spazio di log sufficiente per il carico di lavoro ( innodb_log_file_sizevalori di 4G ora sono abbastanza sicuro), e assicurarsi che innodb_io_capacitye innodb_lru_scan_depthsono impostati su valori realistici. Il flushing adattivo del 10% innodb_adaptive_flushing_lwmè qualcosa in cui non ti estendi molto, è più un meccanismo di difesa contro lo spazio.


2

Solo per dare a InnoDB un po 'di sollievo dalla contesa, potresti giocare innodb_purge_threads.

Prima di MySQL 5.6, il thread principale eseguiva lo svuotamento della pagina. In MySQL 5.6, un thread separato può gestirlo. Il valore predefinito per innodb_purge_threadsin MySQL 5.5 era 0 con un massimo di 1. In MySQL 5.6, il valore predefinito è 1 con un massimo di 32.

Cosa fa innodb_purge_threadseffettivamente l' impostazione ?

Valori diversi da zero eseguono l'operazione di eliminazione in uno o più thread in background, il che può ridurre la contesa interna in InnoDB, migliorando la scalabilità. L'aumento del valore a maggiore di 1 crea molti thread di spurgo separati, che possono migliorare l'efficienza sui sistemi in cui le operazioni DML vengono eseguite su più tabelle.

Vorrei iniziare impostando innodb_purge_threads su 4 e vedere se lo svuotamento della pagina di InnoDB è ridotto.

AGGIORNAMENTO 2014-09-02 12:33 EDT

Morgan Tocker ha sottolineato nel commento sotto che il pulitore di pagine è la vittima e MySQL 5.7 può affrontarlo . Nonostante ciò, la tua situazione è in MySQL 5.6.

Ho dato una seconda occhiata e ho notato che hai innodb_max_dirty_pages_pct a 50.

Il valore predefinito per innodb_max_dirty_pages_pct in MySQL 5.5+ è 75. Abbassarlo aumenterebbe l'incidenza delle bancarelle dal lavaggio. Vorrei fare tre (3) cose

AGGIORNAMENTO 2014-09-03 11:06 EDT

Potrebbe essere necessario modificare il comportamento del lavaggio

Prova a impostare in modo dinamico quanto segue

SET GLOBAL flush = 1;
SET GLOBAL flush_time = 10;

Queste variabili, flush e flush_time , renderanno il flushing più aggressivo chiudendo gli handle di file aperti sulle tabelle ogni 10 secondi. MyISAM può sicuramente trarne vantaggio perché non memorizza nella cache i dati. Tutte le scritture su tabelle MyISAM richiedono blocchi di tabella completi, seguite da scritture atomiche e dipendono dal sistema operativo per le modifiche del disco.

Svuotare InnoDB in questo modo richiederebbe un riavvio mysql. Le opzioni da vedere sono innodb_flush_log_at_trx_commit e innodb_flush_method .

Prima di riavviare, aggiungere questi

[mysqld]
flush = 1
flush_time = 10
innodb_flush_log_at_trx_commit = 0
innodb_flush_method = O_DIRECT

Prima di seguire questa strada, è necessario verificare se l'inserimento nel journal è un problema. Ho visto questo post di mysqlperformanceblog su O_DIRECT essere falsato a causa del kernel. Lo stesso post menziona anche MyISAM interessato.

Ho scritto prima di questo post: ib_logfile aperto con O_SYNC quando innodb_flush_method = O_DSYNC

Provaci !!!


1
Per chiarire: credo che questo carico di lavoro sottolinei i thread di pulizia della pagina anziché i thread di eliminazione. La funzione di pulizia di più pagine è una funzione 5.7, ma è ancora possibile un'ulteriore configurazione in 5.6. Vedi: mysqlserverteam.com/mysql-5-7-improves-dml-oriented-workloads
Morgan Tocker

@MorganTocker @RolandoMySQLDBA Una cosa che mi sar -dè emersa nell'output è che awaitsta salendo di quasi dieci volte durante una delle bancarelle mentre il throughput diminuisce. Pensi sia probabile che ci siano problemi al di fuori di MySQL qui, ad esempio con lo scheduler I / O o l'inserimento nel journal del filesystem?
James L,

Sto cambiando la maggior parte dei parametri che hai suggerito ad eccezione di innodb_purge_threads (che necessita di un riavvio). Non ha fatto molto per il problema. E sono portato a credere che il motore InnoDB non sia il problema qui, poiché anche gli inserti della tabella MyISAM si stanno arrestando.
syneticon-dj,

Pubblica le tue impostazioni per innodb_read_io_threads e innodb_write_io_threads. EseguiSHOW GLOBAL VARIABLES LIKE '%io_threads';
RolandoMySQLDBA

1
@ syneticon-dj Che ne dici di scrivere sullo stesso filesystem dall'esterno di MySQL - anche quelli sono in stallo?
James L,
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.