Summary
This article provides additional information regarding unsupported operations on collection data types in Advanced Replication.
Applies to
- DataStax Enterprise 5.1.0 and newer
Symptoms
Advanced Replication fails to replicate some mutations to the destination cluster. In the logs, Advanced Replication reports some mutations are not supported. Here is a sample log entry from a DSE 5.1.8 cluster:
ERROR [AdvRep-MutationsSenders:12] 2018-06-30 12:34:56,789 NoSpamLogger.java:100 - \
Error replicating mutation from source table collections.films_by_year to destination Wakanda [789012345] com.datastax.bdp.advrep.replication.exceptions.UnsupportedMutationException: \
Mutation is not supported for replication, it contains a complex type Mutation in an UPDATE CQL statement(Collection or UDT.) \
Complex type Mutations are ONLY supported for replication in INSERT or DELETE CQL Statements. at com.datastax.bdp.advrep.CassandraDerived.asMap(CassandraDerived.java:170) ~[dse-advrep-5.1.8.jar:5.1.8] at com.datastax.bdp.advrep.util.cf.RowUtil.asReplicationMessages(RowUtil.java:107) ~[dse-advrep-5.1.8.jar:5.1.8] at com.datastax.bdp.advrep.util.cf.RowUtil.extractReplicationMessages(RowUtil.java:262) ~[dse-advrep-5.1.8.jar:5.1.8] at com.datastax.bdp.advrep.util.cf.RowUtil.extractReplicationMessages(RowUtil.java:230) ~[dse-advrep-5.1.8.jar:5.1.8] at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_92] at java.util.Collections$2.tryAdvance(Collections.java:4717) ~[na:1.8.0_92] at java.util.Collections$2.forEachRemaining(Collections.java:4725) ~[na:1.8.0_92]
...
Cause
As the error message indicates, UPDATE
statements are not supported for unfrozen CQL collection types. Updates are also not supported for unfrozen user-defined data types (UDTs) as documented in DSE Advanced Replication data types. In the above example, the mutation pertains to a map
collection (CassandraDerived.asMap()
).
In Cassandra, all the elements of a frozen value is serialised into a single [blob] value. When a frozen map, set or list is updated, the whole value is overwritten in its entirety.
In contrast, elements of an unfrozen value can be updated/deleted individually or even appended to. Consider the following operation where the movie "Black Panther" is added to a set
of films:
cqlsh> UPDATE collections.films_by_year SET films = films + {'Black Panther'} WHERE year = 2018;
In order to append to the existing value Cassandra requires a read-before-write, i.e. it must read the current value of films
before it can add another element. The CQL statements required to replicate this type of mutation to a remote cluster is quite complex which is the reason it is not currently supported.
Workaround
Advanced Replication can only replicate the entire column value resulting from an INSERT
or DELETE
statement. It is not recommended to get around this limitation by using INSERT
statements to overwrite the entire value since under the hood, Cassandra will delete the entire column and replace it with the new value which will generate tombstones and affect the performance of the cluster as noted in About updating sets and maps caution.
If your use case has a heavy reliance on being able to use UPDATE
statements on unfrozen collections, please get in touch with your DataStax Account Representative to organise a consulting engagement to explore viable alternatives.
Solution
There is an outstanding feature request that is pending development (internal feature ID DSP-12270). Click the "Follow" button above to get notification updates.
See also
Support KB - Using INSERT on set data types can create tombstones