Aclaración sobre MySQL innodb_flush_method variable

21

Permítanme comenzar admitiendo que soy muy ignorante del funcionamiento interno de los discos duros. Entonces, cuando leí el manual de la variable innodb_flush_method , me confundió. ¿Puedo obtener una explicación en términos simples sobre la diferencia en O_DSYNC y O_DIRECT, y cómo saber si se trata de un problema de rendimiento en un servidor de base de datos.

Algunas estadísticas en mi configuración: Mac OSX 10.6 (kernel de 32 bits, ya que la arquitectura está desactualizada) ejecutando MySQL 5.1.49-64bit (esperando que me permita usar la memoria). 8 GB de RAM, ~ 6 GB de datos / índices innodb.

Derek Downey
fuente
2
No sé si Mac OS X admite una opción de E / S directa adecuada; no pensé que lo hiciera. Eres la segunda persona que he visto confundirse hoy con esa página del manual. Tengo un error abierto aquí: bugs.mysql.com/bug.php?id=54306
Morgan Tocker

Respuestas:

16

Aquí hay una explicación sobre cómo fdatasync()funciona vs cómo fsync()funciona

fdatasync()vacía todos los almacenamientos intermedios de datos de un archivo en el disco (antes de que vuelva la llamada al sistema). Se parece fsync()pero no es necesario actualizar los metadatos, como el tiempo de acceso. Las aplicaciones que acceden a bases de datos o archivos de registro a menudo escriben un pequeño fragmento de datos (por ejemplo, una línea en un archivo de registro) y luego llaman de fsync()inmediato para asegurarse de que los datos escritos se almacenan físicamente en el disco duro. Desafortunadamente, fsync()siempre iniciará dos operaciones de escritura

  • una operación de escritura para los datos recién escritos
  • Una operación de escritura para actualizar el tiempo de modificación almacenado en el inodo

Si el tiempo de modificación no es parte del concepto de transacción, fdatasync()puede usarse para evitar operaciones innecesarias de escritura en disco de inodo.

En inglés, O_DSYNCes más rápido que O_DIRECTdesde que O_DIRECTllama fsync()dos veces (una para registros y otra para datos) y fsync()verifica la escritura de datos a través de dos operaciones de escritura. Usando O_DSYNCllamadas fdatsync()y fsync(). Se puede considerar fdatasync()como hacer un asíncrono fsync()(no verificar datos).

Mirando los números, O_DSYNCrealiza cuatro operaciones de escritura, dos de las cuales se verifican, mientras fsync()que cuatro operaciones de escritura, todas verificadas posteriormente.

CONCLUSIÓN

  • O_DSYNC
    • más rápido que O_DIRECT
    • Los datos pueden o no ser consistentes debido a la latencia o un bloqueo absoluto
  • O_DIRECT
    • mas estable
    • datos consistentes
    • naturalmente más lento

Espero que esta respuesta ayude, y espero no haber empeorado las cosas para ti.

RolandoMySQLDBA
fuente
2
Vale la pena señalar: O_DIRECT solo se usa en los archivos de espacio de tabla, no en los registros. Además, si O_DIRECT va a ser útil o no depende del hardware. Me vinculé a un error de documentación abierta como un comentario a la pregunta del autor.
Morgan Tocker
Gracias por aclarar eso, Morgan. Corregiré esto.
RolandoMySQLDBA
O_DSYNC es escritura sincrónica, ¿cómo puede concluir que es más rápido que asincrónico + fsync?
noonex
@noonex fdatasync () es sincrónico para sus datos, no para sus metadatos. Según informit.com/articles/article.aspx?p=23618&seqNum=5 , This means that in principal, fdatasync can execute faster than fsync because it needs to force only one disk write instead of two. However, in current versions of Linux, these two system calls actually do the same thing, both updating the file's modification time.en el momento en que escribí mi publicación hace 3.5 años, era cierto, especialmente con versiones anteriores de Linux.
RolandoMySQLDBA
@noonex Según en.wikipedia.org/wiki/Sync_(Unix) , The related system call fsync() commits just the buffered data relating to a specified file descriptor. fdatasync() is also available to write out just the changes made to the data in the file, and not necessarily the file's related metadata.(Esa Wiki se actualizó por última vez el 28 de julio de 2014).
RolandoMySQLDBA