Merge branch 'cassandra-2.2' into cassandra-3.0
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9784be5e Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9784be5e Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9784be5e Branch: refs/heads/cassandra-3.0 Commit: 9784be5e076ce13426813493662378b52228dd57 Parents: d7068fd 15f03ab Author: Sam Tunnicliffe <s...@beobal.com> Authored: Thu Dec 3 11:45:03 2015 +0000 Committer: Sam Tunnicliffe <s...@beobal.com> Committed: Thu Dec 3 11:45:50 2015 +0000 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../org/apache/cassandra/config/Schema.java | 41 +++++++++----------- .../apache/cassandra/db/ColumnFamilyStore.java | 4 +- src/java/org/apache/cassandra/db/Keyspace.java | 14 +++---- .../cassandra/service/StorageService.java | 19 +++------ 5 files changed, 32 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/9784be5e/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index a82dcfc,12accac..4dd1b97 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,22 -1,8 +1,23 @@@ -2.2.5 +3.0.1 + * Fix NPE on stream read error (CASSANDRA-10771) + * Normalize cqlsh DESC output (CASSANDRA-10431) + * Rejects partition range deletions when columns are specified (CASSANDRA-10739) + * Fix error when saving cached key for old format sstable (CASSANDRA-10778) + * Invalidate prepared statements on DROP INDEX (CASSANDRA-10758) + * Fix SELECT statement with IN restrictions on partition key, + ORDER BY and LIMIT (CASSANDRA-10729) + * Improve stress performance over 1k threads (CASSANDRA-7217) + * Wait for migration responses to complete before bootstrapping (CASSANDRA-10731) + * Unable to create a function with argument of type Inet (CASSANDRA-10741) + * Fix backward incompatibiliy in CqlInputFormat (CASSANDRA-10717) + * Correctly preserve deletion info on updated rows when notifying indexers + of single-row deletions (CASSANDRA-10694) + * Notify indexers of partition delete during cleanup (CASSANDRA-10685) + * Keep the file open in trySkipCache (CASSANDRA-10669) + * Updated trigger example (CASSANDRA-10257) +Merged from 2.2: + * Verify tables in pseudo-system keyspaces at startup (CASSANDRA-10761) - - -2.2.4 + * Fix IllegalArgumentException in DataOutputBuffer.reallocate for large buffers (CASSANDRA-10592) * Show CQL help in cqlsh in web browser (CASSANDRA-7225) * Serialize on disk the proper SSTable compression ratio (CASSANDRA-10775) * Reject index queries while the index is building (CASSANDRA-8505) http://git-wip-us.apache.org/repos/asf/cassandra/blob/9784be5e/src/java/org/apache/cassandra/config/Schema.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/config/Schema.java index 569c87d,110029e..cf3f569 --- a/src/java/org/apache/cassandra/config/Schema.java +++ b/src/java/org/apache/cassandra/config/Schema.java @@@ -605,19 -515,20 +605,17 @@@ public class Schem public void addTable(CFMetaData cfm) { assert getCFMetaData(cfm.ksName, cfm.cfName) == null; - KSMetaData ksm = getKSMetaData(cfm.ksName).cloneWithTableAdded(cfm); - - logger.info("Loading {}", cfm); - update(cfm.ksName, ks -> - { - load(cfm); - - // make sure it's init-ed w/ the old definitions first, - // since we're going to call initCf on the new one manually - Keyspace.open(cfm.ksName); - - return ks.withSwapped(ks.tables.with(cfm)); - }); - - Keyspace.open(cfm.ksName).initCf(cfm.cfId, cfm.cfName, true); ++ // Make sure the keyspace is initialized and initialize the table. ++ Keyspace.open(cfm.ksName).initCf(cfm, true); ++ // Update the keyspaces map with the updated metadata ++ update(cfm.ksName, ks -> ks.withSwapped(ks.tables.with(cfm))); ++ // Update the table ID <-> table name map (cfIdMap) + load(cfm); + - // make sure it's init-ed w/ the old definitions first, - // since we're going to call initCf on the new one manually - Keyspace.open(cfm.ksName); - + // init the new CF before switching the KSM to the new one + // to avoid races as in CASSANDRA-10761 + Keyspace.open(cfm.ksName).initCf(cfm, true); - setKeyspaceDefinition(ksm); MigrationManager.instance.notifyCreateColumnFamily(cfm); } @@@ -659,80 -566,37 +657,77 @@@ CommitLog.instance.forceRecycleAllSegments(Collections.singleton(cfm.cfId)); } - public void addType(UserType ut) + public void addView(ViewDefinition view) { - KSMetaData ksm = getKSMetaData(ut.keyspace); - assert ksm != null; + assert getCFMetaData(view.ksName, view.viewName) == null; - update(view.ksName, ks -> - { - load(view); - - // make sure it's init-ed w/ the old definitions first, - // since we're going to call initCf on the new one manually - Keyspace.open(view.ksName); - logger.info("Loading {}", ut); ++ Keyspace keyspace = Keyspace.open(view.ksName); - return ks.withSwapped(ks.views.with(view)); - }); - ksm.userTypes.addType(ut); ++ // Make sure the keyspace is initialized and initialize the table. ++ keyspace.initCf(view.metadata, true); ++ // Update the keyspaces map with the updated metadata ++ update(view.ksName, ks -> ks.withSwapped(ks.views.with(view))); ++ // Update the table ID <-> table name map (cfIdMap) ++ load(view); - Keyspace.open(view.ksName).initCf(view.metadata.cfId, view.viewName, true); - Keyspace.open(view.ksName).viewManager.reload(); - MigrationManager.instance.notifyCreateUserType(ut); ++ keyspace.viewManager.reload(); + MigrationManager.instance.notifyCreateView(view); } - public void updateType(UserType ut) + public void updateView(ViewDefinition view) { - KSMetaData ksm = getKSMetaData(ut.keyspace); - assert ksm != null; + ViewDefinition current = getKSMetaData(view.ksName).views.get(view.viewName).get(); + boolean changeAffectsStatements = current.metadata.apply(view.metadata); + + Keyspace keyspace = Keyspace.open(current.ksName); + keyspace.getColumnFamilyStore(current.viewName).reload(); + Keyspace.open(current.ksName).viewManager.update(current.viewName); + MigrationManager.instance.notifyUpdateView(current, changeAffectsStatements); + } + + public void dropView(String ksName, String viewName) + { + KeyspaceMetadata oldKsm = getKSMetaData(ksName); + assert oldKsm != null; + ColumnFamilyStore cfs = Keyspace.open(ksName).getColumnFamilyStore(viewName); + assert cfs != null; + + // make sure all the indexes are dropped, or else. + cfs.indexManager.markAllIndexesRemoved(); - logger.info("Updating {}", ut); + // reinitialize the keyspace. + ViewDefinition view = oldKsm.views.get(viewName).get(); + KeyspaceMetadata newKsm = oldKsm.withSwapped(oldKsm.views.without(viewName)); - ksm.userTypes.addType(ut); + unload(view); + setKeyspaceMetadata(newKsm); - MigrationManager.instance.notifyUpdateUserType(ut); + CompactionManager.instance.interruptCompactionFor(Collections.singleton(view.metadata), true); + + if (DatabaseDescriptor.isAutoSnapshot()) + cfs.snapshot(Keyspace.getTimestampedSnapshotName(cfs.name)); + Keyspace.open(ksName).dropCf(view.metadata.cfId); + Keyspace.open(ksName).viewManager.reload(); + MigrationManager.instance.notifyDropView(view); + + CommitLog.instance.forceRecycleAllSegments(Collections.singleton(view.metadata.cfId)); } - public void dropType(UserType ut) + public void addType(UserType ut) { - KSMetaData ksm = getKSMetaData(ut.keyspace); - assert ksm != null; + update(ut.keyspace, ks -> ks.withSwapped(ks.types.with(ut))); + MigrationManager.instance.notifyCreateUserType(ut); + } - ksm.userTypes.removeType(ut); + public void updateType(UserType ut) + { + update(ut.keyspace, ks -> ks.withSwapped(ks.types.without(ut.name).with(ut))); + MigrationManager.instance.notifyUpdateUserType(ut); + } + public void dropType(UserType ut) + { + update(ut.keyspace, ks -> ks.withSwapped(ks.types.without(ut.name))); MigrationManager.instance.notifyDropUserType(ut); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/9784be5e/src/java/org/apache/cassandra/db/ColumnFamilyStore.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/db/ColumnFamilyStore.java index 38c99ea,5325c8a..f0adf39 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@@ -532,9 -506,9 +532,9 @@@ public class ColumnFamilyStore implemen } - public static ColumnFamilyStore createColumnFamilyStore(Keyspace keyspace, String columnFamily, boolean loadSSTables) + public static ColumnFamilyStore createColumnFamilyStore(Keyspace keyspace, CFMetaData metadata, boolean loadSSTables) { - return createColumnFamilyStore(keyspace, columnFamily, Schema.instance.getCFMetaData(keyspace.getName(), columnFamily), loadSSTables); - return createColumnFamilyStore(keyspace, metadata.cfName, StorageService.getPartitioner(), metadata, loadSSTables); ++ return createColumnFamilyStore(keyspace, metadata.cfName, metadata, loadSSTables); } public static synchronized ColumnFamilyStore createColumnFamilyStore(Keyspace keyspace, http://git-wip-us.apache.org/repos/asf/cassandra/blob/9784be5e/src/java/org/apache/cassandra/db/Keyspace.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/db/Keyspace.java index eb28b2c,225369c..7b4f79b --- a/src/java/org/apache/cassandra/db/Keyspace.java +++ b/src/java/org/apache/cassandra/db/Keyspace.java @@@ -298,16 -264,14 +298,16 @@@ public class Keyspac createReplicationStrategy(metadata); this.metric = new KeyspaceMetrics(this); - for (CFMetaData cfm : new ArrayList<>(metadata.cfMetaData().values())) + this.viewManager = new ViewManager(this); + for (CFMetaData cfm : metadata.tablesAndViews()) { logger.trace("Initializing {}.{}", getName(), cfm.cfName); - initCf(cfm.cfId, cfm.cfName, loadSSTables); + initCf(cfm, loadSSTables); } + this.viewManager.reload(); } - private Keyspace(KSMetaData metadata) + private Keyspace(KeyspaceMetadata metadata) { this.metadata = metadata; createReplicationStrategy(metadata); @@@ -376,7 -348,8 +374,7 @@@ { // re-initializing an existing CF. This will happen if you cleared the schema // on this node and it's getting repopulated from the rest of the cluster. - assert cfs.name.equals(cfName); + assert cfs.name.equals(metadata.cfName); - cfs.metadata.reload(); cfs.reload(); } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/9784be5e/src/java/org/apache/cassandra/service/StorageService.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/service/StorageService.java index 0b910f0,68e19c5..2332cea --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@@ -1038,19 -1026,7 +1038,7 @@@ public class StorageService extends Not MigrationManager.instance.register(new AuthMigrationListener()); } - private void maybeAddTable(CFMetaData cfm) - { - try - { - MigrationManager.announceNewColumnFamily(cfm); - } - catch (AlreadyExistsException e) - { - logger.debug("Attempted to create new table {}, but it already exists", cfm.cfName); - } - } - - private void maybeAddKeyspace(KSMetaData ksm) + private void maybeAddKeyspace(KeyspaceMetadata ksm) { try { @@@ -1075,18 -1051,21 +1063,21 @@@ // (#8162 being an example), so even if the table definition exists, we still need to force the "current" // version of the schema, the one the node will be expecting. - KSMetaData defined = Schema.instance.getKSMetaData(expected.name); + KeyspaceMetadata defined = Schema.instance.getKSMetaData(expected.name); + // If the keyspace doesn't exist, create it if (defined == null) { - // The keyspace doesn't exist, create it maybeAddKeyspace(expected); - return; + defined = Schema.instance.getKSMetaData(expected.name); } // While the keyspace exists, it might miss table or have outdated one + // There is also the potential for a race, as schema migrations add the bare + // keyspace into Schema.instance before adding its tables, so double check that + // all the expected tables are present - for (CFMetaData expectedTable : expected.cfMetaData().values()) + for (CFMetaData expectedTable : expected.tables) { - CFMetaData definedTable = defined.cfMetaData().get(expectedTable.cfName); + CFMetaData definedTable = defined.tables.get(expectedTable.cfName).orElse(null); if (definedTable == null || !definedTable.equals(expectedTable)) MigrationManager.forceAnnounceNewColumnFamily(expectedTable); }