Xóa hàng triệu tệp


38

Tôi đã có một thư mục chứa đầy hàng triệu hình ảnh gif. Quá nhiều cho lệnh rm.

Tôi đã thử lệnh find như thế này:

find . -name "*.gif" -print0 | xargs -0 rm

Vấn đề là, nó làm hỏng máy của tôi rất tệ và gây mất thời gian cho khách hàng vì đó là máy chủ.

Có cách nào nhanh hơn để xóa tất cả các tệp này ... mà không khóa máy không?


Tôi ở tốc độ xóa khoảng 6 gb / giờ bằng cách sử dụng lệnh "tìm kiếm tốt đẹp" bên dưới. Có lẽ sẽ mất 48 giờ để loại bỏ tất cả các tệp. Lý do điều này xảy ra là do kịch bản bour ca thất bại. Tôi đã vượt qua "chân trời sự kiện" với lệnh rm, sau đó nó bỏ chạy.

3
Sẽ loại bỏ toàn bộ thư mục không được nhanh hơn đáng kể? Chỉ cần lấy ra các tệp "tốt" trước khi gỡ bỏ các tệp còn lại ...
tucuxi

Chà, mọi tập tin đều tệ ngay bây giờ, vì nó đã được chuyển đến / dir_old và tôi làm lại / dir. Nhưng rmdir sẽ không gặp phải giới hạn như rm *?

@Corepuncher: Tôi hy vọng rằng việc xóa toàn bộ thư mục (như rm -rfsẽ nhanh hơn. Rất đáng để thử.
Jason R

Tôi hiện đang chạy "rm -rf" trên thư mục. Nó đã chạy được hơn 20 phút rồi ... không có thay đổi nào về kích thước đĩa. Nhưng nó cũng không tự động trả về "danh sách tranh luận quá lâu". Vấn đề duy nhất là, nó thực sự làm hỏng máy của tôi và làm cho những thứ khác bị chậm / thất bại. Không chắc bao lâu để cho nó đi.

Câu trả lời:


44

Nhanh hơn không nhất thiết là những gì bạn muốn. Bạn có thể muốn thực sự chạy chậm hơn , vì vậy việc xóa sẽ tiết kiệm ít tài nguyên hơn trong khi nó đang chạy.

Sử dụng tốt (1) để giảm mức độ ưu tiên của lệnh.

nice find . -name "*.gif" -delete

Đối với các quy trình ràng buộc I / O, (1) có thể không đủ. Bộ lập lịch Linux có tính đến I / O, không chỉ CPU, mà bạn có thể muốn kiểm soát tốt hơn mức ưu tiên I / O.

ionice -c 2 -n 7 find . -name "*.gif" -delete

Nếu điều đó không làm điều đó, bạn cũng có thể thêm một giấc ngủ để thực sự làm nó chậm lại.

find . -name "*.gif" -exec sleep 0.01 \; -delete

3
wow ... hàng triệu tệp với một giấc ngủ .1 giây ... cần một ngày cho 864000 tệp.
glglgl

7
@glglgl Được rồi, mông thông minh. Tôi đã thay đổi thời gian chờ. :-P
John Kugelman hỗ trợ Monica

28
Giấc ngủ có thể là một lựa chọn tốt, nhưng sẽ không tốt, vì nhiệm vụ ở đây là ràng buộc IO, không bị ràng buộc CPU; thay vào đó bạn có thể thử ionice. Lưu ý rằng nếu giấc ngủ quá nhỏ sẽ vô dụng.
Matteo Italia

3
@glglgl: điểm chính xác là nếu bạn không muốn gây ra sự gián đoạn dịch vụ trên máy chủ, bạn phải đi chậm, thời gian mà mã này ngủ ở đó để cho máy chủ thực sự hoạt động hữu ích với đĩa.
Matteo Italia

1
+1 cho sleepbổ sung - Tôi đã gặp sự cố với máy chủ bị nghẹt IO mặc dù đã sử dụng ionice -c 3. Nó làm tăng đáng kể thời gian cần thiết để xóa các tệp (tất nhiên), nhưng tôi chờ đợi hơn là mang ứng dụng xuống ...
Ola Tuvesson

22

Vì bạn đang chạy Linux và tác vụ này có thể là I / O bị ràng buộc, tôi khuyên bạn nên ưu tiên cho trình lập lịch biểu I / O của bạn ở chế độ chờ sử dụng ionice(1):

ionice -c3 find . -name '*.gif' -delete

So sánh với lệnh ban đầu của bạn, tôi đoán điều này thậm chí có thể dự phòng một số chu kỳ CPU hơn bằng cách tránh đường ống đến xargs.


@Braiam Ý bạn là gì? Đây không phải là một find ... -execnơi sẽ có ý nghĩa.

Ồ, vâng, xin lỗi. Lỗi của tôi. Bạn có chắc là hiệu quả không?
Braiam

1
Vâng, các find(1)tài liệu tuyên bố như vậy. :) Và rõ ràng là cho phép findbản thân loại bỏ các tệp hiệu quả hơn so với việc ra rmlệnh cho việc này.

