Author: jbellis Date: Fri Oct 1 21:22:25 2010 New Revision: 1003656 URL: http://svn.apache.org/viewvc?rev=1003656&view=rev Log: lock row cache updates to prevent race condition patch by jbellis; reviewed by brandonwilliams for CASSANDRA-1293
Modified: cassandra/trunk/CHANGES.txt cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java cassandra/trunk/src/java/org/apache/cassandra/db/Table.java cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Modified: cassandra/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1003656&r1=1003655&r2=1003656&view=diff ============================================================================== --- cassandra/trunk/CHANGES.txt (original) +++ cassandra/trunk/CHANGES.txt Fri Oct 1 21:22:25 2010 @@ -5,6 +5,7 @@ dev * allow nodes to change IPs between restarts (CASSANDRA-1518) * remember ring state between restarts by default (CASSANDRA-1518) * flush index built flag so we can read it before log replay (CASSANDRA-1541) + * lock row cache updates to prevent race condition (CASSANDRA-1293) 0.7-beta2 Modified: cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=1003656&r1=1003655&r2=1003656&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Fri Oct 1 21:22:25 2010 @@ -551,6 +551,9 @@ public class ColumnFamilyStore implement boolean flushRequested = memtable.isThresholdViolated(); memtable.put(key, columnFamily); + ColumnFamily cachedRow = getRawCachedRow(key); + if (cachedRow != null) + cachedRow.addAll(columnFamily); writeStats.addNano(System.nanoTime() - start); return flushRequested ? memtable : null; Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Table.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Table.java?rev=1003656&r1=1003655&r2=1003656&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/db/Table.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/db/Table.java Fri Oct 1 21:22:25 2010 @@ -362,31 +362,25 @@ public class Table } } - if (mutatedIndexedColumns == null) + synchronized (indexLockFor(mutation.key())) { - // just update the actual value, no extra synchronization + ColumnFamily oldIndexedColumns = null; + if (mutatedIndexedColumns != null) + { + oldIndexedColumns = readCurrentIndexedColumns(key, cfs, mutatedIndexedColumns); + ignoreObsoleteMutations(cf, cfs.metadata.reconciler, mutatedIndexedColumns, oldIndexedColumns); + } + Memtable fullMemtable = cfs.apply(key, cf); if (fullMemtable != null) memtablesToFlush = addFullMemtable(memtablesToFlush, fullMemtable); - } - else - { - synchronized (indexLockFor(mutation.key())) - { - ColumnFamily oldIndexedColumns = readCurrentIndexedColumns(key, cfs, mutatedIndexedColumns); - ignoreObsoleteMutations(cf, cfs.metadata.reconciler, mutatedIndexedColumns, oldIndexedColumns); - Memtable fullMemtable = cfs.apply(key, cf); - if (fullMemtable != null) - memtablesToFlush = addFullMemtable(memtablesToFlush, fullMemtable); + if (mutatedIndexedColumns != null) + { // ignore full index memtables -- we flush those when the "master" one is full applyIndexUpdates(mutation.key(), cf, cfs, mutatedIndexedColumns, oldIndexedColumns); } } - - ColumnFamily cachedRow = cfs.getRawCachedRow(key); - if (cachedRow != null) - cachedRow.addAll(cf); } } finally Modified: cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java?rev=1003656&r1=1003655&r2=1003656&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/db/migration/UpdateColumnFamily.java Fri Oct 1 21:22:25 2010 @@ -51,10 +51,6 @@ public class UpdateColumnFamily extends this.oldCfm = oldCfm; this.newCfm = newCfm; - // we'll allow this eventually. - if (!oldCfm.column_metadata.equals(newCfm.column_metadata)) - throw new ConfigurationException("Column meta information is not identical."); - // clone ksm but include the new cf def. KSMetaData newKsm = makeNewKeyspaceDefinition(ksm); rm = Migration.makeDefinitionMutation(newKsm, null, newVersion); Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1003656&r1=1003655&r2=1003656&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Fri Oct 1 21:22:25 2010 @@ -771,7 +771,7 @@ public class CassandraServer implements throw new InvalidRequestException(String.format("%s live nodes are not enough to support replication factor %s", totalNodes, ks_def.replication_factor)); - //generate a meaningful error if the user setup keyspace and/or column definition incorrectly + // generate a meaningful error if the user setup keyspace and/or column definition incorrectly for (CfDef cf : ks_def.cf_defs) { if (!cf.getKeyspace().equals(ks_def.getName())) @@ -787,13 +787,12 @@ public class CassandraServer implements { cfDefs.add(convertToCFMetaData(cfDef)); } - - KSMetaData ksm = new KSMetaData( - ks_def.name, - (Class<? extends AbstractReplicationStrategy>)Class.forName(ks_def.strategy_class), - ks_def.strategy_options, - ks_def.replication_factor, - cfDefs.toArray(new CFMetaData[cfDefs.size()])); + + KSMetaData ksm = new KSMetaData(ks_def.name, + (Class<? extends AbstractReplicationStrategy>) Class.forName(ks_def.strategy_class), + ks_def.strategy_options, + ks_def.replication_factor, + cfDefs.toArray(new CFMetaData[cfDefs.size()])); applyMigrationOnStage(new AddKeyspace(ksm)); return DatabaseDescriptor.getDefsVersion().toString(); }