Tags give the ability to mark specific points in history as being important
-
26.2.1
protected10b112a2 · ·[26.2.1] - 2026-08-31 Bug fixes webui - Fixed `instancesCurrentStateOffline` in `/api/v1/cluster` counting expelled instances as offline; it now counts only instances whose current state is actually `Offline` - Changed the empty state for tier services from "No data" to the more descriptive "No services"
-
26.2.1-rc3
protected90971984 · ·[26.2.1-rc3] - 2026-08-27 Bug fixes webui - Improve instance address display by truncating long FQDNs while keeping the port always visible for easier node identification - make copypaste button work on non https origins - Improved filter tag display in search-building mode by replacing technical keys with user-friendly names - Updated translation for the Raft leader role: raft leader was replaced with governor to use the correct role terminology - Added an indicator showing that the instance is the leader in the Replication section of the instance pop-up card - Added an informative empty state for unavailable upstream and downstream connections in the Replication section of the instance pop-up card
-
26.2.1-rc2
protecteddcd72bc9 · ·[26.2.1-rc2] - 2026-08-21 Features sql - The `WHERE bucket_id = <CONST>` filter now avoids `Motion(Full)` insertion and routes the query to a single storage. This optimization also helps execute transactions locally and queries with `OPTION(forward = off)`. - Columns in `PRIMARY KEY` and `CREATE INDEX` now accept an optional `ASC` or `DESC` sort order modifier. For example, `PRIMARY KEY (a DESC, b ASC)`, `id UNSIGNED PRIMARY KEY DESC`, and `CREATE INDEX ... (a ASC, b DESC)`. The default order remains `ASC`. Explicit sort order is supported only for `TREE` indexes. - The virtual `bucket_id` column can be the first part of a primary key with its own sort order, for example `PRIMARY KEY (bucket_id DESC, id ASC)`. Bug fixes sql - The `||` operator now has PostgreSQL-compatible precedence: a dedicated tier below `+`/`-` instead of sharing the `*`/`/` tier. Unparenthesized expressions mixing `||` with arithmetic may change meaning ([!3463](https://git.picodata.io/core/picodata/-/merge_requests/3463)). - `||` now accepts any scalar operand next to `text` (`int`, `numeric`, `double`, `bool`, `datetime`, `uuid`). Each argument unconditionally is converted with `CAST(... AS string)`, so its rendering follows Tarantool (e.g. `TRUE`, ISO 8601 datetimes) rather than PostgreSQL. - Parameter types for `$1` used in `||` expressions are now reported correctly over pgproto: an implicit cast no longer overwrites the inferred parameter type. - Executing `SELECT` queries with `ARRAY` columns no longer produces decoding errors on cluster with many replicasets. - Fixed the error `sub-query plan subtree with id XXXX not found`, which occurred in some `EXPLAIN` queries containing `DISTINCT`. - Scalar subqueries in `GROUP BY` expressions now match their twin in the select list and `HAVING`, e.g. `SELECT a + (SELECT 1) FROM t GROUP BY a + (SELECT 1)` no longer fails with `column "a" is not found in grouping expressions`. - A scalar subquery that appears both in `GROUP BY` and in the select list or `HAVING` is now planned and executed once instead of once per occurrence. - A join which pins constants on the sharding keys of both children no longer returns an empty result, e.g. `SELECT * FROM t1 JOIN t2 ON a = 1 AND b = 2` where `t1` is sharded by `a` and `t2` by `b`. - Queries with CTEs and window functions that previously returned an error `node XXXX is outside of the plan id subtree` now work correctly. - Executing certain queries with `UNION` and `EXCEPT` no longer returns an error `Failed to compile SQL statement: Syntax error at line 1 near '('`, e.g. `SELECT 1 UNION SELECT 0 EXCEPT SELECT 1 from t;`. - Scalar aggregate with empty buckets set now returns `0` instead of `NULL`, e.g. query `SELECT count(*) FROM t WHERE a = 1 AND a = 2`. - Queries using `UNION ALL`/`EXCEPT` that involve a sharded table and a global table now return the correct result. - Executing queries with CTEs that do not include projections no longer results in the error `Temporary SQL table _tmp_* not found`. - Queries containing `UNION`/`UNION ALL`, where one of the parts contains a branch with a condition that is always false could return an incorrect (empty) result. Now such queries return the correct result, e.g., `SELECT 1 UNION ALL SELECT a FROM t WHERE false`, `SELECT 1 UNION SELECT a FROM t WHERE a = 1 AND a = 2`. replication - Tiers with `replication_mode = sync` now run Tarantool elections in `election_mode = "manual"`, and the election leader is the only instance which accepts writes. The governor still designates the master in `_pico_replicaset`, but a master which lost the majority is fenced by the election itself and can no longer accept writes. - Fixed a bug where a lagging replica could be chosen for promotion during failover. The elections now provide the "synchronize before promotion" guarantee: a candidate only receives a vote from a peer whose vclock is not ahead of its own. backup - Fixed backup and restore with custom storage directories. SQL `BACKUP` no longer crashes when `memtx.dir` or `vinyl.dir` differs from `instance_dir`, and `picodata restore` now restores data to the configured `wal_dir`, `memtx.dir`, and `vinyl.dir`, including when these directories are nested. -
26.2.1-rc1
protected19e3661d · ·[26.2.1-rc1] - 2026-07-15 Breaking changes - Deprecated `plugin_dir` setting is removed following a major release. Use `share_dir` instead. - Deprecated `advertise_address` setting is removed following a major release. Use `iproto` section instead. - `--cluster-name` argument for `picodata expel` is removed following a major release as it is no longer needed. - Deprecated `ServiceWorkerManager` is removed from `picodata_plugin` following a major release. - `authenticate` function from `picodata_plugin` is now accessible only through `authentication` module. Reexport in `internal` module is removed following a major release. - Deprecated `RegionBuffer::get` is removed following a major release. - `CancellationTokenHandle::cancel()` now returns `Rc<OnceEvent>` instead of `Channel<()>`. Use `finish_event.is_finished()` to check completion or `finish_event.wait_timeout(duration)` to wait with a timeout. api - Rename fields in `/api/v1/health/status` response: `reasons` to `issues`, status level `unhealthy` to `broken`. cli - `picodata demo` subcommand is now gated behind the `demo` Cargo feature, disabled by default. To build with demo, use `CARGO_FLAGS_EXTRA="--features demo"`. metrics - Cache metrics `pico_router_cache_{hits,misses,statements_added,statements_evicted}_total` and `pico_storage_cache_{statements_added,statements_evicted}_total` now carry `tier` and `replicaset` labels (previously unlabelled). `pico_storage_cache_{hits,misses}_total`, `pico_storage_1st_requests_total`, and `pico_storage_2nd_requests_total` gain `tier` and `replicaset` in addition to their existing labels. Aggregations across replicasets may need an explicit `sum without (tier, replicaset)`. Features sql - Added `ARRAY` literal support ([!3180](https://git.picodata.io/core/picodata/-/merge_requests/3180)). - Expanded pgproto support arrays. - Support `LOGICAL`, `BUCKETS`, and `FORWARD` modes of EXPLAIN for transactions ([!3184](https://git.picodata.io/core/picodata/-/merge_requests/3184)). - Add per query bucket estimation to EXPLAIN (RAW) output when BUCKETS mode is specified ([!3280](https://git.picodata.io/core/picodata/-/merge_requests/3280)). - Provide more accurate info about query execution location in EXPLAIN (RAW) output ([!3330](https://git.picodata.io/core/picodata/-/merge_requests/3330)). - Reflect the planning caveats for queries with UNION of global and sharded tables in EXPLAIN(RAW) ([!3357](https://git.picodata.io/core/picodata/-/merge_requests/3357)). - Added support for transactional `INSERT ... ON CONFLICT DO UPDATE` statements inside SQL blocks. - Added an equality-facts analysis pass over the relational plan that derives always-true equalities from `WHERE` / `ON` predicates and stores them per output slot. Downstream stages (motion planning, bucket determination, JPPD transformation) can now answer "is this slot fixed to a constant?" and "do these two slots belong to the same equality class?" in O(1) without re-parsing predicates. Semantic boundaries (LEFT JOIN nullable side, CTE, Motion, set-ops, `LIMIT` / `ORDER BY` / `GROUP BY` / `HAVING`) are respected so unrelated scopes never merge, and parameter placeholders are kept separate from constants to avoid leaking unsafe bindings into execution-time filters. - Implement the `forward` option for DQL/DML queries that controls how queries are routed with respect to bucket ownership: - `on`: scatter-gather across replica set leaders; - `ro_to_rw`: all buckets on one node, forwarding allowed; - `off`: true locality, error if client is not on the correct node. - [picodata#1596] Added support for `ARRAY` columns in `CREATE TABLE` and `ALTER TABLE ADD COLUMN`. Supported syntax: `T[]`, `T[N]`, `T[N][M]`, `T[][]`, `T ARRAY`, `T ARRAY[N]`. Declared type and sizes are documentation only and do not affect the internal implementation for now. - Introduce `CONTEXT` facet in `EXPLAIN` statement that shows query execution options and remove them from `LOGICAL` facet output. - Added new `pico_instance_health_status` SQL scalar function to get current instance's health status, - SQL wrapper over `/api/v1/health/status`. - Extended constant folding: AND/OR identities, identity rules for equality with true and inequality with false. - Provide a way to match vdbe opcode or motion row limit error to specific storage query in EXPLAIN (RAW). - [picodata#2764] Transactional blocks now support LET statements. - [picodata#2765] Transactional blocks now support IF statements. - `EXPLAIN (FMT)` option is now properly supported for all modes (facets). It is now possible to write `explain (fmt)` to get a formatted logical plan or `explain (fmt, raw)` to get a formatted raw query plan. - [picodata#2728] Error generated when `INDEXED BY` is used with non existing index now includes the target table name, making it explicit that the index-table relationship lookup failed rather than a general index lookup. - Add new `BUCKETS` facet to `EXPLAIN` statement. Users can now inspect query buckets without producing a full execution plan. This facet can be combined with `RAW` and `FMT` options. When multiple facets are specified, output sections are separated by headers. - Introduce `LOGICAL` facet in `EXPLAIN` statement. Users can now explicitly request the logical query plan. This facet can be combined with `RAW`, `BUCKETS`, and `FMT` options. The default `EXPLAIN` with no facets specified now emits both `LOGICAL` and `BUCKETS`. - Support `DELETE` statementes inside transactional `DO` blocks. - Support `INSERT` statements inside transactional `DO` blocks. - `EXPLAIN (RAW)` is now more informative and concise due to the new tree-like plan representation. The numbers in square brackets can indicate that a group of operations is performed on the same relation; in addition, they can be used as references to other operations. - Temporary table names now use the `_tmp_` prefix instead of `TMP_`, aligning them with naming convention for system tables. config - Added the `instance.memtx.dir` and `instance.vinyl.dir` configuration parameters, which set the directories where memtx snapshot files and vinyl files are stored respectively. - Added the `instance.wal_dir` configuration parameter, which sets the directory where WAL files are stored [!3294](https://git.picodata.io/core/picodata/-/merge_requests/3294). - Added a new parameter `cluster.tier.wal_mode` which controls how the write-ahead log is flushed to disk, letting you trade durability against write performance: - `write` (default), the fiber handling a transaction waits for `write(2)` to complete but does not wait for `fsync(2)` before returning control to the user. Data lands in the operating system page cache but is not guaranteed to reach disk, so the most recent records may be lost or corrupted if the power or operating system fails. - `fsync`, each `write(2)` is followed by `fsync(2)`, which forces a physical flush to disk and guarantees a consistent database state after a crash. This is the recommended mode when you need reliable recovery from hardware or OS failures. The tradeoff is reduced write performance. - [picodata#760] New configuration parameter `experimental_sharding_implementation` which enables the new behavior on the given tier. The parameter must be specified at cluster bootstrap via the configuration file and cannot be changed after that (in the future this restriction may be lifted). LDAP is now configurable through yaml LDAP authentication can now be configured with `picodata.yaml` configuration file. This also adds ability to use alternative (non-system-wide) trusted root CAs file when connecting to LDAP server via TLS. For now, previous configuration method through environment variables (`TT_LDAP_URL`, `TT_LDAP_DN_FMT`, `TT_LDAP_ENABLE_TLS`) is still supported, but considered obsolete. A warning will be printed on start. Here's an example YAML configuration snippet for configuring LDAP: ```yaml instance: ldap: enabled: true # `false` by default. LDAP authentication will fail if set to `false`. connect: 127.0.0.1:1337 # Address of the LDAP server to connect to. dn_format: "cn=$USER,dc=example,dc=org" # Defines conversion of picodata username to an LDAP Distinguished Name (DN). # Must have exactly one occurrence of `$USER` in it. tls: enabled: true # `false` by default. If `true`, TLS will be used to connect to the server method: start_tls # `implicit` by default. Accepted values are `implicit` and `start_tls`. # `implicit` means using `ldaps`. `start_tls` means using LDAP over TLS (StartTLS). ca_file: /etc/picodata/ldap-root-ca.crt # Path to a file containing alternative trusted root CA certificates, formatted as PEM. # System trusted certificate store will be ignored, and those certificates will be used instead. ``` Migration from legacy environment variables You need to convert the 1. The old value of `TT_LDAP_DN_FMT` should be put into `instance.ldap.dn_format`. The format strings are fully compatible. 2. For `TT_LDAP_URL` and `TT_LDAP_ENABLE_TLS`: | `TT_LDAP_URL` | `TT_LDAP_ENABLE_TLS` | Action | |-----------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| | `ldap://[hostname]:[port]` | not set | Set `instance.ldap.connect` to `[hostname]:[port]`.<br/>Leave other options as default values. | | `ldap://[hostname]:[port]` | `true` | Set `instance.ldap.connect` to `[hostname]:[port]`.<br/>Set `instance.ldap.tls.enabled` to `true`.<br/>Set `instance.ldap.tls.method` to `start_tls`. | | `ldaps://[hostname]:[port]` | not set | Set `instance.ldap.connect` to `[hostname]:[port]`.<br/>Set `instance.ldap.tls.enabled` to `true`.<br/>Set `instance.ldap.tls.method` to `implicit`. | | `ldaps://[hostname]:[port]` | `true` | This is an invalid configuration, since it requests use of StartTLS while also using LDAPS (implicit TLS). It is unrepresentable with the new config. | - [picodata#760] Added validation of cluster.tier config file section against the persisted system table state upon instance restart. - [picodata#2952] Added the `instance.wal_dir` configuration parameter, which sets the directory where WAL files are stored. join - When joining a cluster without an explicit `replicaset_name`, an instance whose name follows the standard naming scheme `<replicaset_name>_<n>` (e.g., `default_6_2`) now prefers joining `<replicaset_name>` (`default_6`) over whichever replicaset would otherwise be picked automatically. This makes it easier to restore a cluster from a backup of just the master instances and rejoin replicas with their expected names. plugin - Added on_cluster_leader_change callback to plugin API. It is called on two (at max) instances: on the old raft leader and on the new one [!3224](https://git.picodata.io/core/picodata/-/merge_requests/3224). - Renamed on_leader_change to on_replicaset_leader_change. Both methods are going to be called before the next major release. replication - Added synchronous replication for tiers via the new `replication_mode` tier option (`async`/`sync`, default `async`), set with `cluster.tier.<name>.replication_mode`. In `sync` mode Picodata enables Tarantool synchronous replication for sharded tables: a write is confirmed only after a quorum of the replicaset (`ReplicationFactor / 2 + 1`) acknowledges it, protecting against data loss and replication conflicts on master failover at the cost of write latency. Picodata automatically configures the synchro quorum, manages txn limbo ownership across master switchovers, and sets the `is_sync` flag on spaces created in the tier ([!2962](https://git.picodata.io/core/picodata/-/merge_requests/2962)). Scope and constraints: - Applies only to sharded (user) tables. Global and system tables (`_pico*`) are replicated globally via Raft and are unaffected. Tarantool system spaces are unaffected too. - The mode is fixed at cluster bootstrap and cannot be changed for an already-deployed cluster. - On quorum loss the replicaset becomes read-only and serves only reads (DQL); recovery is manual — the quorum must be restored by hand. - Replication factor 2 is not recommended with `sync` mode, since the quorum is then also 2 and the replicaset loses write availability on any single instance failure. webui - Optimize `/api/v1/tiers` and `/api/v1/cluster` endpoints to reduce RPC calls. HTTP addresses are now read from `_pico_peer_address` storage instead of RPC, and memory info is only fetched from replicaset leaders. This reduces the number of RPC calls from O(N×RF) to O(N) where N is the number of replicasets. Offline instances now show their HTTP address (from storage) instead of empty string. - Added new instance filters: `isVoter` and `isRaftLeader`. Both support the standard `Is` / `IsOneOf` / `IsNotOneOf` expressions with a Yes/No value set. - Extended the generic `Filter` component to accept boolean-valued tag options in addition to strings. The filter visual style is unchanged. - The replicaset card now renders placeholders for missing instances (instances expected by the replicaset configuration but not currently reported by the cluster). - Added `isRaftLeader` and `isVoter` flags to the instance model. Tier and replicaset cards now show indicators when they contain the raft leader or a voter instance. - The replicaset cards now display indicators if they have the not ready status. - The filter now has the option to select a text search tag without first entering text. - Added an instance details modal, opened by clicking an instance in the list. The modal includes the Overview, Storage, and Replication tabs. These tabs display the instance's general information, Vinyl and Memtx storage configuration, and replication details, including upstream and downstream information for remote nodes. misc - Improved accuracy of `space:len()` for Vinyl tables. Bug fixes - Fixed crash when disabling a plugin with slow background jobs. Previously, if a job didn't finish within the shutdown timeout, the plugin library could be unloaded while the job fiber was still running. - Fix cold restart deadlock where all instances in a replicaset would get empty replication configs, preventing synchronization. The governor now includes only the master in the fallback replication config, preserving conflict isolation while allowing the cluster to recover. - Fixed plugin unnamed background jobs being marked with wrong source location (missing `#[track_caller]` attribute). - Revoking privileges from `admin` user caused a panic. Now, revoking priviliges from `admin` user is forbidden, for same reasons as for the `pico_service` user. - Fixed sentinel panic on long activation wait. - Fixed an out-of-bounds panic in plugin RPC client when selecting a random candidate instance for `RequestTarget::Any`. - [picodata#2838] Fixed panic on single-node cluster forced expel ("removed all voters"), which now returns an explicit error. - [picodata#2888] Fixed a bug where cluster would fail to bootstrap if there were no voter instances in the initial `--peer` set. - Fixed the `Storage cache hitrate` panels in the bundled Grafana dashboard. They previously referenced non-existent metric names (`pico_storage_cache_1st_requests_total` / `…_2nd_requests_total`) and the formula folded DML traffic into the storage hitrate, silently inflating it. The panels now compute `hits / (hits + misses)` from `pico_storage_cache_hits_total` / `pico_storage_cache_misses_total` (DQL-only by construction), aggregated across `rpc_type` so the iproto path (`1st`, `2nd`) and the local fast-path (`local`) are reflected together. - All cache panels in `monitoring/dashboard/Picodata.json` now respect the dashboard's `$tier` and `$replicaset` template variables. - Fixed CAS conflict detection for globally distributed tables with secondary unique indexes. Previously, stale CAS requests could be appended to the raft log with different primary keys but the same secondary unique key, causing replicas to fail applying the later entry and preventing raft from advancing. Such requests are now rejected with a retriable `CasConflictFound` error. - [picodata#2926] Reduced log verbosity in vshard for routine replicaset events. - Implement and export `box_session_user_name` function in tarantool-sys ([tarantool!387](https://git.picodata.io/core/tarantool/-/merge_requests/387)). - Implement a function `tarantool::session::user_name` and use it in the `on_access_denied` trigger to prevent an implicit multi-statement transaction, which panicked ([!3196](https://git.picodata.io/core/picodata/-/merge_requests/3196)). config - Fixed a regression in config parsing. `--iproto-listen`, `--iproto-advertise` and `--http-listen` were triggering an error instead of overriding corresponding value in yaml config when deprecated listen options were used in the config. discovery - Discovery no longer panics on multi-address nodes ([picodata!3312]). sql - Queries of the form `(a OR b) AND (c OR d) AND (e OR f)...` could grow exponentially after DNF conversion. This led to a stack overflow. A limit of 512 disjunctions has been added; if this limit is exceeded, the DNF is not constructed. You may notice this in the `EXPLAIN` output: `Query (WHOLE STORAGE)`. It is recommended to rewrite such queries [picodata!3353]. - Fixed a SQL planner panic caused by stale type metadata after clone-based rewrites such as `BETWEEN` normalization and `GROUP BY` alias expansion. - Fixed a bug preventing scalar functions from being used in GROUP BY. - Fixed a bug with the storage cache that caused an error "Temporary table TMP_ not found". - Fixed a permission error occured during query planning for non-admin users. - Fixed the errors `box.cfg.read_only is true` and `Failed to add a storage reference`, which occurred when restarting a storage instance and previously required a retry. - Fixed `ALTER PLUGIN ADD SERVICE TO TIER` accepting nonexistent tier names. Now validates that the specified tier exists and returns an error otherwise. - Fixed the `query for request_id with plan_id not found` error that occurred on queries with `UNION` of `CTE` on a cluster consisting of multiple instances. - Logical `EXPLAIN` (the default mode) now preserves subquery indentation. - Backup operation will now be automatically aborted if there are offline instances. This prevents cluster being locked in a readonly state. - Fixed the `NO_ROUTE_TO_BUCKET` error that occurred when sending a request to the single node of a replicaset during its restart. This error is now retried by the router. - [picodata#2812] Use direct RPC for query metadata on DQL cache miss - Replace vshard-based Lua dispatch with ConnectionPool::call_raw for the proc_query_metadata callback. This fixes SQL query execution from arbiter tier instances (bucket_count=0) where no vshard router exists. - [picodata#2842] Fixed the `schema version has changed: need to re-compile SQL statement` error, which could occur when you execute multiple DQL queries due to yield during cache eviction. - [picodata#2732] Fixed a panic when attempting to inherit privileges via SQL (e.g., `GRANT admin TO somebody`). We do not support privilege inheritance via `GRANT user1 TO user2`. The system now validates the grantee type and returns a proper `NoSuchRole` error instead of panicking. - Reused CTE bodies are now materialized once per query instead of being silently inlined per reference, fixing wrong results for non-deterministic CTE bodies and avoiding redundant recomputation. - Fixed NOT push-down: no longer short-circuits before recursing into operand subtrees. The pass now also descends into Cast children to simplify NOTs nested inside. - [picodata#2775] Dropping the primary index is now rejected with a clear error. - `_pico_db_config` can no longer be truncated or deleted, as such operations may break instances or clusters. -
26.1.6
protected46530baf · ·[25.1.6] - 2026-07-13 Fixes - Fixed excessive logging when DdlCommit could not be applied on a replica. - Queries of the form `(a OR b) AND (c OR d) AND (e OR f)...` could grow exponentially after DNF conversion. This led to a stack overflow. A limit of 512 disjunctions has been added; if this limit is exceeded, the DNF is not constructed. You may notice this in the `EXPLAIN` output: `Query (STORAGE)`. It is recommended to rewrite such queries [picodata!3353].
-
26.1.5
protectedf8070ddd · ·[26.1.5] - 2026-07-01 Features - [picodata#2952] Added the `instance.wal_dir` configuration parameter, which sets the directory where WAL files are stored. - Extended constant folding: AND/OR identities, identity rules for equality with true and inequality with false. Fixes - [picodata#3312] Discovery no longer panics on multi-address nodes.
-
26.1.3
protected83c615e3 · ·[26.1.3] - 2026-05-21 Breaking changes - `CancellationTokenHandle::cancel()` now returns `Rc<OnceEvent>` instead of `Channel<()>`. Use `finish_event.is_finished()` to check completion or `finish_event.wait_timeout(duration)` to wait with a timeout. - Rename fields in `/api/v1/health/status` response: `reasons` to `issues`, status level `unhealthy` to `broken`. - `picodata demo` subcommand is now gated behind the `demo` Cargo feature, disabled by default. To build with demo, use `CARGO_FLAGS_EXTRA="--features demo"`. Features - Improved accuracy of `space:len()` for Vinyl tables. - Support `DELETE` statementes inside transactional `DO` blocks. - Support `INSERT` statements inside transactional `DO` blocks. - [picodata#1596] Added support for `ARRAY` columns in `CREATE TABLE` and `ALTER TABLE ADD COLUMN`. Supported syntax: `T[]`, `T[N]`, `T[N][M]`, `T[][]`, `T ARRAY`, `T ARRAY[N]`. Declared type and sizes are documentation only and do not affect the internal implementation for now. Fixes - Fixed crash when disabling a plugin with slow background jobs. Previously, if a job didn't finish within the shutdown timeout, the plugin library could be unloaded while the job fiber was still running. - Fixed the `NO_ROUTE_TO_BUCKET` error that occurred when sending a request to the single node of a replicaset during its restart. This error is now retried by the router. - [picodata#2842] Fixed the `schema version has changed: need to re-compile SQL statement` error, which could occur when you execute multiple DQL queries due to yield during cache eviction. - Fixed sentinel panic on long activation wait. - [picodata#2812] Use direct RPC for query metadata on DQL cache miss - Replace vshard-based Lua dispatch with ConnectionPool::call_raw for the proc_query_metadata callback. This fixes SQL query execution from arbiter tier instances (bucket_count=0) where no vshard router exists. - [picodata#2888] Fixed a bug where cluster would fail to bootstrap if there were no voter instances in the initial `--peer` set. - Revoking privileges from `admin` user caused a panic. Now, revoking priviliges from `admin` user is forbidden, for same reasons as for the `pico_service` user. - Fixed `ALTER PLUGIN ADD SERVICE TO TIER` accepting nonexistent tier names. Now validates that the specified tier exists and returns an error otherwise. - Backup operation will now be automatically aborted if there are offline instances. This prevents cluster being locked in a readonly state. - [picodata#2732] Fixed a panic when attempting to inherit privileges via SQL (e.g., `GRANT admin TO somebody`). We do not support privilege inheritance via `GRANT user1 TO user2`. The system now validates the grantee type and returns a proper `NoSuchRole` error instead of panicking. -
26.1.2
protected6db4aba0 · ·[26.1.2] - 2026-04-14 Changed - Optimize `/api/v1/tiers` and `/api/v1/cluster` endpoints to reduce RPC calls. HTTP addresses are now read from `_pico_peer_address` storage instead of RPC, and memory info is only fetched from replicaset leaders. This reduces the number of RPC calls from O(N×RF) to O(N) where N is the number of replicasets. Offline instances now show their HTTP address (from storage) instead of empty string. Fixes - Fixed a SQL planner panic caused by stale type metadata after clone-based rewrites such as `BETWEEN` normalization and `GROUP BY` alias expansion. - Fixed a bug with the storage cache that caused an error "Temporary table TMP_ not found". - Fixed a regression in config parsing. `--iproto-listen`, `--iproto-advertise` and `--http-listen` were triggering an error instead of overriding corresponding value in yaml config when deprecated listen options were used in the config. - Fixed a permission error occured during query planning for non-admin users. - Fix cold restart deadlock where all instances in a replicaset would get empty replication configs, preventing synchronization. The governor now includes only the master in the fallback replication config, preserving conflict isolation while allowing the cluster to recover. - Fixed the errors `box.cfg.read_only is true` and `Failed to add a storage reference`, which occurred when restarting a storage instance and previously required a retry. - Fixed the `query for request_id with plan_id not found` error that occurred on queries with `UNION` of `CTE` on a cluster consisting of multiple instances. - Fixes an issue when http and plugin addresses were inserted into `_pico_peer_address` when an instance joined a mixed-version cluster, causing a panic on older instances. It is also now not possible to bootstrap an 26.1.x instance defining a plugin listener address into a mixed 25.5.x and 26.1.x cluster - cluster has to be fully updated to do that.
-
26.1.1
protectedc6c37afb · ·[26.1.1] - 2026-03-24 Features - Unified socket configuration: introduce new `instance.iproto`, `instance.http`, and `instance.pgproto` config sections that consolidate listen/advertise/TLS settings per protocol. Old top-level parameters (`instance.iproto_listen`, `instance.iproto_advertise`, `instance.http_listen`, `instance.pg`) are deprecated but remain functional. HTTP server is now enabled by default on port 5327. HTTP and pgproto peer addresses are stored in `_pico_peer_address` system table with corresponding connection types (`http`, `pgproto`, `plugin:<name>.<service>`). - Rework SQL execution protocol for DML queries to reduce data transfer. - Support JSON_EXTRACT_PATH function. - Introduce non-blocking SQL execution to prevent fiber starvation. - New column `sync_incarnation` is added to `_pico_instance` system table. - New ALTER SYSTEM parameter `governor_check_replication_error` (default: true) enables the checking if replication is broken on any instance, in which case the instance will be automatically made Offline. - New ALTER SYSTEM parameter `sql_log` (default: false) enables logging of all SQL statements to log file. - Add CREATE TABLE syntax "PRIMARY KEY (bucket_id, ...)": - When this syntax is used, there is no separate 'bucket_id' index; - Instead, 'bucket_id' is included as the first part of the primary key index. - New columns `target_state_reason` & `target_state_change_time` in `_pico_instance` system table - Added env option PICODATA_UNSAFE_FORCE_RECOVERY. - Possible values: true, false. - This option is passed to Tarantool as `force_recovery` option. - If force_recovery equals true, Tarantool tries to continue if there is an error while reading a snapshot file (at server instance start) or a write-ahead log file (at server instance start or when applying an update at a replica. - Introduce `read_preference` option for routing DQL queries to replicas in specific scenarios. - Introduce `pico_stmt_invalidation` option for getting errors when binding invalid statements. - Introduce `pico_query_metadata` option for getting distribution key metadata. - Introduce `sql_preemption_opcode_max` to control the VDBE opcode interval between execution time checks when `sql_preemption` is enabled. - New ALTER SYSTEM parameter `sql_runtime_concurrency_max` (default: `1`) limits the number of simultaneously executing SQL requests per instance. - Support cluster update to next major version (26.1.0). - Support compatibility between the next major Picodata version and older plugin versions. - Add support for `EXPLAIN (RAW)` for queries that fail at local sql execution stage. - Add unlogged tables to SQL: - Unlogged tables' updates are not writeen into the WAL, so they are not persisted on restarts of an instance and are not replicated. On leader change, all unlogged tables are truncated to prevent inconsistencies. Creating unlogged tables is possible with the `CREATE UNLOGGED TABLE ...` syntax. Unlogged tables are implemented as Tarantool data-temporary spaces, so it is not possible to store them using the vinyl engine. - \[breaking\] Instead of always being a tier with name `default`, default tier is now the first tier mentioned in the config. - Add support for `compression_level` Vinyl option for secondary indices created with `CREATE INDEX`. - Add support for Vinyl index options (`bloom_fpr`, `page_size`, `range_size`, `run_count_per_level`, `run_size_ratio`, `compression_level`) in `CREATE TABLE ... WITH (...)` syntax for configuring implicit primary key and bucket_id indices. - Add suppoort for anonymous blocks. An anonymous block is a sequence of statements that execute queries transactionally. Blocks are single-bucket, meaning that all the queries within the block must be executed on the same bucket (or have distribution any). - Add optimization for Limit + Distinct and Limit + OrderBy. When certain conditions are met, the Limit node is added to the local stage of SQL query plan. Supported statements are: - QUERY: execute the given query; - RETURN QUERY: execute the given query and return its result. - Add detailed health status endpoint (`/api/v1/health/status`) with instance, Raft, bucket, and cluster information. - Add support for Kubernetes startup, liveness and readiness probes. - Support `bucket_count=0` for tiers. A tier with `bucket_count=0` has no sharded data (only global system tables) and is intended for "arbiter" tiers used in Raft consensus. Vshard bootstrap and configuration are skipped for such tiers, and replicaset expel proceeds without waiting for bucket transfer. Creating sharded tables on a zero-bucket tier is rejected with a clear error. - Add support for `EXPLAIN (RAW)` for block queries. - Speed up instance restart by actively trying to identify the raft leader instead of waiting for it to send a heartbeat to us. - Refactor the plan id calculation for more accurate and faster caching. - ACL/ALTER SYSTEM/ALTER INDEX RENAME operations now support WAIT APPLIED GLOBALLY / WAIT APPLIED LOCALLY syntax and default to globally, matching DDL behavior. - Add bucket estimation for INSERT queries in explain. - Support reading from global tables in anonymous blocks; writing is not supported yet. - Upgrade Tarantool from 2.11.5 to 2.11.8. - Add migration context validation API into plugin SDK. - Introduce a local SQL execution path for eligible queries that bypasses `iproto` on the current instance; usage is exposed via the `pico_sql_local_query_total` and `pico_sql_local_query_duration` metrics. - Remove unnecessary `Motion(Full)` for queries that are guaranteed to be routed to a single node due to the sharding key filter. CLI - Completely re-architected `picodata demo` subcommand: - Fixed improper signal handling (SIGINT, SIGTERM) and process termination. - Added graceful shutdown and guaranteed cleanup of child processes. - Introduced cluster orchestration model for simplified lifecycle management. - Added configurable command-line parameters and cluster information display. - Add machine-readable output formats to `picodata admin` - Add long version output (-VV) with more info WebUI - Webui now displays the value of `cluster_version` instead of current instance's version. That way you can easily tell if the cluster has been upgraded successfully or not yet. - the display of the target state in the instance card has been removed - the ability to group by replicas has been removed - added a visual indication of the problem status for the offline instance counter - virtualization has been applied to the tiers and instance list - the cluster information is displayed in the header - the filter has been redesigned, now it is constantly displayed in front of the list of shooting ranges or instances. Added the ability to filter by text and by tags, such as dash name, replica set name, instance name, version, status. Fixes - Fixed that governor would hang indefinitely if an Offline replicaset had target_master_name != current_master_name. - Fixed that instance would hang indefinitely when trying to join the cluster if the cluster becomes too big. NOTE: The fix requires modifying the proc_raft_join RPC response format which technically breaks compatibility with previous versions of picodata. However picodata explicitly doesn't support heterogeneous joins (when version of joining instances mismatches version of cluster), so this shouldn't be a problem for anybody. NOTE also that this doesn't affect restarting instances which already joined the cluster. - Fixed a crash when SQL request arrives before instance is properly initialized - Fixed that instances would be made Offline immediately after a raft entry is applied if there weren't any entries applied for a long time before that - Fixed that instances would randomly fail with ER_READONLY during bootstrap - Fixed ER_BOOTSTRAP_CONNECTION_NOT_TO_ALL failure during instance join stage. - Fixed that governor would send redundant proc_sharding RPCs which would make it impossible to deploy huge clusters. Now RPCs from governor are split into batches of configurable size (default 200, ALTER SYSTEM parameter `governor_rpc_batch_size`). - Improve upgrade flow for creating Lua stored functions (exported to SQL). - Node construction is now deferred until actually needed, avoiding unnecessary work for cached queries on any instance execution - Fixed a memory leak in SQL API of plugin SDK - `picodata status` no longer panics when `stdout`, `stderr`, or both are redirected to a broken pipe. - Fixed that the whole replicaset would be broken if one instance get's a replication conflict. (See also https://git.picodata.io/core/picodata/-/issues/2231). - Fixed that governor would sometimes be blocked in read_only on a DDL operation mode not being able to apply any subsequent raft operations. - Introduce unnamed_join alias for motions with joins under them to distinguish columns with identical names - Governor RPC batching is also implemented for proc_apply_schema_change. - Governor RPC batching is also implemented for proc_apply_backup. - Datetime literals should support `yyyy-mm-dd` format, e.g. `select '2026-01-17'::datetime`. - Fix type inference for the `a BETWEEN b AND c` expression; now types of `a`, `b` and `c` should be properly unified, meanining that `select '2026-01-13' between '2026-01-01'::datetime and '2026-01-20'` will work as expected. - Fixed that upgrading between patch versions wouldn't run upgrade scripts. - Fixed assertion failure in CAS right after raft leader change followed by persisted raft log tail truncation. - Fixed instance.vinyl.* options to be applied to primary and bucket_id indices. - Fixed a crash in proc_runtime_info when the last applied raft entry contained a unicode string where a 100th byte position was not on a character boundary. - Fixed that sentinel_loop was broken during upgrade from versions before 25.5.3. - Fixed ignoring `NULLS FIRST` and `NULLS LAST` in unnamed window queries with ordering. - Fixed metadata loss in queries with LIMIT clause in picodata admin. - Fixed invalid volatile flag for rust-implemented builtin functions. - Fixed governor's `ConfigureReplication` step was broken during upgrade from before 25.5.3 - Fixed that instances from tiers with can_vote=false attempting to promote to raft leader. - Fixed that `--pg-advertise` CLI argument was erroneously disallowed to be used simultaneously with `--iproto-advertise`. - Fixed a race condition between DDL (i.e., TRUNCATE) and DQL when the preemption option is enabled. - Fixed concurrent access to storage temporary tables by synchronizing their lifecycle and execution with a per-plan lock. - Fixed a number of vinyl issues by backporting upstream patches - Fixed an issue where upgrade operations were inserted incorrectly when applying system catalog changes for several catalog versions. - Fixed `picodata plugin configure` panic on attempt to update non-existent plugin or a non-existing service of an existing plugin. - Fixed `proposal dropped` errors sometimes being returned from DDL commands for example when raft is unknown. - Fixed an RPC to avoid skipping metrics collection code path on early return in procedure implementation. - Make sure that single-tiered clusters upgraded from 25.3.x always have a default tier. - Fixed that instances would fail with ER_READONLY while joining a replicaset whose master was still bootstrapping. Governor no longer triggers mastership failover for a master that is in the initial Offline(0) join state and has not yet had a chance to become Online. - Fixed local SQL iterators to survive fiber yields during table truncation. - Fixed a caching bug affecting `UNION` queries with global and sharded tables in a cluster of several replicasets. - Fixed a caching bug that caused some different queries to tables with `bucket_id` in the primary key to have the same plan id. - Fixed SUM/AVG type resolution for Double - Fixed incorrect filter pushdown into compound queries containing window functions. Observability - All duration-based metrics now report in fractional seconds instead of milliseconds for consistency with Prometheus and more precision. - RPC request durations now use a monotonic high-precision clock instead of the event-loop clock to improve timing accuracy. - Added SQL temp-table lock metrics: `pico_sql_temp_table_leases_total` and `pico_sql_temp_table_lock_waits_total`. Breaking changes - Remove `tros` and `tarolog` dependencies from `picodata-plugin`. These libraries can still be used as direct dependencies when needed. - Hashing behavior changed for `DOUBLE` type fields in primary keys and distribution keys. Previously, values were always re-encoded as MP_DOUBLE (9 bytes) before hashing. Now, integer-representable doubles (e.g., `1.0`) are converted to integer encoding before hashing, making them hash identically to their integer equivalents (e.g., `1`). This is correct behavior that allows lookups like `SELECT * FROM t WHERE double_col = 1` to find rows inserted with `double_col = 1.0`. However, existing data sharded on `DOUBLE` keys containing integer values may have different bucket assignments after upgrade. -
25.5.8
protected8947561f · ·[25.5.8] - 2026-02-25 Features - New ALTER SYSTEM parameter `sql_log` (default: false) enables logging of all SQL statements to log file. - Introduce `sql_preemption_opcode_max` to control the VDBE opcode interval between execution time checks when `sql_preemption` is enabled. - Fixed local SQL iterators to survive fiber yields during table truncation. Fixes - Fixed that `--pg-advertise` CLI argument was erroneously disallowed to be used simultaneously with `--iproto-advertise`. - Fixed an issue where upgrade operations were inserted incorrectly when applying system catalog changes for several catalog versions.
-
25.5.6
protected14c64653 · ·[25.5.6] - 2026-02-06 WebUI - Webui now displays the value of `cluster_version` instead of current instance's version. That way you can easily tell if the cluster has been upgraded successfully or not yet. Fixes - Fixed governor's `ConfigureReplication` step was broken during upgrade from before 25.5.3 - Fixed that instances from tiers with can_vote=false attempting to promote to raft leader. - Fixed a crash in case of any error during TRUNCATE operation. - Fixed a race condition between DDL (i.e., TRUNCATE) and DQL when the preemption option is enabled.
-
25.5.5
protected2851d7f3 · ·[25.5.5] - 2026-01-26 Fixes - Fixed assertion failure in CAS right after raft leader change followed by persisted raft log tail truncation. - Fixed a crash in proc_runtime_info when the last applied raft entry contained a unicode string where a 100th byte position was not on a character boundary. - Added env option PICODATA_UNSAFE_FORCE_RECOVERY. - Possible values: true, false. - This option is passed to Tarantool as `force_recovery` option. - If force_recovery equals true, Tarantool tries to continue if there is an error while reading a snapshot file (at server instance start) or a write-ahead log file (at server instance start or when applying an update at a replica. - Always open vylog files with O_SYNC. - Fixed that sentinel_loop was broken during upgrade from versions before 25.5.3. -
25.5.4
protected36fbec30 · ·[25.5.4] - 2026-01-21 Fixes - Introduce unnamed_join alias for motions with joins under them to distinguish columns with identical names - Fix erroneous logic of counting rows returned from replicasets which led to undercovered limit exceedance errors. - Fixed that upgrading between patch versions wouldn't run upgrade scripts. - Datetime literals should support `yyyy-mm-dd` format, e.g. `select '2026-01-17'::datetime`. - Fix type inference for the `a BETWEEN b AND c` expression; now types of `a`, `b` and `c` should be properly unified, meanining that `select '2026-01-13' between '2026-01-01'::datetime and '2026-01-20'` will work as expected.