<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://g1r-mp.com/wiki/index.php?action=history&amp;feed=atom&amp;title=MySQL_connection_recovery</id>
	<title>MySQL connection recovery - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://g1r-mp.com/wiki/index.php?action=history&amp;feed=atom&amp;title=MySQL_connection_recovery"/>
	<link rel="alternate" type="text/html" href="https://g1r-mp.com/wiki/index.php?title=MySQL_connection_recovery&amp;action=history"/>
	<updated>2026-09-19T14:00:30Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://g1r-mp.com/wiki/index.php?title=MySQL_connection_recovery&amp;diff=889&amp;oldid=prev</id>
		<title>QCherry: Document upcoming 0.1.4 database recovery; organize wiki navigation</title>
		<link rel="alternate" type="text/html" href="https://g1r-mp.com/wiki/index.php?title=MySQL_connection_recovery&amp;diff=889&amp;oldid=prev"/>
		<updated>2026-09-19T10:51:40Z</updated>

		<summary type="html">&lt;p&gt;Document upcoming 0.1.4 database recovery; organize wiki navigation&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{DISPLAYTITLE:MySQL connection recovery}}&lt;br /&gt;
= MySQL connection recovery =&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Available since 0.1.4 (in development; not included in the public 0.1.3 release). Server-side only.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Enable automatic recovery ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local db = dbConnect(&amp;quot;mysql&amp;quot;, &amp;quot;host=127.0.0.1;port=3306;dbname=g1r_mp&amp;quot;,&lt;br /&gt;
    &amp;quot;g1r_server&amp;quot;, &amp;quot;env:G1R_DB_PASSWORD&amp;quot;, &amp;quot;charset=utf8mb4;autoreconnect=true&amp;quot;)&lt;br /&gt;
if not db then&lt;br /&gt;
    outputDebugString(&amp;quot;Initial database connection failed&amp;quot;, 1)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial call still returns a connection or false synchronously. After a successful initial connection, the same resource-owned handle can recover in the background. Existing scripts retain the previous opt-in policy: &amp;#039;&amp;#039;&amp;#039;autoreconnect defaults to false&amp;#039;&amp;#039;&amp;#039;. TLS, charset, credentials and connection timeouts from dbConnect are reused; application SQL session settings are not replayed.&lt;br /&gt;
&lt;br /&gt;
== Guarantees and limits ==&lt;br /&gt;
* No failed SQL statement is automatically replayed. A lost response to a write does not prove that the write failed: it may already have committed.&lt;br /&gt;
* SQL queued behind a failed operation on that connection is cancelled with error 90011, preserving completion order. New queries are rejected while disconnected or reconnecting. There is no unbounded offline SQL queue.&lt;br /&gt;
* Transport errors 2006, 2013 and 2055 mark the connection unavailable. Ordinary SQL errors do not cause reconnects.&lt;br /&gt;
* Automatic recovery first waits about 1 second, then failed attempts back off to at most 30 seconds plus a small per-connection stagger. Connect/read/write timeouts still apply. Work and idle health checks run on database workers, not the game thread.&lt;br /&gt;
* With autoreconnect enabled, an idle connection is checked after about 30 seconds without work. [[dbIsConnected]] and [[dbGetConnectionState]] report the last observed status, not a synchronous network probe. Extremely short database wait_timeout values can still cause an operation to fail before recovery.&lt;br /&gt;
* A transaction, autocommit-disabled session, or failed control/unknown statement that might have changed session state is fenced as &amp;#039;&amp;#039;&amp;#039;transaction_lost&amp;#039;&amp;#039;&amp;#039;. Even with autoreconnect enabled it requires an explicit [[dbReconnect]] call. This state means recovery is required, &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; that a lost COMMIT definitely rolled back.&lt;br /&gt;
* Reconnection increments generation. Reapply application session initialization and reconcile uncertain writes before resuming gameplay operations. Temporary tables, locks, variables and open transactions do not survive a replaced session.&lt;br /&gt;
* [[dbClose]] and resource shutdown cancel future recovery. Handles and events belong to their creating resource. Event history is bounded; use [[dbGetConnectionState]] as the current snapshot.&lt;br /&gt;
&lt;br /&gt;
== State notifications ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onDatabaseConnectionStateChange&amp;quot;, resourceRoot,&lt;br /&gt;
    function(connection, state, generation, errorCode, errorMessage)&lt;br /&gt;
        if connection ~= db then return end&lt;br /&gt;
        outputDebugString(&amp;quot;Database state: &amp;quot; .. state .. &amp;quot;, generation=&amp;quot; .. generation)&lt;br /&gt;
        -- Pause new database-dependent operations while unavailable.&lt;br /&gt;
        -- Do not automatically resend failed INSERT/UPDATE/COMMIT statements.&lt;br /&gt;
        -- For transaction_lost, reconcile the operation, then explicitly&lt;br /&gt;
        -- request a fresh session with dbReconnect(connection).&lt;br /&gt;
    end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See [[dbReconnect]], [[dbGetConnectionState]] and [[onDatabaseConnectionStateChange]] for exact contracts.&lt;br /&gt;
