This is a patch posted by Marek Stipek's review, with following comment: The row images of a reported cascade action lived in two plain THD members, on the assumption that at most one cascade action is in flight per THD. InnoDB performs the next level of an FK chain from inside the outer cascade action, though (row_update_cascade_for_mysql() recurses into row_ins_foreign_check_on_constraint()). For a chain like gp -> p -> c: - the nested action for c overwrote the before-image captured for p, reported c and freed the images, so thd_fk_cascade_row() for p found no image and silently dropped the row. Only the deepest level reached the binary log, and since its events carry FK_CASCADE_EVENTS_F the replica did not re-run the cascade either: it kept the rows of p, silently diverging from the primary; - the nested capture reused the buffer allocated for p's row length, so a child with a longer row than its parent overran it (debug builds report "Freeing overrun buffer" and crash). Keep the images on a stack instead: capturing a before-image opens a frame with buffers sized for its own table, and thd_fk_cascade_row() or thd_fk_cascade_abort() closes it. InnoDB now closes the frame also when capturing the before-image failed, as the service contract already asked for, so every frame is closed exactly once. Self-referencing foreign keys: the child of such a cascade is the table the statement itself changes, through the instance of it opened for the foreign key. That handler has not read anything, so it has no row template yet, and ha_innobase::fk_cascade_fetch_row() refused to convert the row, although it rebuilds the template anyway, allocating it if needed. The cascaded rows were not logged; when the statement also cascaded into another table, whose rows were, the replica did not re-run the cascade either and kept the self-referencing rows. Drop the check. The same check made capture fail on a replica, for the handler of the child opened for the foreign key there has not read anything either: the pull request documents the feature as inert on the applier and pins it in rpl_fk_cascade_binlog_row_slave_option, but the child is open via FK prelocking there too. With the check gone, a replica with the feature ON (origin OFF) captures the cascades it re-runs and logs them in its own binary log, as any other session does; the test and the design document now say so. Order of the cascaded rows: the queue was emitted at statement end, after all rows of the statement itself. When a cascade changes a row that the statement changes after it - with the self-referencing cascades now captured, e.g. DELETE FROM s WHERE id IN (1,2) with s.parent_id -> s.id ON DELETE SET NULL - the binlog had DELETE 2 before the cascaded UPDATE of 2, and the replica stopped with ERROR 1032. handler::binlog_log_row() now emits the queue before each row of the statement is logged: the cascades that row change ran precede it, as they did in execution. Derived rows and the statement's own go to separate row events, so that FK_CASCADE_DERIVED_F keeps marking exactly the derived ones. - rpl_fk_cascade_binlog_row_mixed_eligibility: a statement with an ineligible child table is not captured at all (an eligible and an ineligible sibling, an ineligible grandchild, an all-eligible control case), checked on the replica and in the binlog. The design document refers to it, but it is not in the pull request. - rpl_fk_cascade_binlog_row_multilevel: cascades through several levels up to the InnoDB maximum of 14 below the parent, and one level deeper (the statement fails, nothing is logged); UPDATE and SET NULL chains, a diamond, savepoints, self-referencing foreign keys with and without another child, and the order of the cascaded rows relative to the statement's own. Each case is checked on the replica. - galera_fk_cascade_binlog_events, ..._log_bin: the same in Galera, without and with a binary log, with parallel applying. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
MariaDB Server
MariaDB Server is one of the most widely deployed open source relational databases. It is built by a global community of contributors together with the MariaDB Foundation and MariaDB plc, and it powers workloads from small applications to large-scale production systems.
MariaDB began as a fork of MySQL, led by the original MySQL developers, and it maintains a high degree of MySQL compatibility. It has since grown into a database with its own capabilities, including native vector search, multiple pluggable storage engines, synchronous clustering, and analytical features, while remaining a straightforward migration target for existing MySQL deployments.
Key features
- Native vector search. A built-in VECTOR data type with approximate nearest-neighbour indexing (HNSW), available since MariaDB 11.8 with no extension required.
- Pluggable storage engines. InnoDB (default for transactional workloads), Aria, MyRocks, ColumnStore for analytics, Spider for sharding, and S3 for archival, among others.
- Replication and clustering. Asynchronous, semi-synchronous, and parallel replication with global transaction IDs, plus Galera synchronous multi-primary clustering.
- Advanced SQL. Common table expressions and recursive CTEs, window functions, system-versioned (temporal) tables, sequences, and a broad set of JSON functions.
- MySQL and Oracle compatibility. Wire-protocol and syntax compatibility with MySQL, plus an Oracle SQL mode supporting PL/SQL-style stored routines.
- Spatial and full-text search. GIS data types and functions, and built-in full-text indexing.
- Security. Role-based access control, pluggable authentication (ed25519, PAM, GSSAPI, and more), data-at-rest encryption, and TLS for connections.
Documentation
- Project home, community, and getting involved
- Reference manual and release notes
- MariaDB compared to MySQL
Releases
MariaDB Server follows a yearly long-term support (LTS) model alongside quarterly rolling releases. Binary LTS releases are maintained for three years and are recommended for production; rolling releases deliver new features sooner with a shorter support window.
For the current version and full history, see Releases and the MariaDB release calendar.
Installing
Packages and installation instructions for all supported platforms are available at https://mariadb.org/download/.
Building from source
To build MariaDB from source and run the test suite, follow the developer guide
It covers building the code correctly, running the MariaDB testing framework, and choosing the right branch to target for contributions.
Contributing
Contributions are welcome, from code and documentation to bug reports and reviews. See CONTRIBUTING.md to get started, and CODING_STANDARDS.md for code style. Contributors and community members are recognised in CREDITS.
Getting help
- Zulip chat
- Maria Discuss mailing list
- Bug reports
- Security vulnerabilities: see SECURITY.md
Licensing
MariaDB Server is licensed under version 2 of the GNU General Public License (GPLv2), without the "any later version" clause. This is inherited from MySQL. License information is in the COPYING file, and third-party license information is in the THIRDPARTY file.
About MariaDB Foundation
MariaDB is brought to you by the MariaDB Foundation and MariaDB plc. The MariaDB Foundation is the custodian of the MariaDB Server codebase, ensuring it stays open and that anyone can contribute. See CREDITS for details on the Foundation and the people developing MariaDB.
MySQL, the base of MariaDB, is a product and trademark of Oracle Corporation, Inc.