Что произойдет, если в разделе ext4 будет превышено ограничение в 4 миллиарда файлов?

Sí, es más eficiente

La forma más fácil de probar es aumentar el conteo para decir 500000 y cronometrarlo:

> time bash s1.sh; time bash s2.sh
bash s1.sh  16,47s user 10,00s system 99% cpu 26,537 total
bash s2.sh  10,51s user 3,50s system 99% cpu 14,008 total

strace (1 )revela por qué (tenemos uno simple write, en lugar de open+5*fcntl+2*dup+2*close+write):

para for i in {1..1000}; do >>x echo "$i"; doneobtenemos:

open("x", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
write(1, "997\n", 4)                    = 4
dup2(10, 1)                             = 1
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0
open("x", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
write(1, "998\n", 4)                    = 4
dup2(10, 1)                             = 1
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0
open("x", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
write(1, "999\n", 4)                    = 4
dup2(10, 1)                             = 1
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0
open("x", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
fcntl(1, F_GETFD)                       = 0
fcntl(1, F_DUPFD, 10)                   = 10
fcntl(1, F_GETFD)                       = 0
fcntl(10, F_SETFD, FD_CLOEXEC)          = 0
dup2(3, 1)                              = 1
close(3)                                = 0
write(1, "1000\n", 5)                   = 5
dup2(10, 1)                             = 1
fcntl(10, F_GETFD)                      = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0

mientras que para exec 3>&1 1>xquedamos mucho más limpios

write(1, "995\n", 4)                    = 4
write(1, "996\n", 4)                    = 4
write(1, "997\n", 4)                    = 4
write(1, "998\n", 4)                    = 4
write(1, "999\n", 4)                    = 4
write(1, "1000\n", 5)                   = 5

Pero tenga en cuenta que la diferencia no se debe a "usar un FD", sino al lugar donde realiza la redirección. Por ejemplo, si tuviera que hacer for i in {1..1000}; do echo "$i"; done > x, obtendría prácticamente el mismo rendimiento que su segundo ejemplo:

bash s3.sh  10,35s user 3,70s system 100% cpu 14,042 total
48
02.07.2019, 10:38
2 ответа

Предположительно, вы увидите ошибку «Нет свободного места на устройстве»:

# truncate -s 100M foobar.img
# mkfs.ext4 foobar.img
Creating filesystem with 102400 1k blocks and 25688 inodes
---> number of inodes determined at mkfs time ^^^^^
# mount -o loop foobar.img loop/
# touch loop/{1..25688}
touch: cannot touch 'loop/25678': No space left on device
touch: cannot touch 'loop/25679': No space left on device
touch: cannot touch 'loop/25680': No space left on device

И на практике вы достигнете этого предела намного раньше, чем «4 миллиарда файлов». Проверьте свои файловые системы с помощью df -hи df -i, чтобы узнать, сколько места осталось.

# df -h loop/
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0       93M  2.1M   84M   3% /dev/shm/loop
# df -i loop/
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/loop0      25688 25688     0  100% /dev/shm/loop

В этом примере, если размер ваших файлов в среднем меньше 4 КБ, пространство inode -заканчивается гораздо раньше, чем пространство хранилища -. Можно указать другое соотношение(mke2fs -N number-of-inodesили -i bytes-per-inodeили -T usage-type, как определено в/etc/mke2fs.conf).

80
27.01.2020, 19:34

После достижения предела последующие попытки создания файлов завершатся с ошибкой ENOSPC, указывающей на то, что в целевой файловой системе нет места для новых файлов.

В описанном вами сценарии это обычно приводит к прерыванию передачи по достижении лимита.

52
27.01.2020, 19:34

Теги

Похожие вопросы