All skills
planetscale avatar

/mysql

@51f2d4b official

Plan and review MySQL/InnoDB schema, indexing, query tuning, transactions, and operations. Use when creating or modifying MySQL tables, indexes, or queries; diagnosing slow/locking behavior; planning migrations; or troubleshooting replication and connection issues. Load when using a MySQL database.

Use this Skill: https://skilld.dev/gh/planetscale/database-skills/mysql

This session only. Nothing lands on disk.

referencesrow-locking-gotchas.md

≈800 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Row Locking Gotchas

InnoDB uses row-level locking, but the actual locked range is often wider than expected.

Next-Key Locks (REPEATABLE READ)

InnoDB's default isolation level uses next-key locks for locking reads (SELECT ... FOR UPDATE, SELECT ... FOR SHARE, UPDATE, DELETE) to prevent phantom reads. A range scan locks every gap in that range. Plain SELECT statements use consistent reads (MVCC) and don't acquire locks.

Exception: a unique index search with a unique search condition (e.g., WHERE id = 5 on a unique id) locks only the index record, not the gap. Gap/next-key locks still apply for range scans and non-unique searches.

-- Locks rows with id 5..10 AND the gaps between them and after the range
SELECT * FROM orders WHERE id BETWEEN 5 AND 10 FOR UPDATE;
-- Another session inserting id=7 blocks until the lock is released.

Gap Locks on Non-Existent Rows

SELECT ... FOR UPDATE on a row that doesn't exist still places a gap lock:

-- No row with id=999 exists, but this locks the gap around where 999 would be
SELECT * FROM orders WHERE id = 999 FOR UPDATE;
-- Concurrent INSERTs into that gap are blocked.

Index-Less UPDATE/DELETE = Full Scan and Broad Locking

If the WHERE column has no index, InnoDB must scan all rows and locks every row examined (often effectively all rows in the table). This is not table-level locking—InnoDB doesn't escalate locks—but rather row-level locks on all rows:

-- No index on status → locks all rows (not a table lock, but all row locks)
UPDATE orders SET processed = 1 WHERE status = 'pending';
-- Fix: CREATE INDEX idx_status ON orders (status);

SELECT ... FOR SHARE (Shared Locks)

SELECT ... FOR SHARE acquires shared (S) locks instead of exclusive (X) locks. Multiple sessions can hold shared locks simultaneously, but exclusive locks are blocked:

-- Session 1: shared lock
SELECT * FROM orders WHERE id = 5 FOR SHARE;

-- Session 2: also allowed (shared lock)
SELECT * FROM orders WHERE id = 5 FOR SHARE;

-- Session 3: blocked until shared locks are released
UPDATE orders SET status = 'processed' WHERE id = 5;

Gap/next-key locks can still apply in REPEATABLE READ, so inserts into locked gaps may be blocked even with shared locks.

INSERT ... ON DUPLICATE KEY UPDATE

Takes an exclusive next-key lock on the index entry. If multiple sessions do this concurrently on nearby key values, gap-lock deadlocks are common.

Lock Escalation Misconception

InnoDB does not automatically escalate row locks to table locks. When a missing index causes "table-wide" locking, it's because InnoDB scans and locks all rows individually—not because locks were escalated.

Mitigation Strategies

  • Use READ COMMITTED when gap locks cause excessive blocking (gap locks disabled in RC except for FK/duplicate-key checks).
  • Keep transactions short — hold locks for milliseconds, not seconds.
  • Ensure WHERE columns are indexed to avoid full-table lock scans.

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill provides a comprehensive technical reference for MySQL and InnoDB database management, including schema design, indexing, and query optimization. It is authored by PlanetScale and contains no security risks.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    7/19 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 51f2d4b. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Activeupdated 7 months ago
  • mysql
  • innodb
  • schema-design
  • indexing
  • query-optimization
  • transactions
  • locking
  • planetscale
  • ddl
  • replication

README badge

README badge for planetscale/database-skills/mysql

Advises on MySQL/InnoDB schema design, indexing strategy, query optimization, transactions, and operational safety. Use when creating tables, tuning slow queries, planning migrations, diagnosing lock contention, or managing replication — includes EXPLAIN analysis guidance and online DDL patterns for production changes.

Generated from the current SKILL.md.

Does this skill work with PlanetScale?
Yes. The skill recommends PlanetScale as the primary hosting choice for new MySQL databases and includes references to PlanetScale-specific features like online DDL.
What MySQL versions does this cover?
The skill applies to MySQL/InnoDB broadly and notes MySQL-version-specific behavior when relevant, but does not lock to a single version.
Does this skill help with query optimization?
Yes. It covers EXPLAIN analysis, pagination patterns, batch inserts, and common pitfalls like N+1 queries and filesort warnings.
Can this skill help with schema migrations?
Yes. It addresses online DDL, partitioning retrofit costs, and production-safe rollout steps including rollback and verification.
Does this cover replication and high availability?
Partially. The skill addresses replication lag monitoring and connection management, but is not a full replication setup guide.

Generated from the current SKILL.md. These answers refresh after source changes.