Skip to content

Commit 4b68cbc

Browse files
committed
Improve logging in Consensus Commit (#2915)
1 parent cc093b8 commit 4b68cbc

26 files changed

+383
-143
lines changed

core/src/main/java/com/scalar/db/common/CoreError.java

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -728,19 +728,35 @@ public enum CoreError implements ScalarDbError {
728728
"",
729729
""),
730730
CONSENSUS_COMMIT_PREPARING_RECORD_EXISTS(
731-
Category.CONCURRENCY_ERROR, "0013", "The record being prepared already exists", "", ""),
731+
Category.CONCURRENCY_ERROR,
732+
"0013",
733+
"The record being prepared already exists. Details: %s",
734+
"",
735+
""),
732736
CONSENSUS_COMMIT_CONFLICT_OCCURRED_WHEN_PREPARING_RECORDS(
733-
Category.CONCURRENCY_ERROR, "0014", "A conflict occurred when preparing records", "", ""),
737+
Category.CONCURRENCY_ERROR,
738+
"0014",
739+
"A conflict occurred when preparing records. Details: %s",
740+
"",
741+
""),
734742
CONSENSUS_COMMIT_CONFLICT_OCCURRED_WHEN_COMMITTING_STATE(
735743
Category.CONCURRENCY_ERROR,
736744
"0015",
737-
"The committing state in the coordinator failed. The transaction has been aborted",
745+
"The committing state in the coordinator failed. The transaction has been aborted. Details: %s",
738746
"",
739747
""),
740748
CONSENSUS_COMMIT_CONFLICT_OCCURRED_WHILE_IMPLICIT_PRE_READ(
741-
Category.CONCURRENCY_ERROR, "0016", "A conflict occurred during implicit pre-read", "", ""),
749+
Category.CONCURRENCY_ERROR,
750+
"0016",
751+
"A conflict occurred during implicit pre-read. Details: %s",
752+
"",
753+
""),
742754
CONSENSUS_COMMIT_READ_UNCOMMITTED_RECORD(
743-
Category.CONCURRENCY_ERROR, "0017", "This record needs to be recovered", "", ""),
755+
Category.CONCURRENCY_ERROR,
756+
"0017",
757+
"This record needs to be recovered. Table: %s; Partition Key: %s; Clustering Key: %s; Transaction ID that wrote the record: %s",
758+
"",
759+
""),
744760
CONSENSUS_COMMIT_CONDITION_NOT_SATISFIED_BECAUSE_RECORD_NOT_EXISTS(
745761
Category.CONCURRENCY_ERROR,
746762
"0018",
@@ -784,7 +800,11 @@ public enum CoreError implements ScalarDbError {
784800
"",
785801
""),
786802
CONSENSUS_COMMIT_CONFLICT_OCCURRED_WHEN_COMMITTING_RECORDS(
787-
Category.CONCURRENCY_ERROR, "0026", "A conflict occurred when committing records", "", ""),
803+
Category.CONCURRENCY_ERROR,
804+
"0026",
805+
"A conflict occurred when committing records. Details: %s",
806+
"",
807+
""),
788808

