Skip to content

3.9.0

Latest

Choose a tag to compare

@sergepetrenko sergepetrenko released this 26 Oct 15:32
· 30 commits to master since this release

Date: 2026-10-23
Tag: 3.9.0

Overview

Tarantool 3.x is the recommended release series. Users of Tarantool 2.11 are
encouraged to update to the latest 3.x release.

This release introduces 32 improvements and resolves 54 bugs since 3.8.1.

Notable changes are:

  • Multiple formerly Enterprise-only features are now available in the Community
    Edition:
    • Read view Lua API (gh-12912).
    • SSL/TLS encryption of IPROTO connections (gh-13173).
    • pap-sha256 authentication type (gh-13174).
  • Read views can now be used from application threads to scale read throughput
    without affecting the TX thread (gh-12951).
  • Memtx MVCC now works with multikey and functional multikey indexes (gh-6385).
  • [Breaking change] Creation of a non-sandboxed function now requires the
    execute privilege on universe. Previously, having create privilege on
    func and write privilege on space _func was enough. Since this is a fix
    for a possible privilege escalation, it is submitted without the usual
    compatibility switch
    (ghs-164).

Please consider the full list of user-visible changes below.

Compatibility

Tarantool 2.x and 3.x are compatible in the binary data layout, client-server
protocol, and replication protocol. It means upgrade may be performed with zero
downtime for read requests and the order-of-network-lag downtime for write
requests.

Please follow the upgrade procedure to plan your update actions.

Users of Tarantool 2.x may be interested in the compat options that
allow to imitate some 2.x behavior. This allows to perform application code
update step-by-step, not all-at-once.

Functionality added or changed

Core

  • The read view Lua API is now available in the Tarantool Community Edition.
    Formerly, it was an exclusive feature of the Enterprise Edition (gh-12912).
  • fiber_new() and fiber_new_ex() are now non-failing (gh-12338).
  • Application threads can now use a database read view opened in the main
    thread (gh-12951).
  • The following box.info fields can now be accessed in application threads:
    package, version, id, uuid, name, replicaset.uuid,
    replicaset.name, cluster.name.
  • Introduced the new read view method :with(), which calls a function
    with a guarantee that the read view object will not be closed until
    the function returns (gh-13037).
  • Added a new option refs to the read view method :info() that makes it
    include a list of read view reference holders in the output (gh-13037).
  • SSL encryption of IPROTO connections is now available in the Tarantool
    Community Edition. Formerly, it was an exclusive feature of the Enterprise
    Edition (gh-13173).
  • The pap-sha256 authentication type is now available in the Tarantool
    Community Edition. Formerly, it was an exclusive feature of the Enterprise
    Edition (gh-13174).
  • Moved the Lua module used for interaction with application threads out of
    the experimental namespace: it can now be required as threads. For
    backward compatibility, the old module name experimental.threads still
    works (gh-12207).
  • Introduced a new range delete API. It can be used to delete a range of keys
    from an index. It is available in Lua as index:delete_range and in the C API
    as box_delete_range (gh-11335).
  • Introduced a new API for closing IPROTO connections. It can be used to close
    either all IPROTO connections or only those that correspond to URIs that are
    not being listened on. It is available in Lua as
    box.iproto.drop_connections.

Memtx

  • Added support for multikey index variants (regular and functional) in memtx
    MVCC (gh-6385).

