재귀적으로 순회하지 않고 ZFS에서 대규모 디렉토리를 일괄 삭제합니다.

재귀적으로 순회하지 않고 ZFS에서 대규모 디렉토리를 일괄 삭제합니다.

zfs데이터세트 하위 디렉터리의 콘텐츠를 삭제하고 싶습니다 . 이것은 많은 양의 데이터입니다. 풀 "nas"의 경우 경로는 다음과 같습니다./nas/dataset/certainFolder

$ du -h -d 1 certainFolder/
1.2T    certainFolder/

기다려야 하는 대신 rm -rf certainFolder/디렉터리에 대한 핸들을 삭제하여 덮어쓸 수 있도록 할 수는 없나요(다시 만들기로 선택한 경우 디렉터리 이름이 동일하더라도)?

예를 들어, zfs파일 시스템 내부, 특히 파일을 기록하는 방법에 대해 잘 알지 못하는 경우 해당 로그/맵에 직접 액세스하여 디렉토리가 더 이상 표시되지 않도록 올바른 항목을 삭제할 수 있는지 알고 싶습니다. . 공간 디렉토리도 일종의 감사에서 제거되어야 합니다.

찾을 수 있는 단축키가 있나요? 일지라도외부 3fs, 아니면 이것이 재귀 삭제 명령이 수행하는 첫 번째 작업, 즉 로그를 훔치고 편집하는 것입니까?

kill thisDir나는 일종의 ID를 제거하고 디렉토리가 더 이상 표시되지 않는 유사한 작업을 수행하기를 바라고 있습니다 ls -la. 분명히 데이터는 여전히 드라이브에 있지만 ZFS가 그렇게 멋지기 때문에 공간은 이제 재사용(덮어쓰기)됩니다.

내 말은 내 생각엔지브스정말 멋지네요. 우리 어떡해요? 이상적으로는? 두 손을 비비세요 :-)

나의 특정 사용 사례(내가 좋아하는 것 외에 zfs)는 백업 아카이브 관리입니다. 데이터는 SMB를 통해 Win Box의 freefilesync(AWESOME PROG)를 통해 zfs 풀로 zfs로 푸시됩니다. 오랫동안 사용할 수 없었던 rm -rf /nas/dataset/certainFolder용어 가 제거 되면 중지됩니다. putty물론 계속하려면 다른 터미널을 열어야 합니다. 그것은 구식이며 rm -rf를 모니터링하는 것은 재미가 없으며 몇 시간이 걸릴 수 있습니다.

예를 들어 핸들을 해제하는 명령을 설정한 &다음 stdout으로 인쇄해야 할 수도 있습니다. 그러면 좋을 것 같습니다. 좀 더 현실적으로zfs destroy nas/dataset; zfs create -p -o compression=on nas/dataset, @Gilles의 응답을 고려한 후 몇 초 내에 데이터 세트를 다시 생성합니다.

답변1

괜찮은 파일 시스템에서는 해제된 블록을 추적하는 것이 불가피하며 ZFS는예외없이.그러나 ZFS에서는 거의 즉시 디렉토리를 삭제하는 쉬운 방법이 있습니다.기본 정리를 "연기"합니다. 기술적으로 Giles의 제안과 매우 유사하지만 본질적으로 건전하고 추가 코드가 필요하지 않습니다.

디렉토리를 삭제하기 전에 파일 시스템의 스냅샷을 생성하면 그 아래에서 아무것도 탐색/해제할 필요가 없고 모든 것이 여전히 스냅샷에 의해 참조되므로 디렉토리 삭제 속도가 매우 빠릅니다. 그런 다음 공간이 점진적으로 복구되도록 백그라운드에서 스냅샷을 삭제할 수 있습니다.

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}

답변2

당신이 요구하는 것은 불가능합니다. 또는 더 정확하게 말하면 디렉터리와 해당 파일을 삭제할 때 지불해야 하는 비용이 있습니다. 삭제할 때 비용을 지불하지 않으면 다른 곳에서 비용을 지불해야 합니다.

디렉토리만 삭제하는 것이 아니라 거의 즉각적으로 삭제됩니다. 디렉터리와 그 안에 있는 모든 파일을 삭제하고 마찬가지로 모든 하위 디렉터리도 반복적으로 삭제합니다. 파일을 삭제한다는 것은 해당 링크 수를 줄이는 것을 의미하며, 링크 수가 0에 도달하고 파일이 0에 도달하지 않으면 해당 리소스(파일 내용 및 파일 메타데이터에 대한 블록 및 inode(파일 시스템이 inode 테이블을 사용하는 경우))가 Open으로 표시됩니다. 유휴용. 이 작업은 디렉터리 트리의 모든 파일에 대해 수행되어야 하므로 소요 시간은 최소한 파일 수에 비례합니다.

