You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by "Alex Petrov (JIRA)" <ji...@apache.org> on 2016/05/17 10:37:12 UTC

[jira] [Comment Edited] (CASSANDRA-10786) Include hash of result set metadata in prepared statement id

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

Alex Petrov edited comment on CASSANDRA-10786 at 5/17/16 10:37 AM:
-------------------------------------------------------------------

I have a patch to fix the described behaviour. In order to verify whether or not the patch works, I had to also come up with at some patch for the client that would work.

After adding result metadata to md5, as the message metadata on the client is never updated and new client ID of the re-prepared message is not saved anywhere, client would fall into the infinite re-prepare loop: 
  * (1) try running the query
  * fail with {{UNPREPARED}}
  * re-prepare (although without saving the new ID)
  * go to (1)

I first tried to transparently swap the request when getting {{UNPREPARED}}, although that would mean that the original "outdated" prepared query would re-prepare no matter how many times it runs (even though results it returns would be correct). On the other hand, making changes in the {{BoundStatement}} itself (or in it's {{PreparedStatement}}) might lead to undesired behaviour on the client-side or even be prone to races (when request is sent assuming one id and metadata and came back after it got swapped).

I put the failing test on ignore for now until we decide what could should be done on the driver side in this case.

I've created a corresponding [java driver issue|https://datastax-oss.atlassian.net/browse/JAVA-1196]


was (Author: ifesdjeen):
I have a patch to fix the described behaviour. In order to verify whether or not the patch works, I had to also come up with at some patch for the client that would work.

After adding result metadata to md5, as the message metadata on the client is never updated and new client ID of the re-prepared message is not saved anywhere, client would fall into the infinite re-prepare loop: 
  * (1) try running the query
  * fail with {{UNPREPARED}}
  * re-prepare (although without saving the new ID)
  * go to (1)

I first tried to transparently swap the request when getting {{UNPREPARED}}, although that would mean that the original "outdated" prepared query would re-prepare no matter how many times it runs (even though results it returns would be correct). On the other hand, making changes in the {{BoundStatement}} itself (or in it's {{PreparedStatement}}) might lead to undesired behaviour on the client-side or even be prone to races (when request is sent assuming one id and metadata and came back after it got swapped).

I put the failing test on ignore for now until we decide what could should be done on the driver side in this case.

> Include hash of result set metadata in prepared statement id
> ------------------------------------------------------------
>
>                 Key: CASSANDRA-10786
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-10786
>             Project: Cassandra
>          Issue Type: Bug
>          Components: CQL
>            Reporter: Olivier Michallat
>            Assignee: Alex Petrov
>            Priority: Minor
>              Labels: client-impacting
>             Fix For: 3.x
>
>
> This is a follow-up to CASSANDRA-7910, which was about invalidating a prepared statement when the table is altered, to force clients to update their local copy of the metadata.
> There's still an issue if multiple clients are connected to the same host. The first client to execute the query after the cache was invalidated will receive an UNPREPARED response, re-prepare, and update its local metadata. But other clients might miss it entirely (the MD5 hasn't changed), and they will keep using their old metadata. For example:
> # {{SELECT * ...}} statement is prepared in Cassandra with md5 abc123, clientA and clientB both have a cache of the metadata (columns b and c) locally
> # column a gets added to the table, C* invalidates its cache entry
> # clientA sends an EXECUTE request for md5 abc123, gets UNPREPARED response, re-prepares on the fly and updates its local metadata to (a, b, c)
> # prepared statement is now in C*’s cache again, with the same md5 abc123
> # clientB sends an EXECUTE request for id abc123. Because the cache has been populated again, the query succeeds. But clientB still has not updated its metadata, it’s still (b,c)
> One solution that was suggested is to include a hash of the result set metadata in the md5. This way the md5 would change at step 3, and any client using the old md5 would get an UNPREPARED, regardless of whether another client already reprepared.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)