SQL

  • The function that calculates a default value for a column can now be
    specified without enclosing it in parentheses (gh-12911).
  • The INSERT INTO TABLE DEFAULT VALUES statement is now supported
    in SQL triggers (gh-12969).
  • Some invalid ALTER TABLE ADD COLUMN/ADD CONSTRAINT statements now fail
    with a plain syntax error instead of a keyword is reserved error (gh-5485).
  • Qualified db.table names in trigger INSERT/UPDATE/DELETE bodies now
    fail with a generic syntax error instead of a special error (gh-5485).
  • JOIN type errors changed: combining INNER with OUTER now reports
    JOIN cannot be both OUTER and INNER; an unrecognized JOIN keyword is
    now a syntax error instead of the unknown or unsupported join type
    error (gh-5485).
  • The SQL query used to create a view is now stored in the corresponding space
    definition in _space as it was provided, without any changes (gh-5485).
  • The SQL query used to create a trigger is now stored in the corresponding
    trigger definition in _trigger as it was provided, without any changes
    (gh-5485).
  • Changed the description of the error that occurs when using bind
    variables in the definition of a view, function, or trigger (gh-5485).
  • The error for using COLLATE in LIMIT or OFFSET is now a semantic error
    rather than a syntactic one (gh-5485).
  • Indexes for column-level PRIMARY KEY and UNIQUE constraints are now created
    before indexes for table-level PRIMARY KEY and UNIQUE constraints, which
    changes the order of automatically generated index names (gh-5485).
  • Errors SQL_PARSER_GENERIC_WITH_POS and SQL_SYNTAX_WITH_POS are no longer
    used and have been removed (gh-5485).
  • SQL now builds an internal AST for queries before building the VDBE.
    This affects the order of error detection - syntactic errors are now
    always detected before semantic errors (gh-5485).

Config

  • Application role health checks may now return a map of named check results.
    Each result is reported as a separate readiness check and may have an
    independent status, reason, and alert code (gh-12914).
  • Added periodic expiration checks for SSL certificate files configured in
    iproto.ssl.ssl_cert. The check runs every 12 hours and immediately after
    configuration reload. It warns no later than 30 days before expiration and
    keeps warning after expiration. The first certificate in each PEM file is
    checked.
  • A configuration reload that changes the URIs of the replica set instances
    (for example, their SSL certificates) now applies iproto.listen at once and
    reconnects the replication with the new URIs after config.reload_jitter
    or, if it is zero, after the remote configuration storage request timeout,
    so that the other instances have time to apply the new configuration
    (gh-13172).
  • Added the iproto.drop_stale_connections option to drop the incoming
    connections accepted on the URIs that are no longer listened on (for example,
    with the old SSL certificates) once the replication is reconnected after
    a configuration reload (gh-13172).
  • Election fencing is now disabled while the replication is reconnected
    with the new URIs of the replica set instances after a configuration
    reload, so reconnecting no longer starts a new election term
    (gh-13172, gh-13287).

Metrics

  • Updated the metrics submodule to 1.8.3.

    Changes since 1.8.1:

    • Added EmmyLua analyzer support and annotations (gh-551).

Build

  • Introduced the ENABLE_BUNDLED_MIMALLOC build option and the
    MIMALLOC_OVERRIDE build parameter (none or cpp). By default, the
    bundled mimalloc allocator is built and serves all C++ operator new and
    operator delete calls process-wide (cpp). The malloc/free family
    used by C code still uses the system allocator. This speeds up workloads with
    many small short-lived allocations in C++ libraries (gh-13202).
  • EmmyLua annotation stubs for the bundled checks and metrics Lua modules
    are now generated at build time and installed into the emmylua directory
    under the Tarantool data directory, so they are shipped in packages
    (gh-13022).

Bugs fixed

