次のパイプラインを実行しています。
tar -c directory | pv -T -c -B 2G | gzip -c9 | pv -T -c -B 2G | split -b 1G - /mnt/usbStick/f.tar.gz_
アイデアは、> 4 GBのディレクトリを大型FAT32形式(< 2 GBファイルのみ安定してサポート)USBスティックにgzipすることです。ただ1GBチャンクsplit
に切ります。.gz
pv
パイプバッファ(各2GB)として使用され、主に圧縮不良データが発生したときの制限を防ぎ、gzip
Uディスクの書き込み速度よりも速く圧縮されたデータを出力します。
質問:
別の1GBセクションが完了したら、split
ファイルを更新して閉じます。フラッシュが完了するまで次のセクションの書き込みを開始しないため、入力の受け入れは停止します。
この時点で、2番目の2GBバッファがいっぱいになり始めると予想しています。しかし、すべてが停止しました。。システムは全体的に完全に死んでいませんが、gzip
CPUの使用を停止し、pv
出力の更新も停止します。後半からはすべてのIOが、さらにパイプまで止まったという結論を下しました。 (私が間違っている場合は、私が間違っていることを証明してください。)(私が間違っています。特定のパイプラインが停止しているだけです。)
問題は、なぜこのように動作するのか、そしてどのように解決するのかです。
編集する
実際にpv
欠陥があります。buffer
うまくいきます。 Ubuntu 16.04に含まれるビルドは、それぞれ最大512KBのブロックを最大2048個しか使用できませんが、buffer -m 1024m -s 512k
デイジーチェーンに接続してより大きなバッファを形成できます。
答え1
これは単純な監視ツールであるため、pv
同期IOを使用するシングルスレッドプログラムであると推測されます。入力と出力が異なる速度で実行されている場合は調整を避けるためにバッファを埋めて空にしますが、パイプの1つが完全に停止した場合(あなたの場合は入力を許可しないsplit
)、呼び出しpv
中に2番目のインスタンスも停止しますwrite
。その後、gzip
より多くのデータを出力し、パイプバッファをオーバーフローして停止するなど、パイプ全体が停止するまで続きます。
試してみてくださいbuffer
これが役立つことを確認する代わりにpv
。buffer
2つのプロセス(入力用、出力用1つ)を作成し、出力が完全に停止してもパイプを実行し続ける必要があります。