[ 
https://issues.apache.org/jira/browse/CASSANDRA-14365?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Vincent White updated CASSANDRA-14365:
--------------------------------------
    Description: 
In the old storage engine, static cells with a collection as part of the 
clustering key fail to validate because a 0 byte collection (like in the cell 
name of a static cell) isn't valid.

To reproduce:

1.
{code:java}
CREATE TABLE test.x (
    id int,
    id2 frozen<map<text, text>>,
    st int static,
    PRIMARY KEY (id, id2)
);

INSERT INTO test.x (id, st) VALUES (1, 2);
{code}
2.
 Kill the cassandra process

3.
 Restart cassandra to replay the commitlog

Outcome:
{noformat}
ERROR [main] 2018-04-05 04:58:23,741 JVMStabilityInspector.java:99 - Exiting 
due to error while processing commit log during initialization.
org.apache.cassandra.db.commitlog.CommitLogReplayer$CommitLogReplayException: 
Unexpected error deserializing mutation; saved to 
/tmp/mutation3825739904516830950dat.  This may be caused by replaying a 
mutation against a table with the same name but incompatible schema.  Exception 
follows: org.apache.cassandra.serializers.MarshalException: Not enough bytes to 
read a set
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.handleReplayError(CommitLogReplayer.java:638)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.replayMutation(CommitLogReplayer.java:565)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.replaySyncSection(CommitLogReplayer.java:517)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:397)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:143)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:181) 
[main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:161) 
[main/:na]
        at 
org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:284) 
[main/:na]
        at 
org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:533) 
[main/:na]
        at 
org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:642) 
[main/:na]


{noformat}
I haven't investigated if there are other more subtle issues caused by these 
cells failing to validate other places in the code, but I believe the fix for 
this is to check for 0 byte length collections and accept them as valid as we 
do with other types.

I haven't had a chance for any extensive testing but this naive patch seems to 
have the desired affect. 


||Patch||
|[2.2 PoC 
Patch|https://github.com/vincewhite/cassandra/commits/zero_length_collection]|


  was:
In the old storage engine, static cells with a collection as part of the 
clustering key fail to validate because a 0 byte collection (like in the cell 
name of a static cell) isn't valid.

To reproduce:

1.
{code:java}
CREATE TABLE test.x (
    id int,
    id2 frozen<map<text, text>>,
    st int static,
    PRIMARY KEY (id, id2)
);

INSERT INTO test.x (id, st) VALUES (1, 2);
{code}
2.
 Kill the cassandra process

3.
 Restart cassandra to replay the commitlog

Outcome:
{noformat}
ERROR [main] 2018-04-05 04:58:23,741 JVMStabilityInspector.java:99 - Exiting 
due to error while processing commit log during initialization.
org.apache.cassandra.db.commitlog.CommitLogReplayer$CommitLogReplayException: 
Unexpected error deserializing mutation; saved to 
/tmp/mutation3825739904516830950dat.  This may be caused by replaying a 
mutation against a table with the same name but incompatible schema.  Exception 
follows: org.apache.cassandra.serializers.MarshalException: Not enough bytes to 
read a set
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.handleReplayError(CommitLogReplayer.java:638)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.replayMutation(CommitLogReplayer.java:565)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.replaySyncSection(CommitLogReplayer.java:517)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:397)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:143)
 [main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:181) 
[main/:na]
        at 
org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:161) 
[main/:na]
        at 
org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:284) 
[main/:na]
        at 
org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:533) 
[main/:na]
        at 
org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:642) 
[main/:na]


{noformat}
I haven't investigated if there are other more subtle issues caused by these 
cells failing to validate other places in the code, but I believe the fix for 
this is to check for 0 byte length collections and accept them as valid as we 
do with other types.

I haven't had a chance for any extensive testing but this naive patch seems to 
have the desired affect. [2.2 PoC 
Patch|https://github.com/vincewhite/cassandra/commits/zero_length_collection]


> Commit log replay failure for static columns with collections in clustering 
> keys
> --------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-14365
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-14365
>             Project: Cassandra
>          Issue Type: Bug
>          Components: Legacy/Core
>            Reporter: Vincent White
>            Assignee: Vincent White
>            Priority: Major
>
> In the old storage engine, static cells with a collection as part of the 
> clustering key fail to validate because a 0 byte collection (like in the cell 
> name of a static cell) isn't valid.
> To reproduce:
> 1.
> {code:java}
> CREATE TABLE test.x (
>     id int,
>     id2 frozen<map<text, text>>,
>     st int static,
>     PRIMARY KEY (id, id2)
> );
> INSERT INTO test.x (id, st) VALUES (1, 2);
> {code}
> 2.
>  Kill the cassandra process
> 3.
>  Restart cassandra to replay the commitlog
> Outcome:
> {noformat}
> ERROR [main] 2018-04-05 04:58:23,741 JVMStabilityInspector.java:99 - Exiting 
> due to error while processing commit log during initialization.
> org.apache.cassandra.db.commitlog.CommitLogReplayer$CommitLogReplayException: 
> Unexpected error deserializing mutation; saved to 
> /tmp/mutation3825739904516830950dat.  This may be caused by replaying a 
> mutation against a table with the same name but incompatible schema.  
> Exception follows: org.apache.cassandra.serializers.MarshalException: Not 
> enough bytes to read a set
>         at 
> org.apache.cassandra.db.commitlog.CommitLogReplayer.handleReplayError(CommitLogReplayer.java:638)
>  [main/:na]
>         at 
> org.apache.cassandra.db.commitlog.CommitLogReplayer.replayMutation(CommitLogReplayer.java:565)
>  [main/:na]
>         at 
> org.apache.cassandra.db.commitlog.CommitLogReplayer.replaySyncSection(CommitLogReplayer.java:517)
>  [main/:na]
>         at 
> org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:397)
>  [main/:na]
>         at 
> org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:143)
>  [main/:na]
>         at 
> org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:181) 
> [main/:na]
>         at 
> org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:161) 
> [main/:na]
>         at 
> org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:284) 
> [main/:na]
>         at 
> org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:533)
>  [main/:na]
>         at 
> org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:642) 
> [main/:na]
> {noformat}
> I haven't investigated if there are other more subtle issues caused by these 
> cells failing to validate other places in the code, but I believe the fix for 
> this is to check for 0 byte length collections and accept them as valid as we 
> do with other types.
> I haven't had a chance for any extensive testing but this naive patch seems 
> to have the desired affect. 
> ||Patch||
> |[2.2 PoC 
> Patch|https://github.com/vincewhite/cassandra/commits/zero_length_collection]|



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

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

Reply via email to