Capstan.Xa.Id (Capstan v1.2.1)

Copy Markdown View Source

The value-free identity of an XA transaction (ADR-0006, Rule 1).

gtrid/bqual are application-chosen bytes — row-value class — so the pool keys on a sha256 digest of the canonical XID frame, and the raw bytes are never stored, logged, or emitted. Even the digest is never emitted (a digest of a low-entropy application XID is dictionary-reversible); it exists as the in-memory pool key ONLY. Telemetry and errors correlate on server-assigned GTIDs, never on anything XID-derived.

Both XID encodings capstan sees produce the same digest:

  • the XA_prepare_log_event (type 38) body — one_phase byte, format_id / gtrid_length / bqual_length as little-endian u32s, then the raw bytes (layout read from the MySQL server source, control_events.cpp);
  • the resolution QUERY text — XA COMMIT X'<hex gtrid>',X'<hex bqual>',<format_id> (and XA ROLLBACK), the canonical hex-literal form the server writes (captured live; test/fixtures/binlog/xa/).

Summary

Types

A parsed resolution statement: the verb and its XID digest.

t()

A parsed XID's value-free identity: the sha256 digest of the canonical frame.

Functions

The digest of a canonical XID. The frame is namespaced and length-prefixed so no two distinct {format_id, gtrid, bqual} triples collide.

Parses an XA COMMIT/XA ROLLBACK resolution QUERY text into its verb + digest.

Types

resolution()

@type resolution() :: {:commit | :rollback, t()}

A parsed resolution statement: the verb and its XID digest.

t()

@type t() :: <<_::256>>

A parsed XID's value-free identity: the sha256 digest of the canonical frame.

xid()

@type xid() :: %{
  one_phase: boolean(),
  format_id: non_neg_integer(),
  gtrid: binary(),
  bqual: binary()
}

Functions

digest(map)

@spec digest(xid()) :: t()

The digest of a canonical XID. The frame is namespaced and length-prefixed so no two distinct {format_id, gtrid, bqual} triples collide.

parse_resolution(sql)

@spec parse_resolution(String.t()) :: {:ok, resolution()} | :error

Parses an XA COMMIT/XA ROLLBACK resolution QUERY text into its verb + digest.

Accepts exactly the canonical hex-literal form the server writes (XA COMMIT X'…',X'…',<format_id>); a bare XA COMMIT-shaped text with no XID (or any other shape) returns :error — the caller treats an unparseable resolution as unmatched and fails closed, never guesses.