This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push:
new 827f5c0 [Bug-fix] Ignore modified table log when table has been
dropped (#5688)
827f5c0 is described below
commit 827f5c086775c54e5cbe84ca0268ba595fd2601d
Author: EmmyMiao87 <[email protected]>
AuthorDate: Tue Apr 27 09:40:17 2021 +0800
[Bug-fix] Ignore modified table log when table has been dropped (#5688)
Although the table lock can control the simultaneous modification of the
table by different threads.
But it cannot control the drop operation of the table by other threads.
For example, when drop table and table update occur at the same time.
1. get table object by thread 1
2. drop table by thread 2 with table lock
3. update table object by thread 1
The above process is possible.
At this time, step 3 actually operates a table that no longer exists, which
will eventually cause the wrong metadata to be recorded.
Fixed #5687
---
.../java/org/apache/doris/alter/AlterHandler.java | 4 +--
.../org/apache/doris/alter/SchemaChangeJobV2.java | 4 +--
.../java/org/apache/doris/catalog/Catalog.java | 38 +++++++++++++++++++---
.../java/org/apache/doris/catalog/Database.java | 2 +-
.../apache/doris/persist/ReplicaPersistInfo.java | 1 -
5 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
b/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
index 98e4e41..4cf206a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
@@ -427,7 +427,7 @@ public abstract class AlterHandler extends MasterDaemon {
if (replica == null) {
throw new MetaNotFoundException("replica " +
task.getNewReplicaId() + " does not exist");
}
-
+
LOG.info("before handle alter task tablet {}, replica: {}, task
version: {}-{}",
task.getSignature(), replica, task.getVersion(),
task.getVersionHash());
boolean versionChanged = false;
@@ -445,7 +445,7 @@ public abstract class AlterHandler extends MasterDaemon {
replica.getLastSuccessVersion(),
replica.getLastSuccessVersionHash());
Catalog.getCurrentCatalog().getEditLog().logUpdateReplica(info);
}
-
+
LOG.info("after handle alter task tablet: {}, replica: {}",
task.getSignature(), replica);
} finally {
tbl.writeUnlock();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
index 665f376..bd22ba2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
@@ -706,7 +706,7 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
this.watershedTxnId = replayedJob.watershedTxnId;
jobState = JobState.WAITING_TXN;
- LOG.info("replay pending schema change job: {}", jobId);
+ LOG.info("replay pending schema change job: {}, table id: {}", jobId,
tableId);
}
/**
@@ -735,7 +735,7 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
// should still be in WAITING_TXN state, so that the alter tasks will
be resend again
this.jobState = JobState.WAITING_TXN;
this.watershedTxnId = replayedJob.watershedTxnId;
- LOG.info("replay waiting txn schema change job: {}", jobId);
+ LOG.info("replay waiting txn schema change job: {} table id: {}",
jobId, tableId);
}
/**
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
index 3ae8116..265d221 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
@@ -147,6 +147,7 @@ import org.apache.doris.load.Load;
import org.apache.doris.load.LoadChecker;
import org.apache.doris.load.LoadErrorHub;
import org.apache.doris.load.LoadJob;
+import org.apache.doris.load.StreamLoadRecordMgr;
import org.apache.doris.load.loadv2.LoadEtlChecker;
import org.apache.doris.load.loadv2.LoadJobScheduler;
import org.apache.doris.load.loadv2.LoadLoadingChecker;
@@ -155,7 +156,6 @@ import org.apache.doris.load.loadv2.LoadTimeoutChecker;
import org.apache.doris.load.routineload.RoutineLoadManager;
import org.apache.doris.load.routineload.RoutineLoadScheduler;
import org.apache.doris.load.routineload.RoutineLoadTaskScheduler;
-import org.apache.doris.load.StreamLoadRecordMgr;
import org.apache.doris.master.Checkpoint;
import org.apache.doris.master.MetaHelper;
import org.apache.doris.meta.MetaContext;
@@ -225,14 +225,10 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
-import com.sleepycat.je.rep.InsufficientLogException;
-import com.sleepycat.je.rep.NetworkRestore;
-import com.sleepycat.je.rep.NetworkRestoreConfig;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.codehaus.jackson.map.ObjectMapper;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
@@ -262,6 +258,11 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
+import com.sleepycat.je.rep.InsufficientLogException;
+import com.sleepycat.je.rep.NetworkRestore;
+import com.sleepycat.je.rep.NetworkRestoreConfig;
+import org.codehaus.jackson.map.ObjectMapper;
+
public class Catalog {
private static final Logger LOG = LogManager.getLogger(Catalog.class);
// 0 ~ 9999 used for qe
@@ -4523,6 +4524,13 @@ public class Catalog {
public void replayAddReplica(ReplicaPersistInfo info) {
Database db = getDb(info.getDbId());
OlapTable olapTable = (OlapTable) db.getTable(info.getTableId());
+ if (olapTable == null) {
+ /**
+ * Same as replayUpdateReplica()
+ */
+ LOG.warn("Olap table is null when the add replica log is replayed,
{}", info);
+ return;
+ }
olapTable.writeLock();
try {
unprotectAddReplica(info);
@@ -4534,6 +4542,19 @@ public class Catalog {
public void replayUpdateReplica(ReplicaPersistInfo info) {
Database db = getDb(info.getDbId());
OlapTable olapTable = (OlapTable) db.getTable(info.getTableId());
+ if (olapTable == null) {
+ /**
+ * In the following cases, doris may record metadata modification
information for a table that no longer exists.
+ * 1. Thread 1: get TableA object
+ * 2. Thread 2: lock db and drop table and record edit log of the
dropped TableA
+ * 3. Thread 1: lock table, modify table and record edit log of
the modified TableA
+ * **The modified edit log is after the dropped edit log**
+ * Because the table has been dropped, the olapTable in here is
null when the modified edit log is replayed.
+ * So in this case, we will ignore the edit log of the modified
table after the table is dropped.
+ */
+ LOG.warn("Olap table is null when the update replica log is
replayed, {}", info);
+ return;
+ }
olapTable.writeLock();
try {
unprotectUpdateReplica(info);
@@ -4554,6 +4575,13 @@ public class Catalog {
public void replayDeleteReplica(ReplicaPersistInfo info) {
Database db = getDb(info.getDbId());
OlapTable tbl = (OlapTable) db.getTable(info.getTableId());
+ if (tbl == null) {
+ /**
+ * Same as replayUpdateReplica()
+ */
+ LOG.warn("Olap table is null when the delete replica log is
replayed, {}", info);
+ return;
+ }
tbl.writeLock();
try {
unprotectDeleteReplica(info);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
index c1d6f97..f1b7e82 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
@@ -433,7 +433,7 @@ public class Database extends MetaObject implements
Writable {
*/
public Table getTableOrThrowException(long tableId, TableType tableType)
throws MetaNotFoundException {
Table table = idToTable.get(tableId);
- if(table == null) {
+ if (table == null) {
throw new MetaNotFoundException("unknown table, tableId=" +
tableId);
}
if (table.getType() != tableType) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/persist/ReplicaPersistInfo.java
b/fe/fe-core/src/main/java/org/apache/doris/persist/ReplicaPersistInfo.java
index ed9935a..fdc8a3b 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/persist/ReplicaPersistInfo.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/persist/ReplicaPersistInfo.java
@@ -392,7 +392,6 @@ public class ReplicaPersistInfo implements Writable {
sb.append("table id: ").append(tableId);
sb.append(" partition id: ").append(partitionId);
sb.append(" index id: ").append(indexId);
- sb.append(" index id: ").append(indexId);
sb.append(" tablet id: ").append(tabletId);
sb.append(" backend id: ").append(backendId);
sb.append(" replica id: ").append(replicaId);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]