This is an automated email from the ASF dual-hosted git repository.

ascherbakov pushed a commit to branch tx_deadlock_recovery_hang
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit e7f3ff5fa9f1f6fd3c8a39843677035a85be5bb8
Author: Alexey Scherbakov <alexey.scherbak...@gmail.com>
AuthorDate: Fri Dec 8 18:40:59 2023 +0300

    Hang on commit
---
 .../apache/ignite/distributed/ItLockTableTest.java | 203 +++++++++++++++++++++
 1 file changed, 203 insertions(+)

diff --git 
a/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItLockTableTest.java
 
b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItLockTableTest.java
new file mode 100644
index 0000000000..dfe256571b
--- /dev/null
+++ 
b/modules/table/src/integrationTest/java/org/apache/ignite/distributed/ItLockTableTest.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.distributed;
+
+import static 
org.apache.ignite.internal.replicator.ReplicaManager.DEFAULT_IDLE_SAFE_TIME_PROPAGATION_PERIOD_MILLISECONDS;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
+import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
+import org.apache.ignite.internal.hlc.HybridClock;
+import org.apache.ignite.internal.logger.IgniteLogger;
+import org.apache.ignite.internal.logger.Loggers;
+import org.apache.ignite.internal.placementdriver.PlacementDriver;
+import org.apache.ignite.internal.raft.configuration.RaftConfiguration;
+import org.apache.ignite.internal.replicator.ReplicaService;
+import org.apache.ignite.internal.schema.Column;
+import org.apache.ignite.internal.schema.SchemaDescriptor;
+import org.apache.ignite.internal.schema.configuration.GcConfiguration;
+import org.apache.ignite.internal.table.TableViewInternal;
+import org.apache.ignite.internal.testframework.IgniteAbstractTest;
+import org.apache.ignite.internal.tx.DeadlockPreventionPolicy;
+import org.apache.ignite.internal.tx.HybridTimestampTracker;
+import org.apache.ignite.internal.tx.InternalTransaction;
+import org.apache.ignite.internal.tx.configuration.TransactionConfiguration;
+import org.apache.ignite.internal.tx.impl.HeapLockManager;
+import org.apache.ignite.internal.tx.impl.TransactionIdGenerator;
+import org.apache.ignite.internal.tx.impl.TxManagerImpl;
+import org.apache.ignite.internal.type.NativeTypes;
+import org.apache.ignite.network.ClusterNode;
+import org.apache.ignite.network.ClusterService;
+import org.apache.ignite.table.RecordView;
+import org.apache.ignite.table.Tuple;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+/**
+ * Test lock table.
+ */
+@ExtendWith(ConfigurationExtension.class)
+public class ItLockTableTest extends IgniteAbstractTest {
+    private static final IgniteLogger LOG = 
Loggers.forClass(ItLockTableTest.class);
+
+    private static int EMP_TABLE_ID = 2;
+
+    private static final int CACHE_SIZE = 10;
+
+    private static final String TABLE_NAME = "test";
+
+    private static SchemaDescriptor TABLE_SCHEMA = new SchemaDescriptor(
+            1,
+            new Column[]{new Column("id".toUpperCase(), NativeTypes.INT32, 
false)},
+            new Column[]{
+                    new Column("name".toUpperCase(), NativeTypes.STRING, true),
+                    new Column("salary".toUpperCase(), NativeTypes.DOUBLE, 
true)
+            }
+    );
+
+    protected TableViewInternal testTable;
+
+    protected final TestInfo testInfo;
+
+    //TODO fsync can be turned on again after 
https://issues.apache.org/jira/browse/IGNITE-20195
+    @InjectConfiguration("mock: { fsync: false }")
+    protected static RaftConfiguration raftConfiguration;
+
+    @InjectConfiguration
+    protected static GcConfiguration gcConfig;
+
+    @InjectConfiguration
+    protected static TransactionConfiguration txConfiguration;
+
+    private ItTxTestCluster txTestCluster;
+
+    private HybridTimestampTracker timestampTracker = new 
HybridTimestampTracker();
+
+    /**
+     * The constructor.
+     *
+     * @param testInfo Test info.
+     */
+    public ItLockTableTest(TestInfo testInfo) {
+        this.testInfo = testInfo;
+    }
+
+    @BeforeEach
+    public void before() throws Exception {
+        txTestCluster = new ItTxTestCluster(
+                testInfo,
+                raftConfiguration,
+                txConfiguration,
+                workDir,
+                1,
+                1,
+                false,
+                timestampTracker
+        ) {
+            @Override
+            protected TxManagerImpl newTxManager(
+                    ClusterService clusterService,
+                    ReplicaService replicaSvc,
+                    HybridClock clock,
+                    TransactionIdGenerator generator,
+                    ClusterNode node,
+                    PlacementDriver placementDriver
+            ) {
+                return new TxManagerImpl(
+                        txConfiguration,
+                        clusterService,
+                        replicaSvc,
+                        new HeapLockManager(
+                                new DeadlockPreventionPolicy() {}),
+                        clock,
+                        generator,
+                        placementDriver,
+                        () -> 
DEFAULT_IDLE_SAFE_TIME_PROPAGATION_PERIOD_MILLISECONDS
+                );
+            }
+        };
+        txTestCluster.prepareCluster();
+
+        testTable = txTestCluster.startTable(TABLE_NAME, EMP_TABLE_ID, 
TABLE_SCHEMA);
+
+        log.info("Tables have been started");
+    }
+
+    @AfterEach
+    public void after() throws Exception {
+        txTestCluster.shutdownCluster();
+    }
+
+    @Test
+    public void testDeadlockRecovery() throws InterruptedException {
+        RecordView<Tuple> view = testTable.recordView();
+        Tuple t1 = tuple(0, "0");
+        assertTrue(view.insert(null, t1));
+
+        Tuple t2 = tuple(1, "1");
+        assertTrue(view.insert(null, t2));
+
+        InternalTransaction tx1 = (InternalTransaction) 
txTestCluster.igniteTransactions().begin();
+        InternalTransaction tx2 = (InternalTransaction) 
txTestCluster.igniteTransactions().begin();
+
+        LOG.info("id1={}", tx1.id());
+        LOG.info("id2={}", tx2.id());
+
+        assertTrue(tx2.id().compareTo(tx1.id()) > 0);
+
+        Tuple t10 = view.get(tx1, keyTuple(0));
+        Tuple t21 = view.get(tx2, keyTuple(1));
+
+        assertEquals(t1.stringValue("name"), t10.stringValue("name"));
+        assertEquals(t2.stringValue("name"), t21.stringValue("name"));
+
+        view.upsertAsync(tx1, tuple(1, "11"));
+        view.upsertAsync(tx2, tuple(0, "00"));
+
+        Thread.sleep(500);
+
+//        assertTrue(TestUtils.waitForCondition(() -> {
+//            int total = 0;
+//            HeapLockManager lockManager = (HeapLockManager) 
txTestCluster.txManagers.get(txTestCluster.localNodeName).lockManager();
+//            for (int j = 0; j < lockManager.getSlots().length; j++) {
+//                LockState slot = lockManager.getSlots()[j];
+//
+//                total += slot.waitersCount();
+//            }
+//
+//            return total == 8;
+//        }, 10_000), "Some lockers are missing");
+
+        tx1.commit();
+    }
+
+    private static Tuple tuple(int id, String name) {
+        return Tuple.create()
+                .set("id", id)
+                .set("name", name);
+    }
+
+    private static Tuple keyTuple(int id) {
+        return Tuple.create()
+                .set("id", id);
+    }
+}

Reply via email to