You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by as...@apache.org on 2023/12/08 15:41:11 UTC

(ignite-3) branch tx_deadlock_recovery_hang created (now e7f3ff5fa9)

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

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


      at e7f3ff5fa9 Hang on commit

This branch includes the following new commits:

     new e7f3ff5fa9 Hang on commit

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(ignite-3) 01/01: Hang on commit

Posted by as...@apache.org.
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 <al...@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);
+    }
+}