NAME
DBIO::MySQL::MariaDBForkGuard - keep a forked child's exit from closing DBD::MariaDB connections it inherited
VERSION
version 0.900004
SYNOPSIS
DBIO::MySQL::MariaDBForkGuard->install;
Nothing calls this by hand: the sync storage and the future_io transport install it after every connect that belongs to DBD::MariaDB.
DESCRIPTION
DBI's END block calls DBI->disconnect_all at every normal exit. DBD::MariaDB (measured with 1.24) carries that out on every connection it lists, whatever InactiveDestroy or AutoInactiveDestroy say. In a forked child that is every connection the child inherited from its parent: the close sends COM_QUIT down the socket both processes share, and the server ends the parent's session. Where a handle had already been destroyed under AutoInactiveDestroy but is still listed, the same call instead dies in a DBI active kids panic and the child's exit status becomes 22. DBD::mysql has no such disconnect_all and is not affected. The report for DBD::MariaDB is drafted in docs/upstream/dbd-mariadb-disconnect-all-after-fork.md and not sent; this class is the workaround (this dist's ADR 0009).
METHODS
install
DBIO::MySQL::MariaDBForkGuard->install;
Load DBD::MariaDB and wrap its disconnect_all. Idempotent: a second call, from any process, changes nothing -- the owner stays the first installer. Returns true when the guard is in place, false when DBD::MariaDB cannot be loaded.
WHAT IT DOES
install wraps DBD::MariaDB::dr::disconnect_all. In the process that installed the guard the wrapper hands over to the original, unchanged. In any other process -- a forked child, however deep -- it does nothing: closing a connection inherited across a fork is never right.
This is process-wide and covers every DBD::MariaDB handle of the process, not only the ones DBIO opened. Two consequences, both deliberate:
A connection a child opens itself is not closed by
disconnect_alleither. ItsDESTROYcloses it (the handle was created in that process, soAutoInactiveDestroydoes not skip it), and so does an explicitdisconnect.The guard is installed by the first DBIO connect over DBD::MariaDB, so it must happen before the fork for the child to have it. A process that forks first and only then opens its first DBIO connection is the installer and treats its own pid as the owner.
It changes no @ISA and no connection() hook: the wrapped sub is replaced in the DBD's own package, once.
SEE ALSO
DBIO::MySQL::Storage - installs it from
_run_connection_actionsDBIO::MySQL::Storage::Async - installs it from
_mysql_connect
AUTHOR
DBIO & DBIx::Class Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.