DROP TABLE 을 했을 때 데이터 파일이 휴지통으로 가는지 즉시 사라지는지가 테이블 종류와 옵션에 따라 다르다. 실수로 지운 뒤 /user/<사용자>/.Trash 를 뒤졌는데 아무것도 없어서 복구하지 못하는 일이 자주 생긴다.
| 테이블 | 옵션 | 메타데이터 | 데이터 파일 |
|---|---|---|---|
| 관리 테이블 | 없음 | 삭제 | HDFS 휴지통으로 이동 |
| 관리 테이블 | PURGE |
삭제 | 즉시 영구 삭제 |
| 외부 테이블 | 없음 | 삭제 | 그대로 남음 |
| 외부 테이블 | external.table.purge=true |
삭제 | 삭제 |
관리 테이블의 기본 동작은 휴지통 이동이다. DROP TABLE t PURGE 를 주면 휴지통을 건너뛰고 바로 지운다.
외부 테이블은 DROP TABLE t PURGE 를 줘도 데이터가 지워지지 않는다. PURGE 키워드는 관리 테이블의 휴지통 경유 여부만 바꾸기 때문이다. 외부 테이블의 데이터까지 지우려면 테이블 속성 external.table.purge 를 켜 두어야 한다.
ALTER TABLE t SET TBLPROPERTIES ('external.table.purge'='true');
.Trash 에서 지운 데이터를 찾지 못하는 이유는 대부분 다음 셋 중 하나다.
첫째, 휴지통 자체가 꺼져 있다. core-site.xml 의 fs.trash.interval 이 0 이면 휴지통을 쓰지 않고 바로 지운다. 분 단위 값이다.
<property>
<name>fs.trash.interval</name>
<value>1440</value>
</property>
둘째, 지운 주체가 내 계정이 아니다. 휴지통은 삭제를 실행한 OS/Kerberos 주체의 홈 아래에 생긴다. HiveServer2 가 doAs 없이 동작하면 삭제 주체는 hive 가 되므로 경로는 /user/hive/.Trash/Current/... 가 된다. 내 계정 휴지통을 봐도 없는 것이 당연하다.
hdfs dfs -ls -R /user/hive/.Trash/Current | grep <테이블이름>
hdfs dfs -ls -R /user/<계정>/.Trash/Current | grep <테이블이름>
셋째, 보존 기간이 지나 체크포인트가 비워졌다. fs.trash.checkpoint.interval 주기로 Current 가 타임스탬프 디렉터리로 넘어가고, fs.trash.interval 이 지나면 지워진다.
복구는 휴지통 안의 경로를 원래 자리로 옮기는 것이다.
hdfs dfs -mv /user/hive/.Trash/Current/warehouse/db.db/t /warehouse/tablespace/managed/hive/db.db/t
메타스토어에서 이미 정의가 지워졌으므로, 파일을 되돌린 뒤 테이블을 다시 만들고 파티션을 복구해야 한다.
MSCK REPAIR TABLE t;
Hive 3 이후 CDP 계열에서는 관리 테이블과 외부 테이블의 웨어하우스 루트가 나뉘어 있다. 휴지통에서 되돌릴 때 원래 경로를 잘못 잡지 않도록 실제 값을 먼저 확인한다.
SET hive.metastore.warehouse.dir;
SET hive.metastore.warehouse.external.dir;
DESCRIBE FORMATTED t;
TRUNCATE TABLE 도 같은 규칙을 따른다. 관리 테이블이면 휴지통으로 가고, 외부 테이블은 기본적으로 자르지 못한다.
DROP DATABASE ... CASCADE 는 그 안의 모든 테이블에 위 규칙을 적용한다. 외부 테이블이 섞여 있으면 데이터가 고아로 남는다.
Ranger 나 파일 권한 때문에 휴지통 디렉터리에 쓰지 못하면 Hadoop 은 휴지통을 건너뛰고 바로 지운다. 이 경우 경고만 남고 삭제는 성공하므로 눈치채기 어렵다.