Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CASSANDRA-10383 #1831

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
282 changes: 141 additions & 141 deletions .circleci/config.yml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
4.2
* Make disabling auto snapshot on selected tables possible (CASSANDRA-10383)
* Introduce compaction priorities to prevent upgrade compaction inability to finish (CASSANDRA-17851)
* Prevent a user from manually removing ephemeral snapshots (CASSANDRA-17757)
* Remove dependency on Maven Ant Tasks (CASSANDRA-17750)
Expand Down
5 changes: 5 additions & 0 deletions NEWS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,18 @@ New features
isEmptyWithoutStatus() our usage of hbState() + applicationState), however there are other failure cases which
block host replacements and require intrusive workarounds and human intervention to recover from when you
have something in hbState() you don't expect. See CASSANDRA-17842 for further details.
- Added new CQL table property 'allow_auto_snapshot' which is by default true. When set to false and 'auto_snapshot: true'
in cassandra.yaml, there will be no snapshot taken when a table is truncated or dropped. When auto_snapshot in
casandra.yaml is set to false, the newly added table property does not have any effect.

Upgrading
---------
- Ephemeral marker files for snapshots done by repairs are not created anymore,
there is a dedicated flag in snapshot manifest instead. On upgrade of a node to version 4.2, on node's start, in case there
are such ephemeral snapshots on disk, they will be deleted (same behaviour as before) and any new ephemeral snapshots
will stop to create ephemeral marker files as flag in a snapshot manifest was introduced instead.
- There was new table property introduced called 'allow_auto_snapshot' (see section 'New features'). Hence, upgraded
node will be on a new schema version. Please do a rolling upgrade of nodes of a cluster to converge to one schema version.

Deprecation
-----------
Expand Down
3 changes: 3 additions & 0 deletions pylib/cqlshlib/cql3handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def __str__(self):
class Cql3ParsingRuleSet(CqlParsingRuleSet):

