diff --git a/CHANGES.txt b/CHANGES.txt index c03ffcafa4..45a4f16b56 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 5.1 + * Split out truncation record lock (CASSANDRA-20480) * Throw new IndexBuildInProgressException when queries fail during index build, instead of IndexNotAvailableException (CASSANDRA-20402) * Fix Paxos repair interrupts running transactions (CASSANDRA-20469) * Various fixes in constraint framework (CASSANDRA-20481) diff --git a/src/java/org/apache/cassandra/db/SystemKeyspace.java b/src/java/org/apache/cassandra/db/SystemKeyspace.java index 64436a9403..81186c512a 100644 --- a/src/java/org/apache/cassandra/db/SystemKeyspace.java +++ b/src/java/org/apache/cassandra/db/SystemKeyspace.java @@ -606,6 +606,8 @@ public final class SystemKeyspace private static volatile Map> truncationRecords; + private static final Object truncationRecordLock = new Object(); + public enum BootstrapState { NEEDS_BOOTSTRAP, @@ -801,27 +803,33 @@ public final class SystemKeyspace return status; } - public static synchronized void saveTruncationRecord(ColumnFamilyStore cfs, long truncatedAt, CommitLogPosition position) + public static void saveTruncationRecord(ColumnFamilyStore cfs, long truncatedAt, CommitLogPosition position) { - String req = "UPDATE system.%s SET truncated_at = truncated_at + ? WHERE key = '%s'"; - executeInternal(format(req, LOCAL, LOCAL), truncationAsMapEntry(cfs, truncatedAt, position)); - truncationRecords = null; - forceBlockingFlush(LOCAL); + synchronized (truncationRecordLock) + { + String req = "UPDATE system.%s SET truncated_at = truncated_at + ? WHERE key = '%s'"; + executeInternal(format(req, LOCAL, LOCAL), truncationAsMapEntry(cfs, truncatedAt, position)); + truncationRecords = null; + forceBlockingFlush(LOCAL); + } } /** * This method is used to remove information about truncation time for specified column family */ - public static synchronized void removeTruncationRecord(TableId id) + public static void removeTruncationRecord(TableId id) { - Pair truncationRecord = getTruncationRecord(id); - if (truncationRecord == null) - return; + synchronized (truncationRecordLock) + { + Pair truncationRecord = getTruncationRecord(id); + if (truncationRecord == null) + return; - String req = "DELETE truncated_at[?] from system.%s WHERE key = '%s'"; - executeInternal(format(req, LOCAL, LOCAL), id.asUUID()); - truncationRecords = null; - forceBlockingFlush(LOCAL); + String req = "DELETE truncated_at[?] from system.%s WHERE key = '%s'"; + executeInternal(format(req, LOCAL, LOCAL), id.asUUID()); + truncationRecords = null; + forceBlockingFlush(LOCAL); + } } private static Map truncationAsMapEntry(ColumnFamilyStore cfs, long truncatedAt, CommitLogPosition position) @@ -850,11 +858,14 @@ public final class SystemKeyspace return record == null ? Long.MIN_VALUE : record.right; } - private static synchronized Pair getTruncationRecord(TableId id) + private static Pair getTruncationRecord(TableId id) { - if (truncationRecords == null) - truncationRecords = readTruncationRecords(); - return truncationRecords.get(id); + synchronized (truncationRecordLock) + { + if (truncationRecords == null) + truncationRecords = readTruncationRecords(); + return truncationRecords.get(id); + } } private static Map> readTruncationRecords()