Skip to content

[Bug] MetaLockUtils.commitLockTables leaks acquired commit locks on rollback (unlocks wrong index) #64682

Description

@LuciferYang

Search before asking

  • I had searched in the issues and found no similar issues.

Version

master (MetaLockUtils.commitLockTables).

What's Wrong?

MetaLockUtils.commitLockTables has a rollback bug: when commitLock() throws for the table at index i, the rollback loop iterates j from i-1 down to 0 but unlocks tableList.get(i) (the table that failed to lock) instead of tableList.get(j) (the previously locked tables):

public static void commitLockTables(List<Table> tableList) {
    for (int i = 0; i < tableList.size(); i++) {
        try {
            tableList.get(i).commitLock();
        } catch (Exception e) {
            for (int j = i - 1; j >= 0; j--) {
                tableList.get(i).commitUnlock();   // should be get(j)
            }
        }
    }
}

Consequences on the failure path:

  • Commit locks already acquired for tables 0..i-1 are never released (leak).
  • The failing table (i) is commitUnlock()-ed repeatedly on a lock it does not hold.
  • The exception is swallowed and the outer loop keeps trying to lock the remaining tables.

The correct siblings tryCommitLockTables and writeLockTablesOrMetaException use get(j) and propagate the failure.

Note: in normal operation commitLock()MonitoredReentrantLock.lock() does not throw, so this catch is defensive and the bug is latent; the fix makes the rare failure path correct.

What You Expected?

On a commit-lock acquisition failure, the locks already acquired should be released (get(j)) and the failure propagated, instead of leaking locks and silently continuing.

How to Reproduce?

Code inspection: commitLockTables unlocks get(i) instead of get(j) in its rollback loop, diverging from every other lock helper in the class. A unit test that injects a table whose commitLock() throws shows the previously-locked table is left locked.

Anything Else?

Fix proposed in PR #64676.

Are you willing to submit PR?

  • Yes I am willing to submit a PR!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions