This is an automated email from the ASF dual-hosted git repository.
abstractdog pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 459f25c826a HIVE-30024: Fix scheduled queries for HA configuration
(#6766)
459f25c826a is described below
commit 459f25c826a8f489045d62ae0403c2f741707411
Author: InvisibleProgrammer <[email protected]>
AuthorDate: Tue Sep 22 11:04:56 2026 +0200
HIVE-30024: Fix scheduled queries for HA configuration (#6766)
---
.../apache/hadoop/hive/metastore/ObjectStore.java | 2 +-
.../client/TestMetastoreScheduledQueries.java | 114 ++++++++++++++++++---
2 files changed, 98 insertions(+), 18 deletions(-)
diff --git
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
index 2dffb7feacb..3ca67b9f6b1 100644
---
a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
+++
b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java
@@ -2953,7 +2953,7 @@ private void
processScheduledQueryPolicies(ScheduledQueryProgressInfo info) thro
query = pm.newQuery(MScheduledExecution.class);
query.setFilter("scheduledQuery == currentSchedule");
- query.setOrdering("scheduledExecutionId descending");
+ query.setOrdering("endTime descending, scheduledExecutionId descending");
query.declareParameters("MScheduledQuery currentSchedule");
query.setRange(0, lastN);
List<MScheduledExecution> list = (List<MScheduledExecution>)
query.execute(schq);
diff --git
a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/client/TestMetastoreScheduledQueries.java
b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/client/TestMetastoreScheduledQueries.java
index 1ac58ded074..a212d20b4ec 100644
---
a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/client/TestMetastoreScheduledQueries.java
+++
b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/client/TestMetastoreScheduledQueries.java
@@ -23,6 +23,7 @@
import static org.apache.hadoop.hive.metastore.utils.TestTxnDbUtil.prepDb;
import static
org.apache.hadoop.hive.metastore.utils.TestTxnDbUtil.queryToString;
import static
org.apache.hadoop.hive.metastore.utils.TestTxnDbUtil.setConfValues;
+import static org.awaitility.Awaitility.await;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
@@ -31,8 +32,8 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import java.sql.SQLException;
import java.sql.Statement;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -41,11 +42,13 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
+import javax.jdo.Transaction;
import org.apache.curator.shaded.com.google.common.collect.Lists;
import org.apache.hadoop.conf.Configuration;
@@ -103,11 +106,7 @@ public TestMetastoreScheduledQueries(String name,
AbstractMetaStoreService metaS
@Before
public void setUp() throws Exception {
-
metaStore.getConf().set(MetastoreConf.ConfVars.SCHEDULED_QUERIES_AUTODISABLE_COUNT.getVarname(),
"-1");
-
metaStore.getConf().set(MetastoreConf.ConfVars.SCHEDULED_QUERIES_SKIP_OPPORTUNITIES_AFTER_FAILURES.getVarname(),
- "0");
- client = metaStore.getClient();
-
+ prepareMetastoreClientWithAutoDisable("-1", "0");
}
@After
@@ -345,28 +344,22 @@ public ScheduledQueryPollResponse call() throws Exception
{
@Test
public void testDisable1() throws Exception {
-
metaStore.getConf().set(MetastoreConf.ConfVars.SCHEDULED_QUERIES_AUTODISABLE_COUNT.getVarname(),
"1");
- client.close();
- client = metaStore.getClient();
+ prepareMetastoreClientWithAutoDisable("1", null);
+
testDisableInternal(2, 5, "dis1");
}
@Test
public void testDisable2() throws Exception {
-
metaStore.getConf().set(MetastoreConf.ConfVars.SCHEDULED_QUERIES_AUTODISABLE_COUNT.getVarname(),
"2");
- client.close();
- client = metaStore.getClient();
+ prepareMetastoreClientWithAutoDisable("2", null);
+
testDisableInternal(3, 5, "dis2");
}
@Test
public void testSkip2() throws Exception {
-
metaStore.getConf().set(MetastoreConf.ConfVars.SCHEDULED_QUERIES_AUTODISABLE_COUNT.getVarname(),
"4");
-
metaStore.getConf().set(MetastoreConf.ConfVars.SCHEDULED_QUERIES_SKIP_OPPORTUNITIES_AFTER_FAILURES.getVarname(),
- "2");
- client.close();
- client = metaStore.getClient();
+ prepareMetastoreClientWithAutoDisable("4", "2");
testDisableInternal(5, 6, "skip2");
try (PersistenceManager pm =
PersistenceManagerProvider.getPersistenceManager()) {
@@ -395,6 +388,93 @@ public void testSkip2() throws Exception {
}
}
+
+ /**
+ * This test stimulates DataNucleus' id pre-allocation feature and creates
id gaps between executions
+ * The test checks if auto disabling still works assuming the execution id
generation doesn't generate strictly
+ * monotonous growing values
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAutoDisablePolicyUsesEndTime() throws Exception {
+ String testNamespace = "endTimeNamespace";
+ prepareMetastoreClientWithAutoDisable("2", "0");
+
+ ScheduledQueryKey key = new ScheduledQueryKey("q1", testNamespace);
+ createEverySecondSchq(key);
+
+ long exec1Id = pollAndGetExecutionId(testNamespace);
+ client.scheduledQueryProgress(
+ new ScheduledQueryProgressInfo(exec1Id, QueryState.FINISHED,
"executor-query-id"));
+
+ long exec2Id = pollAndGetExecutionId(testNamespace);
+ ScheduledQueryProgressInfo exec2Info =
+ new ScheduledQueryProgressInfo(exec2Id, QueryState.FAILED,
"executor-query-id");
+ exec2Info.setErrorMessage("some issue happened");
+ client.scheduledQueryProgress(exec2Info);
+
+ stimulateIdPreallocation(exec1Id, exec2Id);
+
+ long exec3Id = pollAndGetExecutionId(testNamespace);
+ ScheduledQueryProgressInfo exec3Info =
+ new ScheduledQueryProgressInfo(exec3Id, QueryState.FAILED,
"executor-query-id");
+ exec2Info.setErrorMessage("some issue happened");
+ client.scheduledQueryProgress(exec3Info);
+
+ ScheduledQuery schq = client.getScheduledQuery(key);
+ assertTrue("Scheduled query should be enabled", schq.isEnabled());
+ }
+
+ private void stimulateIdPreallocation(long exec1Id, long exec2Id) {
+ int skewedRecentEndTime = getEpochSeconds();
+ try (PersistenceManager pm =
PersistenceManagerProvider.getPersistenceManager()) {
+ Transaction tx = pm.currentTransaction();
+ tx.begin();
+ MScheduledExecution exec1 = pm.getObjectById(MScheduledExecution.class,
exec1Id);
+ exec1.setEndTime(skewedRecentEndTime);
+ MScheduledExecution exec2 = pm.getObjectById(MScheduledExecution.class,
exec2Id);
+ exec2.setEndTime(1);
+ tx.commit();
+ }
+ }
+
+ private void prepareMetastoreClientWithAutoDisable(String autoDisableCount,
String skipOpportunitiesAfterFailures) throws MetaException {
+ if (autoDisableCount != null) {
+
metaStore.getConf().set(ConfVars.SCHEDULED_QUERIES_AUTODISABLE_COUNT.getVarname(),
autoDisableCount);
+ }
+
+ if (skipOpportunitiesAfterFailures != null) {
+
metaStore.getConf().set(ConfVars.SCHEDULED_QUERIES_SKIP_OPPORTUNITIES_AFTER_FAILURES.getVarname(),
skipOpportunitiesAfterFailures);
+ }
+
+ if (client != null) {
+ client.close();
+ }
+ client = metaStore.getClient();
+ }
+
+ private long pollAndGetExecutionId(String testNamespace) {
+ ScheduledQueryPollRequest request = new
ScheduledQueryPollRequest(testNamespace);
+ AtomicReference<Long> executionId = new AtomicReference<>();
+
+ await()
+ .atMost(Duration.ofSeconds(3))
+ .pollInterval(Duration.ofMillis(100))
+ .until(() -> {
+ ScheduledQueryPollResponse response =
client.scheduledQueryPoll(request);
+
+ if (response.isSetQuery()) {
+ executionId.set(response.getExecutionId());
+ return true;
+ }
+
+ return false;
+ });
+
+ return executionId.get();
+ }
+
/**
* Simulates some schq failure scenario.
*