Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix](truncate) fix tablet invert index leaky #37334

Merged
merged 3 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3331,6 +3331,11 @@ public void truncateTable(TruncateTableStmt truncateTableStmt) throws DdlExcepti
List<Partition> newPartitions = Lists.newArrayList();
// tabletIdSet to save all newly created tablet ids.
Set<Long> tabletIdSet = Sets.newHashSet();
Runnable failedCleanCallback = () -> {
for (Long tabletId : tabletIdSet) {
Env.getCurrentInvertedIndex().deleteTablet(tabletId);
}
};
Map<Integer, Integer> clusterKeyMap = new TreeMap<>();
for (int i = 0; i < olapTable.getBaseSchema().size(); i++) {
Column column = olapTable.getBaseSchema().get(i);
Expand Down Expand Up @@ -3383,26 +3388,27 @@ public void truncateTable(TruncateTableStmt truncateTableStmt) throws DdlExcepti

} catch (DdlException e) {
// create partition failed, remove all newly created tablets
for (Long tabletId : tabletIdSet) {
Env.getCurrentInvertedIndex().deleteTablet(tabletId);
}
failedCleanCallback.run();
throw e;
}
Preconditions.checkState(origPartitions.size() == newPartitions.size());

// all partitions are created successfully, try to replace the old partitions.
// before replacing, we need to check again.
// Things may be changed outside the table lock.
olapTable = (OlapTable) db.getTableOrDdlException(copiedTbl.getId());
olapTable.writeLockOrDdlException();
List<Partition> oldPartitions = Lists.newArrayList();
boolean hasWriteLock = false;
try {
olapTable = (OlapTable) db.getTableOrDdlException(copiedTbl.getId());
olapTable.writeLockOrDdlException();
hasWriteLock = true;
olapTable.checkNormalStateForAlter();
// check partitions
for (Map.Entry<String, Long> entry : origPartitions.entrySet()) {
Partition partition = copiedTbl.getPartition(entry.getValue());
Partition partition = olapTable.getPartition(entry.getValue());
if (partition == null || !partition.getName().equalsIgnoreCase(entry.getKey())) {
throw new DdlException("Partition [" + entry.getKey() + "] is changed");
throw new DdlException("Partition [" + entry.getKey() + "] is changed"
+ " during truncating table, please retry");
}
}

Expand Down Expand Up @@ -3446,6 +3452,10 @@ public void truncateTable(TruncateTableStmt truncateTableStmt) throws DdlExcepti
}
}
}
if (DebugPointUtil.isEnable("InternalCatalog.truncateTable.metaChanged")) {
metaChanged = true;
LOG.warn("debug set truncate table meta changed");
}

if (metaChanged) {
throw new DdlException("Table[" + copiedTbl.getName() + "]'s meta has been changed. try again.");
Expand All @@ -3460,8 +3470,13 @@ public void truncateTable(TruncateTableStmt truncateTableStmt) throws DdlExcepti
newPartitions,
truncateEntireTable, truncateTableStmt.toSqlWithoutTable());
Env.getCurrentEnv().getEditLog().logTruncateTable(info);
} catch (DdlException e) {
failedCleanCallback.run();
throw e;
} finally {
olapTable.writeUnlock();
if (hasWriteLock) {
olapTable.writeUnlock();
}
}

