Skip to content

[Transaction] Transaction coordinator sequenceId generate discontinuity. #13116

@congbobo184

Description

@congbobo184

Describe the bug
When all of transaction log has been delete, transaction sequenceID will not generated in order. Now we store the sequenceID by managedLedger properties, bu the properties storage is not synchronized, so it is not reliable.

To Reproduce
You can reproduce in test.

        ManagedLedgerFactoryConfig factoryConf = new ManagedLedgerFactoryConfig();
        factoryConf.setMaxCacheSize(0);

        @Cleanup("shutdown")
        ManagedLedgerFactory factory = new ManagedLedgerFactoryImpl(metadataStore, bkc, factoryConf);
        TransactionCoordinatorID transactionCoordinatorID = new TransactionCoordinatorID(1);
        ManagedLedgerConfig managedLedgerConfig = new ManagedLedgerConfig();
        managedLedgerConfig.setMaxEntriesPerLedger(3);
        managedLedgerConfig.setMinimumRolloverTime(0, TimeUnit.SECONDS);
        managedLedgerConfig.setMaximumRolloverTime(3, TimeUnit.SECONDS);
        MLTransactionLogImpl mlTransactionLog = new MLTransactionLogImpl(transactionCoordinatorID, factory,
                managedLedgerConfig);
        mlTransactionLog.initialize().join();
        MLTransactionMetadataStore transactionMetadataStore =
                new MLTransactionMetadataStore(transactionCoordinatorID, mlTransactionLog,
                        new TransactionTimeoutTrackerImpl(), new TransactionRecoverTrackerImpl());

        Awaitility.await().until(transactionMetadataStore::checkIfReady);
        TxnID txnID = transactionMetadataStore.newTransaction(600000).get();
        transactionMetadataStore.updateTxnStatus(txnID, TxnStatus.COMMITTING, TxnStatus.OPEN, false).get();
        transactionMetadataStore.updateTxnStatus(txnID, TxnStatus.COMMITTED, TxnStatus.COMMITTING, false).get();
        assertEquals(txnID.getLeastSigBits(), 0);

        mlTransactionLog.getManagedLedger().rollCurrentLedgerIfFull();
        Thread.sleep(1000);
        mlTransactionLog.getManagedLedger().close();
        mlTransactionLog = new MLTransactionLogImpl(transactionCoordinatorID, factory,
                managedLedgerConfig);
        mlTransactionLog.initialize().join();
        transactionMetadataStore =
                new MLTransactionMetadataStore(transactionCoordinatorID, mlTransactionLog,
                        new TransactionTimeoutTrackerImpl(), new TransactionRecoverTrackerImpl());

Expected behavior
sequenceId is continuous and increasing

Desktop (please complete the following information):

  • MacOs

Additional context
We should add an interceptor when roll over ledger, store the current sequenceID to current ledger and persist it. When we found the transaction log LAC entry id is -1, we can get the current sequenceID from the managedLedger properties.

Metadata

Metadata

Assignees

Labels

type/bugThe PR fixed a bug or issue reported a bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions