¿Problemas de configuración del storage en entornos Linux?
07/11/2017 -
En esta entrada intentaré describir un problema común de configuración del storage en entornos Linux x86_64 antiguos. Un problema que en los peores casos puede deteriorar el rendimiento de la entrada/salida a disco hasta un 10%. Este defecto lo causa la combinación entre las particiones usadas en los discos y el propio sistema de discos, independientemente del uso al que destinemos la máquina, o de si ejecutamos o no una BBDD.
Las máquinas con una entrada/salida intensiva advertirán más el problema, el cual puede aparecer de repente al actualizar la cabina de discos (sin haber modificado nada en el servidor). En estos casos la mejora del rendimiento de la nueva cabina tiende a enmascarar el problema.
En primer lugar os comentaré las suposiciones que doy por hechas:
- Supongo que usamos discos o luns presentados al servidor mediante iSCSI, FC o FCoE, no aplicaría, por ejemplo, en el caso de NFS.
- Supongo que la cabina que presenta los discos es relativamente moderna, esto es que usa bloques de 4Kb (los discos y cabinas antiguas usan bloques de 512 bytes).
Entremos en materia. Al preparar los discos para su uso en un servidor, uno de los primeros pasos es crear una o varias particiones dentro de ellos. Posteriormente en cada partición podremos crear un filesystem, un volumen ASM u otros sistemas de organización de los datos. La tabla de particiones se ubica justo al inicio del disco y permite localizar a los sistemas operativos las diferentes particiones (una suerte de “discos lógicos” dentro de un disco físico).
El comando típico (y el que aparece en la mayoría de documentación) para crear particiones en Linux es el “fdisk“. Veamos un ejemplo de partición creada “por defecto”:
1
2
3
4
5
6
7
8
9
10
11
12
|
fdisk -lu /dev/xvdd Disk /dev/xvdd : 107.4 GB, 107374182400 bytes 255 heads, 63 sectors /track , 13054 cylinders, total 209715200 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical /physical ): 512 bytes / 4096 bytes I /O size (minimum /optimal ): 4096 bytes / 4096 bytes Disk identifier: 0xcf01b915 Device Boot Start End Blocks Id System /dev/xvdd1 63 209712509 104856223+ 83 Linux Partition 1 does not start on physical sector boundary. |
Este comando nos indica que:
- Los volúmenes o discos tienen un tamaño de bloque de 4Kb, pero estamos trabajando con un tamaño lógico (emulado) de 512 bytes.
- Que la entrada/salida “ideal” es de 4Kb.
- Que la primera (y única) partición de datos empieza en el bloque numero 63 (empezando a contar desde cero). Si alguien se pregunta porque 63, la respuesta es porque corresponde a un valor legado del tiempo en que las máquinas funcionaban con MS DOS y en la actualidad no tiene justificación alguna.
- Finalmente nos intenta avisar de que algo malo esta pasando: “Partition 1 does not start on physical sector boundary.“, este mensaje no aparece siempre, dependerá de la versión de sistema operativo y “fdisk” que usemos. Básicamente nos indica que la partición numero 1 no está alineada con un bloque de 4kb.
He representado gráficamente este problema (de manera muy simplificada):
Distribución de la tabla de particiones, primera partición y bloques de disco.
A causa del tamaño de la tabla de particiones, la primera partición de datos (que viene a continuación de ésta) no está alineada con los bloques físicos de disco (empieza al final de bloque físico numero 8).
Imaginemos que nuestro entorno de BBDD usa una de las cabinas nuevas en modo emulación 512 bytes (el modo llamado 512e), la tabla de particiones es similar a la del dibujo y la BBDD pide un bloque de 512 bytes para lectura.
La cabina o disco tiene que leer 4Kb de datos, transformar una parte de los datos del bloque de 4kb en un bloque simulado de 512 bytes y retornarlo, esto lo hace en la caché del propio disco y es “relativamente” rápido.
El problema empeora si es para escritura, ya que si enviamos un bloque de 512 bytes para ser escrito, la cabina o disco tiene que leer el bloque físico correspondiente de 4Kb, realizar la combinación de nuestro bloque de 512 bytes en el de 4Kb y escribir el de 4Kb al completo.
Muchos pensaréis que el tamaño de bloque de vuestra BBDD es 8Kb (por defecto), por lo que la BBDD siempre va a leer o escribir 8Kb como mínimo (que corresponderán a dos bloques físicos completos de 4Kb). Pues bien, podría ser cierto pero no para todos los ficheros, ya que los “redo logs online” “por defecto” tienen un tamaño de bloque de 512 bytes y, precisamente son ficheros en los que constantemente vamos a estar escribiendo.
Vamos a empeorarlo un poco más:
¿Recordáis que la partición no empezaba justo en un bloque físico de 4Kb? Pues bien, esto implica que cada vez que queramos leer un bloque Oracle de 8Kb obligamos al sistema de disco a leer tres bloques de 4Kb ya que los 8Kb de datos que hemos pedido queda encajados entre tres bloques de 4Kb en el disco.
De nuevo simplificando:
Encaje de un bloque Oracle de 8Kb en disco.
El peor de los casos sería enviar un bloque Oracle para escritura, lo que implicaría tres lecturas de 4Kb y tres escrituras más de 4Kb.
¿Cómo podemos paliar o incluso eliminar estos efectos adversos?
- Particionando correctamente los discos (o usando particiones GPT en lugar de las MBR)
- Usando herramientas de particionado actualizadas (versiones modernas de “fdisk” o “parted”)
- Usando de manera nativa los discos de 4Kb, (posible en la mayoría de S.O. modernos y en lo que se refiere a la BBDD Oracle a partir de la versión 11.2, incluso para los “redo logs”).
Un ejemplo de particionado correcto de disco – en el que se ha indicado que la partición empieza en el sector 2048 (o lo que es lo mismo a 1Mb del inicio del disco) y que por tanto es divisible exactamente en bloques de 4Kb- que evita (en parte) los citados problemas sería el siguiente:
1
2
3
4
5
6
7
8
9
10
11
|
fdisk -lu /dev/xvdc Disk /dev/xvdc : 107.4 GB, 107374182400 bytes 43 heads, 44 sectors /track , 110843 cylinders, total 209715200 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical /physical ): 512 bytes / 4096 bytes I /O size (minimum /optimal ): 4096 bytes / 4096 bytes Disk identifier: 0x5a1058a4 Device Boot Start End Blocks Id System /dev/xvdc1 2048 209715199 104856576 83 Linux |
En el ejecutable “fdisk” de los sistemas operativos modernos (Oracle 7, Redhat 7, Suse 11.3,..) empiezan las particiones de datos a 1Mb “por defecto”.
Para quienes deseen profundizar más en la necesidad de usar tamaños de bloque de 4Kb, así como el modo emulación (también llamado 512e) y sus inconvenientes, facilito un link de la empresa Seagate en que se explica detalladamente.
Igualmente os dejo algunas notas y documentos de Oracle en que se hace referencia a la problemática de las particiones no alineadas:
- Oracle Cloud Performance and Tuning Best Practices
- Extremely Slow I/O Performance On Disk Partitions Created Using fdisk DOS Compatible Mode (Doc ID 2098513.1)
- How To Align Partitions on Large HDD (Doc ID 1523947.1)
- Optimise Oracle VM 3.x Oracle Linux guest write I/O performance through guest/host partition boundary alignment (Doc ID 1632576.1)