|
| 1 | +Tarantool 3.2 |
| 2 | +============= |
| 3 | + |
| 4 | +Release date: August 26, 2024 |
| 5 | + |
| 6 | +Releases on GitHub: :tarantool-release:`3.2.0` |
| 7 | + |
| 8 | +The 3.2 release of Tarantool adds the following main product features and improvements for the Community and Enterprise editions: |
| 9 | + |
| 10 | +* **Community Edition (CE)** |
| 11 | + |
| 12 | + * A new experimental module for validating role configurations. |
| 13 | + * Initial support for encoding structured data using Protobuf. |
| 14 | + * Next and Previous prefix iterators. |
| 15 | + * Support for all UUID versions. |
| 16 | + * Automatic loading of the most often used built-in modules into the console environment. |
| 17 | + |
| 18 | +* **Enterprise Edition (EE)** |
| 19 | + |
| 20 | + * Time-to-live (TTL) for keys in a Tarantool-based configuration storage. |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +.. _3-2-features-for-developers: |
| 25 | + |
| 26 | +Developing applications |
| 27 | +----------------------- |
| 28 | + |
| 29 | +.. _3-2-configuration-validation: |
| 30 | + |
| 31 | +Configuration validation |
| 32 | +~~~~~~~~~~~~~~~~~~~~~~~~ |
| 33 | + |
| 34 | +Tarantool 3.2 includes a new experimental module for :ref:`validating role configurations <roles_create_custom_role_validate>` using a declarative schema. |
| 35 | +For example, you can validate the type of configuration values, provide an array of allowed values, or specify a custom validation function. |
| 36 | + |
| 37 | +Suppose, a sample :ref:`'http-api' custom role <roles_example_custom_role_http_api>` can accept the ``host`` and ``port`` configuration values: |
| 38 | + |
| 39 | +.. code-block:: yaml |
| 40 | +
|
| 41 | + roles: [ http-api ] |
| 42 | + roles_cfg: |
| 43 | + http-api: |
| 44 | + host: '127.0.0.1' |
| 45 | + port: 8080 |
| 46 | +
|
| 47 | +First, you need to load the ``experimental.config.utils.schema`` module: |
| 48 | + |
| 49 | +.. code-block:: lua |
| 50 | +
|
| 51 | + local schema = require('experimental.config.utils.schema') |
| 52 | +
|
| 53 | +The ``validate_port()`` function can be used to check that a port value is between ``1`` and ``65535``: |
| 54 | + |
| 55 | +.. code-block:: lua |
| 56 | +
|
| 57 | + local function validate_port(port, w) |
| 58 | + if port <= 1 or port >= 65535 then |
| 59 | + w.error("'port' should be between 1 and 65535, got %d", port) |
| 60 | + end |
| 61 | + end |
| 62 | +
|
| 63 | +Then, you can create a schema used for validation: |
| 64 | + |
| 65 | +- ``host`` should be one of the specified string values. |
| 66 | +- ``port`` should be a number that is checked using the ``validate_port()`` function declared above. |
| 67 | + |
| 68 | +.. code-block:: lua |
| 69 | +
|
| 70 | + local listen_address_schema = schema.new('listen_address', schema.record({ |
| 71 | + host = schema.enum({ '127.0.0.1', '0.0.0.0' }), |
| 72 | + port = schema.scalar({ |
| 73 | + type = 'integer', |
| 74 | + validate = validate_port, |
| 75 | + }), |
| 76 | + })) |
| 77 | +
|
| 78 | +Finally, you can pass the specified schema to the :ref:`validate() <roles_api_reference_validate>` role's function: |
| 79 | + |
| 80 | +.. code-block:: lua |
| 81 | +
|
| 82 | + local function validate(cfg) |
| 83 | + if cfg.host and cfg.port then |
| 84 | + listen_address_schema:validate(cfg) |
| 85 | + else |
| 86 | + error("You need to set both host and port values") |
| 87 | + end |
| 88 | + end |
| 89 | +
|
| 90 | +
|
| 91 | +
|
| 92 | +.. _3-2-protobuf: |
| 93 | + |
| 94 | +Protobuf encoder |
| 95 | +~~~~~~~~~~~~~~~~ |
| 96 | + |
| 97 | +The 3.2 release adds initial support for encoding structured data using `Protocol buffers <https://protobuf.dev/>`__. |
| 98 | +First, you need to load the ``protobuf`` module: |
| 99 | + |
| 100 | +.. code-block:: lua |
| 101 | +
|
| 102 | + local protobuf = require('protobuf') |
| 103 | +
|
| 104 | +To encode data, you need to define a protocol: |
| 105 | + |
| 106 | +.. code-block:: lua |
| 107 | +
|
| 108 | + local customer_protocol = protobuf.protocol({ |
| 109 | + -- Define a message and enum -- |
| 110 | + }) |
| 111 | +
|
| 112 | +The two main components of the protocol are messages and enums: |
| 113 | + |
| 114 | +- A message specifies the structure of data, in particular, the fields and their types. |
| 115 | +- An enum defines a set of enumerated constants within the message. |
| 116 | + |
| 117 | +To create a message and enum, use the ``message()`` and ``enum()`` functions, respectively: |
| 118 | + |
| 119 | +.. code-block:: lua |
| 120 | +
|
| 121 | + local customer_protocol = protobuf.protocol({ |
| 122 | + protobuf.message('Customer', { |
| 123 | + id = { 'int32', 1 }, |
| 124 | + firstName = { 'string', 2 }, |
| 125 | + lastName = { 'string', 3 }, |
| 126 | + customerType = { 'CustomerType', 4 } |
| 127 | + }), |
| 128 | + protobuf.enum('CustomerType', { |
| 129 | + active = 0, |
| 130 | + inactive = 1, |
| 131 | + }) |
| 132 | + }) |
| 133 | +
|
| 134 | +Once the protocol is specified, use the ``encode()`` method to encode data: |
| 135 | + |
| 136 | +.. code-block:: lua |
| 137 | +
|
| 138 | + local sample_customer = customer_protocol:encode( |
| 139 | + 'Customer', |
| 140 | + { |
| 141 | + id = 3, |
| 142 | + firstName = 'Andrew', |
| 143 | + lastName = 'Fuller', |
| 144 | + customerType = 1 |
| 145 | + } |
| 146 | + ) |
| 147 | +
|
| 148 | +
|
| 149 | +
|
| 150 | +.. _3-2-next-prefix-iterator: |
| 151 | + |
| 152 | +Next and Previous prefix iterators |
| 153 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 154 | + |
| 155 | +This release adds two new :ref:`iterators for TREE indexes <box_index-iterator-types>`: ``np`` (next prefix) and ``pp`` (previous prefix). |
| 156 | +If a key is a string value, a prefix is a common starting substring shared by multiple keys. |
| 157 | + |
| 158 | +Suppose, the ``products`` space contains the following values: |
| 159 | + |
| 160 | +.. code-block:: tarantoolsession |
| 161 | +
|
| 162 | + application:instance001> box.space.products:select() |
| 163 | + --- |
| 164 | + - - ['clothing_pants'] |
| 165 | + - ['clothing_shirt'] |
| 166 | + - ['electronics_laptop'] |
| 167 | + - ['electronics_phone'] |
| 168 | + - ['electronics_tv'] |
| 169 | + - ['furniture_chair'] |
| 170 | + - ['furniture_sofa'] |
| 171 | + - ['furniture_table'] |
| 172 | + ... |
| 173 | +
|
| 174 | +If you use the ``np`` iterator type and set the key value to ``electronics``, the output should look as follows: |
| 175 | + |
| 176 | +.. code-block:: tarantoolsession |
| 177 | +
|
| 178 | + application:instance001> box.space.products:select({ 'electronics' }, { iterator = 'np' }) |
| 179 | + --- |
| 180 | + - - ['furniture_chair'] |
| 181 | + - ['furniture_sofa'] |
| 182 | + - ['furniture_table'] |
| 183 | + ... |
| 184 | +
|
| 185 | +Similarly, you can use the ``pp`` iterator: |
| 186 | + |
| 187 | +.. code-block:: tarantoolsession |
| 188 | +
|
| 189 | + application:instance001> box.space.products:select({ 'electronics' }, { iterator = 'pp' }) |
| 190 | + --- |
| 191 | + - - ['clothing_shirt'] |
| 192 | + - ['clothing_pants'] |
| 193 | + ... |
| 194 | +
|
| 195 | +Note that new iterators work only for the :ref:`memtx engine <engines-memtx>`. |
| 196 | + |
| 197 | + |
| 198 | + |
| 199 | +.. _3-2-uuid-ttl-config-storage: |
| 200 | + |
| 201 | +Tarantool configuration storage: TTL support for keys (EE) |
| 202 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 203 | + |
| 204 | +The Enterprise Edition now includes a time-to-live (TTL) for keys in a Tarantool-based :ref:`configuration storage <configuration_etcd>`. |
| 205 | +You can specify a TTL value in the :ref:`config.storage.put() <config_storage_api_reference_put>` call as follows: |
| 206 | + |
| 207 | +.. code-block:: lua |
| 208 | +
|
| 209 | + config.storage.put('/foo/bar', 'v1', { ttl = 60 }) |
| 210 | +
|
| 211 | +Similarly, you can configure TTL in :ref:`config.storage.txn() <config_storage_api_reference_txn>`: |
| 212 | + |
| 213 | +.. code-block:: lua |
| 214 | +
|
| 215 | + config.storage.txn({ |
| 216 | + predicates = { { 'revision', '==', revision } }, |
| 217 | + on_success = { { 'put', '/foo/bar', 'v1', { ttl = 60 } } } |
| 218 | + }) |
| 219 | +
|
| 220 | +A new ``config.storage.info.features.ttl`` field allows you to check whether the current version of the configuration storage supports requests with TTL. |
| 221 | +In the example below, the :ref:`conn:call() <net_box-call>` method is used to make a remote call to get the ``ttl`` field value: |
| 222 | + |
| 223 | +.. code-block:: lua |
| 224 | +
|
| 225 | + local info = conn.call('config.storage.info') |
| 226 | + if info.features == nil or not info.features.ttl then |
| 227 | + error('...') |
| 228 | + end |
| 229 | +
|
| 230 | +
|
| 231 | +
|
| 232 | +.. _3-2-uuid: |
| 233 | + |
| 234 | +Support for all UUID versions |
| 235 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 236 | + |
| 237 | +Before the 3.2 version, Tarantool supported only UUIDs following the rules for RFC 4122 version 4. |
| 238 | +With v3.2, UUID values of all versions (including new 6, 7, and 8) can be parsed using the :ref:`uuid <uuid-module>` module. |
| 239 | +This improves interoperability with third-party data sources whose data is processed by Tarantool. |
| 240 | + |
| 241 | + |
| 242 | + |
| 243 | +.. _3-2-administration-and-maintenance: |
| 244 | + |
| 245 | +Administration and maintenance |
| 246 | +------------------------------ |
| 247 | + |
| 248 | +.. _3-2-admin-console: |
| 249 | + |
| 250 | +Interactive console |
| 251 | +~~~~~~~~~~~~~~~~~~~ |
| 252 | + |
| 253 | +With this release, both the :ref:`Tarantool <interactive_console>` and :ref:`tt <tt-interactive-console>` interactive consoles automatically add the most often used built-in modules into the environment. |
| 254 | +This means that you can start using a module without loading it with the ``require`` directive. |
| 255 | + |
| 256 | +In the interactive session below, the :ref:`config <config-module>` module is used to get the instance's configuration state right after connecting to this instance: |
| 257 | + |
| 258 | +.. code-block:: tarantoolsession |
| 259 | +
|
| 260 | + application:instance001> config:info('v2') |
| 261 | + --- |
| 262 | + - status: ready |
| 263 | + meta: |
| 264 | + last: &0 [] |
| 265 | + active: *0 |
| 266 | + alerts: [] |
| 267 | + ... |
| 268 | +
|
| 269 | +To enable this new behavior, you need to set the ``console_session_scope_vars`` :ref:`compat <configuration_reference_compat>` option value to ``new``: |
| 270 | + |
| 271 | +.. code-block:: yaml |
| 272 | +
|
| 273 | + compat: |
| 274 | + console_session_scope_vars: 'new' |
| 275 | +
|
| 276 | +
|
| 277 | +
|
| 278 | +.. _3-2-admin-observability: |
| 279 | + |
| 280 | +Observability |
| 281 | +~~~~~~~~~~~~~ |
| 282 | + |
| 283 | +The 3.2 release adds the following improvements related to observability: |
| 284 | + |
| 285 | +- A new :ref:`box.info.config <box_info_config>` field allows you to access an instance's configuration status. |
| 286 | + |
| 287 | +- :ref:`box.info.synchro.queue.term <box_info_synchro>` now includes the ``age`` and ``confirm_lag`` fields: |
| 288 | + |
| 289 | + - ``age`` -- shows how much time the oldest entry in the queue has spent waiting for the quorum. |
| 290 | + - ``confirm_lag`` -- shows how much time the latest successfully confirmed entry has waited for the quorum to gather. |
| 291 | + |
| 292 | +- New :ref:`metrics <metrics-reference>` are added: |
| 293 | + |
| 294 | + - ``tnt_memtx_tuples_data_total`` |
| 295 | + - ``tnt_memtx_tuples_data_read_view`` |
| 296 | + - ``tnt_memtx_tuples_data_garbage`` |
| 297 | + - ``tnt_memtx_index_total`` |
| 298 | + - ``tnt_memtx_index_read_view`` |
| 299 | + - ``tnt_vinyl_memory_tuple`` |
| 300 | + - ``tnt_config_alerts`` |
| 301 | + - ``tnt_config_status`` |
0 commit comments