Skip to content

Split Transaction OPS into Mutable Transaction OPS and Immutable Transaction OPS #69764

Description

@wfxr

Feature Request

The Transaction OPS dashboard should distinguish transactions that produce data or lock mutations from transactions that do not.

Is your feature request related to a problem? Please describe:

The current Transaction OPS panel combines transactions with very different storage effects. It primarily distinguishes transaction outcome and mode, such as committed versus aborted and optimistic versus pessimistic, but it does not show whether a transaction actually contains data mutations or lock writes.

Transaction mode and transaction mutability are different dimensions:

  • An optimistic transaction can be either mutable or immutable.
  • A pessimistic transaction can acquire locks and perform writes, but it can also remain immutable when it only performs non-locking reads.
  • With autocommit enabled and no explicit transaction, SELECT ... FOR UPDATE and SELECT ... FOR SHARE do not acquire locks. They should therefore be treated as immutable even though their SQL text contains a locking clause.

The behavior discussed in PR #63065 makes this ambiguity more visible. A change in how an autocommit locking read is classified by transaction mode can move traffic between the optimistic and pessimistic series without changing whether the statement performs a write or acquires a lock.

As a result, operators cannot use Transaction OPS alone to answer basic workload questions such as:

  • Did transaction traffic increase because of writes and locking operations, or because of read-only queries?
  • Does a change in optimistic or pessimistic OPS represent a real change in storage-side effects?
  • Should an OPS increase be correlated with write pressure and lock contention, or only with read traffic?

This can lead to misleading conclusions during workload analysis, capacity planning, performance diagnosis, and comparison across TiDB versions.

Describe the feature you'd like:

Split Transaction OPS into two transaction-level categories based on actual transaction behavior:

Mutable Transaction OPS

Mutable Transaction OPS should count transactions that contain at least one data mutation or that successfully perform at least one pessimistic or shared lock write. The classification should include mutable transactions regardless of whether they eventually commit or abort.

Representative examples include:

  • A transaction that executes INSERT, UPDATE, or DELETE and produces a data mutation.
  • An explicit transaction that executes SELECT ... FOR UPDATE and acquires pessimistic locks.
  • An explicit transaction that executes SELECT ... FOR SHARE and acquires shared locks.

Immutable Transaction OPS

Immutable Transaction OPS should count transactions that complete without any data mutation or lock write. The classification should be based on what the transaction actually does, rather than on SQL syntax alone.

Representative examples include:

  • An autocommit table SELECT that activates a transaction but performs no write or lock operation.
  • An explicit transaction containing only non-locking reads.
  • SELECT ... FOR UPDATE or SELECT ... FOR SHARE executed with autocommit enabled and without an explicit transaction, because TiDB ignores the lock operation in this context.

Statements that do not activate a KV transaction, such as some constant-only queries, should remain outside the panel if they are outside the existing Transaction OPS counting scope. This proposal does not intend to change the population of transactions counted by the current metric.

Expected dashboard behavior

The dashboard should present Mutable Transaction OPS and Immutable Transaction OPS as separate panels or clearly separated series. Existing dimensions such as commit or abort outcome, optimistic or pessimistic mode, and internal or general scope may remain available where they are useful.

Under the same filters and counting scope, the following relationship should hold:

Mutable Transaction OPS + Immutable Transaction OPS = Transaction OPS

This is a transaction-level distinction. It should not count SQL statements, KV commands, mutations, or lock keys as if each were an independent transaction.

Describe alternatives you've considered:

One alternative is to continue using optimistic and pessimistic transaction mode as a proxy for mutability. This is insufficient because mode describes the transaction execution strategy, not whether the transaction produces data or lock mutations.

Another alternative is to derive the split from existing TiKV transaction command, write-size, or lock-key metrics. These metrics observe different layers and units. A single transaction can issue multiple commands, retries can repeat operations, and aborted transactions may not produce committed writes. They therefore cannot reliably reconstruct a transaction-level mutable versus immutable split.

A third alternative is to rename or further document the current Transaction OPS panel without changing its data. Better documentation would reduce some confusion, but it would still leave operators unable to separate read-only transaction traffic from traffic that writes data or locks.

Teachability, Documentation, Adoption, Migration Strategy:

The panel names and descriptions should define mutability in terms of actual data mutations and lock writes. Documentation should also state that transaction mode is independent of mutability and include the autocommit locking-read example.

This should be an observability-only enhancement. It should not change SQL semantics, transaction protocol behavior, or application behavior. Existing aggregate Transaction OPS should remain derivable from the two categories so that operators can compare the new panels with historical dashboards and existing alerts.

No application migration should be required. Dashboard and alerting users may adopt the more specific categories when they need to distinguish read traffic from transactions that can create write pressure or lock contention.

The implementation should preserve the existing Transaction OPS counting scope and classify each counted transaction exactly once as mutable or immutable.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

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