789809
//
790810
// Errors for the internal error category
@@ -890,20 +910,21 @@ public enum CoreError implements ScalarDbError {
890910
JDBC_TRANSACTION_BEGINNING_TRANSACTION_FAILED(
891911
Category.INTERNAL_ERROR, "0035", "Beginning a transaction failed. Details: %s", "", ""),
892912
CONSENSUS_COMMIT_PREPARING_RECORDS_FAILED(
893-
Category.INTERNAL_ERROR, "0036", "Preparing records failed", "", ""),
894-
CONSENSUS_COMMIT_VALIDATION_FAILED(Category.INTERNAL_ERROR, "0037", "Validation failed", "", ""),
913+
Category.INTERNAL_ERROR, "0036", "Preparing records failed. Details: %s", "", ""),
914+
CONSENSUS_COMMIT_VALIDATION_FAILED(
915+
Category.INTERNAL_ERROR, "0037", "Validation failed. Details: %s", "", ""),
895916
CONSENSUS_COMMIT_EXECUTING_IMPLICIT_PRE_READ_FAILED(
896-
Category.INTERNAL_ERROR, "0038", "Executing implicit pre-read failed", "", ""),
917+
Category.INTERNAL_ERROR, "0038", "Executing implicit pre-read failed. Details: %s", "", ""),
897918
CONSENSUS_COMMIT_READING_RECORD_FROM_STORAGE_FAILED(
898919
Category.INTERNAL_ERROR,
899920
"0039",
900-
"Reading a record from the underlying storage failed",
921+
"Reading a record from the underlying storage failed. Details: %s",
901922
"",
902923
""),
903924
CONSENSUS_COMMIT_SCANNING_RECORDS_FROM_STORAGE_FAILED(
904925
Category.INTERNAL_ERROR,
905926
"0040",
906-
"Scanning records from the underlying storage failed",
927+
"Scanning records from the underlying storage failed. Details: %s",
907928
"",
908929
""),
909930
CONSENSUS_COMMIT_ROLLBACK_FAILED_BECAUSE_TRANSACTION_ALREADY_COMMITTED(
@@ -919,7 +940,7 @@ public enum CoreError implements ScalarDbError {
919940
Category.INTERNAL_ERROR, "0044", "The Upsert operation failed. Details: %s", "", ""),
920941
JDBC_TRANSACTION_UPDATE_OPERATION_FAILED(
921942
Category.INTERNAL_ERROR, "0045", "The Update operation failed. Details: %s", "", ""),
922-
HANDLING_BEFORE_PREPARATION_SNAPSHOT_HOOK_FAILED(
943+
CONSENSUS_COMMIT_HANDLING_BEFORE_PREPARATION_SNAPSHOT_HOOK_FAILED(
923944
Category.INTERNAL_ERROR,
924945
"0046",
925946
"Handling the before-preparation snapshot hook failed. Details: %s",
@@ -938,7 +959,7 @@ public enum CoreError implements ScalarDbError {
938959
CONSENSUS_COMMIT_RECOVERING_RECORDS_FAILED(
939960
Category.INTERNAL_ERROR, "0057", "Recovering records failed. Details: %s", "", ""),
940961
CONSENSUS_COMMIT_COMMITTING_RECORDS_FAILED(
941-
Category.INTERNAL_ERROR, "0058", "Committing records failed", "", ""),
962+
Category.INTERNAL_ERROR, "0058", "Committing records failed. Details: %s", "", ""),
942963

943964
//
944965
// Errors for the unknown transaction status error category
@@ -952,21 +973,31 @@ public enum CoreError implements ScalarDbError {
952973
CONSENSUS_COMMIT_COMMITTING_STATE_FAILED_WITH_NO_MUTATION_EXCEPTION_BUT_COORDINATOR_STATUS_DOES_NOT_EXIST(
953974
Category.UNKNOWN_TRANSACTION_STATUS_ERROR,
954975
"0001",
955-
"Committing state failed with NoMutationException, but the coordinator status does not exist",
976+
"Committing state failed with NoMutationException, but the coordinator status does not exist. Details: %s",
977+
"",
978+
""),
979+
CONSENSUS_COMMIT_CANNOT_COORDINATOR_STATUS(
980+
Category.UNKNOWN_TRANSACTION_STATUS_ERROR,
981+
"0002",
982+
"The coordinator status cannot be retrieved. Details: %s",
956983
"",
957984
""),
958-
CONSENSUS_COMMIT_CANNOT_GET_STATE(
959-
Category.UNKNOWN_TRANSACTION_STATUS_ERROR, "0002", "The state cannot be retrieved", "", ""),
960985
CONSENSUS_COMMIT_UNKNOWN_COORDINATOR_STATUS(
961986
Category.UNKNOWN_TRANSACTION_STATUS_ERROR,
962987
"0003",
963-
"The coordinator status is unknown",
988+
"The coordinator status is unknown. Details: %s",
964989
"",
965990
""),
966991
CONSENSUS_COMMIT_ABORTING_STATE_FAILED_WITH_NO_MUTATION_EXCEPTION_BUT_COORDINATOR_STATUS_DOES_NOT_EXIST(
967992
Category.UNKNOWN_TRANSACTION_STATUS_ERROR,
968993
"0004",
969-
"Aborting state failed with NoMutationException, but the coordinator status does not exist",
994+
"Aborting state failed with NoMutationException, but the coordinator status does not exist. Details: %s",
995+
"",
996+
""),
997+
CONSENSUS_COMMIT_ONE_PHASE_COMMITTING_RECORDS_FAILED(
998+
Category.UNKNOWN_TRANSACTION_STATUS_ERROR,
999+
"0005",
1000+
"One-phase committing records failed. Details: %s",
9701001
"",
9711002
""),
9721003
;
Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,62 @@
11
package com.scalar.db.exception.storage;
22

3+
import com.google.common.collect.ImmutableList;
4+
import com.scalar.db.api.Delete;
5+
import com.scalar.db.api.Mutation;
6+
import com.scalar.db.api.Put;
7+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
8+
import java.util.List;
9+
310
public class NoMutationException extends ExecutionException {
411

5-
public NoMutationException(String message) {
6-
super(message);
12+
private final List<? extends Mutation> mutations;
13+
14+
public NoMutationException(
15+
String message, @SuppressFBWarnings("EI_EXPOSE_REP2") List<? extends Mutation> mutations) {
16+
super(addTransactionIdToMessage(message, mutations));
17+
this.mutations = mutations;
718
}
819

9-
public NoMutationException(String message, Throwable cause) {
10-
super(message, cause);
20+
public NoMutationException(
21+
String message,
22+
@SuppressFBWarnings("EI_EXPOSE_REP2") List<? extends Mutation> mutations,
23+
Throwable cause) {
24+
super(addTransactionIdToMessage(message, mutations), cause);
25+
this.mutations = mutations;
26+
}
27+
28+
public List<? extends Mutation> getMutations() {
29+
return ImmutableList.copyOf(mutations);
30+
}
31+
32+
private static String addTransactionIdToMessage(
33+
String message, List<? extends Mutation> mutations) {
34+
StringBuilder builder = new StringBuilder(message).append(". Mutations: [");
35+
36+
boolean first = true;
37+
for (Mutation mutation : mutations) {
38+
assert mutation.forFullTableName().isPresent();
39+
assert mutation instanceof Put || mutation instanceof Delete;
40+
41+
if (!first) {
42+
builder.append(", ");
43+
} else {
44+
first = false;
45+
}
46+
builder
47+
.append("{Type: ")
48+
.append(mutation.getClass().getSimpleName())
49+
.append(", Table: ")
50+
.append(mutation.forFullTableName().get())
51+
.append(", Partition Key: ")
52+
.append(mutation.getPartitionKey())
53+
.append(", Clustering Key: ")
54+
.append(mutation.getClusteringKey())
55+
.append(", Condition: ")
56+
.append(mutation.getCondition())
57+
.append("}");
58+
}
59+
60+
return builder.append("]").toString();
1161
}
1262
}

core/src/main/java/com/scalar/db/storage/cassandra/BatchHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void handle(List<? extends Mutation> mutations) throws ExecutionException
5757
ResultSet results = execute(mutations);
5858
// it's for conditional update. non-conditional update always return true
5959
if (!results.wasApplied()) {
60-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage());
60+
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), mutations);
6161
}
6262
} catch (WriteTimeoutException e) {
6363
logger.warn("Write timeout happened during batch mutate operation", e);

core/src/main/java/com/scalar/db/storage/cassandra/MutateStatementHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.scalar.db.common.CoreError;
1313
import com.scalar.db.exception.storage.ExecutionException;
1414
import com.scalar.db.exception.storage.NoMutationException;
15+
import java.util.Collections;
1516
import javax.annotation.Nonnull;
1617
import javax.annotation.concurrent.ThreadSafe;
1718

@@ -39,7 +40,8 @@ public ResultSet handle(Operation operation) throws ExecutionException {
3940

4041
Mutation mutation = (Mutation) operation;
4142
if (mutation.getCondition().isPresent() && !results.one().getBool(0)) {
42-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage());
43+
throw new NoMutationException(
44+
CoreError.NO_MUTATION_APPLIED.buildMessage(), Collections.singletonList(mutation));
4345
}
4446
return results;
4547
} catch (WriteTimeoutException e) {

core/src/main/java/com/scalar/db/storage/cosmos/BatchHandler.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public void handle(List<? extends Mutation> mutations) throws ExecutionException
4949
try {
5050
executeStoredProcedure(mutations, tableMetadata);
5151
} catch (CosmosException e) {
52-
throwException(e);
52+
throwException(e, mutations);
5353
} catch (RuntimeException e) {
5454
throw new ExecutionException(
5555
CoreError.COSMOS_ERROR_OCCURRED_IN_MUTATION.buildMessage(e.getMessage()), e);
@@ -84,11 +84,13 @@ private void executeStoredProcedure(
8484
.execute(args, cosmosMutation.getStoredProcedureOptions());
8585
}
8686

87-
private void throwException(CosmosException exception) throws ExecutionException {
87+
private void throwException(CosmosException exception, List<? extends Mutation> mutations)
88+
throws ExecutionException {
8889
int statusCode = exception.getSubStatusCode();
8990

9091
if (statusCode == CosmosErrorCode.PRECONDITION_FAILED.get()) {
91-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), exception);
92+
throw new NoMutationException(
93+
CoreError.NO_MUTATION_APPLIED.buildMessage(), mutations, exception);
9294
} else if (statusCode == CosmosErrorCode.RETRY_WITH.get()) {
9395
throw new RetriableExecutionException(
9496
CoreError.COSMOS_RETRY_WITH_ERROR_OCCURRED_IN_MUTATION.buildMessage(

core/src/main/java/com/scalar/db/storage/cosmos/MutateStatementHandler.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.scalar.db.exception.storage.NoMutationException;
1111
import com.scalar.db.exception.storage.RetriableExecutionException;
1212
import java.util.ArrayList;
13+
import java.util.Collections;
1314
import java.util.List;
1415
import javax.annotation.concurrent.ThreadSafe;
1516

@@ -32,7 +33,7 @@ public void handle(Mutation mutation) throws ExecutionException {
3233
try {
3334
execute(mutation);
3435
} catch (CosmosException e) {
35-
throwException(e);
36+
throwException(e, mutation);
3637
} catch (RuntimeException e) {
3738
throw new ExecutionException(
3839
CoreError.COSMOS_ERROR_OCCURRED_IN_MUTATION.buildMessage(e.getMessage()), e);
@@ -56,11 +57,15 @@ protected void executeStoredProcedure(Mutation mutation, TableMetadata tableMeta
5657
.execute(args, cosmosMutation.getStoredProcedureOptions());
5758
}
5859

59-
private void throwException(CosmosException exception) throws ExecutionException {
60+
private void throwException(CosmosException exception, Mutation mutation)
61+
throws ExecutionException {
6062
int statusCode = exception.getSubStatusCode();
6163

6264
if (statusCode == CosmosErrorCode.PRECONDITION_FAILED.get()) {
63-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), exception);
65+
throw new NoMutationException(
66+
CoreError.NO_MUTATION_APPLIED.buildMessage(),
67+
Collections.singletonList(mutation),
68+
exception);
6469
} else if (statusCode == CosmosErrorCode.RETRY_WITH.get()) {
6570
throw new RetriableExecutionException(
6671
CoreError.COSMOS_RETRY_WITH_ERROR_OCCURRED_IN_MUTATION.buildMessage(

core/src/main/java/com/scalar/db/storage/dynamo/BatchHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public void handle(List<? extends Mutation> mutations) throws ExecutionException
8686
boolean allReasonsAreTransactionConflicts = true;
8787
for (CancellationReason reason : e.cancellationReasons()) {
8888
if (reason.code().equals("ConditionalCheckFailed")) {
89-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), e);
89+
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), mutations, e);
9090
}
9191
if (!reason.code().equals("TransactionConflict") && !reason.code().equals("None")) {
9292
allReasonsAreTransactionConflicts = false;

core/src/main/java/com/scalar/db/storage/dynamo/DeleteStatementHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.scalar.db.exception.storage.NoMutationException;
1313
import com.scalar.db.exception.storage.RetriableExecutionException;
1414
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
15+
import java.util.Collections;
1516
import java.util.Map;
1617
import java.util.Optional;
1718
import javax.annotation.concurrent.ThreadSafe;
@@ -50,7 +51,8 @@ public void handle(Delete delete) throws ExecutionException {
5051
try {
5152
delete(delete, tableMetadata);
5253
} catch (ConditionalCheckFailedException e) {
53-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), e);
54+
throw new NoMutationException(
55+
CoreError.NO_MUTATION_APPLIED.buildMessage(), Collections.singletonList(delete), e);
5456
} catch (TransactionConflictException e) {
5557
throw new RetriableExecutionException(
5658
CoreError.DYNAMO_TRANSACTION_CONFLICT_OCCURRED_IN_MUTATION.buildMessage(

core/src/main/java/com/scalar/db/storage/dynamo/PutStatementHandler.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.scalar.db.exception.storage.NoMutationException;
1414
import com.scalar.db.exception.storage.RetriableExecutionException;
1515
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
16+
import java.util.Collections;
1617
import java.util.Map;
1718
import java.util.Optional;
1819
import javax.annotation.concurrent.ThreadSafe;
@@ -51,7 +52,8 @@ public void handle(Put put) throws ExecutionException {
5152
try {
5253
execute(put, tableMetadata);
5354
} catch (ConditionalCheckFailedException e) {
54-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), e);
55+
throw new NoMutationException(
56+
CoreError.NO_MUTATION_APPLIED.buildMessage(), Collections.singletonList(put), e);
5557
} catch (TransactionConflictException e) {
5658
throw new RetriableExecutionException(
5759
CoreError.DYNAMO_TRANSACTION_CONFLICT_OCCURRED_IN_MUTATION.buildMessage(

core/src/main/java/com/scalar/db/storage/jdbc/JdbcDatabase.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.scalar.db.exception.storage.RetriableExecutionException;
2222
import java.sql.Connection;
2323
import java.sql.SQLException;
24+
import java.util.Collections;
2425
import java.util.List;
2526
import java.util.Optional;
2627
import javax.annotation.concurrent.ThreadSafe;
@@ -138,7 +139,8 @@ public void put(Put put) throws ExecutionException {
138139
try {
139140
connection = dataSource.getConnection();
140141
if (!jdbcService.put(put, connection)) {
141-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage());
142+
throw new NoMutationException(
143+
CoreError.NO_MUTATION_APPLIED.buildMessage(), Collections.singletonList(put));
142144
}
143145
} catch (SQLException e) {
144146
throw new ExecutionException(
@@ -160,7 +162,8 @@ public void delete(Delete delete) throws ExecutionException {
160162
try {
161163
connection = dataSource.getConnection();
162164
if (!jdbcService.delete(delete, connection)) {
163-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage());
165+
throw new NoMutationException(
166+
CoreError.NO_MUTATION_APPLIED.buildMessage(), Collections.singletonList(delete));
164167
}
165168
} catch (SQLException e) {
166169
throw new ExecutionException(
@@ -210,7 +213,7 @@ public void mutate(List<? extends Mutation> mutations) throws ExecutionException
210213
throw new ExecutionException(
211214
CoreError.JDBC_ERROR_OCCURRED_IN_MUTATION.buildMessage(e.getMessage()), e);
212215
}
213-
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage());
216+
throw new NoMutationException(CoreError.NO_MUTATION_APPLIED.buildMessage(), mutations);
214217
} else {
215218
connection.commit();
216219
}

0 commit comments

Comments
 (0)