[
https://issues.apache.org/jira/browse/PHOENIX-7026?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17783751#comment-17783751
]
ASF GitHub Bot commented on PHOENIX-7026:
-----------------------------------------
palashc commented on code in PR #1726:
URL: https://github.com/apache/phoenix/pull/1726#discussion_r1385432753
##########
phoenix-core/src/test/java/org/apache/phoenix/cache/ServerMetadataCacheTest.java:
##########
@@ -911,7 +913,330 @@ public void testSelectQueryDropIndex() throws Exception {
}
}
+ /**
+ * Test the case when a client upserts into multiple tables before calling
commit.
+ * Verify that last ddl timestamp was validated for all involved tables
only once.
+ */
+ @Test
+ public void testUpsertMultipleTablesWithOldDDLTimestamp() throws Exception
{
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ String url1 = QueryUtil.getConnectionUrl(props, config, "client1");
+ String url2 = QueryUtil.getConnectionUrl(props, config, "client2");
+ String tableName1 = generateUniqueName();
+ String tableName2 = generateUniqueName();
+ ConnectionQueryServices spyCqs1 =
Mockito.spy(driver.getConnectionQueryServices(url1, props));
+ ConnectionQueryServices spyCqs2 =
Mockito.spy(driver.getConnectionQueryServices(url2, props));
+
+ try (Connection conn1 = spyCqs1.connect(url1, props);
+ Connection conn2 = spyCqs2.connect(url2, props)) {
+
+ //client-1 creates 2 tables
+ createTable(conn1, tableName1, NEVER);
+ createTable(conn1, tableName2, NEVER);
+
+ //client-2 populates its cache, 1 getTable call for each table
+ query(conn2, tableName1);
+ query(conn2, tableName2);
+
+ //client-1 alters one of the tables
+ alterTableAddColumn(conn1, tableName2, "v3");
+
+ //client-2 upserts multiple rows to both tables before calling
commit
+ //verify the table metadata was fetched for each table
+ multiTableUpsert(conn2, tableName1, tableName2);
+ Mockito.verify(spyCqs2, Mockito.times(2)).getTable(eq(null),
+ any(byte[].class),
eq(PVarchar.INSTANCE.toBytes(tableName1)),
+ anyLong(), anyLong());
+ Mockito.verify(spyCqs2, Mockito.times(2)).getTable(eq(null),
+ any(byte[].class),
eq(PVarchar.INSTANCE.toBytes(tableName2)),
+ anyLong(), anyLong());
+ }
+ }
+
+ /**
+ * Test upserts into a multi-level view hierarchy.
+ */
+ @Test
+ public void testUpsertViewWithOldDDLTimestamp() throws Exception {
Review Comment:
I added one where a client drops a parent view concurrently with another
client upserting into its child view.
> Validate LAST_DDL_TIMESTAMP for write requests.
> -----------------------------------------------
>
> Key: PHOENIX-7026
> URL: https://issues.apache.org/jira/browse/PHOENIX-7026
> Project: Phoenix
> Issue Type: Sub-task
> Components: core
> Reporter: Rushabh Shah
> Assignee: Palash Chauhan
> Priority: Major
>
> We need to validate LAST_DDL_TIMESTAMP for write requests.
> We can't create an extra RPC like we do for read requests (PHOENIX-7025)
> since the semantics for executeQuery() and executeMutation() is very
> different.
> The usual semantic for batch write requests (assuming auto commit OFF) is:
> {noformat}
> conn = DriverManager.getConnection(getUrl(), props);
> conn.createStatement().execute("upsert into foo values (1,2)");
> conn.createStatement().execute("upsert into foo values (3,4)");
> conn.createStatement().execute("upsert into foo values (5,6)");
> conn.createStatement().execute("upsert into bar values ('a','b')");
> conn.createStatement().execute("upsert into bar values ('c','d')");
> conn.commit();
> {noformat}
> If we introduce an RPC for every execute() method, then it increases the
> latency of the write request.
> There are 2 options I can think of:
> # Call validateDDLTimestamp rpc for the very first execute() method for
> every table in the batch.
> ** Pros:
> *** An extra RPC is made only once in the whole batch for every table.
> *** Easy to implement.
> *** In case of StaleMetadataCacheException, the retry is very easy to
> implement.
> ** Cons:
> # Call validateDDLTimestamp rpc for all the tables in the batch when we call
> conn.commit()
> ** Pros
> *** We add only 1 extra RPC irrespective of the number of tables in the
> batch.
> ** Cons
> *** In case of StaleMetadataCacheException, the retry becomes very complex.
> We will have to re-create all the mutations that we have created in the
> executeMutation phase.
> *** If autocommit is turned ON, then we introduce an extra RPC for every
> execute() call which will introduce regression in this feature.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)