MySQL NDB Cluster 9.4 Release Notes
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)”).
These release notes were created with the assistance of HeatWave GenAI.
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.
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)
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)