리소스를 무료로 표시하는 비용을 연기할 수 있습니다. 예를 들어, 디렉터리에 포함된 파일을 삭제하지 않고 디렉터리를 삭제할 수 있는 가비지 수집 파일 시스템이 있습니다. 가비지 수집기의 작업은 디렉터리 구조를 통해 액세스할 수 없는 파일을 감지하고 해당 파일을 사용 가능한 것으로 표시합니다. 가비지 수집 파일 시스템에서 수행되는 작업은 rm -f directory; garbage-collect기존 파일 시스템에서 수행되는 작업과 동일하지만 트리거가 다릅니다. rm -rfGC로 인해 거의 필요하지 않은 추가 복잡성이 발생하므로 파일 시스템은 가비지 수집되는 일이 거의 없습니다. GC 시간은 파일 시스템에 사용 가능한 블록이 필요하지만 찾을 수 없는 경우 언제든지 발생할 수 있으므로 작업 성능은 작업뿐만 아니라 과거 기록에 따라 달라지며 이는 일반적으로 바람직하지 않습니다. 실제 여유 공간을 얻으려면 가비지 수집기를 실행해야 합니다.

일반 파일 시스템에서 GC 동작을 시뮬레이션하려면 다음을 수행할 수 있습니다.

mv directory .DELETING; rm -rf .DELETING &

(오류 확인, 정전 복구 등과 같은 많은 중요한 세부 사항을 생략했습니다.) 디렉터리 이름은 즉시 존재하지 않게 되며 공간은 점차적으로 회수됩니다.

GC 없이 제거 중 비용 지불을 방지하는 또 다른 방법은 할당 중에 비용을 지불하는 것입니다. 디렉터리 트리를 삭제된 것으로 표시하고 블록을 할당하는 동안 삭제된 디렉터리를 탐색합니다. 이는 하드 링크와 조정하기 어렵지만 하드 링크가 없는 파일 시스템에서는 O(1) 할당 비용 증가로 이를 수행할 수 있습니다. 그러나 이렇게 하면 매우 일반적인 작업(파일 생성 또는 확대)이 더 비싸지고 유일한 이점은 상대적으로 드문 작업(큰 디렉터리 트리 삭제)이 더 저렴하다는 것입니다.

디렉토리 트리가 자체 블록 풀에 저장되어 있는 경우 해당 디렉토리 트리를 대량으로 삭제할 수 있습니다. (참고: 저는 "풀"이라는 단어를 ZFS의 "스토리지 풀"과 다른 의미로 사용합니다. 정확한 용어가 무엇인지 모르겠습니다.) 이는 매우 빠를 수 있습니다. 하지만 사용 가능한 공간으로 무엇을 합니까? 파일을 개별적으로 삭제하는 것보다 훨씬 저렴하지만 다른 풀에 재할당하는 경우 비용이 발생합니다. 미사용 예약공간으로 남겨두시면 즉시 회수가 불가능합니다. 디렉토리 트리에 대해 별도의 풀을 갖는다는 것은 해당 풀의 크기를 (동적으로 또는 명시적으로) 늘리거나 줄이는 비용이 증가한다는 것을 의미합니다. 트리를 자체 스토리지 풀로 만들면 트리 안팎으로 파일을 이동하는 비용도 늘어납니다.

답변3

속도가 빨라야 한다면 새 임시 디렉터리와 mv그 아래 디렉터리를 생성한 다음 재귀적으로 임시 디렉터리를 삭제합니다.

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &

답변4

삭제하고 빠르게 다시 생성하려는 폴더가 다른 데이터세트의 하위 디렉터리가 아닌 자체 데이터세트에 있는 경우 다음을 수행할 수 있습니다.

zfs rename pool/dataset pool/dataset.old
zfs create -o ...options... pool/dataset
zfs destroy -r pool/dataset.old

pool/dataset기존 제품이 폐기되면 새 제품을 즉시 사용할 수 있습니다.

