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 0554e89  [Alter] Fix bug of assertion failure when submitting schema 
change job (#3181)
0554e89 is described below

commit 0554e89645aedc88f28ba0f0d25039e4d64d60da
Author: Mingyu Chen <[email protected]>
AuthorDate: Tue Mar 31 12:06:30 2020 +0800

    [Alter] Fix bug of assertion failure when submitting schema change job 
(#3181)
    
    When creating a schema change job, we will create a corresponding shadow 
replica for each replica.
    Here we should check the state of the replica and only create replicas in 
the normal state.
    
    The process here may need to be modified later. We should completely allow 
users to submit alter jobs
    under any circumstances, and then in the job scheduling process, 
dynamically detect changes in the replicas
    and do replica repairs, instead of forcing a check on submission.
---
 .../doris/alter/MaterializedViewHandler.java       |  2 +-
 .../apache/doris/alter/SchemaChangeHandler.java    | 33 +++++++++++++++++++++-
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git 
a/fe/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java 
b/fe/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
index 3ccee56..1f1b90b 100644
--- a/fe/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
+++ b/fe/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
@@ -376,7 +376,7 @@ public class MaterializedViewHandler extends AlterHandler {
                                 baseReplica.getId(), baseTabletId, 
baseReplica.getState(), baseReplica.getLastFailedVersion());
                         continue;
                     }
-                    Preconditions.checkState(baseReplica.getState() == 
Replica.ReplicaState.NORMAL);
+                    Preconditions.checkState(baseReplica.getState() == 
Replica.ReplicaState.NORMAL, baseReplica.getState());
                     // replica's init state is ALTER, so that tablet report 
process will ignore its report
                     Replica mvReplica = new Replica(mvReplicaId, backendId, 
Replica.ReplicaState.ALTER,
                                                     
Partition.PARTITION_INIT_VERSION, Partition
diff --git a/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java 
b/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
index 4279f71..2fc03a4 100644
--- a/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
+++ b/fe/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
@@ -1082,6 +1082,7 @@ public class SchemaChangeHandler extends AlterHandler {
             long shadowIndexId = catalog.getNextId();
 
             // create SHADOW index for each partition
+            List<Tablet> addedTablets = Lists.newArrayList();
             for (Partition partition : olapTable.getPartitions()) {
                 long partitionId = partition.getId();
                 TStorageMedium medium = 
olapTable.getPartitionInfo().getDataProperty(partitionId).getStorageMedium();
@@ -1089,24 +1090,54 @@ public class SchemaChangeHandler extends AlterHandler {
                 MaterializedIndex shadowIndex = new 
MaterializedIndex(shadowIndexId, IndexState.SHADOW);
                 MaterializedIndex originIndex = 
partition.getIndex(originIndexId);
                 TabletMeta shadowTabletMeta = new TabletMeta(dbId, tableId, 
partitionId, shadowIndexId, newSchemaHash, medium);
+                short replicationNum = 
olapTable.getPartitionInfo().getReplicationNum(partitionId);
                 for (Tablet originTablet : originIndex.getTablets()) {
                     long originTabletId = originTablet.getId();
                     long shadowTabletId = catalog.getNextId();
 
                     Tablet shadowTablet = new Tablet(shadowTabletId);
                     shadowIndex.addTablet(shadowTablet, shadowTabletMeta);
+                    addedTablets.add(shadowTablet);
 
                     schemaChangeJob.addTabletIdMap(partitionId, shadowIndexId, 
shadowTabletId, originTabletId);
                     List<Replica> originReplicas = originTablet.getReplicas();
 
+                    int healthyReplicaNum = 0;
                     for (Replica originReplica : originReplicas) {
                         long shadowReplicaId = catalog.getNextId();
                         long backendId = originReplica.getBackendId();
-                        Preconditions.checkState(originReplica.getState() == 
ReplicaState.NORMAL);
+                        
+                        if (originReplica.getState() == 
Replica.ReplicaState.CLONE
+                                || originReplica.getState() == 
Replica.ReplicaState.DECOMMISSION
+                                || originReplica.getLastFailedVersion() > 0) {
+                            LOG.info("origin replica {} of tablet {} state is 
{}, and last failed version is {}, skip creating shadow replica",
+                                    originReplica.getId(), originReplica, 
originReplica.getState(), originReplica.getLastFailedVersion());
+                            continue;
+                        }
+                        Preconditions.checkState(originReplica.getState() == 
ReplicaState.NORMAL, originReplica.getState());
+                        // replica's init state is ALTER, so that tablet 
report process will ignore its report
                         Replica shadowReplica = new Replica(shadowReplicaId, 
backendId, ReplicaState.ALTER,
                                 Partition.PARTITION_INIT_VERSION, 
Partition.PARTITION_INIT_VERSION_HASH,
                                 newSchemaHash);
                         shadowTablet.addReplica(shadowReplica);
+                        healthyReplicaNum++;
+                    }
+
+                    if (healthyReplicaNum < replicationNum / 2 + 1) {
+                        /*
+                         * TODO(cmy): This is a bad design.
+                         * Because in the schema change job, we will only send 
tasks to the shadow replicas that have been created,
+                         * without checking whether the quorum of replica 
number are satisfied.
+                         * This will cause the job to fail until we find that 
the quorum of replica number
+                         * is not satisfied until the entire job is done.
+                         * So here we check the replica number strictly and do 
not allow to submit the job
+                         * if the quorum of replica number is not satisfied.
+                         */
+                        for (Tablet tablet : addedTablets) {
+                            
Catalog.getCurrentInvertedIndex().deleteTablet(tablet.getId());
+                        }
+                        throw new DdlException(
+                                "tablet " + originTabletId + " has few healthy 
replica: " + healthyReplicaNum);
                     }
                 }
                 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to