This is an automated email from the ASF dual-hosted git repository.
vpyatkov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new cd5720b790 IGNITE-19329 Tx. POSITIVE_INF inside SortedIndexLocker is
not unique across partitions (#2074)
cd5720b790 is described below
commit cd5720b790e4cd767e374b01977cdccb229d7360
Author: Vladislav Pyatkov <[email protected]>
AuthorDate: Wed May 17 12:09:22 2023 +0400
IGNITE-19329 Tx. POSITIVE_INF inside SortedIndexLocker is not unique across
partitions (#2074)
---
.../ignite/internal/sql/engine/ItDmlTest.java | 18 ++++++++
.../apache/ignite/internal/table/TableImpl.java | 1 +
.../table/distributed/SortedIndexLocker.java | 49 ++++++++++++++++++----
.../PartitionReplicaListenerIndexLockingTest.java | 1 +
.../replication/PartitionReplicaListenerTest.java | 2 +-
5 files changed, 61 insertions(+), 10 deletions(-)
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
index f0ce4c9335..7203ab60b2 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/sql/engine/ItDmlTest.java
@@ -136,6 +136,24 @@ public class ItDmlTest extends
ClusterPerClassIntegrationTest {
.check();
}
+ /**
+ * Test ensures inserts are possible after read lock on a range.
+ */
+ @Test
+ public void rangeReadAndExclusiveInsert() {
+ sql("CREATE TABLE test (id INT, aff_key INT, val INT, PRIMARY KEY (id,
aff_key)) COLOCATE BY (aff_key) ");
+ sql("CREATE INDEX test_val_asc_idx ON test (val ASC)");
+ sql("INSERT INTO test VALUES (1, 1, 1), (2, 1, 2), (3, 1, 3)");
+
+ log.info("Data was loaded.");
+
+ Transaction tx = CLUSTER_NODES.get(0).transactions().begin();
+
+ sql(tx, "SELECT * FROM test WHERE val <= 1 ORDER BY val");
+
+ sql("INSERT INTO test VALUES (4, 1, 4)"); // <-- this INSERT uses
implicit transaction
+ }
+
/**
* Test ensures that big insert although being split to several chunks
will share the same implicit transaction.
*/
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/TableImpl.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/TableImpl.java
index 1e406f54c6..c1200dc027 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/TableImpl.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/TableImpl.java
@@ -326,6 +326,7 @@ public class TableImpl implements Table {
indexId,
partitionId -> new SortedIndexLocker(
indexId,
+ partitionId,
lockManager,
tbl.storage().getOrCreateSortedIndex(partitionId,
indexId),
searchRowResolver
diff --git
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
index 804e922fab..e82347efbb 100644
---
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
+++
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
@@ -25,7 +25,9 @@ import org.apache.ignite.internal.schema.BinaryRow;
import org.apache.ignite.internal.schema.BinaryTuple;
import org.apache.ignite.internal.schema.BinaryTuplePrefix;
import org.apache.ignite.internal.schema.BinaryTupleSchema;
-import org.apache.ignite.internal.schema.BinaryTupleSchema.Element;
+import org.apache.ignite.internal.schema.Column;
+import org.apache.ignite.internal.schema.NativeTypes;
+import org.apache.ignite.internal.schema.SchemaDescriptor;
import org.apache.ignite.internal.storage.RowId;
import org.apache.ignite.internal.storage.index.IndexRow;
import org.apache.ignite.internal.storage.index.PeekCursor;
@@ -43,12 +45,19 @@ import org.jetbrains.annotations.Nullable;
* <p>Simply acquires lock on a given row for lookup and remove, acquires lock
on a next key for insert.
*/
public class SortedIndexLocker implements IndexLocker {
- /** Index INF+ value object. */
- private static final BinaryTuple POSITIVE_INF = new BinaryTuple(
- BinaryTupleSchema.create(new Element[0]),
- new BinaryTupleBuilder(0, false).build()
+
+ private static final SchemaDescriptor INFINITY_TUPLE_SCHEMA = new
SchemaDescriptor(
+ 1,
+ new Column[]{
+ new Column("indexId", NativeTypes.UUID, false),
+ new Column("partId", NativeTypes.INT32, false)
+ },
+ new Column[0]
);
+ /** Index INF+ value object. */
+ private final BinaryTuple positiveInf;
+
private final UUID indexId;
private final LockManager lockManager;
@@ -62,16 +71,38 @@ public class SortedIndexLocker implements IndexLocker {
* Constructs the object.
*
* @param indexId An identifier of the index this locker is created for.
+ * @param partId Partition number.
* @param lockManager A lock manager to acquire locks in.
* @param storage A storage of an index this locker is created for.
* @param indexRowResolver A convertor which derives an index key from
given table row.
*/
- public SortedIndexLocker(UUID indexId, LockManager lockManager,
SortedIndexStorage storage,
+ public SortedIndexLocker(UUID indexId, int partId, LockManager
lockManager, SortedIndexStorage storage,
Function<BinaryRow, BinaryTuple> indexRowResolver) {
this.indexId = indexId;
this.lockManager = lockManager;
this.storage = storage;
this.indexRowResolver = indexRowResolver;
+
+ this.positiveInf = createInfiniteBoundary(partId, indexId);
+ }
+
+ /**
+ * Creates a tuple for positive infinity boundary.
+ *
+ * @param partId Partition id.
+ * @param indexId Index id.
+ * @return Infinity binary tuple.
+ */
+ private static BinaryTuple createInfiniteBoundary(int partId, UUID
indexId) {
+ var binarySchema =
BinaryTupleSchema.createSchema(INFINITY_TUPLE_SCHEMA, new int[]{
+ INFINITY_TUPLE_SCHEMA.column("indexId").schemaIndex(),
+ INFINITY_TUPLE_SCHEMA.column("partId").schemaIndex()
+ });
+
+ return new BinaryTuple(
+ binarySchema,
+ new BinaryTupleBuilder(binarySchema.elementCount(),
false).appendUuid(indexId).appendInt(partId).build()
+ );
}
/** {@inheritDoc} */
@@ -143,8 +174,8 @@ public class SortedIndexLocker implements IndexLocker {
return row0 == row1 || row0.rowId().equals(row1.rowId());
}
- private static BinaryTuple indexKey(@Nullable IndexRow indexRow) {
- return (indexRow == null) ? POSITIVE_INF : indexRow.indexColumns();
+ private BinaryTuple indexKey(@Nullable IndexRow indexRow) {
+ return (indexRow == null) ? positiveInf : indexRow.indexColumns();
}
/** {@inheritDoc} */
@@ -161,7 +192,7 @@ public class SortedIndexLocker implements IndexLocker {
if (cursor.hasNext()) {
nextKey = cursor.next().indexColumns();
} else { // Otherwise INF.
- nextKey = POSITIVE_INF;
+ nextKey = positiveInf;
}
var nextLockKey = new LockKey(indexId, nextKey.byteBuffer());
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
index 44a8fbc65c..fd9c72973c 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
@@ -161,6 +161,7 @@ public class PartitionReplicaListenerIndexLockingTest
extends IgniteAbstractTest
IndexLocker sortedIndexLocker = new SortedIndexLocker(
SORTED_INDEX_ID,
+ PART_ID,
LOCK_MANAGER,
(SortedIndexStorage) sortedIndexStorage.storage(),
row2SortKeyConverter
diff --git
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
index 5079324369..cbf3f6b19b 100644
---
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
+++
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
@@ -351,7 +351,7 @@ public class PartitionReplicaListenerTest extends
IgniteAbstractTest {
);
IndexLocker pkLocker = new HashIndexLocker(pkIndexId, true,
lockManager, row2Tuple);
- IndexLocker sortedIndexLocker = new SortedIndexLocker(sortedIndexId,
lockManager, indexStorage, row2Tuple);
+ IndexLocker sortedIndexLocker = new SortedIndexLocker(sortedIndexId,
partId, lockManager, indexStorage, row2Tuple);
IndexLocker hashIndexLocker = new HashIndexLocker(hashIndexId, false,
lockManager, row2Tuple);
DummySchemaManagerImpl schemaManager = new
DummySchemaManagerImpl(schemaDescriptor);