하위 데이터세트를 삭제하지 않으려는 경우(예 pool/dataset/child: 상위 데이터세트와 함께 이름이 변경됨 pool/dataset.old/child) 상황은 약간 더 복잡하지만 하위 디렉터리를 삭제하려는 경우보다 더 복잡하지는 않습니다. 대부분의 하위 디렉터리가 삭제되어도 유지됩니다. 그냥 새 이름으로 다시 이름을 바꾸세요.pool/dataset 앞으로pool/dataset.old예를 들어, 파괴 zfs rename pool/dataset.old/child pool/dataset/child. 마찬가지로 back mv의 하위 디렉터리 pool/dataset.oldpool/dataset.

하위 디렉터리인 경우 다른 파일 시스템에서와 마찬가지로 다음을 수행할 수 있습니다.

mv subdir subdir.old
mkdir subdir
chmod ... subdir ; chown ... subdir    # if and as required
rm -rf subdir.old/ &

이것은 Giles가 그의 답변에서 말한 것과 거의 동일합니다.

마찬가지로, 하위 하위 디렉토리를 유지하려면 rm -rf예를 들어 실행하기 전에 해당 하위 디렉토리를 새 하위 디렉토리로 다시 이동하세요 mv subdir/child subdir/.

나는 적어도 1990년대부터 수십 년 동안 이 작업을 해왔습니다. 이 zfs rename버전은 동일한 접근 방식의 확실한 진화일 뿐입니다. MS-DOS에서 디렉토리 이름을 바꿀 수 있는지는 기억나지 않지만, 그렇다면 1980년대 MS-DOS에서도 그렇게 했을 것입니다.

.old그런데 데이터세트와 하위 디렉터리의 경우 즉시 삭제할 필요는 없습니다 . 나는 보관하고 싶은 모든 항목을 복구했다고 확신할 때까지 또는 사용 중인 디스크 공간을 복구해야 할 때까지 보관하는 경향이 있습니다. 나는 돌아올 수 없는 지점을 가능한 한 오랫동안 지연시키는 것을 좋아합니다.


그런데 일반적으로 하위 디렉토리 ZFS 대신 데이터 세트를 사용하는 것이 좋습니다. 각 데이터 세트(예: 압축 유형, 할당량, 보존, 시간/상대 시간, 암호화 등)에 대해 서로 다른 설정을 가질 수 있고 각 데이터 세트는 개별적으로 설정할 수 있기 때문입니다. 스냅샷을 찍고 백업했습니다 zfs send.

그러나 이에 대한 비용은 파일이나 하위 디렉터리 트리를 다른 데이터 세트로 이동하는 것이 복사 및 삭제 작업이라는 점입니다. 이는 이를 다른 디스크, 파티션, LV 등의 다른 파일 시스템으로 이동할 때와 같습니다. 데이터 세트실제로 자체 마운트 지점이 있는 다른 독립적인 파일 시스템입니다. 바라보다동일한 풀에 있는 하나의 zfs 파일 시스템에서 다른 zfs 파일 시스템으로 파일을 이동하는 방법은 무엇입니까?- 거기에 달린 댓글 하나가 나를 오늘 여기로 이끌었습니다.

또한 주목할 만한 점은 데이터 세트의 마운트 지점이 다음과 같을 수 있다는 것입니다.어딘가에파일 시스템 계층에서는 상위 항목 아래에 직접 마운트할 필요가 없으며 필요에 따라 마운트 지점을 변경할 수 있습니다. 예를 들어, "rpool"이라는 작은 SSD 루트 풀과 "export"라는 대량 데이터용 대형 HDD 풀이 있는 경우 내보내기를 위해 rpool의 큰 하위 디렉터리(및 데이터 세트)를 이동하고 동일한 위치에 계속 설치할 수 있습니다. 위치. 예를 들어

zfs create export/share-doc
mv /usr/share/doc/* /export/share-doc/
zfs set mountpoint=/usr/share/doc export/share-doc

(이것은 단순화된 예입니다. 실제로 저는 fs 계층 구조를 복사하는 경향이 있습니다. 예를 들어 내보내기/usr, 내보내기/usr/share, 내보내기/usr/share/doc에 대한 데이터 세트를 생성합니다. a) 풀의 최상위 수준을 유지합니다. 깔끔한 b ) 다른 하위 디렉터리나 데이터세트를 그곳으로 이동해야 하는 경우)

데이터 세트 이름과 계층 구조 및 마운트 지점 간의 차이점을 이해하는 것이 중요합니다. 데이터세트를 반복적으로 삭제하면 설치된 위치에 관계없이 해당 하위 데이터세트도 삭제됩니다. 따라서 유지하고 싶은 자녀의 이름을 바꾸는 것을 잊지 마십시오.

관련 정보