Table of Contents
Discrepancia de resultados al visualizar el espacio en disco (du / df)
La diferencia de resultados entre el comando du y df puede ser muy amplia dependiendo del entorno donde nos encontremos, en algunos entornos la diferencia es de cientos de gigabytes. Como veremos esto puede deberse a varios factores. Se mostrarán unos casos con ejemplos prácticos para poder entender mejor el por qué de los diferentes reportes de cada herramienta. Se comentarán y explicarán otras situaciones vinculadas al tamaño de ficheros y su uso de disco.
El comando df muestra un espacio ocupado mayor al que contabiliza el comando du
Por norma esa disparidad de resultados tiene como culpable ficheros que han sido borrados del sistema, pero que por alguna razón siguen siendo utilizado por procesos.
- du muestra siempre un resultado certero sobre lo que ocupan los ficheros que se encuentran en disco y no han sido eliminados. Con la opción “–apparent-size” se puede consultar lo que ocupa realmente un archivo, su contenido.
- df al contrario mostrará el resultado que ofrece el comando du + los ficheros eliminados que sigan estando en uso por procesos.
Identificar ficheros que han sido eliminados pero siguen siendo utilizados por procesos (sin usar lsof).
find /proc/*/fd -ls | grep '(deleted)' 86784 0 lrwx------ 1 root root 64 Mar 13 16:40 /proc/1910/fd/4 -> /tmp/ibRjqNKo\ (deleted) 86785 0 lrwx------ 1 root root 64 Mar 13 16:40 /proc/1910/fd/5 -> /tmp/ib3kxrZf\ (deleted) 86786 0 lrwx------ 1 root root 64 Mar 13 16:40 /proc/1910/fd/6 -> /tmp/ibETN5d7\ (deleted) 86787 0 lrwx------ 1 root root 64 Mar 13 16:40 /proc/1910/fd/7 -> /tmp/ibHi4KKP\ (deleted) 86791 0 lrwx------ 1 root root 64 Mar 13 16:40 /proc/1910/fd/11 -> /tmp/ibREFcxH\ (deleted) 86448 0 lr-x------ 1 developer developer 64 Mar 13 16:40 /proc/21566/fd/3 -> /home/developer/fichero1g\ (deleted)
Identificar ficheros que han sido eliminados pero siguen siendo utilizados por procesos con lsof.
lsof -nP | grep '(deleted)'
Listar los procesos que utilizan dichos ficheros borrados.
$ ps aux | grep -E "1910|21566" mysql 1910 0.0 9.9 1141612 388824 ? Sl 09:03 0:27 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock 5000 21566 98.5 30.2 1515624 1184876 pts/4 R+ 16:30 13:57 vi fichero1g
Si los procesos que siguen trabajando con ficheros eliminados del sistema de ficheros son eliminados, el resultado del comando du y df será prácticamente el mismo.
También puede influir la caché de entrada / salida del almacenamiento, por lo que se debería usar la opción “--sync” de df como se puede ver en el siguiente ejemplo.
# La partición se ha formateado usando un tamaño de bloque de 1024bytes (1k) mkfs -t xfs -b size=1024 /dev/sdb1 mount /dev/sdb1 /mnt/ df --block-size=1k /mnt/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb1 5215276 8264 5207012 1% /mnt # El tamaño de bloque es de 1k, por lo tanto, aunque el tamaño real del archivo es de 2 Bytes, ocupará en disco 1k. echo 1 > /mnt/a # Parece que han aumentado el espacio usado en 8k df --block-size=1k /mnt/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb1 5215276 8272 5207004 1% /mnt # Sincronizamos y ahora se puede apreciar el uso de disco (8264k + 1k) df --sync --block-size=1k /mnt/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb1 5215276 8265 5207011 1% /mnt
Otra causa de discrepancia entre los comandos du y df puede ser que los puntos de montaje se activaran sobre directorios no vacíos. Al ser montado, todo lo que se encuentre dentro sería invisible y por lo tanto du no lo encontraría.
du -hcs /mnt/* 10K /mnt/fichero 16K /mnt/lost+found 26K total umount /mnt/ du -hcs /mnt/* 2.0G /mnt/test.tmp 2.0G total
Conceptos básicos sobre almacenamiento
A la hora de escribir y leer información de un dispositivo, entran en juego el concepto sector lógico y sector físico. Este último se refiere al tamaño mínimo de disco real que se utiliza en cada operación de entrada y salida. El sector lógico es la capa por encima que se encarga de establecer y manejar ese tamaño de sector al sistema operativo. Estos son los formatos que se pueden encontrar en los discos hasta la fecha.
Formato lógico físico 512n(nativo): 512 512 512e(emulado): 512 4096 Permite usar los discos actuales con aplicaciones / hardware antiguas. 4Kn(nativo): 4096 4096 Puede dar problemas con aplicaciones antiguas. 4K-ready host: Funciona como discos 512 nativos y 512e.
Los SSD realmente no funcionan internamente con bloques / sectores, todos estos términos vienen heredados de los discos mecánicos y para mantener una compatibilidad a nivel de aplicación se sigue manteniendo este tipo de conceptos. En algunos dispositivos SSD es factible cambiar incluso el tamaño de bloque físico, ya que a efectos prácticos no deja de ser algo virtual (leer).
La mayoría de discos SSD usan 512b para el sector lógico / físico, mientras que discos físicos mayores a 3T siempre usan 4K. El formato más utilizado suele ser el 512e, esto implica que para el sistema operativo el tamaño de cada operación de entrada / salida debe ser de 512 bytes. Pero físicamente el dispositivo se encargará de ocupar después los 4k.
Comandos para poder visualizar el tamaño de sector lógico y físico.
# hdparm hdparm -I /dev/sdb | grep "Logical S\|Physical S" Logical Sector size: 512 bytes Physical Sector size: 4096 bytes # fdisk fdisk -l /dev/sdb | grep -i "Disk \/\|sector size" Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors Sector size (logical/physical): 512 bytes / 4096 bytes # Kernel (LVM dm-0, dm-1,..) cat /sys/block/sda/queue/logical_block_size 512 cat /sys/block/sda/queue/physical_block_size 4096 # lsblk (Naturalmente todos los LVs de un mismo disco tendrán la misma configuración). lsblk -o NAME,PHY-SeC,LOG-SEC NAME PHY-SEC LOG-SEC fd0 512 512 sda 4096 512 ├─sda1 4096 512 └─sda2 4096 512 ├─centos-root 4096 512 ├─centos-swap 4096 512 ├─centos-lv_logs 4096 512 ├─centos-lv_files 4096 512 └─centos-lv_code 4096 512 sr0 512 512 # S.M.A.R.T smartctl -a
Tamaño de bloque usado por el sistema de ficheros.
# XFS xfs_info / | grep bsize data = bsize=4096 blocks=122096390, imaxpct=25 # EXTX (Volumen lógico LVM) tune2fs -l /dev/mapper/Volgroup00-lv_root | grep "Block size" Block size: 4096
du muestra un espacio ocupado desmesurado a simple vista
Normalmente esto sucede cuando existe una gran cantidad de ficheros muy pequeños, sobre todo al copiar ficheros de un sistema a otro. El comando df usa bloques de 1k para contabilizar el espacio mientras que el comando du de manera estándar utiliza 4k. Los discos mecánicos de “Formato Avanzado” (a partir del 2010) traducen cada sector físico de 4096 bytes en ocho sectores lógicos de 512 bytes (sector lógico). Para el firmware, el sistema operativo y todos los utilitarios del disco el disco aparenta tener sectores de 512 bytes.
Por lo tanto, si se escribe un fichero de 15 bytes, en disco ocupará 4096 (4k) en disco. Pero esto mientras se estén utilizando las opciones por defecto al ejecutar el comando, veamos el manual de “du”. Si se usa la opción -b se obtendría el tamaño real del archivo, es decir, cuanto ocupa la información que lo contiene.
-b, --bytes equivalent to '--apparent-size --block-size=1' -t, --threshold=SIZE exclude entries smaller than SIZE if positive, or entries greater than SIZE if negative du --all --human-readable --apparent-size (shorthand: du -ah --apparent-size) du displays the disk usage for each file and directory. The options explained: --all, -a - show sizes for files as well, not just directories --human-readable, -h - show sizes in a human readable format, e.g. 10K (10 kilobytes), 10 (10 bytes) --apparent-size - show the actual file size, not the sizes as used by the disk.
Tamaño del archivo en disco / Tamaño real del archivo.
# 8 El fichero ocupa 8 bytes pero en disco son 4k. echo a > file $ du file 4 file du -b file 2 file ### Ejemplo con directorio que contiene muchos ficheros pequeños. # En Gigabytes. du -hcs /mnt/pimprod_assets_new/* 28G /mnt/pimprod_assets_new/images 28G total # En Kilobytes. du -kcs /mnt/pimprod_assets_new/* 29168640 /mnt/pimprod_assets_new/images 29168640 total # En Megabytes. du -mcs /mnt/pimprod_assets_new/* 28485 /mnt/pimprod_assets_new/images 28485 total # En bytes, lo que realmente ocupan las cadenas de bits que forman el archivo. Sin contabilizar lo que ocupa en el disco. du -hcs --apparent-size /mnt/pimprod_assets_new/* 4,1G /mnt/pimprod_assets_new/images 4,1G total
Se puede apreciar que la suma de todos los ficheros realmente tienen un tamaño de 4.1G, pero utilizan 28Gb de espacio en disco, más de 6 veces su tamaño.
Los puntos de montaje remotos (NFS / SAMBA) y su configuración cliente / servidor
Cuando se utilizan puntos de montaje remotos, el comando df muestra las estadísticas de uso de disco referente al servidor, es decir del punto de montaje remoto donde se supone está la carpeta que se nos permite montar. Por lo tanto, si la carpeta montada no es la raíz, el tamaño del directorio montado nunca se corresponderá con el mostrado por el comando du al analizar el punto de montaje desde el cliente.
Otra cosa a tener en cuenta es que desde diferentes ubicaciones se pueden obtenerse diferentes valores al tratar con ficheros pequeños. Eso se puede deber a varios factores, por ejemplo el protocolo cifs utilizado, versión y opciones en el montaje en la parte cliente. También la configuración de la red / pila TCP/IP puede jugar un papel importante ya que en ocasiones se implementa el tamaño de bloque en relación al MTU y el tamaño de segmento TCP.
Ejemplo usando diferente versiones del protocolo samba a la hora de montar un directorio remoto.
# Usando una versión 3.X de samba al conectar. du -k /media/keepass/file.kdbx 1024 /media/keepass/file.kdbx # Usando la versión 1.0 de samba al conectar. du -k /media/keepass/file.kdbx 236 /media/keepass/file.kdbx
Como se puede ver, cada fichero ocupa 1 Mbyte, por poco contenido que tenga. Por lo tanto si se copian 100 archivos desde un sistema de ficheros local formateado con un tamaño de bloque de 4K (predeterminado actualmente), al consultar el espacio del punto de montaje remoto nos mostrará 400Mbytes, mientras que en local ocupan en disco únicamente 400K. Hay que tener en cuenta que eso no asegura que en el disco remoto esos ficheros estén ocupando tal cantidad de espacio, en este caso 400 Mbytes.
¿Influye por tanto el tamaño de bloque a la hora de formatear un dispositivo?
En términos de ahorro de espacio por supuesto, pero solo en casos muy concretos como en el uso de ficheros pequeños, es decir inferiores al tamaño de bloque. En este test se utiliza una partición de 1Gb donde se van a crear todos ficheros de 51 bytes hasta ocupar toda la capacidad, el tamaño del archivo es trivial mientras no sea superior al del bloque. El siguiente comando creará ficheros numerados insertando dentro de ellos caracteres (51 bytes), el sistema de ficheros es XFS.
for i in {1..600000}; do printf "ääääääääääää\nßßßßßßßßßßßßß" ${i} $(($RANDOM % 100000000)) > File${i}.txt; done
Los resultados fueron los siguientes.
Formato usando Bloques de 1k: 500413 files Formato usando Bloques de 4k: 212162 files
Al usar un sistema de ficheros con tamaño de bloque de 1k (XFS) se consiguió poder almacenar más del doble de información. Como se verá en otro punto, en sistemas de ficheros EXT4 pese a variar el tamaño de bloque se mantiene constante la cantidad de ficheros pequeños que se pueden almacenar.
¿Hay alguna relación entre el tamaño de bloque del disco y el que puede ser especificado en aplicaciones como dd o fio?
No, la típica opción para definir el tamaño de bloque “bs” suele ser usada para especificar la cantidad de bytes que se leerán o escribirán en cada operación de escritura o lectura individual, la cual es usada por dichas aplicaciones como referencia. Dicha opción no tiene relación con el tamaño de bloque del disco / sistema de ficheros. No se puede obligar a una aplicación a que use un tamaño de bloque en concreto.
¿Se puede dar un tamaño de bloque superior a 4K?
En sistemas Linux el sector de bloque máximo a utilizar está limitado al tamaño de página que usa el núcleo, el cual es 4K. Modificar ese valor implica grandes cambios en el kernel y no es algo actualmente factible.
Prueba usando un tamaño de bloque de 64K en XFS.
mkfs -t xfs -f -b size=65536 /dev/sdb1 mount /dev/sdb1 /mnt/ mount: mount /dev/sdb1 on /mnt failed: Function not implemented # No es posible montar el disco. getconf PAGE_SIZE 4096
Link de interés: Paginación en Linux
¿Se puede dar un tamaño de bloque al formatear que sea menor / mayor al tamaño físico?
El límite máximo a la hora de dar un formato es el tamaño de página. Pero no hay problema en utilizar un tamaño de bloque mayor o menor a la hora de formatear mientras este sea múltiplo y no sobrepase el tamaño de página. Por ejemplo se puede definir un tamaño de bloque en EXT4 de 1k y usar un disco 512e (tamaño de bloque físico de 4k). También es factible tener un sistema de fichero que usa 4k cuando el disco es 512n (tamaño de bloque físico de 512b).
En algunos casos se nos mostraran avisos al formatear. Que no se muestren errores a la hora de formatear no quiere decir que el montaje vaya a ser exitoso. A continuación se muestran dos ejemplos.
Dar un formato XFS usando como tamano de bloque 1k cuando el disco tiene un tamaño de sector físico de 4096. Esto no impide el montaje de la partición, es simplemente un aviso.
mkfs -t xfs -f -b size=1024 /dev/sdc1 specified blocksize 1024 is less than device physical sector size 4096 ...
Ejemplo usando ext3 y forzando el uso de bloques de 8K, como se observa se formatea correctamente pero posteriormente no puede ser montado.
mkfs -t ext3 -b 8192 /dev/VolGroup00/test_lv Warning: blocksize 8192 not usable on most systems. mkfs.ext3: 8192-byte blocks too big for system (max 4096) Proceed anyway? (y,n) y Warning: 8192-byte blocks too big for system (max 4096), forced to continue ... tune2fs -l /dev/VolGroup00/test_lv |grep "Block size" Block size: 8192 mount /dev/VolGroup00/test_lv /mnt1/ mount: wrong fs type, bad option, bad superblock on /dev/VolGroup00/test_lv, missing codepage or other error In some cases useful info is found in syslog - try dmesg | tail or so dmesg: EXT3-fs: Unsupported filesystem blocksize 8192 on dm-16.
Cómo ejecutar el comando du para que contabilice el espacio ocupado como lo hace df
# du du -cs -B1k --apparent-size /mnt/samba 203155275 /mnt/samba 203155275 total #df df /mnt/samba S.ficheros bloques de 1K Usados Disponibles Uso% Montado en //XXX/carpeta 367001600 204972520 162029080 56% /mnt/samba
¿Por qué el comando ls / du no sirven para medir el uso en disco de los ficheros?
Como hemos comentado ya varias veces, una cosa es el tamaño de los ficheros / directorios y otro lo que ocupan en disco (sector físico).
Estos comandos du y df ofrecen el mismo resultado.
# 1 Byte. ls -lt --block-size=1 du -b # 1 Kbyte. ls -l --block-size=1024 du -k --apparent-size
Formatear una partición con ext4 estableciendo diferentes tamaño de bloque (4k vs 1k).
# Ext4 con tamaño de bloque de 4K. mkfs -t ext4 -b 4096 /dev/sdb1 mount /dev/sdb1 /mnt/ echo "Servus" > mnt/fichero du -k mnt/fichero 4 mnt/fichero du -b mnt/fichero 7 mnt/fichero # Ext4 con tamaño de bloque de 1K. mkfs -t ext4 -b 1024 /dev/sdb1 mount /dev/sdb1 /mnt/ echo "Servus" > mnt/fichero du -k mnt/fichero 1 mnt/fichero du -b mnt/fichero 7
Lógicamente esto es posible cuando el sector físico del disco es de 512, ya que si fuera de 4k no sería posible establecer un tamaño de 1K de manera funcional.
El comando df muestra discrepancias entre el espacio total, el usado y el disponible
A la hora de dar formato a una partición, el sistema de ficheros reserva una parte llamada espacio de root (1%,5%,15%). De esta forma el sistema funciona aunque esté la partición llena y se facilita el poder eliminar espacio. En sistemas de ficheros Ext también se reserva una parte para el funcionamiento de por ejemplo fsck y otro tipo de información como tablas de inodo, Data Bitmap, GDT Blocks, etc.
Naturalmente como se configuren dichas opciones a la hora de formatear afectará en mayor o menor medida. A esto debemos sumarle que algunas aplicaciones muestran 1 kilobyte como 1000 bytes y otras 1024 bytes.
Pruebas de discrepancia entre espacio total y ocupado + disponible al utilizar diferentes sistemas de ficheros.
# 1k bloks /dev/sdb1 fdisk -s /dev/sdb1 5225516 # Tamaño total, usado y disponible dell mismo disco dependiendo del sistema de ficheros en uso. Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb1 5077288 11294 4796528 1% /mnt ext4 /dev/sdb1 5142868 11284 4870310 1% /mnt ext2 /dev/sdb1 5215276 8264 5207012 1% /mnt xfs
Dentro de un mismo sistema de ficheros como puede ser XFS, dependiendo como se le haya configurado el blockdevice, este también influirá en el espacio disponible.
Veamos este ejemplo usando diferentes tamaño de bloque con XFS.
Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdb1 5215276 32944 5182332 1% /mnt xfs (Block size 4096 bytes) /dev/sdb1 5215276 8264 5207012 1% /mnt xfs (Block size 1024 bytes)
NOTA: Lo que un sistema de ficheros reserva para su propio funcionamiento se hace también por bloques, por lo ha mayor tamaño de bloque, más espacio reserva.
Tamaño de directorios según el sistema de ficheros
Los directorios en sistemas Unix son listas de nombres y números de inodo. Cada sistema de ficheros maneja los archivos de una manera diferente. En algunos sistemas de ficheros como XFS, dependiendo del tamaño del directorio (tamaño de la lista nombre - inodo), esta información no es necesaria que se almacene en un bloque del disco como comprobaremos a continuación.
Creamos el directorio 1 subdirectorios anidados 2 y 3.
mkdir -p 1/2/3
Consultar los bytes de un directorio (Recordar que no se consulta el tamaño del archivo y no lo que ocupa en disco). El comando ls -ls por defecto utiliza también bloques de 1k.
# Ext4 4 drwxr-xr-x 3 busi busi 4096 dic 26 17:44 1 4 drwxr-xr-x 3 busi busi 4096 dic 26 17:44 2 4 drwxr-xr-x 2 busi busi 4096 dic 26 17:44 3 # XFS 0 drwxr-xr-x. 3 root root 15 Dec 26 17:41 1 0 drwxr-xr-x. 3 root root 15 Dec 26 17:41 2 0 drwxr-xr-x. 2 root root 6 Dec 26 17:41 3
Como se puede ver, en el sistema de ficheros XFS un directorio vacio no ocupa espacio en disco. En actuales versiones de XFS un directorio vacío (sin subdiretorios) tiene un tamaño de 6 bytes pero no ocupan ningún bloque. Esto varía dependiendo de como internamente XFS define diferentes tipos de directorios. Estos tipos son “Shortform Directories” “Block Directories” “Leaf Directories” “Node Directories” y “Tree Directories”.
En el ejemplo, nosotros hemos creado directorios muy pequeños y según el manual de xfs, estos directorios pequeños son almacenados dentro de un inodo. Por lo que no ocupan ningún bloque extra (lógicamente se almacena en el espacio previamente reservado para los inodos a la hora de formatear el disco / partición).
Directorios más grandes que el concebido en XFS para un inodo, denominados “block directories” ocupan 4k..
Directorios muy grandes son almacenados en ficheros, ocupando siempre un entero múltiplo del tamaño de bloque y tiene la información organizado en forma de Ábol-B para encontrar pares (nombre - inodo) de una manera rápida.
Documentación de XFS de interés.
En futuras versiones de linux es posiblme que se implemente el llamado “inode data inline” para que ficheros muy pequeños puedan ser guardados también dentro del inodo: https://lwn.net/Articles/759183/.
¿Influye el tipo de disco y el tamaño de bloque usado al formatear?
Depende, cada sistema de ficheros se comporta de manera diferente. Por ejemplo, a efectos prácticos en ext4 no se aprecia diferencias cuando se formatea una partición usando un tamaño de bloque de 1K o de 4K, ya sea en discos 4096n, 512e u 512n. A continuación se muestran unas pruebas usando una partición de 1G la cual llenaremos de ficheros hasta completar su capacidad.
### Partición de 1G - Tamaño de bloque del sistema de ficheros EXT4 1k - Disco 512e (Lógico 512b / Físico 4k). df /mnt/test S.ficheros bloques de 1K Usados Disponibles Uso% Montado en /dev/sdc1 1015452 2830 956098 1% /mnt/test # Creamos todos los ficheros de 51 bytes posibles dentro de /mnt/test. for i in {1..600000}; do printf "ääääääääääää\nßßßßßßßßßßßßß" ${i} $(($RANDOM % 100000000)) > File${i}.txt; done # Contabilizamos el número de ficheros. ls -lt | wc -l 65527 # Se contabiliza lo que ocupan en disco. du -kcs ../test/ 67760 ../test/ # Se contabiliza el verdadero tamaño del directorio (en bytes). du -bcs ../test/ 5630415 ../test/ ### Partición de 1G - Tamaño de bloque del sistema de ficheros EXT4 4k - Disco 512e (Lógico 512b / Físico 4k). # Uso de la partición. df /mnt/test S.ficheros bloques de 1K Usados Disponibles Uso% Montado en /dev/sdc1 999320 2564 927944 1% /mnt/test # Creamos todos los ficheros de 51 bytes posibles. for i in {1..600000}; do printf "ääääääääääää\nßßßßßßßßßßßßß" ${i} $(($RANDOM % 100000000)) > File${i}.txt; done # Contabilizamos el número de ficheros. ls -lt | wc -l 65527 # Se contabiliza lo que ocupan en disco. du -ks ../test/ 264236 ../test/ # Se contabiliza el verdadero tamaño del directorio (en bytes). du -bs ../test/ 5529039 ../test/
Como se puede ver, el número de ficheros que se puede crear es siempre el mismo, pero el tamaño que ocupan sí varía al usar un tamaño de bloque diferente al formatear. De todas maneras el tamaño que ocupan no es muy relevante ya que no se permite escribir ningún dato más en disco pese a que herramientas como df indiquen que el 70% del disco está disponible.
Ahora se procede a hacer lo mismo usando XFS.
### Partición de 1G - Tamaño de bloque del sistema de ficheros XFS 1k - Disco 512e (Lógico 512b / Físico 4k). # Uso de la partición. df /mnt/test S.ficheros bloques de 1K Usados Disponibles Uso% Montado en /dev/sdc1 1038336 9396 1028940 1% /mnt/test # Creamos todos los ficheros de 51 bytes posibles dentro de /mnt/test. for i in {1..600000}; do printf "ääääääääääää\nßßßßßßßßßßßßß" ${i} $(($RANDOM % 100000000)) > File${i}.txt; done # Contabilizamos el número de ficheros. ls -lt | wc -l 524510 # Se contabiliza lo que ocupan en disco. du -ks ../test/ 546675 ../test/ # Se contabiliza el verdadero tamaño del directorio (en bytes). du -bs ../test/ 43719687 ../test/ ### Partición de 1G - Tamaño de bloque del sistema de ficheros XFS 4k - Disco 512e (Lógico 512b / Físico 4k). # Uso de la partición. df /mnt/test S.ficheros bloques de 1K Usados Disponibles Uso% Montado en /dev/sdc1 1038336 34112 1004224 4% /mnt/test # Creamos todos los ficheros de 51 bytes posibles en /mnt/test. for i in {1..600000}; do printf "ääääääääääää\nßßßßßßßßßßßßß" ${i} $(($RANDOM % 100000000)) > File${i}.txt; done # Contabilizamos el número de ficheros. ls -lt | wc -l 220918 # Se contabiliza lo que ocupan en disco. du -ks ../test/ 893552 ../test/ # Se contabiliza el verdadero tamaño del directorio (en bytes). du -bs ../test/ 18369231 ../test/
En este caso con el sistema de ficheros XFS sí que se ve diferencia, no solo en el tamaño que ocupan en disco, sino del número máximo de ficheros que dicha partición ha almacenado, siendo esta muy superior (más del doble) en el caso de usar 512b.
Como se puede ver el tipo de sistemas de ficheros y su tamaño de bloque puede ofrecer más o menos capacidad de almacenamiento, siendo esta en algunos casos más del doble. Pero antes de apresurarse sería conveniente también realizar pruebas de rendimiento sobre dichos ficheros.
Si al realizar el mismo test se hace sobre un disco de 512n (512 nativo), en XFS el número de ficheros pequeños que se pueden almacenar es un poco superior, tan solo 64 (524574-524510).
### Partición de 1G - tamaño de bloque del sistema de ficheros XFS 1k - Disco 512n (Lógico 512b / Físico 512b). # Uso de la partición. df /mnt/test S.ficheros bloques de 1K Usados Disponibles Uso% Montado en /dev/sdc1 1015452 2830 956098 1% /mnt/test # Creamos todos los ficheros de 51 bytes posibles. for i in {1..600000}; do printf "ääääääääääää\nßßßßßßßßßßßßß" ${i} $(($RANDOM % 100000000)) > File${i}.txt; done # Contabilizamos el número de ficheros. ls -lt | wc -l 524574 # Se contabiliza lo que ocupan en disco. du -k ../test/ 67742 ../test/ # Se contabiliza el verdadero tamaño del directorio (en bytes). du -b ../test/ 5611983 ../test/
NOTA: En las pruebas realizadas sobre ext4 se obtuvo el mismo número de ficheros que en discos de 4k, usando cualquier tipo de tamaño de bloque para dar formato.
"No space left on device" Cuando el comando df muestra mucho espacio disponible
Depende del sistema de ficheros en uso y el número de ficheros pequeños contenidos en una partición, es posible encontrarse en situaciones como la siguiente.
# EXT4 # Se intenta crear un archivo en "/mnt/test/" pero el kernel de linux nos avisa de que no es posible, no hay espacio en el dispositivo. dmesg > /mnt/test/test1 bash: /mnt/test/test1: No space left on device # Salida de df avisando de que aproximadamente el 70% de la partición está disponible. # 1k df /mnt/test/ Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdc1 999320 266768 663740 29% /mnt/test # 1M df -h /mnt/test/ Filesystem Size Used Avail Use% Mounted on /dev/sdc1 976M 261M 649M 29% /mnt/test
Esto es algo que suele pasar cuando una partición EXT4 tiene muchísimos ficheros más pequeños que el tamaño de bloque. En sistemas XFS sería inusual encontrarse este tipo de situaciones. Leer el punto anterior para obtener más información.
Archivos dispersos: Ocupan unos pocos bytes pero 0 Kb /Mb
En informática, un archivo disperso es un tipo de archivo que intenta utilizar más eficientemente el espacio del sistema de archivos cuando los bloques (el espacio) asignados a los archivos están en su mayor parte vacíos. Se encuentran en áreas de archivos ordinarios que ni siquiera están asignados por el sistema de archivos subyacente. Estas áreas se llaman agujeros y los archivos que contienen se llaman archivos dispersos.
Esto se consigue escribiendo una breve información (metadatos) representando los bloques vacíos en el disco en vez del verdadero espacio “vacío” que constituye el bloque, utilizando así menos espacio en disco. El tamaño del bloque completo se escribe en el disco como el tamaño real únicamente cuando el bloque contiene “datos reales” (no vacíos). Al leer los archivos dispersos, por ejemplo en hexadecimal con el comando “xxd”, el sistema de archivos de forma transparente convierte los metadatos referentes a esos bloques vacíos, en bloques llenos de ceros. Todo eso se realiza en tiempo de ejecución, por lo que la aplicación no es consciente de esta conversión.
La mayoría de los sistemas de archivos modernos soportan archivos dispersos, incluyendo la mayoría de variantes de Unix y NTFS,3 pero no de HFS+. Los archivos dispersos se utilizan comúnmente para imágenes de disco, copia de bases de datos, archivos de registro y en aplicaciones científicas.
dd if=/dev/random of=/mnt/test.img bs=1024 count=0 seek=$[1024*10] ls -l /mnt/test.img -rw-r--r--. 1 root root 10485760 Dec 22 22:01 /mnt/test.img du -b /mnt/test.img 10485760 /mnt/test.img du -k /mnt/test.img 0 /mnt/test.img du -h /mnt/test.img 0 /mnt/test.img # Se observa que el contenido son todo 0. xxd test.img | head -n 2 00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
¿Cómo se pueden encontrar en el sistema de ficheros archivos dispersos?
find /mnt/ -type f -printf "%S\t%p\n" | gawk '$1 < 1.0 {print}'
Ficheros loopback en discos con sectores lógicos de 4K (4K nativo)
En sistemas operativos Unix-like, un “loop device”, “vnd” (vnode disk) o “lofi” (loop file interface) es un pseudo-dispositivo que hace que se pueda acceder a un fichero como un dispositivo de bloques. Antes de su uso, se tiene que conectar el “loop device” a un fichero existente en el sistema de ficheros, el cual tiene se puede crear con el comando dd en el tamaño deseado.
Esta asociación proporciona al usuario una interfaz que permite que se use el fichero en lugar de un dispositivo especial de bloque. Por tanto, si el archivo contiene todo un sistema de archivos, el fichero puede ser montado como si fuera un disco.
Este tipo de archivos se usan a veces para almacenar imágenes ISO de discos y disquetes. Montar un archivo que contiene un sistema de ficheros en un “loop device” hace que se pueda acceder a los archivos de ese sistema de ficheros. Aparecen en el directorio del punto de montaje.
A partir de los kernels 4.4 de Linux es factible establecer el tamaño de bloque lógico para un fichero loopback creado con losetup. Por defecto se usan 512 bytes, pero si el sistema está corriendo sobre un disco 4K nativo, esta opción puede ser interesante si se trabaja con este tipo de ficheros.
Ejemplo creando un fichero loopback de 100 Mbytes con un bloque lógico de 4k.
dd if=/dev/zero of=fichero0 bs=1M count=10 losetup --sector-size 4k /dev/loop0 fichero0 mkfs -t xfs -f -b size=4k fichero0 mount fichero0 /mnt/loopback_4K # NOTA: Si el disco no es 4k nativo el comando fallará. # Eliminar el fichero loopback. umount /mnt/loopback_4K losetup -d /dev/loop0 rm fichero0