MySQL NDB Cluster 9.4 Release Notes

2 Changes in MySQL NDB Cluster 9.4.0 (2025-07-23, Innovation Release)

MySQL NDB Cluster 9.4.0 is a new Innovation release of NDB Cluster, based on MySQL Server 9.4 and including features in version 9.4 of the NDB storage engine, as well as fixing recently discovered bugs in previous NDB Cluster releases.

Obtaining MySQL NDB Cluster 9.4.  NDB Cluster 9.4 source code and binaries can be obtained from https://dev.mysql.com/downloads/cluster/.

For an overview of major changes made in NDB Cluster 9.4, see What is New in MySQL NDB Cluster 9.4.

This release also incorporates all bug fixes and changes made in previous NDB Cluster releases, as well as all bug fixes and feature changes which were added in mainline MySQL 9 through MySQL 9.4.0 (see Section 2, “Changes in MySQL NDB Cluster 9.4.0 (2025-07-23, Innovation Release)”).

Note

These release notes were created with the assistance of HeatWave GenAI.

Functionality Added or Changed

  • MySQL NDB ClusterJ: The handling of "table not found" conditions in MySQL NDB Cluster has been improved for consistency. Previously, ClusterJ sometimes threw a ClusterJUserException and at other times a ClusterJDatastoreException when a table was not found. Now, all such conditions are reported using a new exception class, ClusterJTableException, after checking the NDB error code. Additionally, a new property, com.mysql.clusterj.table.wait.msec, has been introduced to allow configuration of a wait-and-retry loop for "table not found" conditions.

    The new feature also allows a better handling of schema changes that take place on a NDB Cluster. (Bug #37884530)

    References: See also: Bug #37861635, Bug #118032.

  • MySQL NDB ClusterJ: A single SessionFactory can now handle multiple databases. This is achieved through a new variant of SessionFactory.getSession() that takes a database name as its argument. In this new design, an umbrella SessionFactory manages a set of SessionFactory objects, each of which connects to a single database through a shared pool of connections, so that connections to databases in the same NDB cluster share the same connection.

    This new feature is not enabled by default, but requires setting the property com.mysql.clusterj.multi.database to true, and com.mysql.clusterj.connection.pool.size must not be 0 (default and recommended value is 1). (Bug #37792409)

    References: See also: Bug #36974092, Bug #115884.

  • MySQL NDB ClusterJ: When a user created two ClusterJ SessionFactory objects with the same connection string but different database names, two different Ndb_cluster_connection objects were created for the two databases, which consumed a lot of extra resources.

    Starting from 9.4.0, different SessionFactory objects will share the same underlying connection from a global connection pool when connecting to different databases in the same NDB cluster, reducing resource utilization and increasing performance. In this new implementation, each NDB Cluster now has a system name, and the connection to a cluster is by a Connection.java interface, which is returned by a new Session.getConnection() method. See the ClusterJ API Reference for details. (Bug #36974092)

    References: See also: Bug #37792409, Bug #117893.

  • MySQL NDB ClusterJ: ClusterJ has also been improved by having the implementations of the finalize() method replaced by the Cleaner API. (Bug #30719755)

  • MySQL NDB ClusterJ: Enhancements have been made to improve the scalability of ClusterJ applications when using the session.newInstance and session.release interfaces. A new session cache, which is a cache of Ndb objects maintained in DbFactoruImpl, has been introduced, reducing an application's overhead and improving its performance. The cache size can be controlled using the com.mysql.clusterj.max.cached.instances configuration parameter, which enables the session cache by default with a maximum size of 100. (Bug #102510, Bug #32474777)

  • Timestamps in NDB node logs are now printed with microsecond resolution. (Bug #37924338)

  • MySQL Cluster now supports explicit default expressions for columns of NDB tables used with the MySQL server. For example, you can now create a an NDB table like the one shown here:

    CREATE TABLE t1 (
      i INT         DEFAULT 0,
      c VARCHAR(10) DEFAULT '',
      f FLOAT       DEFAULT (RAND() * RAND()),
      b BINARY(16)  DEFAULT (UUID_TO_BIN(UUID())),
      d DATE        DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR)
    ) ENGINE=NDBCLUSTER;
    

    For information about supported column data types and default behavior, see Data Type Default Values.

    Note

    Default column value expressions are supported only when NDB tables are accessed using the MySQL server (mysqld), and are not visible to NDB API applications.

    (WL #16678)

Bugs Fixed

  • NDB Client Programs: ndb_restore, when applying the log, allowed an infinite number of retries due to temporary errors, rather than limiting these to 11 as expected. (Bug #37883579)

    References: This issue is a regression of: Bug #31546136.

  • NDB Client Programs: When restoring from backup with DefaultOperationRedoProblemAction=ABORT, an error in data node handling of a redo log part overload condition resulted in an incorrect error code (626 in this case) being sent back to ndb_restore, which caused ndb_restore to exit prematurely since it did not expect such an error. (Bug #37687485)

    References: This issue is a regression of: Bug #13219, Bug #13930, Bug #13980.

  • MySQL NDB ClusterJ: Handling of schema changes failed when multiple threads were involved. To improve the handling, session.unloadSchema() has been changed, and three new public methods have been defined: boolean isStaleMetadata(), boolean isSchemaChangePending(), void awaitSchemaChange(). When ClusterJ detects that a schema change has caused a domain type handler to become invalid, it throws an ClusterJDatastoreException, and the application can now do the following:

    • Call isStaleMetadata().

    • If isStaleMetadata() returns true, the exception was caused by stale metadata due to schema changes. The thread can then call session.unloadSchema(). When multiple threads are involved, the first thread to enter unloadSchema() will acquire a lock and refresh the metadata. Any other threads calling getDomainTypeHandler() for the domain object while the refresh is in progress receive an exception. The threads can then retry the data operation when the refresh is finished.

      After the table metatdata has been refreshed, ClusterJ writes a log message containing the former and current version numbers of the table metadata.

    • If isStaleMetadata() returns false, then user can call isSchemaChangePending() to see if another thread is trying to refresh the metadata. If that is the case, the user can use awaitSchemaChange() to wait for the lock to be released before it retries the data operation.

    Our thanks to Salman Niazi of Hopsworks for contributing the changes and tests for Session.unloadSchema(), which make this feature possible. (Bug #37861635, Bug #37856493)

  • MySQL NDB ClusterJ: Added support for using LONGVARCHAR and DATE types as primary keys in Cluster/J.

    Our thanks to Mikael Ronström of Hopsworks for the contribution. (Bug #37782638)

  • MySQL NDB ClusterJ: Logging for ClusterJ has been improved by adopting the pattern in java.util.logging of Java 1.8, in which a log message is constructed only when the corresponding log level has been enabled, thus improving the efficiency of logging. (Bug #37722667)

  • MySQL NDB ClusterJ: When users attempted to set a NOT NULL string column to NULL, an empty string was inserted.

    Our thanks to Salman Niazi of Hopsworks for contributing the fix for the issue. (Bug #117205, Bug #37476251)

  • Improved password handling for file system encryption.

    Our thanks to Axel Svensson for the contribution. (Bug #37909595)

  • CREATE TABLESPACE, when the specified logfile group did not exist, was rejected with error 723 No such table existed, which did not correctly identify the source of the problem with the SQL statement. Now in such cases, the server issues Error 789 Logfile group not found. (Bug #37802388)

  • Warning 1296 The temporary named table ... already exists showed the table and schema names in the wrong order.

    Our thanks to Axel Svensson for the contribution. (Bug #117918, Bug #37807409)