Skip to content

Commit 044443f

Browse files
authored
Remove before images after committing or rolling back records in Consensus Commit (#2787)
1 parent 6ccaeec commit 044443f

File tree

5 files changed

+648
-192
lines changed

5 files changed

+648
-192
lines changed

core/src/main/java/com/scalar/db/transaction/consensuscommit/AbstractMutationComposer.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
import com.google.common.annotations.VisibleForTesting;
44
import com.google.common.collect.ImmutableList;
55
import com.scalar.db.api.Mutation;
6+
import com.scalar.db.api.PutBuilder;
7+
import com.scalar.db.api.TableMetadata;
8+
import com.scalar.db.io.DataType;
69
import java.util.ArrayList;
710
import java.util.List;
11+
import java.util.Set;
812
import javax.annotation.concurrent.NotThreadSafe;
913

1014
@NotThreadSafe
@@ -34,4 +38,50 @@ public AbstractMutationComposer(String id, TransactionTableMetadataManager table
3438
public List<Mutation> get() {
3539
return ImmutableList.copyOf(mutations);
3640
}
41+
42+
static void setBeforeImageColumnsToNull(
43+
PutBuilder.Buildable putBuilder,
44+
Set<String> beforeImageColumnNames,
45+
TableMetadata tableMetadata) {
46+
for (String beforeImageColumnName : beforeImageColumnNames) {
47+
DataType columnDataType = tableMetadata.getColumnDataType(beforeImageColumnName);
48+
switch (columnDataType) {
49+
case BOOLEAN:
50+
putBuilder.booleanValue(beforeImageColumnName, null);
51+
break;
52+
case INT:
53+
putBuilder.intValue(beforeImageColumnName, null);
54+
break;
55+
case BIGINT:
56+
putBuilder.bigIntValue(beforeImageColumnName, null);
57+
break;
58+
case FLOAT:
59+
putBuilder.floatValue(beforeImageColumnName, null);
60+
break;
61+
case DOUBLE:
62+
putBuilder.doubleValue(beforeImageColumnName, null);
63+
break;
64+
case TEXT:
65+
putBuilder.textValue(beforeImageColumnName, null);
66+
break;
67+
case BLOB:
68+
putBuilder.blobValue(beforeImageColumnName, (byte[]) null);
69+
break;
70+
case DATE:
71+
putBuilder.dateValue(beforeImageColumnName, null);
72+
break;
73+
case TIME:
74+
putBuilder.timeValue(beforeImageColumnName, null);
75+
break;
76+
case TIMESTAMP:
77+
putBuilder.timestampValue(beforeImageColumnName, null);
78+
break;
79+
case TIMESTAMPTZ:
80+
putBuilder.timestampTZValue(beforeImageColumnName, null);
81+
break;
82+
default:
83+
throw new AssertionError("Unknown data type: " + columnDataType);
84+
}
85+
}
86+
}
3787
}

core/src/main/java/com/scalar/db/transaction/consensuscommit/CommitMutationComposer.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
package com.scalar.db.transaction.consensuscommit;
22

33
import static com.scalar.db.api.ConditionalExpression.Operator;
4+
import static com.scalar.db.transaction.consensuscommit.Attribute.COMMITTED_AT;
45
import static com.scalar.db.transaction.consensuscommit.Attribute.ID;
56
import static com.scalar.db.transaction.consensuscommit.Attribute.STATE;
67
import static com.scalar.db.transaction.consensuscommit.Attribute.toIdValue;
78
import static com.scalar.db.transaction.consensuscommit.Attribute.toStateValue;
89

910
import com.google.common.annotations.VisibleForTesting;
11+
import com.scalar.db.api.ConditionBuilder;
1012
import com.scalar.db.api.ConditionalExpression;
1113
import com.scalar.db.api.Consistency;
1214
import com.scalar.db.api.Delete;
1315
import com.scalar.db.api.DeleteIf;
1416
import com.scalar.db.api.Mutation;
1517
import com.scalar.db.api.Operation;
1618
import com.scalar.db.api.Put;
17-
import com.scalar.db.api.PutIf;
19+
import com.scalar.db.api.PutBuilder;
1820
import com.scalar.db.api.Selection;
21+
import com.scalar.db.api.TableMetadata;
1922
import com.scalar.db.api.TransactionState;
2023
import com.scalar.db.exception.storage.ExecutionException;
2124
import com.scalar.db.io.Key;
2225
import com.scalar.db.util.ScalarDbUtils;
26+
import java.util.LinkedHashSet;
2327
import java.util.Optional;
2428
import javax.annotation.Nullable;
2529
import javax.annotation.concurrent.NotThreadSafe;
@@ -82,17 +86,33 @@ private void add(Selection base, @Nullable TransactionResult result) throws Exec
8286

8387
private Put composePut(Operation base, @Nullable TransactionResult result)
8488
throws ExecutionException {
85-
return new Put(getPartitionKey(base, result), getClusteringKey(base, result).orElse(null))
86-
.forNamespace(base.forNamespace().get())
87-
.forTable(base.forTable().get())
88-
.withConsistency(Consistency.LINEARIZABLE)
89-
.withCondition(
90-
new PutIf(
91-
new ConditionalExpression(ID, toIdValue(id), Operator.EQ),
92-
new ConditionalExpression(
93-
STATE, toStateValue(TransactionState.PREPARED), Operator.EQ)))
94-
.withValue(Attribute.toCommittedAtValue(current))
95-
.withValue(Attribute.toStateValue(TransactionState.COMMITTED));
89+
PutBuilder.Buildable putBuilder =
90+
Put.newBuilder()
91+
.namespace(base.forNamespace().get())
92+
.table(base.forTable().get())
93+
.partitionKey(getPartitionKey(base, result))
94+
.condition(
95+
ConditionBuilder.putIf(ConditionBuilder.column(ID).isEqualToText(id))
96+
.and(
97+
ConditionBuilder.column(STATE)
98+
.isEqualToInt(TransactionState.PREPARED.get()))
99+
.build())
100+
.bigIntValue(COMMITTED_AT, current)
101+
.intValue(STATE, TransactionState.COMMITTED.get())
102+
.consistency(Consistency.LINEARIZABLE);
103+
getClusteringKey(base, result).ifPresent(putBuilder::clusteringKey);
104+
105+
// Set before image columns to null
106+
if (result != null) {
107+
TransactionTableMetadata transactionTableMetadata =
108+
tableMetadataManager.getTransactionTableMetadata(base);
109+
LinkedHashSet<String> beforeImageColumnNames =
110+
transactionTableMetadata.getBeforeImageColumnNames();
111+
TableMetadata tableMetadata = transactionTableMetadata.getTableMetadata();
112+
setBeforeImageColumnsToNull(putBuilder, beforeImageColumnNames, tableMetadata);
113+
}
114+
115+
return putBuilder.build();
96116
}
97117

98118
private Delete composeDelete(Operation base, @Nullable TransactionResult result)

core/src/main/java/com/scalar/db/transaction/consensuscommit/RollbackMutationComposer.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.scalar.db.api.Put;
1919
import com.scalar.db.api.PutBuilder;
2020
import com.scalar.db.api.Selection;
21+
import com.scalar.db.api.TableMetadata;
2122
import com.scalar.db.api.TransactionState;
2223
import com.scalar.db.exception.storage.ExecutionException;
2324
import com.scalar.db.io.Column;
@@ -77,8 +78,11 @@ private Put composePut(Operation base, TransactionResult result) throws Executio
7778
&& (result.getState().equals(TransactionState.PREPARED)
7879
|| result.getState().equals(TransactionState.DELETED));
7980

80-
TransactionTableMetadata metadata = tableMetadataManager.getTransactionTableMetadata(base);
81-
LinkedHashSet<String> beforeImageColumnNames = metadata.getBeforeImageColumnNames();
81+
TransactionTableMetadata transactionTableMetadata =
82+
tableMetadataManager.getTransactionTableMetadata(base);
83+
LinkedHashSet<String> beforeImageColumnNames =
84+
transactionTableMetadata.getBeforeImageColumnNames();
85+
TableMetadata tableMetadata = transactionTableMetadata.getTableMetadata();
8286

8387
List<Column<?>> columns = new ArrayList<>();
8488
result
@@ -98,9 +102,8 @@ private Put composePut(Operation base, TransactionResult result) throws Executio
98102
}
99103
});
100104

101-
Key partitionKey = ScalarDbUtils.getPartitionKey(result, metadata.getTableMetadata());
102-
Optional<Key> clusteringKey =
103-
ScalarDbUtils.getClusteringKey(result, metadata.getTableMetadata());
105+
Key partitionKey = ScalarDbUtils.getPartitionKey(result, tableMetadata);
106+
Optional<Key> clusteringKey = ScalarDbUtils.getClusteringKey(result, tableMetadata);
104107

105108
PutBuilder.Buildable putBuilder =
106109
Put.newBuilder()
@@ -115,6 +118,9 @@ private Put composePut(Operation base, TransactionResult result) throws Executio
115118
clusteringKey.ifPresent(putBuilder::clusteringKey);
116119
columns.forEach(putBuilder::value);
117120

121+
// Set before image columns to null
122+
setBeforeImageColumnsToNull(putBuilder, beforeImageColumnNames, tableMetadata);
123+
118124
return putBuilder.build();
119125
}
120126

0 commit comments

Comments
 (0)