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