Skip to content

Commit 20a0638

Browse files
committed
Add a detailed review of the key features in release 3.4
1 parent 05f4b25 commit 20a0638

File tree

1 file changed

+249
-0
lines changed

1 file changed

+249
-0
lines changed

doc/release/3.4.0.rst

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
Tarantool 3.4
2+
=============
3+
4+
Release date: April 14, 2024
5+
6+
Releases on GitHub: :tarantool-release:`3.4.0`
7+
8+
The 3.4 release of Tarantool adds the following main product features and improvements
9+
for the Community and Enterprise editions:
10+
11+
* **Community Edition (CE)**
12+
13+
* Memtx <-> vinyl cross-engine transactions.
14+
* New ``index:quantile()`` function for finding a quantile key in an indexed data range.
15+
* Functional indexes in the MVCC transaction manager.
16+
* Vinyl now supports ``np`` (next prefix) and ``pp`` (previous prefix) iterators.
17+
* Fixed incorrect number comparisons and duplicates in unique indexes.
18+
* Runtime priviledges for ``lua_call`` are now granted before ``box.cfg()``.
19+
* The ``stop`` callbacks for the roles are now called during graceful shutdown,
20+
in the reverse order of roles startup.
21+
* New ``has_role``, ``is_router``, and ``is_storage`` methods in the
22+
``config`` module to check if a role is enabled on an instance.
23+
* LuaJIT profilers are now more user-friendly.
24+
* Built-in logger now encodes table arguments in the JSON format.
25+
* Multiple bugfixes for MVCC, vinyl, WAL, and snapshotting.
26+
* Fixed memory overgrowing for cdata-intensive workloads.
27+
28+
* **Enterprise Edition (EE)**
29+
30+
* New in-memory columnar storage engine: ``memcs``.
31+
* New bootstrap strategy in failover: ``native``.
32+
* New public API for accessing remote ``config.storage`` clusters as key-value storages.
33+
* Two-phase appointment process to avoid incorrect behavior of the failover coordinator.
34+
35+
.. _3-4-memcs:
36+
37+
[EE] New in-memory columnar storage engine: ``memcs``
38+
-----------------------------------------------------
39+
40+
The engine stores data in the memtx arena but in contrast to memtx it doesn't
41+
organize data in tuples. Instead, it stores data in columns. Each format field
42+
is assigned its own BPS tree-like structure (BPS vector), which stores values
43+
only of that field. If the field type fits in 8 bytes, raw field values are
44+
stored directly in tree leaves without any encoding. For values larger than 8
45+
bytes, like decimal, uuid or strings, the leaves store pointers to
46+
MsgPack-encoded data.
47+
48+
The main benefit of such data organization is a significant performance boost
49+
of columnar data sequential scans compared to memtx thanks to CPU cache
50+
locality. That's why memcs supports a special C api for such columnar scans:
51+
see `box_index_arrow_stream()` and `box_raw_read_view_arrow_stream()`.
52+
Peak performance is achieved when scanning embedded field types.
53+
54+
Querying full tuples, like in memtx, is also supported, but the performance is
55+
worse compared to memtx, because a tuple has to be constructed on the runtime
56+
arena from individual field values gathered from each column tree.
57+
58+
Other features include:
59+
* Point lookup.
60+
* Stable iterators.
61+
* Insert/replace/delete/update.
62+
* Batch insertion in the Arrow format.
63+
* Transactions, including cross-engine transactions with memtx
64+
(with ``memtx_use_mvcc_engine = false``).
65+
* Read view support.
66+
* Secondary indexes with an ability to specify covered columns and sequentially scan
67+
indexed + covered columns.
68+
69+
Embedded field types include only fixed-width types:
70+
* Integer: (u)int8/16/32/64.
71+
* Floating point: float32/64.
72+
73+
Types with external storage include:
74+
* Strings.
75+
* All the other types supported by Tarantool: UUID, Decimal, Datetime, etc.
76+
77+
By default, NULL values are stored explicitly and use up the same space as
78+
any other valid column value (1, 2, 4 or 8 bytes depending on an exact field
79+
type), however RLE encoding of NULLs is also supported. For reference,
80+
RLE-encoding of a column with 90% evenly distributed NULL values reduces
81+
memory consumption of that column by around 5 times.
82+
83+
.. _3-4-cross-engine:
84+
85+
[CE] Memtx <-> vinyl cross-engine transactions
86+
----------------------------------------------
87+
88+
Tarantool now supports mixing statements for memtx and vinyl in the same transaction,
89+
for example:
90+
91+
.. code-block:: lua
92+
93+
local memtx = box.schema.space.create('memtx', {engine = 'memtx'})
94+
memtx:create_index('primary')
95+
local vinyl = box.schema.space.create('vinyl', {engine = 'vinyl'})
96+
vinyl:create_index('primary')
97+
98+
memtx:insert({1, 'a'})
99+
vinyl:insert({2, 'b'})
100+
101+
box.begin()
102+
memtx:replace(vinyl:get(2))
103+
vinyl:replace(memtx:get(1))
104+
box.commit()
105+
106+
.. note::
107+
108+
* Accessing a vinyl space may trigger a fiber yield (to read a file from the disk),
109+
so MVCC must be enabled in memtx to make use of the new feature:
110+
111+
.. code-block:: lua
112+
113+
box.cfg{memtx_use_mvcc_engine = true}
114+
115+
* Vinyl operations may yield implicitly, so a transaction may be aborted
116+
with TRANSACTION_CONFLICT in case of concurrent transactions.
117+
118+
.. _3-4-native:
119+
120+
[EE] New boostrap strategy in failover: ``native``
121+
--------------------------------------------------
122+
123+
Now supervised failover coordinator supports three bootstrap strategies:
124+
native, supervised, auto.
125+
126+
The new ``native `` strategy acts more or less similar to the ``auto`` strategy,
127+
but relaxes its limitations. It is based on the supervised strategy and basically
128+
performs two things:
129+
* issues ``box.ctl.make_bootstrap_leader({graceful = true})`` to bootstrap
130+
a replicaset;
131+
* issues ``box.ctl.make_bootstrap_leader()`` to keep the bootstrap leader
132+
record pointing to the instance that is currently in the RW mode (to register
133+
new replicas).
134+
135+
To enable the ``native `` bootstrap strategy, set it in the ``replication`` section
136+
of the cluster's configuration, together with a proper failover strategy
137+
(for ``native``, you can choose any failover strategy you like, for example ``supervised``):
138+
139+
.. code-block:: yaml
140+
141+
replication:
142+
failover: supervised
143+
bootstrap_strategy: native
144+
145+
.. _3-4-runtime-priv:
146+
147+
[CE] Runtime priviledges for ``lua_call`` granted before ``box.cfg()``
148+
----------------------------------------------------------------------
149+
150+
It is now possible to grant execution privileges for Lua functions
151+
through the declarative configuration, even when the database is in
152+
read-only mode or has an outdated schema version. You might also
153+
permit ``guest`` to execute Lua functions before the initial bootstrap.
154+
155+
You can specify function permissions using the ``lua_call`` option in
156+
the configuration, for example:
157+
158+
.. code-block:: lua
159+
160+
credentials:
161+
users:
162+
alice:
163+
privileges:
164+
- permissions: [execute]
165+
lua_call: [my_func]
166+
167+
This grants the ``alice`` user permission to execute the ``my_func`` Lua
168+
function, regardless of the database's mode or status. The special option
169+
``lua_call: [all]`` is also supported, granting access to all global Lua
170+
functions except built-in ones, bypassing database restrictions.
171+
172+
Privileges will still be written to the database when possible to
173+
maintain compatibility and consistency with other privilege types.
174+
175+
[CE] New methods in the ``config`` module to check instance roles
176+
-----------------------------------------------------------------
177+
178+
Three new methods are now available in the ``config`` module:
179+
180+
* ``has_role(<role_name>, {instance = <instance_name})`` returns ``true`` if
181+
the instance with the name ``<instance_name>`` has the role ``<role_name>``
182+
enabled in the current configuration, or ``false`` if not.
183+
The second argument is optional: if not provided, the check is performed
184+
for the instance the method is called on.
185+
186+
* ``is_router({instance = <instance_name})`` returns ``true`` if the instance
187+
with the name ``<instance_name>`` is a vshard router, according to the current
188+
configuration, or ``false`` if not.
189+
The argument is optional: if not provided, the check is performed for
190+
the instance the method is called on.
191+
192+
* ``is_storage({instance = <instance_name})`` returns ``true`` if the instance
193+
with the name ``<instance_name>`` is a vshard storage, according to the current
194+
configuration, or ``false`` if not.
195+
The argument is optional: if not provided, the check is performed for
196+
the instance the method is called on.
197+
198+
.. _3-4-storage-client-api:
199+
200+
[EE] New public API: ``config.storage_client``
201+
----------------------------------------------
202+
203+
Remote ``config.storage`` clusters can now be accessed by using the
204+
``config.storage_client.connect(endpoints[, {options}])`` method.
205+
The returned object represents a connection to a remote key-value
206+
storage accessed through the ``:get()``, ``:put()``, ``:info()``, ``:txn()``
207+
methods with the same signature as in the server
208+
:ref:`config.storage <config_module_api_reference>` API.
209+
210+
The ``config.storage_client`` API has also several specific methods:
211+
``:is_connected()``, ``:watch()``, ``:reconnect()``, ``:close()``.
212+
213+
Here are some usage examples:
214+
215+
.. code-block:: lua
216+
217+
-- Connect to a config.storage cluster using the endpoints
218+
-- configured in the `config.storage` section.
219+
--
220+
-- You can provide endpoints as a Lua table:
221+
--
222+
-- local endpoints = {
223+
-- {
224+
-- uri = '127.0.0.1:4401',
225+
-- login = 'sampleuser',
226+
-- password = '123456',
227+
-- }
228+
-- }
229+
230+
local endpoints = config:get('config.storage.endpoints')
231+
local client = config.storage_client.connect(endpoints)
232+
233+
-- Put a value to the connected client.
234+
client:put('/v', 'a')
235+
236+
-- Get all stored values.
237+
local values = client:get('/')
238+
239+
-- Clean the storage.
240+
local response = client:delete('/')
241+
242+
-- Watch for key changes.
243+
local log = require('log')
244+
local w = client:watch('/config/main', function()
245+
log.info('config has been updated')
246+
end)
247+
248+
-- Unregister a watcher.
249+
w:unregister()

0 commit comments

Comments
 (0)