Программа GNU sort – сжатие – сжатие только первой временной

Я сортирую большие файлы (> 100Go), и чтобы сократить время, затрачиваемое на запись на диск, я пытаюсь использовать параметр --compress-program GNU sort. (Связано: Как сортировать большие файлы? )

Однако в некоторых случаях оказывается, что только первая временная сжимается. Я хотел бы знать, почему и что я могу сделать, чтобы сжать все временные.

Я использую:

  • sort (GNU coreutils) 8.25
  • lzop 1.03 / LZO library 2.09

Шаги по воспроизведению проблемы:

Вам понадобится что-то вроде ~ 15Go свободного пространства, ~ 10Go ram, некоторое время

Сначала создайте файл 10Go со следующим кодом C:

 #include <stdio.h> #include <stdlib.h> int main(void) { unsigned long n; unsigned char i; srand(42); for(n = 0; n < 1000000000; n++) { for(i = 0; i < 3; i++) { printf("%03d", rand() % 1000); } printf("\n"); } fflush(stdout); return 0; } 

И запустив его:

 $ gcc -Wall -O3 -o generate generate.c $ ./generate > test.input # takes a few minutes $ head -n 4 test.input 166740881 241012758 021940535 743874143 

Затем запустите процесс сортировки:

 $ LC_ALL=C sort -T . -S 9G --compress-program=lzop test.input -o test.output 

Через некоторое время приостановите процесс и перечислите темпари, созданные в той же папке (из-за -T . ):

 $ ls -s sort* 890308 sortc1JZsR 890308 sorte7O878 378136 sortrK37RZ $ file sort* sortc1JZsR: ASCII text sorte7O878: ASCII text sortrK37RZ: lzop compressed data - version 1.030, LZO1X-1, os: Unix 

Похоже, что только sortrK37RZ (первый временный созданный) был сжат.

[Изменить] Выполнение этой же команды sort с -S установленным в 7G является прекрасным (т.е. все временные файлы сжимаются), а с 8G проблема присутствует.

[Изменить] lzop не вызывается для другого временного

Я попытался использовать следующий скрипт в качестве обертки для lzop :

 #!/bin/bash set -e echo "$$: start at $(date)" >> log lzop $@ echo "$$: end at $(date)" >> log 

Вот содержимое файла log , когда на диск записываются несколько временных файлов:

 11109: start at Sun Apr 10 22:56:51 CEST 2016 11109: end at Sun Apr 10 22:57:17 CEST 2016 

Поэтому я предполагаю, что программа сжатия вообще не вызывается.

Не воспроизводится здесь?

 $ shuf -i1-10000000 > t.in $ sort -S50M -T. t.in --compress-program=lzop # ^z $ file sort* | tee >(wc -l) > >(grep -v lzop) 7 $ fg # ^c $ sort --version | head -n1 sort (GNU coreutils) 8.25 

Я предполагаю, что проблема связана с отказом fork () процесса сжатия из-за большого размера памяти, а затем возвращается к стандартной записи. IE sort (1) использует fork () / exec (), когда в идеале он должен использовать posix_spawn () для более эффективного преобразования процесса сжатия. Теперь fork () – CoW, но все еще накладные расходы на подготовку связанных структур бухгалтерского учета для такого большого процесса. В будущих версиях sort (1) мы будем использовать posix_spawn (), чтобы избежать этих накладных расходов (glibc только что получил полезную реализацию posix_spawn () с версии 2.23).

Тем временем я предлагаю использовать намного меньшие -S. Возможно, -S1G и ниже.