&lt;br /&gt;
== gothic_rp integration ==&lt;br /&gt;
The 0.1.4 gamemode uses automatic recovery for its regular connection and explicit recovery for its serialized transaction connection. During an outage it rejects new database-dependent work. Recovery resets any surviving abandoned transaction and uses a separate databaseRecovered event: it does not replay startup migrations, world restoration or login for already authenticated players.&lt;br /&gt;
&lt;br /&gt;
Transactions in the gamemode&amp;#039;s helper write a UUID receipt in the same InnoDB transaction as the business data. If the COMMIT response is lost, a locking receipt lookup resolves whether it committed before releasing the transaction callback. Receipt handling is a &amp;#039;&amp;#039;&amp;#039;gothic_rp implementation&amp;#039;&amp;#039;&amp;#039;, not an automatic guarantee for arbitrary dbQuery/dbExec users. The helper rejects transaction-control and DDL steps; its tables must remain transactional. Successfully resolved receipts are deleted on a best-effort basis; records left after a process crash are harmless and may require administrative retention cleanup.&lt;br /&gt;
&lt;br /&gt;
Character autosave now waits for SQL acknowledgement before clearing the dirty flag; an older acknowledgement cannot clear a newer save. Live characters are saved again after recovery. This is &amp;#039;&amp;#039;&amp;#039;not durable offline persistence&amp;#039;&amp;#039;&amp;#039;: disconnecting a player or stopping/crashing the game server while the database is unavailable can lose unsaved in-memory state. Failed writes are not blindly replayed after login.&lt;br /&gt;
&lt;br /&gt;
== Test checklist ==&lt;br /&gt;
On an isolated test database, test idle timeout, a killed connection, database restart, prolonged downtime, interrupted transaction, a lost COMMIT response, stopping the resource during recovery, and an ordinary SQL syntax error. Verify callback uniqueness, no duplicate monetary/item updates, unchanged ownership limits and continued server responsiveness. Never run destructive connection tests against a live player database.&lt;br /&gt;
&lt;br /&gt;
== Background ==&lt;br /&gt;
The native connector&amp;#039;s implicit reconnect remains disabled; recovery is controlled by G1R:MP. See [https://mariadb.com/docs/connectors/mariadb-connector-c/api-functions/mysql_ping MariaDB mysql_ping] and [https://mariadb.com/docs/server/reference/sql-statements/transactions/rollback MariaDB ROLLBACK].&lt;br /&gt;
&lt;br /&gt;
[[Category:Database Functions]]&lt;br /&gt;
[[Category:Lua Examples]]&lt;/div&gt;</summary>
		<author><name>QCherry</name></author>
	</entry>
</feed>