1
Tôi đã thử một số phiên bản được đề xuất trên một thư mục có 4 triệu tệp trên máy chủ sản xuất và đây là phiên bản duy nhất không làm hỏng hệ thống. ionice -c3làm giảm giá trị để chạy khi IO không hoạt động, vì vậy điều này là hoàn hảo. Lưu ý rằng vì -deletekhông phải là tiêu chuẩn để tìm, bạn có thể thực hiện tương tự (bao gồm cả phản hồi mà nó hoạt động) bằng cách sử dụng lệnh này: ionice -c 3 find . -name '*.gif' -exec echo {} \; -exec rm {} \;- Chậm nhưng không có iowaits của các quy trình quan trọng.
Christopher Lörken

13

Không.

Không có cách nào nhanh hơn, xuất hiện từ định dạng mềm của đĩa. Các tệp được cấp cho rm cùng một lúc (tối đa giới hạn của dòng lệnh, nó cũng có thể được đặt thành xargs), tốt hơn nhiều so với gọi rm trên mỗi tệp. Vì vậy, không có cách nào nhanh hơn.

Sử dụng nice(hoặc renicetrên một quy trình đang chạy) chỉ giúp một phần, vì đó là để lập lịch cho tài nguyên CPU , không phải đĩa! Và việc sử dụng CPU sẽ rất thấp. Đây là một điểm yếu của linux - nếu một quá trình "ăn hết" đĩa (tức là hoạt động rất nhiều với nó), toàn bộ máy bị kẹt. Hạt nhân sửa đổi để sử dụng thời gian thực có thể là một giải pháp.

Những gì tôi sẽ làm trên máy chủ là để thủ công cho các quá trình khác thực hiện công việc của họ - bao gồm tạm dừng để giữ cho máy chủ "thở":

find . -name "*.gif" > files
split -l 100 files files.
for F in files.* do
    cat $F | xargs rm
    sleep 5 
done

Điều này sẽ đợi 5 giây sau mỗi 100 tệp. Sẽ mất nhiều thời gian hơn nhưng khách hàng của bạn không nên nhận thấy bất kỳ sự chậm trễ nào.


"Các tập tin được đưa ra để rm cùng một lúc (lên đến giới hạn của dòng lệnh" -so khi vỏ được lệnh rm *, nó mở rộng *vào phù hợp với tất cả các tên tập tin và vượt qua nó để rm? Đó là cực kỳ ngu ngốc. Tại sao shell mở rộng ký tự đại diện?

:-D @Joker_vD, bạn đang nói đùa, như tên của bạn cho thấy? :-)
Tomas

2
@Joker_vD: Khả năng tương thích với quyết định Unix từ năm 1970 trở đi. Windows không làm điều đó. Ở đó, các chương trình có thể chuyển các ký tự đại diện cho FindNextFile / FindNextFile để chúng nhận được kết quả cùng một lúc.
MSalters

