[fix](statistics)Fix empty table keep auto analyze bug. (#40811) (#40896)

backport: https://github.com/apache/doris/pull/40811
This commit is contained in:
Jibing-Li
2024-09-18 12:51:44 +08:00
committed by GitHub
parent 4511d3e900
commit c176c9feb0
4 changed files with 73 additions and 21 deletions

View File

@ -63,7 +63,7 @@ public class AnalysisInfoBuilder {
private boolean usingSqlForPartitionColumn;
private long tblUpdateTime;
private boolean emptyJob;
private boolean userInject;
private boolean userInject = false;
private long rowCount;
public AnalysisInfoBuilder() {

View File

@ -26,6 +26,7 @@ import org.apache.doris.common.io.Writable;
import org.apache.doris.persist.gson.GsonPostProcessable;
import org.apache.doris.persist.gson.GsonUtils;
import org.apache.doris.statistics.AnalysisInfo.JobType;
import org.apache.doris.statistics.util.StatisticsUtil;
import com.google.common.annotations.VisibleForTesting;
import com.google.gson.annotations.SerializedName;
@ -159,7 +160,9 @@ public class TableStatsMeta implements Writable, GsonPostProcessable {
public void update(AnalysisInfo analyzedJob, TableIf tableIf) {
updatedTime = analyzedJob.tblUpdateTime;
userInjected = analyzedJob.userInject;
if (analyzedJob.userInject) {
userInjected = true;
}
for (Pair<String, String> colPair : analyzedJob.jobColumns) {
ColStatsMeta colStatsMeta = colToColStatsMeta.get(colPair);
if (colStatsMeta == null) {
@ -179,15 +182,18 @@ public class TableStatsMeta implements Writable, GsonPostProcessable {
indexesRowCount.putAll(analyzedJob.indexesRowCount);
clearStaleIndexRowCount((OlapTable) tableIf);
}
if (analyzedJob.emptyJob) {
return;
}
if (analyzedJob.jobColumns.containsAll(
tableIf.getColumnIndexPairs(
tableIf.getSchemaAllIndexes(false).stream().map(Column::getName).collect(Collectors.toSet())))) {
tableIf.getSchemaAllIndexes(false).stream()
.filter(c -> !StatisticsUtil.isUnsupportedType(c.getType()))
.map(Column::getName).collect(Collectors.toSet())))) {
updatedRows.set(0);
newPartitionLoaded.set(false);
}
// Set userInject back to false after manual analyze.
if (JobType.MANUAL.equals(jobType) && !analyzedJob.userInject) {
userInjected = false;
}
}
}

View File

@ -43,7 +43,6 @@ import org.apache.doris.catalog.Partition;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.catalog.ScalarType;
import org.apache.doris.catalog.StructType;
import org.apache.doris.catalog.TableAttributes;
import org.apache.doris.catalog.TableIf;
import org.apache.doris.catalog.Type;
import org.apache.doris.catalog.VariantType;
@ -878,27 +877,26 @@ public class StatisticsUtil {
}
public static boolean isEmptyTable(TableIf table, AnalysisInfo.AnalysisMethod method) {
int waitRowCountReportedTime = 90;
int waitRowCountReportedTime = 120;
if (!(table instanceof OlapTable) || method.equals(AnalysisInfo.AnalysisMethod.FULL)) {
return false;
}
OlapTable olapTable = (OlapTable) table;
long rowCount = 0;
for (int i = 0; i < waitRowCountReportedTime; i++) {
if (olapTable.getRowCount() > 0) {
return false;
}
// If visible version is 2, table is probably not empty. So we wait row count to be reported.
// If visible version is not 2 and getRowCount return 0, we assume it is an empty table.
if (olapTable.getVisibleVersion() != TableAttributes.TABLE_INIT_VERSION + 1) {
return true;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.info("Sleep interrupted.", e);
rowCount = olapTable.getRowCountForIndex(olapTable.getBaseIndexId(), true);
// rowCount == -1 means new table or first load row count not fully reported, need to wait.
if (rowCount == -1) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.info("Sleep interrupted.");
}
continue;
}
break;
}
return true;
return rowCount == 0;
}
}