-
Notifications
You must be signed in to change notification settings - Fork 3.7k
[DynamicPartition] Optimize the rule of creating dynamic partition #3679
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
Changes from all commits
2c862e8
c78b750
7545b5c
5dd0738
90faac2
0d23693
82a3cee
888d123
2dc45ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,7 +30,6 @@ | |
| import org.apache.doris.catalog.DynamicPartitionProperty; | ||
| import org.apache.doris.catalog.HashDistributionInfo; | ||
| import org.apache.doris.catalog.OlapTable; | ||
| import org.apache.doris.catalog.PartitionInfo; | ||
| import org.apache.doris.catalog.PartitionKey; | ||
| import org.apache.doris.catalog.RangePartitionInfo; | ||
| import org.apache.doris.catalog.Table; | ||
|
|
@@ -127,20 +126,20 @@ private Map<String, String> createDefaultRuntimeInfo() { | |
| return defaultRuntimeInfo; | ||
| } | ||
|
|
||
| private ArrayList<AddPartitionClause> getAddPartitionClause(OlapTable olapTable, Column partitionColumn, String partitionFormat) { | ||
| private ArrayList<AddPartitionClause> getAddPartitionClause(Database db, OlapTable olapTable, | ||
| Column partitionColumn, String partitionFormat) { | ||
| ArrayList<AddPartitionClause> addPartitionClauses = new ArrayList<>(); | ||
| Calendar calendar = Calendar.getInstance(); | ||
| DynamicPartitionProperty dynamicPartitionProperty = olapTable.getTableProperty().getDynamicPartitionProperty(); | ||
| RangePartitionInfo rangePartitionInfo = (RangePartitionInfo) olapTable.getPartitionInfo(); | ||
| Calendar currentDate = Calendar.getInstance(dynamicPartitionProperty.getTimeZone()); | ||
| for (int i = 0; i <= dynamicPartitionProperty.getEnd(); i++) { | ||
| String prevBorder = DynamicPartitionUtil.getPartitionRange(dynamicPartitionProperty.getTimeUnit(), | ||
| i, (Calendar) calendar.clone(), partitionFormat); | ||
| // continue if partition already exists | ||
| String nextBorder = DynamicPartitionUtil.getPartitionRange(dynamicPartitionProperty.getTimeUnit(), | ||
| i + 1, (Calendar) calendar.clone(), partitionFormat); | ||
| String prevBorder = DynamicPartitionUtil.getPartitionRangeString(dynamicPartitionProperty, | ||
| (Calendar) currentDate.clone(), i, partitionFormat); | ||
| String nextBorder = DynamicPartitionUtil.getPartitionRangeString(dynamicPartitionProperty, | ||
| (Calendar) currentDate.clone(), i + 1, partitionFormat); | ||
| PartitionValue lowerValue = new PartitionValue(prevBorder); | ||
| PartitionValue upperValue = new PartitionValue(nextBorder); | ||
| PartitionInfo partitionInfo = olapTable.getPartitionInfo(); | ||
| RangePartitionInfo info = (RangePartitionInfo) (partitionInfo); | ||
|
|
||
| boolean isPartitionExists = false; | ||
| Range<PartitionKey> addPartitionKeyRange; | ||
| try { | ||
|
|
@@ -149,10 +148,11 @@ private ArrayList<AddPartitionClause> getAddPartitionClause(OlapTable olapTable, | |
| addPartitionKeyRange = Range.closedOpen(lowerBound, upperBound); | ||
| } catch (AnalysisException e) { | ||
| // keys.size is always equal to column.size, cannot reach this exception | ||
| LOG.warn("Keys size is not equal to column size. Error={}", e.getMessage()); | ||
| LOG.warn("Keys size is not equal to column size. Error={}, db: {}, table: {}", e.getMessage(), | ||
| db.getFullName(), olapTable.getName()); | ||
| continue; | ||
| } | ||
| for (Range<PartitionKey> partitionKeyRange : info.getIdToRange(false).values()) { | ||
| for (Range<PartitionKey> partitionKeyRange : rangePartitionInfo.getIdToRange(false).values()) { | ||
| // only support single column partition now | ||
| try { | ||
| RangeUtils.checkRangeIntersect(partitionKeyRange, addPartitionKeyRange); | ||
|
|
@@ -161,7 +161,7 @@ private ArrayList<AddPartitionClause> getAddPartitionClause(OlapTable olapTable, | |
| if (addPartitionKeyRange.equals(partitionKeyRange)) { | ||
| clearCreatePartitionFailedMsg(olapTable.getName()); | ||
| } else { | ||
| recordCreatePartitionFailedMsg(olapTable.getName(), e.getMessage()); | ||
| recordCreatePartitionFailedMsg(db.getFullName(), olapTable.getName(), e.getMessage()); | ||
| } | ||
| break; | ||
| } | ||
|
|
@@ -174,7 +174,8 @@ private ArrayList<AddPartitionClause> getAddPartitionClause(OlapTable olapTable, | |
| PartitionKeyDesc partitionKeyDesc = new PartitionKeyDesc(Collections.singletonList(lowerValue), Collections.singletonList(upperValue)); | ||
| HashMap<String, String> partitionProperties = new HashMap<>(1); | ||
| partitionProperties.put("replication_num", String.valueOf(DynamicPartitionUtil.estimateReplicateNum(olapTable))); | ||
| String partitionName = dynamicPartitionProperty.getPrefix() + DynamicPartitionUtil.getFormattedPartitionName(prevBorder, dynamicPartitionProperty.getTimeUnit()); | ||
| String partitionName = dynamicPartitionProperty.getPrefix() + DynamicPartitionUtil.getFormattedPartitionName( | ||
| dynamicPartitionProperty.getTimeZone(), prevBorder, dynamicPartitionProperty.getTimeUnit()); | ||
| SingleRangePartitionDesc rangePartitionDesc = new SingleRangePartitionDesc(true, partitionName, | ||
| partitionKeyDesc, partitionProperties); | ||
|
|
||
|
|
@@ -192,15 +193,23 @@ private ArrayList<AddPartitionClause> getAddPartitionClause(OlapTable olapTable, | |
| return addPartitionClauses; | ||
| } | ||
|
|
||
| private ArrayList<DropPartitionClause> getDropPartitionClause(OlapTable olapTable, Column partitionColumn, String partitionFormat) { | ||
| /* | ||
| * 1. get the range of [start, 0) as a reserved range. | ||
| * 2. get DropPartitionClause of partitions which range are before this reserved range. | ||
| */ | ||
| private ArrayList<DropPartitionClause> getDropPartitionClause(Database db, OlapTable olapTable, Column partitionColumn, String partitionFormat) { | ||
| ArrayList<DropPartitionClause> dropPartitionClauses = new ArrayList<>(); | ||
| Calendar calendar = Calendar.getInstance(); | ||
| DynamicPartitionProperty dynamicPartitionProperty = olapTable.getTableProperty().getDynamicPartitionProperty(); | ||
| if (dynamicPartitionProperty.getStart() == DynamicPartitionProperty.MIN_START_OFFSET) { | ||
| // not set start offset, so not drop any partition | ||
| return dropPartitionClauses; | ||
| } | ||
|
|
||
| String lowerBorder = DynamicPartitionUtil.getPartitionRange(dynamicPartitionProperty.getTimeUnit(), | ||
| dynamicPartitionProperty.getStart(), (Calendar) calendar.clone(), partitionFormat); | ||
| String upperBorder = DynamicPartitionUtil.getPartitionRange(dynamicPartitionProperty.getTimeUnit(), | ||
| 0, (Calendar) calendar.clone(), partitionFormat); | ||
| Calendar currentDate = Calendar.getInstance(dynamicPartitionProperty.getTimeZone()); | ||
| String lowerBorder = DynamicPartitionUtil.getPartitionRangeString(dynamicPartitionProperty, | ||
| (Calendar) currentDate.clone(), dynamicPartitionProperty.getStart(), partitionFormat); | ||
| String upperBorder = DynamicPartitionUtil.getPartitionRangeString(dynamicPartitionProperty, | ||
| (Calendar) currentDate.clone(), 0, partitionFormat); | ||
| PartitionValue lowerPartitionValue = new PartitionValue(lowerBorder); | ||
| PartitionValue upperPartitionValue = new PartitionValue(upperBorder); | ||
| Range<PartitionKey> reservePartitionKeyRange; | ||
|
|
@@ -210,7 +219,8 @@ private ArrayList<DropPartitionClause> getDropPartitionClause(OlapTable olapTabl | |
| reservePartitionKeyRange = Range.closedOpen(lowerBound, upperBound); | ||
| } catch (AnalysisException e) { | ||
| // keys.size is always equal to column.size, cannot reach this exception | ||
| LOG.warn("Keys size is not equal to column size. Error={}", e.getMessage()); | ||
| LOG.warn("Keys size is not equal to column size. Error={}, db: {}, table: {}", e.getMessage(), | ||
| db.getFullName(), olapTable.getName()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe we should remove the warning, because dynamic_partition.start is default to Integer.MIN_VALUE, so we may got a AnalysisException like this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I will check this offset to make it reasonable.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just make a check that if |
||
| return dropPartitionClauses; | ||
| } | ||
| RangePartitionInfo info = (RangePartitionInfo) (olapTable.getPartitionInfo()); | ||
|
|
@@ -249,8 +259,8 @@ private void executeDynamicPartition() { | |
| ArrayList<DropPartitionClause> dropPartitionClauses; | ||
| String tableName; | ||
| boolean skipAddPartition = false; | ||
| db.readLock(); | ||
| OlapTable olapTable; | ||
| db.readLock(); | ||
| try { | ||
| olapTable = (OlapTable) db.getTable(tableId); | ||
| // Only OlapTable has DynamicPartitionProperty | ||
|
|
@@ -264,8 +274,7 @@ private void executeDynamicPartition() { | |
| if (olapTable.getState() != OlapTable.OlapTableState.NORMAL) { | ||
| String errorMsg = "Table[" + olapTable.getName() + "]'s state is not NORMAL." | ||
| + "Do not allow doing dynamic add partition. table state=" + olapTable.getState(); | ||
| recordCreatePartitionFailedMsg(olapTable.getName(), errorMsg); | ||
| LOG.info(errorMsg); | ||
| recordCreatePartitionFailedMsg(db.getFullName(), olapTable.getName(), errorMsg); | ||
| skipAddPartition = true; | ||
| } | ||
|
|
||
|
|
@@ -275,19 +284,25 @@ private void executeDynamicPartition() { | |
| // scheduler time should be record even no partition added | ||
| createOrUpdateRuntimeInfo(olapTable.getName(), LAST_SCHEDULER_TIME, TimeUtils.getCurrentFormatTime()); | ||
| RangePartitionInfo rangePartitionInfo = (RangePartitionInfo) olapTable.getPartitionInfo(); | ||
| if (rangePartitionInfo.getPartitionColumns().size() != 1) { | ||
| // currently only support partition with single column. | ||
| iterator.remove(); | ||
| continue; | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The single column check work is done when create table, no need to check here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is just a self-defence~ |
||
| Column partitionColumn = rangePartitionInfo.getPartitionColumns().get(0); | ||
| String partitionFormat; | ||
| try { | ||
| partitionFormat = DynamicPartitionUtil.getPartitionFormat(partitionColumn); | ||
| } catch (DdlException e) { | ||
| recordCreatePartitionFailedMsg(olapTable.getName(), e.getMessage()); | ||
| recordCreatePartitionFailedMsg(db.getFullName(), olapTable.getName(), e.getMessage()); | ||
| continue; | ||
| } | ||
|
|
||
| if (!skipAddPartition) { | ||
| addPartitionClauses = getAddPartitionClause(olapTable, partitionColumn, partitionFormat); | ||
| addPartitionClauses = getAddPartitionClause(db, olapTable, partitionColumn, partitionFormat); | ||
| } | ||
| dropPartitionClauses = getDropPartitionClause(olapTable, partitionColumn, partitionFormat); | ||
| dropPartitionClauses = getDropPartitionClause(db, olapTable, partitionColumn, partitionFormat); | ||
| tableName = olapTable.getName(); | ||
| } finally { | ||
| db.readUnlock(); | ||
|
|
@@ -299,7 +314,7 @@ private void executeDynamicPartition() { | |
| Catalog.getCurrentCatalog().dropPartition(db, olapTable, dropPartitionClause); | ||
| clearDropPartitionFailedMsg(tableName); | ||
| } catch (DdlException e) { | ||
| recordDropPartitionFailedMsg(tableName, e.getMessage()); | ||
| recordDropPartitionFailedMsg(db.getFullName(), tableName, e.getMessage()); | ||
| } finally { | ||
| db.writeUnlock(); | ||
| } | ||
|
|
@@ -311,15 +326,15 @@ private void executeDynamicPartition() { | |
| Catalog.getCurrentCatalog().addPartition(db, tableName, addPartitionClause); | ||
| clearCreatePartitionFailedMsg(tableName); | ||
| } catch (DdlException e) { | ||
| recordCreatePartitionFailedMsg(tableName, e.getMessage()); | ||
| recordCreatePartitionFailedMsg(db.getFullName(), tableName, e.getMessage()); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void recordCreatePartitionFailedMsg(String tableName, String msg) { | ||
| LOG.warn("dynamic add partition failed: " + msg); | ||
| private void recordCreatePartitionFailedMsg(String dbName, String tableName, String msg) { | ||
| LOG.warn("dynamic add partition failed: {}, db: {}, table: {}", msg, dbName, tableName); | ||
| createOrUpdateRuntimeInfo(tableName, DYNAMIC_PARTITION_STATE, State.ERROR.toString()); | ||
| createOrUpdateRuntimeInfo(tableName, CREATE_PARTITION_MSG, msg); | ||
| } | ||
|
|
@@ -329,8 +344,8 @@ private void clearCreatePartitionFailedMsg(String tableName) { | |
| createOrUpdateRuntimeInfo(tableName, CREATE_PARTITION_MSG, DEFAULT_RUNTIME_VALUE); | ||
| } | ||
|
|
||
| private void recordDropPartitionFailedMsg(String tableName, String msg) { | ||
| LOG.warn("dynamic drop partition failed: " + msg); | ||
| private void recordDropPartitionFailedMsg(String dbName, String tableName, String msg) { | ||
| LOG.warn("dynamic drop partition failed: {}, db: {}, table: {}", msg, dbName, tableName); | ||
| createOrUpdateRuntimeInfo(tableName, DYNAMIC_PARTITION_STATE, State.ERROR.toString()); | ||
| createOrUpdateRuntimeInfo(tableName, DROP_PARTITION_MSG, msg); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as following comment