@Tomas Không phải trong trường hợp này. Thành thật mà nói, tôi có thể thấy 2 vấn đề với thiết kế như vậy ngay lập tức: đầu tiên, dòng lệnh không phải là cao su; thứ hai, chương trình không thể biết liệu nó được gọi với *hay /*nghi ngờ về quyết định đó của người dùng.

1
@Joker_vD Có rất nhiều điều hay về shell khi thực hiện mở rộng ký tự đại diện. Nó khác với Windows, nhưng đừng vội kết luận rằng nó cực kỳ ngu ngốc chỉ vì nó khác với những gì bạn đã từng sử dụng. Nếu bạn muốn biết thêm, tôi khuyến khích bạn Google hoặc gửi câu hỏi trên trang web Stack Exchange có liên quan. Đó là một sự trật bánh rất lớn cho khu vực bình luận này.
John Kugelman hỗ trợ Monica

5

Nếu số lượng tệp sẽ bị xóa vượt quá số lượng tệp bị bỏ lại, thì đó có thể không phải là cách tiếp cận hiệu quả nhất để chuyển cây cây bị xóa và thực hiện tất cả các cập nhật hệ thống tệp đó. (Nó tương tự như thực hiện quản lý bộ nhớ đếm tham chiếu vụng về, truy cập mọi đối tượng trong một cây lớn để bỏ tham chiếu của nó, thay vì biến mọi thứ không mong muốn thành rác trong một bước, sau đó quét qua những gì có thể tiếp cận để dọn sạch.)

Điều đó có nghĩa là, nhân bản các phần của cây sẽ được giữ cho một tập khác. Tạo lại một hệ thống tập tin mới, trống trên ổ đĩa gốc. Sao chép các tập tin được giữ lại trở lại đường dẫn ban đầu của họ. Điều này mơ hồ tương tự như sao chép bộ sưu tập rác .

Sẽ có một số thời gian chết, nhưng nó có thể tốt hơn so với sự gián đoạn hiệu suất và dịch vụ liên tục.

Nó có thể không thực tế trong hệ thống và tình huống của bạn, nhưng thật dễ dàng để tưởng tượng các trường hợp rõ ràng trong đó đây là cách để đi.

Chẳng hạn, giả sử bạn muốn xóa tất cả các tệp trong một hệ thống tệp. Điều gì sẽ là điểm đệ quy và xóa từng cái một? Chỉ cần ngắt kết nối nó và thực hiện "mkfs" trên đầu phân vùng để tạo một hệ thống tập tin trống.

Hoặc giả sử bạn muốn xóa tất cả các tệp ngoại trừ một nửa tá các tệp quan trọng? Đưa nửa tá ra khỏi đó và ... "mkfs" trên đầu trang.

Cuối cùng, có một số điểm hòa vốn khi có đủ các tệp phải ở lại, nó trở nên rẻ hơn để thực hiện xóa đệ quy, có tính đến các chi phí khác như bất kỳ thời gian chết nào.


4

Bạn đã thử chưa:

find . -name "*.gif" -exec rm {} +

Dấu + ở cuối sẽ khiến find bao gồm nhiều tệp hơn cho lệnh rm duy nhất được thực thi. Kiểm tra câu hỏi này để biết thêm chi tiết.


Nó thực thi nhanh hơn nhiều so với -print0 | Giải pháp xargs vì quy trình rm không được gọi cho mọi tệp mà cho tập hợp lớn của chúng và do đó nó gây ra tải thấp hơn.

@JohnKugelman Bạn đúng, nhưng đó là một phần mở rộng GNU không phải lúc nào cũng có sẵn với lệnh find .
CodeGnome

OK, thú vị, nhưng đây là điều khá mới (cũng như -delete) mà không phải lúc nào cũng có ở đó ..
Tomas

Tuy nhiên, điều này chắc chắn không mang lại điều gì tốt hơn so với giải pháp của OP.
Tomas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.