Skip to content

Commit 4e04ee8

Browse files
HIVE-29528: Cleanup managed DB dir after async drop (apache#6397)
1 parent b2e2523 commit 4e04ee8

7 files changed

Lines changed: 67 additions & 12 deletions

File tree

ql/src/java/org/apache/hadoop/hive/ql/txn/compactor/CleanupRequest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class CleanupRequest {
3030
private final String location;
3131
private final List<Path> obsoleteDirs;
3232
private final boolean purge;
33+
private final boolean softDelete;
34+
private final boolean sourceOfReplication;
3335
private final String runAs;
3436
private final String dbName;
3537
private final String fullPartitionName;
@@ -38,6 +40,8 @@ public CleanupRequest(CleanupRequestBuilder builder) {
3840
this.location = builder.location;
3941
this.obsoleteDirs = builder.obsoleteDirs;
4042
this.purge = builder.purge;
43+
this.softDelete = builder.softDelete;
44+
this.sourceOfReplication = builder.sourceOfReplication;
4145
this.runAs = builder.runAs;
4246
this.dbName = builder.dbName;
4347
this.fullPartitionName = builder.fullPartitionName;
@@ -55,6 +59,14 @@ public boolean isPurge() {
5559
return purge;
5660
}
5761

62+
public boolean isSoftDelete() {
63+
return softDelete;
64+
}
65+
66+
public boolean isSourceOfReplication() {
67+
return sourceOfReplication;
68+
}
69+
5870
public String runAs() {
5971
return runAs;
6072
}
@@ -74,6 +86,8 @@ public static class CleanupRequestBuilder {
7486
private String location;
7587
private List<Path> obsoleteDirs;
7688
private boolean purge;
89+
private boolean softDelete;
90+
private boolean sourceOfReplication;
7791
private String runAs;
7892
private String dbName;
7993
private String fullPartitionName;
@@ -93,6 +107,16 @@ public CleanupRequestBuilder setPurge(boolean purge) {
93107
return this;
94108
}
95109

110+
public CleanupRequestBuilder setSoftDelete(boolean softDelete) {
111+
this.softDelete = softDelete;
112+
return this;
113+
}
114+
115+
public CleanupRequestBuilder setSourceOfReplication(boolean sourceOfReplication) {
116+
this.sourceOfReplication = sourceOfReplication;
117+
return this;
118+
}
119+
96120
public CleanupRequestBuilder setDbName(String dbName) {
97121
this.dbName = dbName;
98122
return this;

ql/src/java/org/apache/hadoop/hive/ql/txn/compactor/FSRemover.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,18 @@ private List<Path> removeFiles(CleanupRequest cr)
9999
LOG.info("About to remove {} obsolete directories from {}. {}", cr.getObsoleteDirs().size(),
100100
cr.getLocation(), CompactorUtil.getDebugInfo(cr.getObsoleteDirs()));
101101
boolean needCmRecycle;
102+
Database db = null;
102103
try {
103-
Database db = metadataCache.computeIfAbsent(cr.getDbName(),
104+
db = metadataCache.computeIfAbsent(cr.getDbName(),
104105
() -> CompactorUtil.resolveDatabase(conf, cr.getDbName()));
105106
needCmRecycle = ReplChangeManager.isSourceOfReplication(db);
106107
} catch (NoSuchObjectException ex) {
107108
// can not drop a database which is a source of replication
108-
needCmRecycle = false;
109+
needCmRecycle = cr.isSourceOfReplication();
109110
} catch (RuntimeException ex) {
110111
if (ex.getCause() instanceof NoSuchObjectException) {
111112
// can not drop a database which is a source of replication
112-
needCmRecycle = false;
113+
needCmRecycle = cr.isSourceOfReplication();
113114
} else {
114115
throw ex;
115116
}
@@ -126,6 +127,21 @@ private List<Path> removeFiles(CleanupRequest cr)
126127
deleted.add(dead);
127128
}
128129
}
130+
removeDbDirIfOrphaned(db, cr, fs);
129131
return deleted;
130132
}
133+
134+
private void removeDbDirIfOrphaned(Database db, CleanupRequest cr, FileSystem fs) throws IOException {
135+
if (db != null || !cr.isSoftDelete()) {
136+
return;
137+
}
138+
Path databasePath = new Path(cr.getLocation()).getParent();
139+
if (!FileUtils.isDirEmpty(fs, databasePath)) {
140+
return;
141+
}
142+
if (cr.isSourceOfReplication()) {
143+
replChangeManager.recycle(databasePath, ReplChangeManager.RecycleType.MOVE, cr.isPurge());
144+
}
145+
FileUtils.deleteDir(fs, databasePath, cr.isPurge(), conf);
146+
}
131147
}

ql/src/java/org/apache/hadoop/hive/ql/txn/compactor/handler/CompactionCleaner.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ private void cleanUsingLocation(CompactionInfo ci, String path, boolean requires
198198
deleted = fsRemover.clean(getCleaningRequestBasedOnLocation(ci, path));
199199
}
200200
if (!deleted.isEmpty()) {
201-
ci.setSoftDelete(true);
202-
txnHandler.markCleaned(ci);
201+
txnHandler.markCleaned(ci.asSoftDeleted());
203202
} else {
204203
txnHandler.clearCleanerStart(ci);
205204
}
@@ -287,6 +286,8 @@ private CleanupRequest getCleaningRequestBasedOnLocation(CompactionInfo ci, Stri
287286
.setFullPartitionName(ci.getFullPartitionName())
288287
.setRunAs(ci.runAs)
289288
.setPurge(ifPurge)
289+
.setSoftDelete(true)
290+
.setSourceOfReplication(ci.isSourceOfReplication())
290291
.setObsoleteDirs(Collections.singletonList(obsoletePath))
291292
.build();
292293
}

ql/src/test/org/apache/hadoop/hive/ql/TestTxnCommands.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.hadoop.hive.ql;
1919

2020
import java.io.File;
21+
import java.io.FileNotFoundException;
2122
import java.io.FileOutputStream;
2223
import java.io.IOException;
2324
import java.util.ArrayList;
@@ -1827,11 +1828,9 @@ private void dropDatabaseCascadeNonBlocking() throws Exception {
18271828

18281829
runCleaner(hiveConf);
18291830

1830-
stat = fs.listStatus(new Path(getWarehouseDir(), database + ".db"),
1831-
t -> t.getName().matches("(mv_)?" + tableName + "2" + SOFT_DELETE_TABLE_PATTERN));
1832-
if (stat.length != 0) {
1833-
Assert.fail("Table data was not removed from FS");
1834-
}
1831+
Assert.assertThrows(database + ".db directory should not exist", FileNotFoundException.class, () -> {
1832+
fs.listStatus(new Path(getWarehouseDir(), database + ".db"));
1833+
});
18351834
}
18361835

18371836
@Test

standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/AcidEventListener.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.hadoop.hive.metastore;
2020

2121
import org.apache.hadoop.conf.Configuration;
22+
import org.apache.hadoop.hive.common.repl.ReplConst;
2223
import org.apache.hadoop.hive.metastore.api.CompactionRequest;
2324
import org.apache.hadoop.hive.metastore.api.CompactionType;
2425
import org.apache.hadoop.hive.metastore.api.Database;
@@ -91,6 +92,10 @@ public void onDropTable(DropTableEvent tableEvent) throws MetaException {
9192
rqst.setRunas(TxnUtils.findUserToRunAs(table.getSd().getLocation(), table, conf));
9293
rqst.putToProperties("location", table.getSd().getLocation());
9394
rqst.putToProperties("ifPurge", Boolean.toString(isMustPurge(tableEvent.getEnvironmentContext(), table)));
95+
if (Boolean.parseBoolean(tableEvent.getEnvironmentContext().getProperties()
96+
.get(ReplConst.SOURCE_OF_REPLICATION))) {
97+
rqst.putToProperties(ReplConst.SOURCE_OF_REPLICATION, Boolean.TRUE.toString());
98+
}
9499
txnHandler.submitForCleanup(rqst, table.getWriteId(), currentTxn);
95100
} catch (InterruptedException | IOException e) {
96101
throwMetaException(e);

standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/handler/DropDatabaseHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.concurrent.atomic.AtomicReference;
2929

3030
import org.apache.hadoop.fs.Path;
31+
import org.apache.hadoop.hive.common.repl.ReplConst;
3132
import org.apache.hadoop.hive.metastore.Batchable;
3233
import org.apache.hadoop.hive.metastore.HMSHandler;
3334
import org.apache.hadoop.hive.metastore.IHMSHandler;
@@ -136,6 +137,9 @@ public DropDatabaseResult execute() throws TException, IOException {
136137
if (isSoftDelete) {
137138
context = new EnvironmentContext();
138139
context.putToProperties(hive_metastoreConstants.TXN_ID, String.valueOf(request.getTxnId()));
140+
if (ReplChangeManager.isSourceOfReplication(db)) {
141+
context.putToProperties(ReplConst.SOURCE_OF_REPLICATION, Boolean.TRUE.toString());
142+
}
139143
request.setDeleteManagedDir(false);
140144
}
141145
DropTableRequest dropRequest = new DropTableRequest(name, table.getTableName());

standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/txn/entities/CompactionInfo.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import org.apache.commons.lang3.builder.ToStringBuilder;
2121
import org.apache.hadoop.hive.common.ValidCompactorWriteIdList;
22+
import org.apache.hadoop.hive.common.repl.ReplConst;
2223
import org.apache.hadoop.hive.metastore.api.CompactionInfoStruct;
2324
import org.apache.hadoop.hive.metastore.api.CompactionType;
2425
import org.apache.hadoop.hive.metastore.api.MetaException;
@@ -371,11 +372,16 @@ public boolean isAbortedTxnCleanup() {
371372
return type == CompactionType.ABORT_TXN_CLEANUP;
372373
}
373374

374-
public void setSoftDelete(boolean softDelete) {
375-
this.softDelete = softDelete;
375+
public CompactionInfo asSoftDeleted() {
376+
this.softDelete = true;
377+
return this;
376378
}
377379

378380
public boolean isSoftDelete() {
379381
return softDelete;
380382
}
383+
384+
public boolean isSourceOfReplication() {
385+
return Boolean.parseBoolean(getProperty(ReplConst.SOURCE_OF_REPLICATION));
386+
}
381387
}

0 commit comments

Comments
 (0)