Skip to content

[Bug]: pessimistic INSERT ... SELECT holds PK table lock too early on purchase_order_detail #24200

@LeftHandCold

Description

@LeftHandCold

Is there an existing issue for the same bug?

  • I have checked the existing issues.

Branch Name

3.0-dev

Commit ID

9016584

Other Environment Information

  • Hardware parameters: cn.s8c64g
  • OS type: Linux
  • Others:
    • CN: 33366666-3331-3934-3564-643931656131
    • tenant/account: ws_bf2d347f
    • transaction mode: Pessimistic

Actual Behavior

Large INSERT INTO ... SELECT ... statements against jst_receipts_tables.purchase_order_detail can hang for a long time when the target table has a real primary key. Profiles show the statement entering Compile.prePipelineInitializer() and blocking in lockop.LockTable() / lockservice.waiter.wait() before the pipeline starts. Once the table lock is acquired, the statement can hold it for the whole source scan and block later writers on the same table.

Expected Behavior

For pessimistic INSERT ... SELECT ..., table-lock semantics should be preserved, but the table lock should not be acquired in prePipelineInitializer() before the source side starts running. The lock hold window should be minimized to reduce long blocking on the target table.

Steps to Reproduce

  1. Create a target table with a real primary key.
  2. In a pessimistic transaction, run a large INSERT INTO purchase_order_detail ... SELECT ... that scans a large source dataset.
  3. Observe that the statement can hang before pipeline execution with profiles showing lockservice.waiter.wait -> lockop.LockTable -> Compile.lockTable -> Compile.prePipelineInitializer.
  4. Remove the primary key from the target table and rerun the same statement. The statement finishes much faster and no longer hits the same table-lock path.

Additional information

  • The locked table id observed in production was 5396701, which maps to jst_receipts_tables.purchase_order_detail.
  • Root cause analysis showed the lock target was generated from the real PK and escalated to a table lock, then acquired too early in the execution lifecycle.
  • The fix keeps table-lock semantics for pessimistic INSERTs, but defers pre-pipeline table locking for Query_INSERT so the lock is acquired by the pipeline LockOp instead of prePipelineInitializer().

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions