Skip to content

fix(linux-drivers): stop an editor script before its next statement on MySQL, MariaDB and SQLite - #3780

Merged
datlechin merged 2 commits into
mainfrom
fix/3766-mysql-stop-batch-race
Oct 22, 2026
Merged

datlechin merged 2 commits into
mainfrom
fix/3766-mysql-stop-batch-race

Conversation

@datlechin

@datlechin datlechin commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Summary

  • MySQL/MariaDB editor runs send one statement per round trip, split as the mysql client splits. Sent whole, the server starts the next statement as soon as the last result is written, so a KILL that failed or came late let it run while the run read Cancelled.
  • Text without DELIMITER lines still goes as written when it is one statement, or when only the server can find the statement ends: a statement not opened by a known plain keyword (a routine body, a compound statement), a /*! comment, or text sql_mode reads its own way (a backslash in a string, [name], $$).
  • The run checks for a stop before each statement, so nothing after the running one is sent, whatever the KILL did. The row limit's SET now runs under the same watch.
  • TimedOut { server_cancelled } comes from the statement's own 1317 or server timeout, not from the KILL returning OK. A KILL with no answer by the end of the grace ends the session.
  • The KILL's control connection is pinged before reuse and replaced when the server closed it since the last stop.
  • SQL Server: a batch that ended on its own while the stop waited for a token boundary no longer reads as a confirmed stop.
  • SQLite: a stop also ends a script between statements, since the interrupt reaches a statement only every 1,000 instructions.
  • Tests changed on purpose: editor_session::consumer_gone_kills_the_rest_of_the_batch is now consumer_gone_sends_nothing_after_the_running_statement, with no 100 MB SELECT; the split test for SELECT 1; SELECT 2 now expects two texts.

Deliberately not fixed here

  • The Linux editor drops MySQL /*!...*/ comments at a statement's edges, so a dump's /*!40103 SET TIME_ZONE='+00:00' */; never runs. Running them needs catalog refresh and Safe Mode to read them too, and Safe Mode cannot tell where a version-gated /*!NNNNN ... '*/' ... */ ends without the server's version.

Test plan

  • New tests, each failing on main: editor_session::consumer_gone_sends_nothing_after_the_running_statement, a_stop_whose_kill_is_refused_sends_nothing_after_the_running_statement, a_stop_lands_after_the_server_closed_the_kill_connection, a_deadline_reaches_a_run_still_setting_its_row_limit (MySQL and MariaDB), sessions::a_stop_during_one_statement_runs_nothing_after_it (SQLite).
  • Unit tests for the split, the stop results and the SQL Server stop error.
  • The reported test, twice 30 runs in a row on MySQL 8.0 and MariaDB 10.11 with half the CPUs held busy: 30 and 28 passed, and the other 2 timed out starting the container. Every run that reached the test passed.
  • The MySQL docker suite passes locally except the six TLS VerifyFull cases that need CI's certificates.

Fixes #3766

…n MySQL, MariaDB and SQLite

Sent whole, MySQL starts the next statement once the last result is written, so a KILL that missed let it run while the run read Cancelled.
@datlechin
datlechin enabled auto-merge (squash) October 22, 2026 10:40
@datlechin
datlechin merged commit dacad31 into main Oct 22, 2026
31 checks passed
@datlechin
datlechin deleted the fix/3766-mysql-stop-batch-race branch October 22, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MySQL editor stop races the server to the next statement (flaky consumer_gone_kills_the_rest_of_the_batch)

1 participant