Group commit per il log binario
Le Group Commit sono un'importante ottimizzazione di MariaDB 5.3, utile se il server è eseguito con innodb_flush_logs_at_trx_commit=1
e/o sync_binlog=1
. Queste impostazioni sono necessarie per accertarsi che, se il server va in crash, tutte le transazioni che sono state segnate come concluse prima dell'arresto continueranno a essere presenti nel database dopo il crash recovery ("durability", la "D" in ACID). Inoltre, entrambe le impostazioni sono necessarie per consentire il recupero di uno stato coerente dopo il crash; se non sono entrambe impostate, è possibile che il recupero porti a uno stato in cui le transazioni nel log binario manchino nelle tabelle InnoDB/XtraDB, o viceversa, perciò gli slave replicheranno dati errati.
Quando queste impostazioni sono attive, il server esegue una chiamata a fsync()
(o fdatasync()
o simili) sul file del log delle transazioni o del log binario di XtraDB durante il COMMIT
, per accertarsi che i dati vengano registrati in modo persistente sul disco. L'operazione fsync()
richiede tempo, ed è probabile che diminuisca le prestazioni, intese come numero di commit al secondo che è possibile sostenere.
Lo scopo delle group commit è ammortizzare i costi di ogni fsync()
su diversi commit che vengono da diverse transazioni eseguite in parallelo. Se ad esempio 10 transazioni parallele eseguono commit, il server può accedere al disco un'unica volta con una singola chiamata a fsync()
, invece di chiamare fsync()
ogni volta. Ciò può ridurre di molto la necessità di chiamare fsync()
, aumentando sensibilmente il numero di commit al secondo.
Le group commit vengono usate automaticamente; non è necessario impostare alcuna opzione per abilitarle e non hanno conseguenze negative (in termini di performance o di affidabilità o altro).
Tuttavia, per poter notare gli effetti positivi di questa ottimizzazione, il carico di lavoro deve essere parallelizzato a sufficienza. Normalmente, questo accade se vi sono almeno tre sensazioni parallele: mentre la prima transazione attende il completamento di fsync()
, le altre due si accodano aspettando il loro turno per chiamare fsync()
. Al termine della prima transazione, può essere eseguita una sola fsync()
per le transazioni in attesa, risparmiando (in questo caso) una delle tre chiamate.
In aggiunta al parallelismo, è necessario avere abbastanza transazioni al secondo che attengono di poter eseguire un commit, in modo che le chiamate a fsync()
siano effettivamente un collo di bottiglia. Se non è così (perché le transazioni raramente o mai attendono il completamento di un fsync()
),le group commit non portano alcun miglioramente.
Nuove variabili di stato
Per il log binario, vi sono due nuove variabili di stato per verificare quanto le group commit riescano a ridurre il numero di chiamate a fsync()
:
binlog_commits
- Nome Variabile:
binlog_commits
- Contesto: Sessione
- Tipo:
Numero
E' il numero totale dei commit delle transazioni nel log binario.
binlog_group_commits
- Nome Variabile:
binlog_group_commits
- Contesto: Sessione
- Tipo:
Numero
E' il numero totale delle group commit eseguite nel log binario (una group commit è quando un gruppo di transazioni vengono scritte nel binary log contemporaneamente, con una sola chiamata a fsync()
). Se sync_binlog=1
, questo è il numero di fsync()
chiamate per i commit delle transazioni al binary log
La misura di quanto ogni group commit sia efficiente nel ridurre il numero di chiamate a fsync()
può essere determinata dal rapporto tra queste due variabili di stato. binlog_commits
avrà sempre un valore maggiore o uguale a binlog_group_commits
; più grande è la differenza, più le group commit hanno diminuito le esecuzioni di fsync()
.
Per leggere queste variabili, si può usare una semplice query come la seguente:
SHOW STATUS LIKE 'binlog_%commits';
(Ulteriori informazioni sull'efficienza delle group commit in XtraDB si possono ottenere da variabili di stato simili, come innodb_data_fsyncs
; tuttavia i dati sono leggermente più difficili da interpretare, perché XtraDB/InnoDB utilizza fsync()
anche per scopi diversi dal (group) commit).
Per ulteriori informazioni sul progetto e l'implementazione delle group commit, si veda MWL#116.