Core

  • [Breaking change] Fixed missing privilege verification. Creation of a
    non-sandboxed function now requires the execute privilege on universe
    (ghs-164).
  • box.cfg() called with a non-table argument now fails with a clear
    cfg should be a table error instead of a confusing internal one (gh-13145).
  • Deprecated box.cfg options set via TT_* environment variables are now
    translated to their replacement options, and the translation no longer
    silently overrides an explicitly provided value of a replacement option
    (gh-13144).
  • Fixed a bug where a redundant deprecation warning about
    replication_connect_quorum was logged when bootstrap_strategy was
    explicitly set to 'legacy' in the same box.cfg() call (gh-12933).
  • Fixed application thread startup failures caused by concurrent module path
    lookup on macOS, and a crash in fio.dirname() when the directory part of a
    path is at least 1024 bytes long (gh-13130).
  • Fixed a bug where Tarantool crashed when application threads concurrently
    handled access denial errors (gh-13293).
  • Fixed a macOS backtrace crash when an image has no symbol
    for a frame (gh-13330).
  • Fixed native thread stack bounds supplied to ASan on macOS (gh-13330).
  • Read view creation is now throttled: opening a non-system read view less
    than 100 ms after the previous one now makes the calling fiber yield until
    the interval elapses (gh-13332).
  • Reject oversized Unix socket paths instead of connecting to a truncated path
    (gh-13330).
  • Fixed memory leaks in CSV parsers and memtx bitset
    indexes on macOS (gh-13330, gh-1215).
  • Fixed crashes due to Lua stack leaks in net.box reconnects, Lua triggers,
    numeric configuration reads, quorum formula evaluation, and others (gh-11061).
  • Fixed the owner check on space alter (tarantool/security#173).
  • Fixed a crash on fallback from IPROTO_AUTH override handler (gh-13291).
  • Fixed a crash on fallback from IPROTO_UNKNOWN override handler
    (gh-13320).
  • Deletion from _func_index now requires the drop privilege on the space
    (tarantool/security#176).
  • Fixed an out-of-bounds read when a np or pp iterator was requested
    with a key that has more parts than the index (gh-13286).
  • Fixed a bug where on_replace triggers received the original request type
    when a before_replace trigger changed the operation. They now receive the
    type of the operation actually applied and written to WAL (gh-13416).
  • Fixed crashes in triggers during WAL recovery and replication of transactions
    containing NOP statements. Transaction iterators now skip all NOPs (gh-13163).

Memtx

  • Fixed a bug where an iterator over a multikey or functional index, after the
    index was modified concurrently, returned some entries of the tuple it was
    paused on twice or skipped them (gh-13410).
  • Fixed a use-after-free in a transaction that used select with the offset
    option concurrently with a replace that was rolled back later, with MVCC
    enabled (gh-13411).
  • Fixed a crash when using count on a functional index in a read view with
    MVCC enabled (gh-13469).
  • Fixed a crash on a write to a space with a functional index whose row was
    deleted from _func_index, with MVCC enabled (gh-13477).
  • Fixed a crash on continuing a reverse iterator with MVCC enabled after the
    tuple it pointed to was removed from the index, e.g. because its transaction
    was aborted (gh-13403).
  • Fixed a crash after a failed replace in a space with a functional index
    whose function raised an error for the replaced tuple (gh-13481).
  • Fixed an out-of-bounds read on a delete of a tuple missing from a bitset
    index being built in the background, which could delete another tuple
    from the index (gh-13487).
  • Fixed a use-after-free in a transaction that used select with the offset
    option on a functional index concurrently with an update of the indexed
    tuple, with MVCC enabled (gh-13497).

Vinyl

  • Fixed Vinyl metadata log (vylog) corruption during recovery, which could
    cause box.snapshot() to fail with the Invalid VYLOG file error and
    prevent the instance from restarting (gh-13448).

Replication

  • Fixed a debug-build crash that could happen when a quorum of acks was
    collected for a synchronous transaction while a PROMOTE or DEMOTE was
    being written to the journal (gh-13066).
  • Fixed an out-of-bounds write triggered by a replication peer sending an
    IPROTO_RAFT message whose vote contains an ID outside the valid replica ID
    range.
  • Fixed a bug where a replica's garbage collection consumer retained outdated
    WAL files after reconnecting to an upstream with a newer vclock (gh-13068).

Raft

  • Fixed a bug where an old leader could rejoin with a new one while having
    mismatched data, and this would remain undetected. This could happen when
    synchronous transactions are rolled back due to a timeout (gh-13085).
  • Fixed a bug where a synchronous transaction, temporarily blocked because the
    synchronous transaction queue was full (replication.synchro_queue_max_size
    was reached), during a leader change or a timeout
    (replication.synchro_timeout) could be rolled back, but then appear again
    and even be committed (locally after a restart or on another node) (gh-13095).
  • Fixed a bug where box.ctl.promote() could hang indefinitely on
    a read-only instance, even if the election was won and the
    synchronous transaction queue was claimed successfully
    (gh-10040).
  • Fixed a bug where box.cfg() on a freshly bootstrapped instance with
    election_mode set to 'candidate' or 'manual' could sometimes return
    with the instance in a read-only state for some time afterwards, even
    when no read-only mode was explicitly configured (gh-12972).

LuaJIT

The JIT engine is now enabled on Tarantool startup for macOS builds.

Patches from the vanilla LuaJIT trunk were backported (gh-12880). The following
issues were fixed as part of this activity:

  • Fixed stack overflow relimit handling.
  • Fixed container of packed bitfield.
  • Fixed fp:seek() with the string argument.
  • Fixed tobit conversions for aarch64 in the VM.
  • Fixed pointer difference operation on 64-bit platforms.

Lua

  • Preserve subsecond file timestamps in fio.stat(), fio.lstat(), and
    file:stat() on macOS (gh-13330).

Http client

  • Fixed an infinite loop when an HTTP response has an incomplete header
    section (gh-5937).

Popen

  • popen.new({}) now fails instantly and reports an appropriate error
    (gh-4913).
  • Quote empty arguments in <popen handle>.command so they are visible in the
    rendered command string (gh-4914).

SQL

  • Fixed an assertion that occurred when adding a column with a UNIQUE or
    PRIMARY KEY constraint to a view (gh-13009).
  • Fixed a memory leak in the ALTER TABLE ADD CONSTRAINT CHECK and
    ALTER TABLE ADD CONSTRAINT FOREIGN KEY statements (gh-13106).
  • Fixed assertions that occurred due to insertion of an incorrect trigger
    definition into _trigger or insertion of an incorrect view definition
    into _space (gh-13067).
  • A named bind variable must now always begin with #, :, or @ followed by
    a letter or a non-digit identifier character (variants such as @number are
    no longer supported). A numeric bind variable must begin with $ followed by
    a number (variants such as $name are no longer supported). An anonymous
    bind variable is denoted by ? followed by a non-numeric, non-alphabetic
    character (gh-13012).
  • Now a table constraint will find the columns it uses, even if those
    columns are defined after the constraint (gh-13136).
  • Fixed a bug where an unquoted SQL identifier whose uppercase form is longer
    than the original (for example, some Unicode letters) produced an
    unterminated name from partly uninitialized memory (gh-13160).
  • Rules for table-valued functions have been removed from
    the SQL parser (gh-13133).

Config

  • Fixed credentials error reporting by adding the pending operation to WAL write
    failure messages (gh-10359).
  • Fixed repeated calls to an application role's stop() callback after the
    role is removed from configuration (gh-13014).

Datetime

  • The correct timezone behavior for datetime objects can
    now be enabled by setting the configuration option
    compat.datetime_apply_timezone_action to 'new'. It makes
    changing the timezone of a datetime object preserve the represented
    timestamp and affect the represented time of day (gh-10363).

Iproto

  • Fixed a crash caused by IPROTO_EXECUTE and IPROTO_PREPARE requests
    containing SQL fields with unexpected MessagePack types
    (ghs-174).
  • Fixed the decoding of SQL request keys encoded using a non-optimal,
    multibyte MessagePack integer representation
    (ghs-174).
  • Fixed a bug where an oversized packet length caused a large input buffer
    allocation before the packet size was validated when no payload bytes were
    received (ghs-177).

Msgpack

  • Fixed a stack overflow when unpacking MsgPack input with deeply
    nested values containing arrays and maps
    (ghs-165).