[ 
https://issues.apache.org/jira/browse/CASSANDRA-17248?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17605998#comment-17605998
 ] 

Jaydeepkumar Chovatia edited comment on CASSANDRA-17248 at 9/16/22 9:35 PM:
----------------------------------------------------------------------------

[~ifesdjeen], I think this fix does not solve the regression as there is still 
a regression when we are upgrading from the pre-3.0.26 version.
 # For example, there are three Cassandra nodes, N1, N2, and N3 running a 
version before 3.0.26
 # There are two keyspaces k1 and k2, which has the exact same table schema in 
them. Say k1.t1 schema = k2.t1 schema
 # Application behavior with pre 3.0.26 with the prepared statement as follows: 
{code:java}
Application1 (Contacting the N1):
a. gocql.Execute("Use K1")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID1 (as expected){code}
{code:java}
Application2 (Contacting the N1):
a. gocql.Execute("Use K2")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID2 (as expected){code}

 # Now we upgrade N1 from 3.0.14 --> 3.0.26 (which has this fix) and yet N2, N3 
are on pre 3.0.26 versions

 * 
{code:java}
Application1 (Contacting the N1):
a. gocql.Execute("Use K1")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID1 (as expected){code}
{code:java}
Application2 (Contacting the N1):
a. gocql.Execute("Use K2")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID1 (Unexpected behavior!!!!){code}

If we look at the expected output after step3.c ({_}ID1 and ID2{_}), then it 
does not match with the expected output after step4.c ({_}ID1,{_} 
{_}*{color:#ff0000}ID1{color}*{_})

And I believe this regression is because while we are upgrading, the boolean 
flag "{_}newPreparedStatementBehaviour"{_} will be "{_}false{_}," so we exclude 
the keyspace names in the hash calculation; hence two same non-qualified query 
for a different keyspace would have the same hash, which is 
*{color:#ff0000}incorrect behavior with 3.0.26,{color}* and that brings 
unexpected behavior such as the query for _K1_ might be served by _K2_ on the 
server side or vice versa

The following code line from this fix is the issue.
{code:java}
ResultMessage.Prepared nonQualifiedWithoutKeyspace = 
storePreparedStatement(queryString, null, prepared, forThrift);    
if (!newPreparedStatementBehaviour)   
    return nonQualifiedWithoutKeyspace;    
return nonQualifiedWithKeyspace;{code}
However, pre 3.0.26, we used to always consider keyspace in the calculation so 
hash ID would never collide for the same non-qualified query.
{code:java}
ResultMessage.Prepared existing = getStoredPreparedStatement(queryString, 
clientState.getRawKeyspace(), forThrift)
if (existing != null)
    return existing; {code}
Could you please validate the above theory?

 

Jaydeep

 


was (Author: chovatia.jayd...@gmail.com):
[~ifesdjeen], I think this fix does not solve the regression as there is still 
a regression when we are upgrading from the pre-3.0.26 version.
 # For example, there are three Cassandra nodes, N1, N2, and N3 running a 
version before 3.0.26
 # There are two keyspaces k1 and k2, which has the exact same table schema in 
them. Say k1.t1 schema = k2.t1 schema
 # Application behavior with pre 3.0.26 with the prepared statement as follows: 
{code:java}
Application1 (Contacting the N1):
a. gocql.Execute("Use K1")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID1 (as expected){code}
{code:java}
Application2 (Contacting the N1):
a. gocql.Execute("Use K2")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID2 (as expected){code}

 # Now we upgrade N1 from 3.0.14 --> 3.0.26 (which has this fix) and yet N2, N3 
are on pre 3.0.26 versions

 * 
{code:java}
Application1 (Contacting the N1):
a. gocql.Execute("Use K1")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID1 (as expected){code}
{code:java}
Application2 (Contacting the N1):
a. gocql.Execute("Use K2")
b. PreparedStatement ps = gocql.Prepare("SELECT * FROM T1")
c. Print(ps.preparedID) // prints ID1 (Unexpected behavior!!!!){code}

If we look at the expected output after step3.c ({_}ID1 and ID2{_}), then it 
does not match with the expected output after step4.c ({_}ID1,{_} 
{_}*{color:#ff0000}ID1{color}*{_})

And I believe this regression is because while we are upgrading the flag 
"{_}newPreparedStatementBehaviour"{_} will be "{_}false{_}," so we exclude the 
keyspace names in the hash calculation; hence two same non-qualified query for 
a different keyspace would have the same hash, which is 
*{color:#ff0000}incorrect behavior with 3.0.26,{color}* and that brings 
unexpected behavior such as the query for _K1_ might be served by _K2_ on the 
server side or vice versa

The following code line from this fix is the issue.
{code:java}
ResultMessage.Prepared nonQualifiedWithoutKeyspace = 
storePreparedStatement(queryString, null, prepared, forThrift);    
if (!newPreparedStatementBehaviour)   
    return nonQualifiedWithoutKeyspace;    
return nonQualifiedWithKeyspace;{code}
However, pre 3.0.26, we used to always consider keyspace in the calculation so 
hash ID would never collide for the same non-qualified query.
{code:java}
ResultMessage.Prepared existing = getStoredPreparedStatement(queryString, 
clientState.getRawKeyspace(), forThrift)
if (existing != null)
    return existing; {code}
Could you please validate the above theory?

 

Jaydeep

 

> Fix Prepared Statements behaviours after 15252
> ----------------------------------------------
>
>                 Key: CASSANDRA-17248
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-17248
>             Project: Cassandra
>          Issue Type: Bug
>          Components: Messaging/Client
>            Reporter: Alex Petrov
>            Assignee: Alex Petrov
>            Priority: Normal
>             Fix For: 3.0.26, 3.11.12, 4.0.2
>
>
> [CASSANDRA-15252] has fixed an important issue: unwanted hash changes when 
> preparing fully qualified prepared statements which was causing 
> cluster-killing re-prepare loops. However, the fix introduced a regression: 
> non-qualified statements can get prepared against one keyspace but then 
> executed on another under some circumstances. This patch reconciles all 
> behaviours.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to