Binding SMALLINT to NULL -> MarshalException Preventing Cassandra Restart

81 views
Skip to first unread message

Affan Salman

unread,
May 24, 2016, 1:06:07 PM5/24/16
to cpp-dri...@lists.datastax.com

Hi,

Using cass_statement_bind_null() to UPDATE a SMALLINT COLUMN results in
the following error upon restart of the Cassandra server precluding
daemon startup:

INFO  16:40:44 Completed loading (8 ms; 21 keys) KeyCache cache
INFO  16:40:44 Replaying ./bin/../data/commitlog/CommitLog-6-1464106983530.log, ./bin/../data/commitlog/CommitLog-6-1464106983531.log
ERROR 16:40:44 Exiting due to error while processing commit log during initialization.
org.apache.cassandra.db.commitlog.CommitLogReplayer$CommitLogReplayException: Unexpected error deserializing mutation; saved to /tmp/mutation3698878320718606344dat.  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: Expected 2 bytes for a smallint (0)
	at org.apache.cassandra.db.commitlog.CommitLogReplayer.handleReplayError(CommitLogReplayer.java:644) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.db.commitlog.CommitLogReplayer.replayMutation(CommitLogReplayer.java:558) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.db.commitlog.CommitLogReplayer.replaySyncSection(CommitLogReplayer.java:511) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:406) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.db.commitlog.CommitLogReplayer.recover(CommitLogReplayer.java:153) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:189) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.db.commitlog.CommitLog.recover(CommitLog.java:169) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:283) [apache-cassandra-3.0.4.jar:3.0.4]
	at org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:551) [apache-cassandra-3.0.4.jar:3.0.4]

The attempted mutation replay fails to handle the NULL smallint.

This is easy to reproduce with a small C program by simply running it
and restarting the respective Cassandra server:

#include <cassandra.h>
#include <stdio.h>

void print_error(CassFuture* future) {
    const char* message;
    size_t      message_length;

    cass_future_error_message(future, &message, &message_length);
    fprintf(stderr, "Error: %.*s\n", (int) message_length, message);
}

static CassError set_smallint_null(CassSession *session)
{
    CassError      rc        = CASS_OK;
    const char*    cql       = "UPDATE example.write_type_mapping SET smallint_value = ? WHERE id = ?";
    CassStatement* statement = NULL;
    CassFuture*    future    = NULL;

    statement = cass_statement_new(cql, 2);

    cass_statement_bind_null(statement, 0);
    cass_statement_bind_int32(statement, 1, 1);

    future = cass_session_execute(session, statement);
    cass_future_wait(future);

    rc = cass_future_error_code(future);
    if (rc != CASS_OK) {
        print_error(future);
    }

    cass_future_free(future);
    cass_statement_free(statement);

    return rc;
}

int main()
{
    CassFuture*  connect_future = NULL;
    CassCluster* cluster        = cass_cluster_new();
    CassSession* session        = cass_session_new();

    /* Add contact point */
    cass_cluster_set_contact_points(cluster, "127.0.0.1");
    cass_cluster_set_protocol_version(cluster, 4);

    /* Provide the cluster object as configuration to connect the session */
    connect_future = cass_session_connect(session, cluster);

    if (cass_future_error_code(connect_future) == CASS_OK)
    {
        set_smallint_null(session);
    }
}

The TABLE example.write_type_mapping is defined as:

CREATE TABLE example.write_type_mapping (
    id int PRIMARY KEY,
    ascii_value ascii,
    bigint_value bigint,
    bool_value boolean,
    double_value double,
    float_value float,
    int_value int,
    smallint_value smallint,
    text_value text,
    varchar_value text
) WITH bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND comment = ''
    AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'}
    AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'}
    AND crc_check_chance = 1.0
    AND dclocal_read_repair_chance = 0.1
    AND default_time_to_live = 0
    AND gc_grace_seconds = 864000
    AND max_index_interval = 2048
    AND memtable_flush_period_in_ms = 0
    AND min_index_interval = 128
    AND read_repair_chance = 0.0
    AND speculative_retry = '99PERCENTILE';

If it helps, I have tested with the other integer types as well as the
rest of the data types listed in the TABLE DDL and none of them produce
this issue for me.

Some basic version and platform information:

CPP Driver Version: 2.3
Cassandra Version:  3.0.4
Platform:           Ubuntu 14.04.3 (3.13.0-45-generic SMP) x86_64

Can you please let me know if you need any other details?

Regards, Affan Salman

Affan Salman

unread,
May 24, 2016, 2:50:14 PM5/24/16
to cpp-dri...@lists.datastax.com

I wrote:

> Using cass_statement_bind_null() to UPDATE a SMALLINT COLUMN results in
> the following error upon restart of the Cassandra server precluding
> daemon startup:

Just thought I'd update the list:

I was able to easily start the server by removing the commit log files
in my environment. Prevention, however, is clearly better. :-)

Regards, Affan Salman
Reply all
Reply to author
Forward
0 new messages