columnfamily_layout_options = (
('allow_auto_snapshot', None),
('bloom_filter_fp_chance', None),
('comment', None),
('gc_grace_seconds', None),
Expand Down Expand Up @@ -514,6 +515,8 @@ def cf_prop_val_completer(ctxt, cass):
return [Hint('<true|false>')]
if this_opt in ('read_repair'):
return [Hint('<\'none\'|\'blocking\'>')]
if this_opt == 'allow_auto_snapshot':
return [Hint('<boolean>')]
return [Hint('<option_value>')]


Expand Down
8 changes: 5 additions & 3 deletions pylib/cqlshlib/test/test_cqlsh_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,8 @@ def create_columnfamily_table_template(self, name):
self.trycompletions(prefix + ' new_table (col_a int PRIMARY KEY) W',
immediate='ITH ')
self.trycompletions(prefix + ' new_table (col_a int PRIMARY KEY) WITH ',
choices=['bloom_filter_fp_chance', 'compaction',
choices=['allow_auto_snapshot',
'bloom_filter_fp_chance', 'compaction',
'compression',
'default_time_to_live', 'gc_grace_seconds',
'max_index_interval',
Expand All @@ -625,7 +626,8 @@ def create_columnfamily_table_template(self, name):
'COMPACT', 'caching', 'comment',
'min_index_interval', 'speculative_retry', 'additional_write_policy', 'cdc', 'read_repair'])
self.trycompletions(prefix + ' new_table (col_a int PRIMARY KEY) WITH ',
choices=['bloom_filter_fp_chance', 'compaction',
choices=['allow_auto_snapshot',
'bloom_filter_fp_chance', 'compaction',
'compression',
'default_time_to_live', 'gc_grace_seconds',
'max_index_interval',
Expand Down Expand Up @@ -673,7 +675,7 @@ def create_columnfamily_table_template(self, name):
choices=[';', 'AND'])
self.trycompletions(prefix + " new_table (col_a int PRIMARY KEY) WITH compaction = "
+ "{'class': 'SizeTieredCompactionStrategy'} AND ",
choices=['bloom_filter_fp_chance', 'compaction',
choices=['allow_auto_snapshot', 'bloom_filter_fp_chance', 'compaction',
'compression',
'default_time_to_live', 'gc_grace_seconds',
'max_index_interval',
Expand Down
1 change: 1 addition & 0 deletions pylib/cqlshlib/test/test_cqlsh_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ def test_describe_columnfamily_output(self):
varcharcol text,
varintcol varint
) WITH additional_write_policy = '99p'
AND allow_auto_snapshot = true
AND bloom_filter_fp_chance = 0.01
AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
AND cdc = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ public static Set<String> allKeywords()

private TableParams build(TableParams.Builder builder)
{
if (hasOption(Option.ALLOW_AUTO_SNAPSHOT))
builder.allowAutoSnapshot(getBoolean(Option.ALLOW_AUTO_SNAPSHOT.toString(), true));

if (hasOption(Option.BLOOM_FILTER_FP_CHANCE))
builder.bloomFilterFpChance(getDouble(Option.BLOOM_FILTER_FP_CHANCE));

Expand Down
11 changes: 8 additions & 3 deletions src/java/org/apache/cassandra/db/ColumnFamilyStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2581,7 +2581,7 @@ private void truncateBlocking(boolean noSnapshot)

if (!noSnapshot &&
((keyspace.getMetadata().params.durableWrites && !memtableWritesAreDurable()) // need to clear dirty regions
|| DatabaseDescriptor.isAutoSnapshot())) // need sstable for snapshot
|| isAutoSnapshotEnabled()))
{
replayAfter = forceBlockingFlush(FlushReason.TRUNCATE);
viewManager.forceBlockingFlush(FlushReason.TRUNCATE);
Expand Down Expand Up @@ -2614,7 +2614,7 @@ public void run()
"Stopping parent sessions {} due to truncation of tableId="+metadata.id);
data.notifyTruncated(truncatedAt);

if (!noSnapshot && DatabaseDescriptor.isAutoSnapshot())
if (!noSnapshot && isAutoSnapshotEnabled())
snapshot(Keyspace.getTimestampedSnapshotNameWithPrefix(name, SNAPSHOT_TRUNCATE_PREFIX), DatabaseDescriptor.getAutoSnapshotTtl());

discardSSTables(truncatedAt);
Expand Down Expand Up @@ -3073,6 +3073,11 @@ public boolean isKeyCacheEnabled()
return metadata().params.caching.cacheKeys() && CacheService.instance.keyCache.getCapacity() > 0;
}

public boolean isAutoSnapshotEnabled()
{
return metadata().params.allowAutoSnapshot && DatabaseDescriptor.isAutoSnapshot();
}

/**
* Discard all SSTables that were created before given timestamp.
*
Expand Down Expand Up @@ -3207,7 +3212,7 @@ void onTableDropped()

CompactionManager.instance.interruptCompactionForCFs(concatWithIndexes(), (sstable) -> true, true);

if (DatabaseDescriptor.isAutoSnapshot())
if (isAutoSnapshotEnabled())
snapshot(Keyspace.getTimestampedSnapshotNameWithPrefix(name, ColumnFamilyStore.SNAPSHOT_DROP_PREFIX), DatabaseDescriptor.getAutoSnapshotTtl());

CommitLog.instance.forceRecycleAllSegments(Collections.singleton(metadata.id));
Expand Down
54 changes: 33 additions & 21 deletions src/java/org/apache/cassandra/schema/SchemaKeyspace.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ private SchemaKeyspace()
"CREATE TABLE %s ("
+ "keyspace_name text,"
+ "table_name text,"
+ "allow_auto_snapshot boolean,"
+ "bloom_filter_fp_chance double,"
+ "caching frozen<map<text, text>>,"
+ "comment text,"
Expand Down Expand Up @@ -168,6 +169,7 @@ private SchemaKeyspace()
+ "base_table_id uuid,"
+ "base_table_name text,"
+ "where_clause text,"
+ "allow_auto_snapshot boolean,"
+ "bloom_filter_fp_chance double,"
+ "caching frozen<map<text, text>>,"
+ "comment text,"
Expand Down Expand Up @@ -563,6 +565,11 @@ private static void addTableParamsToRowBuilder(TableParams params, Row.SimpleBui
// in mixed operation with pre-4.1 versioned node during upgrades.
if (params.memtable != MemtableParams.DEFAULT)
builder.add("memtable", params.memtable.configurationKey());

// As above, only add the allow_auto_snapshot column if the value is not default (true) and
// auto-snapshotting is enabled, to avoid RTE in pre-4.2 versioned node during upgrades
if (!params.allowAutoSnapshot)
builder.add("allow_auto_snapshot", false);
}

private static void addAlterTableToSchemaMutation(TableMetadata oldTable, TableMetadata newTable, Mutation.SimpleBuilder builder)
Expand Down Expand Up @@ -954,27 +961,32 @@ private static TableMetadata fetchTable(String keyspaceName, String tableName, T
@VisibleForTesting
static TableParams createTableParamsFromRow(UntypedResultSet.Row row)
{
return TableParams.builder()
.bloomFilterFpChance(row.getDouble("bloom_filter_fp_chance"))
.caching(CachingParams.fromMap(row.getFrozenTextMap("caching")))
.comment(row.getString("comment"))
.compaction(CompactionParams.fromMap(row.getFrozenTextMap("compaction")))
.compression(CompressionParams.fromMap(row.getFrozenTextMap("compression")))
.memtable(MemtableParams.get(row.has("memtable") ? row.getString("memtable") : null)) // memtable column was introduced in 4.1
.defaultTimeToLive(row.getInt("default_time_to_live"))
.extensions(row.getFrozenMap("extensions", UTF8Type.instance, BytesType.instance))
.gcGraceSeconds(row.getInt("gc_grace_seconds"))
.maxIndexInterval(row.getInt("max_index_interval"))
.memtableFlushPeriodInMs(row.getInt("memtable_flush_period_in_ms"))
.minIndexInterval(row.getInt("min_index_interval"))
.crcCheckChance(row.getDouble("crc_check_chance"))
.speculativeRetry(SpeculativeRetryPolicy.fromString(row.getString("speculative_retry")))
.additionalWritePolicy(row.has("additional_write_policy") ?
SpeculativeRetryPolicy.fromString(row.getString("additional_write_policy")) :
SpeculativeRetryPolicy.fromString("99PERCENTILE"))
.cdc(row.has("cdc") && row.getBoolean("cdc"))
.readRepair(getReadRepairStrategy(row))
.build();
TableParams.Builder builder = TableParams.builder()
.bloomFilterFpChance(row.getDouble("bloom_filter_fp_chance"))
.caching(CachingParams.fromMap(row.getFrozenTextMap("caching")))
.comment(row.getString("comment"))
.compaction(CompactionParams.fromMap(row.getFrozenTextMap("compaction")))
.compression(CompressionParams.fromMap(row.getFrozenTextMap("compression")))
.memtable(MemtableParams.get(row.has("memtable") ? row.getString("memtable") : null)) // memtable column was introduced in 4.1
.defaultTimeToLive(row.getInt("default_time_to_live"))
.extensions(row.getFrozenMap("extensions", UTF8Type.instance, BytesType.instance))
.gcGraceSeconds(row.getInt("gc_grace_seconds"))
.maxIndexInterval(row.getInt("max_index_interval"))
.memtableFlushPeriodInMs(row.getInt("memtable_flush_period_in_ms"))
.minIndexInterval(row.getInt("min_index_interval"))
.crcCheckChance(row.getDouble("crc_check_chance"))
.speculativeRetry(SpeculativeRetryPolicy.fromString(row.getString("speculative_retry")))
.additionalWritePolicy(row.has("additional_write_policy") ?
SpeculativeRetryPolicy.fromString(row.getString("additional_write_policy")) :
SpeculativeRetryPolicy.fromString("99PERCENTILE"))
.cdc(row.has("cdc") && row.getBoolean("cdc"))
.readRepair(getReadRepairStrategy(row));

// allow_auto_snapshot column was introduced in 4.2
if (row.has("allow_auto_snapshot"))
builder.allowAutoSnapshot(row.getBoolean("allow_auto_snapshot"));

return builder.build();
}

private static List<ColumnMetadata> fetchColumns(String keyspace, String table, Types types)
Expand Down
6 changes: 6 additions & 0 deletions src/java/org/apache/cassandra/schema/TableMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,12 @@ public Builder params(TableParams val)
return this;
}

public Builder allowAutoSnapshot(boolean val)
{
params.allowAutoSnapshot(val);
return this;
}

public Builder bloomFilterFpChance(double val)
{
params.bloomFilterFpChance(val);
Expand Down
18 changes: 17 additions & 1 deletion src/java/org/apache/cassandra/schema/TableParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public final class TableParams
{
public enum Option
{
ALLOW_AUTO_SNAPSHOT,
BLOOM_FILTER_FP_CHANCE,
CACHING,
COMMENT,
Expand All @@ -67,6 +68,7 @@ public String toString()
}

public final String comment;
public final boolean allowAutoSnapshot;
public final double bloomFilterFpChance;
public final double crcCheckChance;
public final int gcGraceSeconds;
Expand All @@ -87,6 +89,7 @@ public String toString()
private TableParams(Builder builder)
{
comment = builder.comment;
allowAutoSnapshot = builder.allowAutoSnapshot;
bloomFilterFpChance = builder.bloomFilterFpChance == null
? builder.compaction.defaultBloomFilterFbChance()
: builder.bloomFilterFpChance;
Expand Down Expand Up @@ -114,7 +117,8 @@ public static Builder builder()

public static Builder builder(TableParams params)
{
return new Builder().bloomFilterFpChance(params.bloomFilterFpChance)
return new Builder().allowAutoSnapshot(params.allowAutoSnapshot)
.bloomFilterFpChance(params.bloomFilterFpChance)
.caching(params.caching)
.comment(params.comment)
.compaction(params.compaction)
Expand Down Expand Up @@ -204,6 +208,7 @@ public boolean equals(Object o)
TableParams p = (TableParams) o;

return comment.equals(p.comment)
&& allowAutoSnapshot == p.allowAutoSnapshot
&& bloomFilterFpChance == p.bloomFilterFpChance
&& crcCheckChance == p.crcCheckChance
&& gcGraceSeconds == p.gcGraceSeconds
Expand All @@ -225,6 +230,7 @@ public boolean equals(Object o)
public int hashCode()
{
return Objects.hashCode(comment,
allowAutoSnapshot,
bloomFilterFpChance,
crcCheckChance,
gcGraceSeconds,
Expand All @@ -247,6 +253,7 @@ public String toString()
{
return MoreObjects.toStringHelper(this)
.add(Option.COMMENT.toString(), comment)
.add(Option.ALLOW_AUTO_SNAPSHOT.toString(), allowAutoSnapshot)
.add(Option.BLOOM_FILTER_FP_CHANCE.toString(), bloomFilterFpChance)
.add(Option.CRC_CHECK_CHANCE.toString(), crcCheckChance)
.add(Option.GC_GRACE_SECONDS.toString(), gcGraceSeconds)
Expand All @@ -269,6 +276,8 @@ public void appendCqlTo(CqlBuilder builder, boolean isView)
{
// option names should be in alphabetical order
builder.append("additional_write_policy = ").appendWithSingleQuotes(additionalWritePolicy.toString())
.newLine()
.append("AND allow_auto_snapshot = ").append(allowAutoSnapshot)
.newLine()
.append("AND bloom_filter_fp_chance = ").append(bloomFilterFpChance)
.newLine()
Expand Down Expand Up @@ -315,6 +324,7 @@ public void appendCqlTo(CqlBuilder builder, boolean isView)
public static final class Builder
{
private String comment = "";
private boolean allowAutoSnapshot = true;
private Double bloomFilterFpChance;
private double crcCheckChance = 1.0;
private int gcGraceSeconds = 864000; // 10 days
Expand Down Expand Up @@ -347,6 +357,12 @@ public Builder comment(String val)
return this;
}

public Builder allowAutoSnapshot(boolean val)
{
allowAutoSnapshot = val;
return this;
}

public Builder bloomFilterFpChance(double val)
{
bloomFilterFpChance = val;
Expand Down