github ArcadeData/arcadedb 26.6.1

10 hours ago

ArcadeDB 26.6.1 Release Notes

Overview

ArcadeDB 26.6.1 is a stability, durability and security hardening release with over 280 commits and 66 resolved issues. The headline news is end-to-end TLS/SSL for the HA cluster, a deep wave of durability and crash-recovery hardening across the WAL, page and serialization layers, and a broad security hardening pass (schema authorization, IMPORT DATABASE source validation, injection fixes and a full CodeQL cleanup). On top of that comes a long list of High Availability / Raft, OpenCypher, SQL, vector index and wire-protocol fixes, plus Studio and operational improvements.

Major Highlights

TLS/SSL Across the HA Cluster

The Raft-based HA cluster can now run fully encrypted. Inter-node replication traffic supports SSL/TLS, and the snapshot installer was fixed so a follower can download a leader snapshot over the HTTPS listener instead of crashing with Unsupported or unrecognized SSL message. (#4470)

Durability & Crash-Recovery Hardening

A large batch of fixes closes data-integrity gaps in the storage, WAL and serialization layers so committed transactions survive crashes and power loss, and recovery never silently drops data:

  • WAL is now fsynced on commit by default, and data files are fsynced before WAL files are deleted on clean close. (#4330, #4332)
  • Crash recovery now aborts on a WAL version gap and preserves the WAL files instead of silently skipping the gap. (#4331, #4320)
  • MutablePage.move no longer mis-tracks the modified range on backward shifts, so defrag bytes are no longer omitted from the WAL. (#4319)
  • Binary serialization fixes: property count now matches the bytes written, and partial reads are handled via readFully. (#4328, #4329)
  • Short-write / short-read returns are now respected in PaginatedComponentFile. (#4321)
  • LZ4 compression no longer corrupts data when Binary.position() > 0. (#4317)
  • Simple-8b codec validation no longer silently truncates Long.MAX_VALUE / Long.MIN_VALUE. (#4336)
  • migratedFileIds is now persisted in schema.json, so compaction no longer silently drops in-flight transactions across restart. (#4333)
  • java.lang.NegativeArraySizeException on transaction commit fixed. (#4420)

Security Hardening

  • All LocalDocumentType / LocalProperty schema mutators now require the UPDATE_SCHEMA permission (previously only createProperty was gated). (#4423)
  • IMPORT DATABASE now validates its source and requires admin privilege, closing SSRF / LFI vectors. (#4422)
  • SQL injection fixed in RemoteVertex.newEdge by switching to parameter binding (also fixes breakage on apostrophes). (#4327)
  • JavaScript injection in the polyglot engine closed by replacing the "looks-like-JSON" source-concatenation heuristic with Value.execute(). (#4326)
  • Full CodeQL cleanup: open Java and JavaScript code-scanning alerts resolved at their true sources (workflow permissions, ReDoS, path-injection). (#4383, #4386, #4388)

Major Fixes

High Availability & Clustering

  • TimeSeries data now replicates correctly across an HA cluster, and a compaction/append deadlock that caused a WAL version gap on Raft followers was eliminated. (#4414, #4458)
  • Concurrent single-row time-series INSERTs no longer silently lose samples (sealed-slot lost update). (#4453)
  • Bolt writes to a follower no longer fail with "no authenticated user in the current security context"; the authenticated user is now bound on DatabaseContext in the Bolt executor. (#4456)
  • PeerAddressAllowlistFilter no longer rejects legitimate peers during a Kubernetes DNS-resolution race (incomplete allowlist on startup/restart). (#4471)
  • Stale-follower recovery is fixed when a snapshot download fails on a quiet cluster.
  • New configurable paths: arcadedb.ha.raftStorageDirectory for the Raft storage directory (#4446), configurable server log directory for read-only root filesystems (#4451), and arcadedb.ha.clusterTokenPath to read the cluster shared secret from a file (#4431).
  • RemoteDatabase no longer reuses a session id across servers on HA failover during an open transaction; a TransactionException is now raised on server switch. (#4373)
  • RemoteHttpComponent no longer mutates leaderServer / currentServer non-atomically during retries. (#4372)
  • New STICKY strategy pins HTTP transactions to a concrete cluster member. (#4273)
  • getReplicaAddresses now excludes the local peer instead of the leader. (#4274)
  • /api/v1/server?mode=cluster returns the ha section again after the Raft migration. (#4261)
  • New "Force Resync" button in Studio to recover a diverged follower from the leader.
  • HA bootstrap-fingerprint replay race fixed, and HA node aliases corrected. (#4259)
  • Massive-insertion cluster configuration issues resolved, plus assorted HA log improvements.

Concurrency & Async

  • FileManager no longer mutates its ArrayList<ComponentFile> from multiple threads without synchronization (fixes CME / AIOOBE). (#4371)
  • LockManager.tryLock now re-attempts putIfAbsent after a wait timeout and tracks the remaining timeout per await. (#4367)
  • DatabaseAsyncTransaction now rolls back before retrying after a ConcurrentModificationException, invokes the per-task onErrorCallback, and no longer swallows final-retry failures or contaminates the shared transaction. (#4368, #4369, #4370)
  • PageManager.putPageInReadCache no longer leaks RAM accounting when replacing an existing CachedPage. (#4390)

OpenCypher

  • CREATE INDEX now implicitly creates the referenced property (Neo4j-style lazy schema). (#4354)
  • nodes(), relationships() and length() on variable-length path patterns (e.g. [*1..3]) are now implemented. (#4353)
  • Records written via SQL are now visible to subsequent Cypher queries (and vice versa) within the same connection/transaction. (#4355)
  • EXPLAIN no longer fails with an idempotency error on a multi-statement query containing CREATE. (#4366)
  • Label disjunction (n:A|B) no longer returns 0 rows. (#4221)
  • allShortestPaths() now returns all co-shortest paths instead of just one.
  • MERGE now uses a bound anchor as the traversal start instead of a full edge-type scan (performance), and no longer crashes on a single-quote property value with UNWIND or rebinds the variable from an OPTIONAL MATCH null endpoint. (#4213, #4210)
  • DATETIME property comparison with datetime() no longer returns 0 rows. (#4231)
  • Redundant AND true / OR false branches are now simplified in WHERE clauses. (#4405)
  • MATCH ... WHERE ID(n) IN $ids now accepts a long[] parameter array.
  • Query results are now consistent between parameterized and hard-coded values.

SQL

  • IN :param with a collection parameter now returns rows when an index is used. (#4468)
  • MOVE VERTEX no longer generates an internal error. (#4461, #4347)
  • expand() projection now honors its AS alias instead of always being named value. (#4389)
  • IN (SELECT …) no longer always returns empty (InCondition now unwraps single-property results). (#4337)
  • MERGE on a UNIQUE-indexed property no longer throws DuplicatedKeyException when the same key appears twice in a batch (Neo4j matches the second occurrence). (#4351)
  • node.* and rel.* functions no longer silently return null/0 from SQL. (#4216)
  • TimeSeries timestamps are now returned in queries. (#4418)
  • New cypherRID(<cypher-rid>) SQL function and asCypherRID() method for interoperating with Cypher numeric ids.
  • ResultInternal.getProperty no longer re-surfaces removed properties via element fall-through. (#4398)
  • EdgeLinkedList.removeVertex / removeEdge now iterate all segments to remove every matching entry. (#4395)
  • MultiIterator.countEntries no longer discards the count for non-resettable iterables. (#4396)
  • MATCHES now keys its regex Pattern cache by the regex string rather than hashCode() (collision no longer returns the wrong pattern). (#4397)
  • Case conversions across the function library now use Locale.ROOT. (#4393)
  • RangeFunction and the math functions are now guarded against long-range overflow / infinite loops. (#4391, #4392)
  • CREATE INDEX ON ... (...) without an index type now raises a clear parsing error instead of an NPE.
  • Inserting edges between existing nodes with mandatory properties now works. (#4413)
  • Multiple-inheritance handling fixed, and point() over a latitude property surfaced as a string no longer throws a ClassCastException.
  • SEARCH_INDEX() negative Lucene clauses now return correct results. (#4220)

Vector & Index

  • TRUNCATE TYPE no longer resets an LSM_VECTOR index dimension to 0, nor leaves UNIQUE indexes in an inconsistent state requiring DROP TYPE. (#4359, #4352)
  • LSMVectorIndex now converts JVector's EUCLIDEAN return to L2² distance in all search paths, so K-NN no longer returns the worst matches first. (#4334)
  • LSMVectorIndexCompactor now handles the old-format tombstone rewind correctly. (#4335)
  • NPE in discoverAndLoadCompactedSubIndex that prevented loading compacted vector sub-indexes at startup fixed.
  • LSM_VECTOR inactivity rebuild timer is now re-armed after a skip. (#4272)
  • REBUILD INDEX now works for BY ITEM indexes. (#4448)
  • vector.fuse() is now recognised as a SQL function (no more "Unknown method name: fuse").

Wire Protocols

  • Bolt: parameterized Cypher MATCH queries via the JavaScript neo4j-driver now work (#4452); integer property values are no longer coerced to strings after CREATE INDEX, and index-backed lookups return rows.
  • PostgreSQL: scalar columns are now advertised with native OIDs. (#4202)
  • gRPC: correct exceptions are now thrown (NOT_FOUND for RecordNotFoundException on lookupByRid) (#4364); LocalDateTime / LocalDate and ISO-string fallback handled in ProtoUtils (#4358); InsertStream with CONFLICT_IGNORE + PER_STREAM no longer rolls back the whole stream on a commit-time duplicate (#4214); null values are no longer returned as the string "null"; count(*) field type is now consistent between RemoteDatabase and RemoteGrpcDatabase; reloading a not-yet-committed record no longer errors.
  • HTTP: PostCommandHandler "Cannot execute command" fixed (#4432); the redundant decode of command/query in the HTTP layer was removed; DuplicatedKeyException now returns HTTP 409 Conflict instead of 503 Service Unavailable. (#4350)

Studio & Operations

  • Optional production-mode Studio: a new global setting enables Studio in production on request. (#4417)
  • New show/hide toggle for the Appearance section in the graph side panel. (#4394)
  • AI assistant flow, database selection and layout improvements; query profiler "Analyze with AI"; refreshed server and profiler metrics.
  • MessageFormat placeholders are now substituted in JUL log records. (#4275)
  • New offline build mode for the distribution builder, and Python bindings build-script / vector-handling refactor.

Dependencies

Notable upgrades in this release include:

  • Netty 4.2.14.Final
  • Undertow 2.4.1.Final
  • Protobuf 4.35.0
  • JLine 4.1.3
  • JUnit Jupiter 6.1.0
  • Jackson Databind 2.21.4
  • Apache Commons Configuration 2.15.1
  • Swagger 2.2.50 / Swagger Parser 2.1.43
  • SLF4J 2.0.18
  • Logback 1.5.33
  • Jedis 7.5.2

Plus the usual round of Studio frontend updates (ApexCharts, SweetAlert2, SwaggerUI, Marked, PDFMake, PostCSS, Terser and the webpack/build toolchain), e2e test-harness bumps (Playwright, TestContainers, protobufjs), CI / GitHub Actions updates and pre-commit hook refreshes.

Don't miss a new arcadedb release

NewReleases is sending notifications on new releases.