erasePartitionDropBackendReplicas(oldPartitions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
import org.apache.doris.common.util.DebugPointUtil.DebugPoint;
import org.apache.doris.utframe.TestWithFeService;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class AddExistsPartitionTest extends TestWithFeService {

Expand All @@ -42,15 +46,20 @@ public void testAddExistsPartition() throws Exception {
createTable("CREATE TABLE test.tbl (k INT) DISTRIBUTED BY HASH(k) "
+ " BUCKETS 5 PROPERTIES ( \"replication_num\" = \"" + backendNum() + "\" )");
List<Long> backendIds = Env.getCurrentSystemInfo().getAllBackendIds();
Map<Long, Set<Long>> oldBackendTablets = Maps.newHashMap();
for (long backendId : backendIds) {
Assertions.assertEquals(5, Env.getCurrentInvertedIndex().getTabletIdsByBackendId(backendId).size());
Set<Long> tablets = Sets.newHashSet(Env.getCurrentInvertedIndex().getTabletIdsByBackendId(backendId));
Assertions.assertEquals(5, tablets.size());
oldBackendTablets.put(backendId, tablets);
}

String addPartitionSql = "ALTER TABLE test.tbl ADD PARTITION IF NOT EXISTS tbl"
+ " DISTRIBUTED BY HASH(k) BUCKETS 5";
Assertions.assertNotNull(getSqlStmtExecutor(addPartitionSql));
for (long backendId : backendIds) {
Assertions.assertEquals(5, Env.getCurrentInvertedIndex().getTabletIdsByBackendId(backendId).size());
Set<Long> tablets = Sets.newHashSet(Env.getCurrentInvertedIndex().getTabletIdsByBackendId(backendId));
Assertions.assertEquals(5, tablets.size());
Assertions.assertEquals(oldBackendTablets.get(backendId), tablets);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,27 @@
import org.apache.doris.analysis.ShowStmt;
import org.apache.doris.analysis.ShowTabletStmt;
import org.apache.doris.analysis.TruncateTableStmt;
import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ExceptionChecker;
import org.apache.doris.common.util.DebugPointUtil;
import org.apache.doris.common.util.DebugPointUtil.DebugPoint;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.ShowExecutor;
import org.apache.doris.qe.ShowResultSet;
import org.apache.doris.utframe.UtFrameUtils;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

public class TruncateTableTest {
Expand All @@ -44,6 +53,8 @@ public class TruncateTableTest {

@BeforeClass
public static void setup() throws Exception {
Config.disable_balance = true;
Config.enable_debug_points = true;
UtFrameUtils.createDorisCluster(runningDir);
connectContext = UtFrameUtils.createDefaultCtx();
// create database
Expand Down Expand Up @@ -165,6 +176,51 @@ public void testTruncateTable() throws Exception {
checkShowTabletResultNum("test.tbl", "p20210904", 5);
}

@Test
public void testTruncateTableFailed() throws Exception {
String createTableStr = "create table test.tbl2(d1 date, k1 int, k2 bigint)"
+ "duplicate key(d1, k1) "
+ "PARTITION BY RANGE(d1)"
+ "(PARTITION p20210901 VALUES [('2021-09-01'), ('2021-09-02')))"
+ "distributed by hash(k1) buckets 2 "
+ "properties('replication_num' = '1');";
createTable(createTableStr);
String partitionName = "p20210901";
Database db = Env.getCurrentInternalCatalog().getDbNullable("test");
OlapTable tbl2 = db.getOlapTableOrDdlException("tbl2");
Assert.assertNotNull(tbl2);
Partition p20210901 = tbl2.getPartition(partitionName);
Assert.assertNotNull(p20210901);
long partitionId = p20210901.getId();
p20210901.setVisibleVersionAndTime(2L, System.currentTimeMillis());

try {
List<Long> backendIds = Env.getCurrentSystemInfo().getAllBackendIds();
Map<Long, Set<Long>> oldBackendTablets = Maps.newHashMap();
for (long backendId : backendIds) {
Set<Long> tablets = Sets.newHashSet(Env.getCurrentInvertedIndex().getTabletIdsByBackendId(backendId));
oldBackendTablets.put(backendId, tablets);
}

DebugPointUtil.addDebugPoint("InternalCatalog.truncateTable.metaChanged", new DebugPoint());

String truncateStr = "truncate table test.tbl2 partition (" + partitionName + ");";
TruncateTableStmt truncateTableStmt = (TruncateTableStmt) UtFrameUtils.parseAndAnalyzeStmt(
truncateStr, connectContext);
ExceptionChecker.expectThrowsWithMsg(DdlException.class,
"Table[tbl2]'s meta has been changed. try again",
() -> Env.getCurrentEnv().truncateTable(truncateTableStmt));

Assert.assertEquals(partitionId, tbl2.getPartition(partitionName).getId());
for (long backendId : backendIds) {
Set<Long> tablets = Sets.newHashSet(Env.getCurrentInvertedIndex().getTabletIdsByBackendId(backendId));
Assert.assertEquals(oldBackendTablets.get(backendId), tablets);
}
} finally {
DebugPointUtil.removeDebugPoint("InternalCatalog.truncateTable.metaChanged");
}
}

private static void createDb(String sql) throws Exception {
CreateDbStmt createDbStmt = (CreateDbStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
Env.getCurrentEnv().createDb(createDbStmt);
Expand Down
Loading