This is an automated email from the ASF dual-hosted git repository.
yihua pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hudi.git
The following commit(s) were added to refs/heads/master by this push:
new a33b2a5e03f [HUDI-7834] Create placeholder table versions and
introduce new hoodie table property to track initial table version (#11406)
a33b2a5e03f is described below
commit a33b2a5e03f434e3ce270a128be626ae9e9e78c9
Author: Balaji Varadarajan <[email protected]>
AuthorDate: Fri Jun 7 18:43:33 2024 -0700
[HUDI-7834] Create placeholder table versions and introduce new hoodie
table property to track initial table version (#11406)
Co-authored-by: Balaji Varadarajan <[email protected]>
Co-authored-by: Y Ethan Guo <[email protected]>
---
.../apache/hudi/cli/commands/RepairsCommand.java | 4 +++
.../upgrade/EightToSevenDowngradeHandler.java | 37 +++++++++++++++++++
.../table/upgrade/SevenToEightUpgradeHandler.java | 38 ++++++++++++++++++++
.../table/upgrade/SevenToSixDowngradeHandler.java | 40 +++++++++++++++++++++
.../table/upgrade/SixToSevenUpgradeHandler.java | 42 ++++++++++++++++++++++
.../hudi/table/upgrade/UpgradeDowngrade.java | 8 +++++
.../hudi/common/table/HoodieTableConfig.java | 16 +++++++++
.../hudi/common/table/HoodieTableMetaClient.java | 3 ++
.../hudi/common/table/HoodieTableVersion.java | 10 ++++--
.../common/table/TestHoodieTableMetaClient.java | 1 +
.../RepairOverwriteHoodiePropsProcedure.scala | 5 ++-
.../sql/hudi/procedure/TestRepairsProcedure.scala | 1 +
.../TestUpgradeOrDowngradeProcedure.scala | 4 +--
13 files changed, 203 insertions(+), 6 deletions(-)
diff --git
a/hudi-cli/src/main/java/org/apache/hudi/cli/commands/RepairsCommand.java
b/hudi-cli/src/main/java/org/apache/hudi/cli/commands/RepairsCommand.java
index 57ec8ccf57b..569136e0b50 100644
--- a/hudi-cli/src/main/java/org/apache/hudi/cli/commands/RepairsCommand.java
+++ b/hudi-cli/src/main/java/org/apache/hudi/cli/commands/RepairsCommand.java
@@ -161,6 +161,10 @@ public class RepairsCommand {
newProps.load(fileInputStream);
}
Map<String, String> oldProps = client.getTableConfig().propsMap();
+ // Copy Initial Version from old-props to new-props
+ if (oldProps.containsKey(HoodieTableConfig.INITIAL_VERSION.key())) {
+ newProps.put(HoodieTableConfig.INITIAL_VERSION.key(),
oldProps.get(HoodieTableConfig.INITIAL_VERSION.key()));
+ }
HoodieTableConfig.create(client.getStorage(), client.getMetaPath(),
newProps);
// reload new props as checksum would have been added
newProps =
diff --git
a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/EightToSevenDowngradeHandler.java
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/EightToSevenDowngradeHandler.java
new file mode 100644
index 00000000000..3bb22481681
--- /dev/null
+++
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/EightToSevenDowngradeHandler.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hudi.table.upgrade;
+
+import org.apache.hudi.common.config.ConfigProperty;
+import org.apache.hudi.common.engine.HoodieEngineContext;
+import org.apache.hudi.config.HoodieWriteConfig;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Version 7 is going to be placeholder version for bridge release 0.16.0.
+ * Version 8 is the placeholder version to track 1.x.
+ */
+public class EightToSevenDowngradeHandler implements DowngradeHandler {
+ @Override
+ public Map<ConfigProperty, String> downgrade(HoodieWriteConfig config,
HoodieEngineContext context, String instantTime, SupportsUpgradeDowngrade
upgradeDowngradeHelper) {
+ return Collections.emptyMap();
+ }
+}
diff --git
a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SevenToEightUpgradeHandler.java
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SevenToEightUpgradeHandler.java
new file mode 100644
index 00000000000..9ed4f192786
--- /dev/null
+++
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SevenToEightUpgradeHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hudi.table.upgrade;
+
+import org.apache.hudi.common.config.ConfigProperty;
+import org.apache.hudi.common.engine.HoodieEngineContext;
+import org.apache.hudi.config.HoodieWriteConfig;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * Version 7 is going to be placeholder version for bridge release 0.16.0.
+ * Version 8 is the placeholder version to track 1.x.
+ */
+public class SevenToEightUpgradeHandler implements UpgradeHandler {
+ @Override
+ public Map<ConfigProperty, String> upgrade(HoodieWriteConfig config,
HoodieEngineContext context,
+ String instantTime,
SupportsUpgradeDowngrade upgradeDowngradeHelper) {
+ return Collections.emptyMap();
+ }
+}
diff --git
a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SevenToSixDowngradeHandler.java
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SevenToSixDowngradeHandler.java
new file mode 100644
index 00000000000..5cf9b42bab2
--- /dev/null
+++
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SevenToSixDowngradeHandler.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hudi.table.upgrade;
+
+import org.apache.hudi.common.config.ConfigProperty;
+import org.apache.hudi.common.engine.HoodieEngineContext;
+import org.apache.hudi.config.HoodieWriteConfig;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * There is no format change between table version 6 and 7.
+ * Table version 7 is meant for required bridge release upgrade before
upgrading to 1.0.
+ * Version 7 is going to be placeholder version for bridge release 0.16.0.
+ * Version 8 is the placeholder version to track 1.x.
+ */
+public class SevenToSixDowngradeHandler implements DowngradeHandler {
+
+ @Override
+ public Map<ConfigProperty, String> downgrade(HoodieWriteConfig config,
HoodieEngineContext context, String instantTime, SupportsUpgradeDowngrade
upgradeDowngradeHelper) {
+ return Collections.emptyMap();
+ }
+}
diff --git
a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SixToSevenUpgradeHandler.java
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SixToSevenUpgradeHandler.java
new file mode 100644
index 00000000000..eb3c97bfcef
--- /dev/null
+++
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/SixToSevenUpgradeHandler.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hudi.table.upgrade;
+
+import org.apache.hudi.common.config.ConfigProperty;
+import org.apache.hudi.common.engine.HoodieEngineContext;
+import org.apache.hudi.config.HoodieWriteConfig;
+
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * There is no format change between table version 6 and 7.
+ * Table version 7 is meant for required bridge release upgrade before
upgrading to 1.0.
+ * Version 7 is going to be placeholder version for bridge release 0.16.0.
+ * Version 8 is the placeholder version to track 1.x.
+ */
+public class SixToSevenUpgradeHandler implements UpgradeHandler {
+
+ @Override
+ public Map<ConfigProperty, String> upgrade(HoodieWriteConfig config,
HoodieEngineContext context,
+ String instantTime,
+ SupportsUpgradeDowngrade
upgradeDowngradeHelper) {
+ return Collections.emptyMap();
+ }
+}
diff --git
a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/UpgradeDowngrade.java
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/UpgradeDowngrade.java
index b5177a5746b..c089f671481 100644
---
a/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/UpgradeDowngrade.java
+++
b/hudi-client/hudi-client-common/src/main/java/org/apache/hudi/table/upgrade/UpgradeDowngrade.java
@@ -174,6 +174,10 @@ public class UpgradeDowngrade {
return new FourToFiveUpgradeHandler().upgrade(config, context,
instantTime, upgradeDowngradeHelper);
} else if (fromVersion == HoodieTableVersion.FIVE && toVersion ==
HoodieTableVersion.SIX) {
return new FiveToSixUpgradeHandler().upgrade(config, context,
instantTime, upgradeDowngradeHelper);
+ } else if (fromVersion == HoodieTableVersion.SIX && toVersion ==
HoodieTableVersion.SEVEN) {
+ return new SixToSevenUpgradeHandler().upgrade(config, context,
instantTime, upgradeDowngradeHelper);
+ } else if (fromVersion == HoodieTableVersion.SEVEN && toVersion ==
HoodieTableVersion.EIGHT) {
+ return new SevenToEightUpgradeHandler().upgrade(config, context,
instantTime, upgradeDowngradeHelper);
} else {
throw new HoodieUpgradeDowngradeException(fromVersion.versionCode(),
toVersion.versionCode(), true);
}
@@ -192,6 +196,10 @@ public class UpgradeDowngrade {
return new FiveToFourDowngradeHandler().downgrade(config, context,
instantTime, upgradeDowngradeHelper);
} else if (fromVersion == HoodieTableVersion.SIX && toVersion ==
HoodieTableVersion.FIVE) {
return new SixToFiveDowngradeHandler().downgrade(config, context,
instantTime, upgradeDowngradeHelper);
+ } else if (fromVersion == HoodieTableVersion.SEVEN && toVersion ==
HoodieTableVersion.SIX) {
+ return new SevenToSixDowngradeHandler().downgrade(config, context,
instantTime, upgradeDowngradeHelper);
+ } else if (fromVersion == HoodieTableVersion.EIGHT && toVersion ==
HoodieTableVersion.SEVEN) {
+ return new EightToSevenDowngradeHandler().downgrade(config, context,
instantTime, upgradeDowngradeHelper);
} else {
throw new HoodieUpgradeDowngradeException(fromVersion.versionCode(),
toVersion.versionCode(), false);
}
diff --git
a/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableConfig.java
b/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableConfig.java
index 9210d1521ed..87263a13f9d 100644
---
a/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableConfig.java
+++
b/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableConfig.java
@@ -116,6 +116,13 @@ public class HoodieTableConfig extends HoodieConfig {
.withDocumentation("Version of table, used for running upgrade/downgrade
steps between releases with potentially "
+ "breaking/backwards compatible changes.");
+ public static final ConfigProperty<HoodieTableVersion> INITIAL_VERSION =
ConfigProperty
+ .key("hoodie.table.initial.version")
+ .defaultValue(HoodieTableVersion.ZERO)
+ .withDocumentation("Initial Version of table when the table was
created. Used for upgrade/downgrade"
+ + " to identify what upgrade/downgrade paths happened on the
table. This is only configured "
+ + "when the table is initially setup.");
+
public static final ConfigProperty<String> PRECOMBINE_FIELD = ConfigProperty
.key("hoodie.table.precombine.field")
.noDefaultValue()
@@ -512,6 +519,15 @@ public class HoodieTableConfig extends HoodieConfig {
: VERSION.defaultValue();
}
+ /**
+ * @return the hoodie.table.initial.version from hoodie.properties file.
+ */
+ public HoodieTableVersion getTableInitialVersion() {
+ return contains(INITIAL_VERSION)
+ ? HoodieTableVersion.versionFromCode(getInt(INITIAL_VERSION))
+ : INITIAL_VERSION.defaultValue();
+ }
+
public void setTableVersion(HoodieTableVersion tableVersion) {
setValue(VERSION, Integer.toString(tableVersion.versionCode()));
}
diff --git
a/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableMetaClient.java
b/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableMetaClient.java
index b41e447de08..e8e99ff9a0c 100644
---
a/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableMetaClient.java
+++
b/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableMetaClient.java
@@ -76,6 +76,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import static org.apache.hudi.common.table.HoodieTableConfig.INITIAL_VERSION;
import static org.apache.hudi.common.util.ConfigUtils.containsConfigProperty;
import static org.apache.hudi.common.util.ConfigUtils.getStringWithAltKeys;
import static org.apache.hudi.common.util.StringUtils.getUTF8Bytes;
@@ -623,6 +624,8 @@ public class HoodieTableMetaClient implements Serializable {
}
initializeBootstrapDirsIfNotExists(basePath, storage);
+ // When the table is initialized, set the initial version to be the
current version.
+ props.put(INITIAL_VERSION.key(),
String.valueOf(HoodieTableVersion.current().versionCode()));
HoodieTableConfig.create(storage, metaPathDir, props);
}
diff --git
a/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableVersion.java
b/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableVersion.java
index a0ec92473ca..f3ed871e125 100644
---
a/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableVersion.java
+++
b/hudi-common/src/main/java/org/apache/hudi/common/table/HoodieTableVersion.java
@@ -40,8 +40,12 @@ public enum HoodieTableVersion {
// 0.12.0 onwards
FIVE(5),
// 0.14.0 onwards
- SIX(6);
-
+ SIX(6),
+ // 0.16.0
+ SEVEN(7),
+ // 1.0 beta
+ EIGHT(8);
+
private final int versionCode;
HoodieTableVersion(int versionCode) {
@@ -53,7 +57,7 @@ public enum HoodieTableVersion {
}
public static HoodieTableVersion current() {
- return SIX;
+ return EIGHT;
}
public static HoodieTableVersion versionFromCode(int versionCode) {
diff --git
a/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/TestHoodieTableMetaClient.java
b/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/TestHoodieTableMetaClient.java
index 0ab72016893..b4e2fca80d3 100644
---
a/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/TestHoodieTableMetaClient.java
+++
b/hudi-hadoop-common/src/test/java/org/apache/hudi/common/table/TestHoodieTableMetaClient.java
@@ -63,6 +63,7 @@ public class TestHoodieTableMetaClient extends
HoodieCommonTestHarness {
"Metapath should be ${basepath}/.hoodie");
assertTrue(metaClient.getTableConfig().getProps().containsKey(HoodieTableConfig.TABLE_CHECKSUM.key()));
assertTrue(HoodieTableConfig.validateChecksum(metaClient.getTableConfig().getProps()));
+ assertEquals(HoodieTableVersion.current(),
metaClient.getTableConfig().getTableInitialVersion());
}
@Test
diff --git
a/hudi-spark-datasource/hudi-spark/src/main/scala/org/apache/spark/sql/hudi/command/procedures/RepairOverwriteHoodiePropsProcedure.scala
b/hudi-spark-datasource/hudi-spark/src/main/scala/org/apache/spark/sql/hudi/command/procedures/RepairOverwriteHoodiePropsProcedure.scala
index 3273c737747..fcc883c4aaf 100644
---
a/hudi-spark-datasource/hudi-spark/src/main/scala/org/apache/spark/sql/hudi/command/procedures/RepairOverwriteHoodiePropsProcedure.scala
+++
b/hudi-spark-datasource/hudi-spark/src/main/scala/org/apache/spark/sql/hudi/command/procedures/RepairOverwriteHoodiePropsProcedure.scala
@@ -20,7 +20,6 @@ package org.apache.spark.sql.hudi.command.procedures
import org.apache.hudi.common.table.{HoodieTableConfig, HoodieTableMetaClient}
import org.apache.hudi.hadoop.fs.HadoopFSUtils
-import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.Path
import org.apache.spark.internal.Logging
import org.apache.spark.sql.Row
@@ -68,6 +67,10 @@ class RepairOverwriteHoodiePropsProcedure extends
BaseProcedure with ProcedureBu
var newProps = new Properties
loadNewProps(overwriteFilePath, newProps)
val oldProps = metaClient.getTableConfig.propsMap
+ // Copy Initial Version from old props to new props
+ if (oldProps.containsKey(HoodieTableConfig.INITIAL_VERSION.key)) {
+ newProps.put(HoodieTableConfig.INITIAL_VERSION.key,
oldProps.get(HoodieTableConfig.INITIAL_VERSION.key))
+ }
HoodieTableConfig.create(metaClient.getStorage, metaClient.getMetaPath,
newProps)
// reload new props as checksum would have been added
newProps = HoodieTableMetaClient.reload(metaClient).getTableConfig.getProps
diff --git
a/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestRepairsProcedure.scala
b/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestRepairsProcedure.scala
index 154d9ecfb5a..c8c7e0cda8c 100644
---
a/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestRepairsProcedure.scala
+++
b/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestRepairsProcedure.scala
@@ -141,6 +141,7 @@ class TestRepairsProcedure extends
HoodieSparkProcedureTestBase {
|[hoodie.datasource.write.partitionpath.urlencode,false,null]
|[hoodie.table.checksum,,]
|[hoodie.table.create.schema,,]
+ |[hoodie.table.initial.version,8,8]
|[hoodie.table.keygenerator.type,NON_PARTITION,null]
|[hoodie.table.name,,]
|[hoodie.table.precombine.field,ts,null]
diff --git
a/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestUpgradeOrDowngradeProcedure.scala
b/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestUpgradeOrDowngradeProcedure.scala
index bc6f266eb94..3db05e6572d 100644
---
a/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestUpgradeOrDowngradeProcedure.scala
+++
b/hudi-spark-datasource/hudi-spark/src/test/scala/org/apache/spark/sql/hudi/procedure/TestUpgradeOrDowngradeProcedure.scala
@@ -54,10 +54,10 @@ class TestUpgradeOrDowngradeProcedure extends
HoodieSparkProcedureTestBase {
var metaClient = createMetaClient(spark, tablePath)
// verify hoodie.table.version of the original table
- assertResult(HoodieTableVersion.SIX.versionCode) {
+ assertResult(HoodieTableVersion.EIGHT.versionCode) {
metaClient.getTableConfig.getTableVersion.versionCode()
}
- assertTableVersionFromPropertyFile(metaClient,
HoodieTableVersion.SIX.versionCode)
+ assertTableVersionFromPropertyFile(metaClient,
HoodieTableVersion.EIGHT.versionCode)
// downgrade table to ZERO
checkAnswer(s"""call downgrade_table(table => '$tableName', to_version
=> 'ZERO')""")(Seq(true))