From fcfe80c5463bcb181b4093a004e927434f591073 Mon Sep 17 00:00:00 2001 From: Evgeniy Osintsev Date: Wed, 14 Jul 2021 15:24:00 +0400 Subject: [PATCH 01/10] Restructure Storage engines chapter. Add initial structure and topics in brief for memtx Part of #1632 --- doc/book/box/engines/index.rst | 25 ++++++++---- doc/book/box/engines/memtx.rst | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 doc/book/box/engines/memtx.rst diff --git a/doc/book/box/engines/index.rst b/doc/book/box/engines/index.rst index c9304407b1..5883816897 100644 --- a/doc/book/box/engines/index.rst +++ b/doc/book/box/engines/index.rst @@ -1,16 +1,15 @@ .. _engines-chapter: -******************************************************************************** Storage engines -******************************************************************************** +=============== A storage engine is a set of very-low-level routines which actually store and retrieve tuple values. Tarantool offers a choice of two storage engines: -* memtx (the in-memory storage engine) is the default and was the first to +* doc:`memtx ` (the in-memory storage engine) is the default and was the first to arrive. -* vinyl (the on-disk storage engine) is a working key-value engine and will +* doc:`vinyl ` (the on-disk storage engine) is a working key-value engine and will especially appeal to users who like to see data go directly to disk, so that recovery time might be shorter and database size might be larger. @@ -18,6 +17,19 @@ retrieve tuple values. Tarantool offers a choice of two storage engines: with memtx. Where that is the case, the relevant description in this manual contains a note beginning with the words "Note re storage engine". +[TODO] +Below you can find comparing of the two engines in brief / in a nutshell. +All the technical details on how each engine works you can find in the dedicated +sections: + +.. toctree:: + :maxdepth: 2 + + memtx + vinyl + + +[TODO] -- re-write or move to the vinyl page Further in this section we discuss the details of storing data using the vinyl storage engine. @@ -30,9 +42,8 @@ when creating a space, for example: .. _vinyl_diff: -================================================================================ Differences between memtx and vinyl storage engines -================================================================================ +--------------------------------------------------- The primary difference between memtx and vinyl is that memtx is an "in-memory" engine while vinyl is an "on-disk" engine. An in-memory storage engine is @@ -70,4 +81,4 @@ memory is not a realistic option. | | transaction is committed to WAL | get() or pairs() | +---------------------------------------------+------------------------------------------------------+------------------------------------------------------+ -.. include:: vinyl.rst + diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst new file mode 100644 index 0000000000..6aae6b4d0a --- /dev/null +++ b/doc/book/box/engines/memtx.rst @@ -0,0 +1,69 @@ +.. _engines-memtx: + +Storing data with memtx +======================= + +.. contents:: + :local: + :depth: 1 + +[TODO] -- below is the skeleton of the section + +Main big topics to be covered: + +* memory model (allocation -- in one thread; the small memory allocator; verify with Lyapunov) +* persisting data on disk (xlog, snapshots) -- and link box ref. about these things +* accessing the data (indexes - as a minimal decription explain TREE index) -- and link to https://www.tarantool.io/en/doc/latest/book/box/indexes/ and box ref. about indexes + + +Draft storyline: + +* All data is in memory +* Access to data is from one thread +* Changes are being written in the Write Ahead Log (WAL) +* Indexes are build to access the data +* Data snapshots are taken periodically +* WAL is replicated + +TBD: +- briefly about 3 threads -- link to https://www.tarantool.io/en/doc/latest/book/box/atomic/ +- about Arena -- from Mons's presentation and link to box reference where schemas on mem. distribution +- about Actor model? +- how detailed about allocations? to describe the entire hierarchy: slab_arena, slab_cache, mempool, small alloc., ibuf/obuf/region, matras? +- hash and hash table Light -- do we need this here and how detailed? +- tree -- how detailed? +- what about fibers and cooperative multitasking? +- something else? + + +Memory model +------------ + +- all data in memory +- 3 threads but only the transaction processor thread can access the database, and there is only one transaction processor thread for each Tarantool instance +- what happens in TX thread -- more detailed about **Arena** structure +- hierarchy of allocators? + + +Persisting data +--------------- + +- changes are being written to WAL +- WAL is on disc -- persistence +- DB snapshot is taken periodically -- persistence + + +Accessing data +-------------- + +- indexes are build to access the data +- type of indexes -- link to the Indexes chapter +- details about our btree?? +- links to the necessary pages to get details about accessing the data +- hashes ?? + +?Replication +------------ + +- WAL is replicated -- you can build a distributed application based on Tarantool +- references to the relevant doc sections? From 4f0354aedc25a20ae3c03429e02c7bbc030354ba Mon Sep 17 00:00:00 2001 From: Evgeniy Osintsev Date: Thu, 15 Jul 2021 22:11:25 +0400 Subject: [PATCH 02/10] Update description and doc structure Part of #1632 --- doc/book/box/engines/index.rst | 33 +- doc/book/box/engines/memtx.rst | 150 +++++-- doc/book/box/engines/memtx/arena.svg | 349 +++++++++++++++++ .../box/engines/memtx/fibers-channels.svg | 360 +++++++++++++++++ doc/book/box/engines/memtx/iproto.svg | 360 +++++++++++++++++ doc/book/box/engines/memtx/replica-xlogs.svg | 366 +++++++++++++++++ doc/book/box/engines/memtx/snapshot03.svg | 370 ++++++++++++++++++ doc/book/box/engines/memtx/spaces_indexes.svg | 349 +++++++++++++++++ doc/book/box/engines/memtx/wal.svg | 363 +++++++++++++++++ 9 files changed, 2643 insertions(+), 57 deletions(-) create mode 100644 doc/book/box/engines/memtx/arena.svg create mode 100644 doc/book/box/engines/memtx/fibers-channels.svg create mode 100644 doc/book/box/engines/memtx/iproto.svg create mode 100644 doc/book/box/engines/memtx/replica-xlogs.svg create mode 100644 doc/book/box/engines/memtx/snapshot03.svg create mode 100644 doc/book/box/engines/memtx/spaces_indexes.svg create mode 100644 doc/book/box/engines/memtx/wal.svg diff --git a/doc/book/box/engines/index.rst b/doc/book/box/engines/index.rst index 5883816897..ecbe529a59 100644 --- a/doc/book/box/engines/index.rst +++ b/doc/book/box/engines/index.rst @@ -6,16 +6,16 @@ Storage engines A storage engine is a set of very-low-level routines which actually store and retrieve tuple values. Tarantool offers a choice of two storage engines: -* doc:`memtx ` (the in-memory storage engine) is the default and was the first to - arrive. +* :doc:`memtx ` is the in-memory storage engine used by default. -* doc:`vinyl ` (the on-disk storage engine) is a working key-value engine and will - especially appeal to users who like to see data go directly to disk, so that - recovery time might be shorter and database size might be larger. +* :doc:`vinyl ` is the on-disk storage engine. It is a working key-value engine + and especially appeals to users who like to see data go directly to disk so that + the recovery time can be shorter and database size can be larger. - On the other hand, vinyl lacks some functions and options that are available - with memtx. Where that is the case, the relevant description in this manual - contains a note beginning with the words "Note re storage engine". +[TODO] to remove or move +On the other hand, vinyl lacks some functions and options that are available +with memtx. Where that is the case, the relevant description in this manual +contains a note beginning with the words "Note re storage engine". [TODO] Below you can find comparing of the two engines in brief / in a nutshell. @@ -23,11 +23,10 @@ All the technical details on how each engine works you can find in the dedicated sections: .. toctree:: - :maxdepth: 2 - - memtx - vinyl + :maxdepth: 1 + memtx + vinyl [TODO] -- re-write or move to the vinyl page Further in this section we discuss the details of storing data using @@ -45,11 +44,11 @@ when creating a space, for example: Differences between memtx and vinyl storage engines --------------------------------------------------- -The primary difference between memtx and vinyl is that memtx is an "in-memory" -engine while vinyl is an "on-disk" engine. An in-memory storage engine is +The primary difference between memtx and vinyl is that memtx is an in-memory +engine while vinyl is an on-disk engine. An in-memory storage engine is generally faster (each query is usually run under 1 ms), and the memtx engine -is justifiably the default for Tarantool, but on-disk engine such as vinyl is -preferable when the database is larger than the available memory and adding more +is justifiably the default for Tarantool. But on-disk engine such as vinyl is +preferable when the database is larger than the available memory, and adding more memory is not a realistic option. .. container:: table @@ -80,5 +79,3 @@ memory is not a realistic option. | yield | Does not yield on the select requests unless the | Yields on the select requests or on its equivalents: | | | transaction is committed to WAL | get() or pairs() | +---------------------------------------------+------------------------------------------------------+------------------------------------------------------+ - - diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst index 6aae6b4d0a..6b59ade4c6 100644 --- a/doc/book/box/engines/memtx.rst +++ b/doc/book/box/engines/memtx.rst @@ -3,55 +3,105 @@ Storing data with memtx ======================= -.. contents:: - :local: - :depth: 1 +``memtx`` is the Tarantool’s in-memory storage engine. It keeps all the data in random-access memory (RAM). +It also keeps persistent copies of the data in non-volatile storage, such as disk, when users request snapshots. +If an instance of the server stops and the random-access memory is lost, then restarts, +it reads the latest snapshot and then replays the transactions that are in the log, and therefore no data is lost. -[TODO] -- below is the skeleton of the section +?TOC here? -Main big topics to be covered: +.. contents:: + :local: + :depth: 1 -* memory model (allocation -- in one thread; the small memory allocator; verify with Lyapunov) -* persisting data on disk (xlog, snapshots) -- and link box ref. about these things -* accessing the data (indexes - as a minimal decription explain TREE index) -- and link to https://www.tarantool.io/en/doc/latest/book/box/indexes/ and box ref. about indexes +//TBD -- put this at the end as a summary points. +In a nutshell, the main key points describing the principles of how memtx works are: +* All data is in memory (RAM). +* Access to data is from one thread. +* Data change requests are written in the write-ahead log (WAL). +* Data snapshots are taken periodically. +* Indexes are build to access the data. +* WAL can be replicated. -Draft storyline: +.. _memtx-memory: -* All data is in memory -* Access to data is from one thread -* Changes are being written in the Write Ahead Log (WAL) -* Indexes are build to access the data -* Data snapshots are taken periodically -* WAL is replicated +Memory model +------------ -TBD: -- briefly about 3 threads -- link to https://www.tarantool.io/en/doc/latest/book/box/atomic/ -- about Arena -- from Mons's presentation and link to box reference where schemas on mem. distribution -- about Actor model? -- how detailed about allocations? to describe the entire hierarchy: slab_arena, slab_cache, mempool, small alloc., ibuf/obuf/region, matras? -- hash and hash table Light -- do we need this here and how detailed? -- tree -- how detailed? -- what about fibers and cooperative multitasking? -- something else? +The ``memtx`` engine keeps all the data in RAM, and therefore has very low read latency. +There is a fixed number of independent :ref:`execution threads `. +The threads do not share state. Instead they exchange data using low-overhead message queues. +While this approach limits the number of cores that the instance uses, +it removes competition for the memory bus and ensures peak scalability of memory access and network throughput. -Memory model ------------- +Only one thread, namely, the **transaction processor thread** (further, **TX thread**) +can access the database, and there is only one TX thread for each Tarantool instance. +Within the TX thread there is a memory area allocated for Tarantool to store data. It's called **Arena**. + +.. image:: memtx/arena.svg + +Data is stored in :term:`spaces `. Spaces contain database records—:term:`tuples `. +To access and manipulate the data stored in spaces and tuples, Tarantool builds :doc:`indexes `. + +All that are managed by special memory allocators working within the Arena. +The slab allocator is the main allocator used to store tuples. +Tarantool has a built-in module called ``box.slab`` which provides the slab allocator statistics +that can be used to monitor the total memory usage and memory fragmentation. +For details, see the ``box.slab`` module :doc:`reference `. + +.. image:: memtx/spaces_indexes.svg + +Also inside the TX thread, there is an event loop. Within the event loop, there are a number of :ref:`fibers `. +Fibers are cooperative primitives that allows interaction with spaces, that is, reading and writting the data. +Fibers can interact with the event loop and between each other directly or by using special primitives called channels. +Due to the usage of fibers and cooperative multitasking, the ``memtx`` engine is lock-free in typical situations. + +.. image:: memtx/fibers-channels.svg + +To interact with external users, there is a separate :ref:`network thread ` also called the **IPROTO thread**. +The IPROTO thread receives a request for the network, parses and checks the statement, +and transforms it into a special structure—a message containing an executable statement and its options. +Then the IPROTO thread ships this message to the TX thread and runs the user's request in a separate fiber. + +.. image:: memtx/iproto.svg + +.. _memtx-persist: + +Data persistence +---------------- + +To ensure :ref:`data persistence `, Tarantool does two things. -- all data in memory -- 3 threads but only the transaction processor thread can access the database, and there is only one transaction processor thread for each Tarantool instance -- what happens in TX thread -- more detailed about **Arena** structure -- hierarchy of allocators? +* After executing a data change request in memory, Tarantool writes each such request to the :ref:`write-ahead log (WAL) ` files (``.xlog``) + that are stored on disk. Tarantool does this via a separate thread called the **WAL thread**. +.. image:: memtx/wal.svg -Persisting data ---------------- +* Tarantool periodically takes the entire :doc:`database snapshot ` and saves it on disk. + It is necessary for accelerating restart because when there are too many WAL files, it can be difficult for Tarantool to restart quickly. + To save a snapshot, there is a special fiber called the **snapshot daemon**. + It reads the consistent content of the entire Arena and writes it on disk into a snapshot file (``.snap``). + Due of the cooperative multitasking, Tarantool cannot write directly on disk because it is a locking operation. + That is why Tarantool interacts with disk via a separate pool of threads from the :doc:`fio ` library. -- changes are being written to WAL -- WAL is on disc -- persistence -- DB snapshot is taken periodically -- persistence +.. image:: memtx/snapshot03.svg +So, even in emergency situations such as an outage or a Tarantool instance crash, +when the in-memory database is lost, all the data can be restored fully during Tarantool restart. + +What happens during the restart: + +1. Tarantool finds the latest snapshot file and reads it. +2. Tarantool finds all the WAL files created after that snapshot and reads them as well. +3. When the snapshot and WAL files have been read, there is a fully recovered in-memory data set + corresponding to the state when the Tarantool instance stopped. +4. While reading the snapshot and WAL files, Tarantool is building the primary indexes. +5. When all the data is in memory again, Tarantool is building the secondary indexes. +6. Tarantool runs an application. + +.. _memtx-indexes: Accessing data -------------- @@ -62,8 +112,30 @@ Accessing data - links to the necessary pages to get details about accessing the data - hashes ?? -?Replication ------------- +https://www.tarantool.io/en/doc/latest/book/box/indexes/ +https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/create_index/ + + + +Replicating data +---------------- + +Replication allows multiple Tarantool instances to work on copies of the same database. +The copies are kept in sync because each instance can communicate its changes to all the other instances. +It is implemented via WAL replication. + +//TBD +To send data to a replica, Tarantool runs another thread called **relay**. +Its purpose is to read the WAL files and send them to replicas. +On a replica, the fiber called **applier** is run. It receives the //information about the changes from a remote node and applies these changes to the replica's Arena. +And all these changes are being written to WAL files via the replica's WAL thread as if the changes are done locally. + +.. image:: memtx/replica-xlogs.svg + +For more information on replication, refer to the :doc:`corresponding chapter `. + + +//TBD Although this subject matter is not related directly to the memtx engine as such, it helps understand the entire picture how Tarantool works. +Зная, как это все устроено, вы можете понимать и предсказывать поведение того или иного участка Tarantool, и понимать, что с этим делать. + -- WAL is replicated -- you can build a distributed application based on Tarantool -- references to the relevant doc sections? diff --git a/doc/book/box/engines/memtx/arena.svg b/doc/book/box/engines/memtx/arena.svg new file mode 100644 index 0000000000..28423aed63 --- /dev/null +++ b/doc/book/box/engines/memtx/arena.svg @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + fio + + + + + + + + + + snapshot + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + + + + + + + diff --git a/doc/book/box/engines/memtx/fibers-channels.svg b/doc/book/box/engines/memtx/fibers-channels.svg new file mode 100644 index 0000000000..3dc76102d7 --- /dev/null +++ b/doc/book/box/engines/memtx/fibers-channels.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + fio + + + + + + + + + + snapshot + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + + + + + + + diff --git a/doc/book/box/engines/memtx/iproto.svg b/doc/book/box/engines/memtx/iproto.svg new file mode 100644 index 0000000000..0564ceaa1a --- /dev/null +++ b/doc/book/box/engines/memtx/iproto.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + fio + + + + + + + + + + snapshot + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + + + + + + + diff --git a/doc/book/box/engines/memtx/replica-xlogs.svg b/doc/book/box/engines/memtx/replica-xlogs.svg new file mode 100644 index 0000000000..de3dbf98bd --- /dev/null +++ b/doc/book/box/engines/memtx/replica-xlogs.svg @@ -0,0 +1,366 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snapshot + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + + fio + + + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + diff --git a/doc/book/box/engines/memtx/snapshot03.svg b/doc/book/box/engines/memtx/snapshot03.svg new file mode 100644 index 0000000000..2230404040 --- /dev/null +++ b/doc/book/box/engines/memtx/snapshot03.svg @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snapshot + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + + fio + + + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + + + + + + + diff --git a/doc/book/box/engines/memtx/spaces_indexes.svg b/doc/book/box/engines/memtx/spaces_indexes.svg new file mode 100644 index 0000000000..c488bcb6f6 --- /dev/null +++ b/doc/book/box/engines/memtx/spaces_indexes.svg @@ -0,0 +1,349 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + fio + + + + + + + + + + snapshot + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + + + + + + + diff --git a/doc/book/box/engines/memtx/wal.svg b/doc/book/box/engines/memtx/wal.svg new file mode 100644 index 0000000000..655914b6ac --- /dev/null +++ b/doc/book/box/engines/memtx/wal.svg @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + TX + + + + + + Arena + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IPROTO + + + + + + + + + + + + EV + + + + + + + f + + + + + + f + + + + + + f + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + snap + + + daemon + + + + + + + + + + fio + + + + + + + + + + snapshot + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + RELAY + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + applier + + + + + + + + + IPROTO + + + + + + + + + + WAL + + + + + + + xlog + + + + + + + xlog + + + + + + + + + + + + + + + + + + + From c71155758b53b1ea0a14d312b96c88f0d867bc04 Mon Sep 17 00:00:00 2001 From: Evgeniy Osintsev Date: Thu, 29 Jul 2021 22:49:33 +0400 Subject: [PATCH 03/10] Return excluded vynil.rst back Part of #1632 --- conf.py | 1 - 1 file changed, 1 deletion(-) diff --git a/conf.py b/conf.py index e744a54436..4267a42585 100644 --- a/conf.py +++ b/conf.py @@ -62,7 +62,6 @@ 'book/connectors/__*', 'book/replication/*_1.rst', 'book/replication/*_2.rst', - 'book/box/engines/vinyl.rst', 'getting_started/using_package_manager.rst', 'getting_started/using_docker.rst', 'dev_guide/box_protocol.rst', From 07da4429a33223778e4bb0700ef464c5fce01aab Mon Sep 17 00:00:00 2001 From: Evgeniy Osintsev Date: Fri, 30 Jul 2021 11:22:42 +0400 Subject: [PATCH 04/10] Update memtx overview page and storage enging chapter index page Part of #1632 --- doc/book/box/engines/index.rst | 32 +-- doc/book/box/engines/memtx.rst | 67 +++-- doc/book/box/engines/memtx/arena.svg | 349 -------------------------- doc/book/box/engines/memtx/arena2.svg | 3 + doc/book/box/indexes.rst | 2 + 5 files changed, 42 insertions(+), 411 deletions(-) delete mode 100644 doc/book/box/engines/memtx/arena.svg create mode 100644 doc/book/box/engines/memtx/arena2.svg diff --git a/doc/book/box/engines/index.rst b/doc/book/box/engines/index.rst index ecbe529a59..3c38c8ef5d 100644 --- a/doc/book/box/engines/index.rst +++ b/doc/book/box/engines/index.rst @@ -3,23 +3,14 @@ Storage engines =============== -A storage engine is a set of very-low-level routines which actually store and +A storage engine is a set of low-level routines which actually store and retrieve tuple values. Tarantool offers a choice of two storage engines: * :doc:`memtx ` is the in-memory storage engine used by default. +* :doc:`vinyl ` is the on-disk storage engine. -* :doc:`vinyl ` is the on-disk storage engine. It is a working key-value engine - and especially appeals to users who like to see data go directly to disk so that - the recovery time can be shorter and database size can be larger. - -[TODO] to remove or move -On the other hand, vinyl lacks some functions and options that are available -with memtx. Where that is the case, the relevant description in this manual -contains a note beginning with the words "Note re storage engine". - -[TODO] -Below you can find comparing of the two engines in brief / in a nutshell. -All the technical details on how each engine works you can find in the dedicated +Below you can find comparing of the two engines in brief. +All the details on how each engine works you can find in the dedicated sections: .. toctree:: @@ -28,21 +19,10 @@ sections: memtx vinyl -[TODO] -- re-write or move to the vinyl page -Further in this section we discuss the details of storing data using -the vinyl storage engine. - -To specify that the engine should be vinyl, add the clause ``engine = 'vinyl'`` -when creating a space, for example: - -.. code-block:: lua - - space = box.schema.space.create('name', {engine='vinyl'}) - .. _vinyl_diff: -Differences between memtx and vinyl storage engines ---------------------------------------------------- +Difference between memtx and vinyl storage engines +-------------------------------------------------- The primary difference between memtx and vinyl is that memtx is an in-memory engine while vinyl is an on-disk engine. An in-memory storage engine is diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst index 6b59ade4c6..d676f8ff05 100644 --- a/doc/book/box/engines/memtx.rst +++ b/doc/book/box/engines/memtx.rst @@ -3,49 +3,35 @@ Storing data with memtx ======================= -``memtx`` is the Tarantool’s in-memory storage engine. It keeps all the data in random-access memory (RAM). -It also keeps persistent copies of the data in non-volatile storage, such as disk, when users request snapshots. -If an instance of the server stops and the random-access memory is lost, then restarts, -it reads the latest snapshot and then replays the transactions that are in the log, and therefore no data is lost. - -?TOC here? +This chapter gives an overview of the ``memtx`` in-memory storage engine used in Tarantool by default. +The following topics are described in brief with the references to the chapters explaining the subject matter in details. .. contents:: :local: :depth: 1 -//TBD -- put this at the end as a summary points. -In a nutshell, the main key points describing the principles of how memtx works are: - -* All data is in memory (RAM). -* Access to data is from one thread. -* Data change requests are written in the write-ahead log (WAL). -* Data snapshots are taken periodically. -* Indexes are build to access the data. -* WAL can be replicated. - .. _memtx-memory: Memory model ------------ -The ``memtx`` engine keeps all the data in RAM, and therefore has very low read latency. +The ``memtx`` storage engine keeps all data in random-access memory (RAM), and therefore has very low read latency. There is a fixed number of independent :ref:`execution threads `. -The threads do not share state. Instead they exchange data using low-overhead message queues. +The threads don't share state. Instead they exchange data using low-overhead message queues. While this approach limits the number of cores that the instance uses, it removes competition for the memory bus and ensures peak scalability of memory access and network throughput. Only one thread, namely, the **transaction processor thread** (further, **TX thread**) can access the database, and there is only one TX thread for each Tarantool instance. -Within the TX thread there is a memory area allocated for Tarantool to store data. It's called **Arena**. +Within the TX thread, there is a memory area allocated for Tarantool to store data. It's called **Arena**. -.. image:: memtx/arena.svg +.. image:: memtx/arena2.svg Data is stored in :term:`spaces `. Spaces contain database records—:term:`tuples `. To access and manipulate the data stored in spaces and tuples, Tarantool builds :doc:`indexes `. -All that are managed by special memory allocators working within the Arena. +All that are managed by special `memory allocators `__ working within the Arena. The slab allocator is the main allocator used to store tuples. Tarantool has a built-in module called ``box.slab`` which provides the slab allocator statistics that can be used to monitor the total memory usage and memory fragmentation. @@ -56,12 +42,12 @@ For details, see the ``box.slab`` module :doc:`reference `. Fibers are cooperative primitives that allows interaction with spaces, that is, reading and writting the data. Fibers can interact with the event loop and between each other directly or by using special primitives called channels. -Due to the usage of fibers and cooperative multitasking, the ``memtx`` engine is lock-free in typical situations. +Due to the usage of fibers and :ref:`cooperative multitasking `, the ``memtx`` engine is lock-free in typical situations. .. image:: memtx/fibers-channels.svg To interact with external users, there is a separate :ref:`network thread ` also called the **IPROTO thread**. -The IPROTO thread receives a request for the network, parses and checks the statement, +The IPROTO thread receives a request from the network, parses and checks the statement, and transforms it into a special structure—a message containing an executable statement and its options. Then the IPROTO thread ships this message to the TX thread and runs the user's request in a separate fiber. @@ -74,7 +60,7 @@ Data persistence To ensure :ref:`data persistence `, Tarantool does two things. -* After executing a data change request in memory, Tarantool writes each such request to the :ref:`write-ahead log (WAL) ` files (``.xlog``) +* After executing data change requests in memory, Tarantool writes each such request to the :ref:`write-ahead log (WAL) ` files (``.xlog``) that are stored on disk. Tarantool does this via a separate thread called the **WAL thread**. .. image:: memtx/wal.svg @@ -106,16 +92,18 @@ What happens during the restart: Accessing data -------------- -- indexes are build to access the data -- type of indexes -- link to the Indexes chapter -- details about our btree?? -- links to the necessary pages to get details about accessing the data -- hashes ?? +To access and manipulate the data stored in memory, Tarantool builds indexes. +Indexes are also stored in memory within the Arena. + +Tarantool supports a number of :ref:`index types ` intended for different usage scenarios. +The possible types are TREE, HASH, BITSET, and RTREE. -https://www.tarantool.io/en/doc/latest/book/box/indexes/ -https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/create_index/ +Select query are possible against secondary index keys as well as primary keys. +Indexes can have multi-part keys. +For detailed information about indexes, refer to the :doc:`/book/box/indexes` page. +.. _memtx-replication: Replicating data ---------------- @@ -124,18 +112,25 @@ Replication allows multiple Tarantool instances to work on copies of the same da The copies are kept in sync because each instance can communicate its changes to all the other instances. It is implemented via WAL replication. -//TBD To send data to a replica, Tarantool runs another thread called **relay**. Its purpose is to read the WAL files and send them to replicas. -On a replica, the fiber called **applier** is run. It receives the //information about the changes from a remote node and applies these changes to the replica's Arena. -And all these changes are being written to WAL files via the replica's WAL thread as if the changes are done locally. +On a replica, the fiber called **applier** is run. It receives the changes from a remote node and applies them to the replica's Arena. +All the changes are being written to WAL files via the replica's WAL thread as if they are done locally. .. image:: memtx/replica-xlogs.svg For more information on replication, refer to the :doc:`corresponding chapter `. +.. _memtx-summary: -//TBD Although this subject matter is not related directly to the memtx engine as such, it helps understand the entire picture how Tarantool works. -Зная, как это все устроено, вы можете понимать и предсказывать поведение того или иного участка Tarantool, и понимать, что с этим делать. +Summary +------- +The main key points describing how the in-memory storage engine works can be summarized in the following way: +* All data is in RAM. +* Access to data is from one thread. +* Tarantool writes all data change requests in WAL. +* Data snapshots are taken periodically. +* Indexes are build to access the data. +* WAL can be replicated. diff --git a/doc/book/box/engines/memtx/arena.svg b/doc/book/box/engines/memtx/arena.svg deleted file mode 100644 index 28423aed63..0000000000 --- a/doc/book/box/engines/memtx/arena.svg +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - - - - - - - - - - TX - - - - - - Arena - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IPROTO - - - - - - - - - - - - EV - - - - - - f - - - - - - f - - - - - - f - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - snap - - - daemon - - - - - - - - - - fio - - - - - - - - - - snapshot - - - - - - - - - - WAL - - - - - - - xlog - - - - - - - xlog - - - - - - - - - - - - - RELAY - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - applier - - - - - - - - - IPROTO - - - - - - - - - - WAL - - - - - - - xlog - - - - - - - xlog - - - - - - - - - - - - - - - - - - - diff --git a/doc/book/box/engines/memtx/arena2.svg b/doc/book/box/engines/memtx/arena2.svg new file mode 100644 index 0000000000..ebca26d03b --- /dev/null +++ b/doc/book/box/engines/memtx/arena2.svg @@ -0,0 +1,3 @@ + + +T
TX
thread
TX...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/doc/book/box/indexes.rst b/doc/book/box/indexes.rst index d2654358b7..1b27a3dd9f 100644 --- a/doc/book/box/indexes.rst +++ b/doc/book/box/indexes.rst @@ -251,6 +251,8 @@ then it also changes the index keys defined for the tuple. restrictions. Read more about index operations in reference for :doc:`box.index submodule `. +.. _index-types: + -------------------------------------------------------------------------------- Index types -------------------------------------------------------------------------------- From 13ff6402e977de63348688c0f66cfecc68aa77f3 Mon Sep 17 00:00:00 2001 From: Evgeniy Osintsev Date: Fri, 30 Jul 2021 11:42:59 +0400 Subject: [PATCH 05/10] Correct content after review Part of #1632 --- doc/book/box/engines/index.rst | 2 +- doc/book/box/engines/memtx.rst | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/book/box/engines/index.rst b/doc/book/box/engines/index.rst index 3c38c8ef5d..c14e047f0a 100644 --- a/doc/book/box/engines/index.rst +++ b/doc/book/box/engines/index.rst @@ -4,7 +4,7 @@ Storage engines =============== A storage engine is a set of low-level routines which actually store and -retrieve tuple values. Tarantool offers a choice of two storage engines: +retrieve :term:`tuple ` values. Tarantool offers a choice of two storage engines: * :doc:`memtx ` is the in-memory storage engine used by default. * :doc:`vinyl ` is the on-disk storage engine. diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst index d676f8ff05..cbd2581aa8 100644 --- a/doc/book/box/engines/memtx.rst +++ b/doc/book/box/engines/memtx.rst @@ -67,6 +67,7 @@ To ensure :ref:`data persistence `, Tarantool does two th * Tarantool periodically takes the entire :doc:`database snapshot ` and saves it on disk. It is necessary for accelerating restart because when there are too many WAL files, it can be difficult for Tarantool to restart quickly. + To save a snapshot, there is a special fiber called the **snapshot daemon**. It reads the consistent content of the entire Arena and writes it on disk into a snapshot file (``.snap``). Due of the cooperative multitasking, Tarantool cannot write directly on disk because it is a locking operation. @@ -124,7 +125,7 @@ For more information on replication, refer to the :doc:`corresponding chapter Date: Tue, 17 Aug 2021 11:07:55 +0300 Subject: [PATCH 06/10] Corrections after review Part of #1632 --- doc/book/box/engines/memtx.rst | 37 ++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst index cbd2581aa8..dbb0fcf1c8 100644 --- a/doc/book/box/engines/memtx.rst +++ b/doc/book/box/engines/memtx.rst @@ -4,7 +4,7 @@ Storing data with memtx ======================= This chapter gives an overview of the ``memtx`` in-memory storage engine used in Tarantool by default. -The following topics are described in brief with the references to the chapters explaining the subject matter in details. +The following topics are described with the references to the other chapters explaining the subject matter in details. .. contents:: :local: @@ -17,6 +17,14 @@ Memory model The ``memtx`` storage engine keeps all data in random-access memory (RAM), and therefore has very low read latency. +The obvious question that can be asked here is the following: +if all the data is stored in memory, how can you prevent the data loss in case of emergency such as outage or Tarantool instance failure? + +First of all, Tarantool persists all data changes by writing them to the write-ahead log (WAL) that is stored on disk. +Read more about that in the :ref:`memtx-persist` section. +In case of a distributed application, there is an option of synchronous replication that ensures keeping the data consistent on a quorum of replicas. +Though it is not directly a memory model topic, it is a part of the answer regarding data safety. Read more in the :ref:`memtx-replication` section. + There is a fixed number of independent :ref:`execution threads `. The threads don't share state. Instead they exchange data using low-overhead message queues. While this approach limits the number of cores that the instance uses, @@ -24,6 +32,7 @@ it removes competition for the memory bus and ensures peak scalability of memory Only one thread, namely, the **transaction processor thread** (further, **TX thread**) can access the database, and there is only one TX thread for each Tarantool instance. + Within the TX thread, there is a memory area allocated for Tarantool to store data. It's called **Arena**. .. image:: memtx/arena2.svg @@ -31,7 +40,7 @@ Within the TX thread, there is a memory area allocated for Tarantool to store da Data is stored in :term:`spaces `. Spaces contain database records—:term:`tuples `. To access and manipulate the data stored in spaces and tuples, Tarantool builds :doc:`indexes `. -All that are managed by special `memory allocators `__ working within the Arena. +All that is managed by special `memory allocators `__ working within the Arena. The slab allocator is the main allocator used to store tuples. Tarantool has a built-in module called ``box.slab`` which provides the slab allocator statistics that can be used to monitor the total memory usage and memory fragmentation. @@ -46,10 +55,10 @@ Due to the usage of fibers and :ref:`cooperative multitasking ` also called the **IPROTO thread**. -The IPROTO thread receives a request from the network, parses and checks the statement, +To interact with external users, there is a separate :ref:`network thread ` also called the **iproto thread**. +The iproto thread receives a request from the network, parses and checks the statement, and transforms it into a special structure—a message containing an executable statement and its options. -Then the IPROTO thread ships this message to the TX thread and runs the user's request in a separate fiber. +Then the iproto thread ships this message to the TX thread and runs the user's request in a separate fiber. .. image:: memtx/iproto.svg @@ -66,7 +75,7 @@ To ensure :ref:`data persistence `, Tarantool does two th .. image:: memtx/wal.svg * Tarantool periodically takes the entire :doc:`database snapshot ` and saves it on disk. - It is necessary for accelerating restart because when there are too many WAL files, it can be difficult for Tarantool to restart quickly. + It is necessary for accelerating instance's restart because when there are too many WAL files, it can be difficult for Tarantool to restart quickly. To save a snapshot, there is a special fiber called the **snapshot daemon**. It reads the consistent content of the entire Arena and writes it on disk into a snapshot file (``.snap``). @@ -75,8 +84,8 @@ To ensure :ref:`data persistence `, Tarantool does two th .. image:: memtx/snapshot03.svg -So, even in emergency situations such as an outage or a Tarantool instance crash, -when the in-memory database is lost, all the data can be restored fully during Tarantool restart. +So, even in emergency situations such as an outage or a Tarantool instance failure, +when the in-memory database is lost, the data can be restored fully during Tarantool restart. What happens during the restart: @@ -109,6 +118,10 @@ For detailed information about indexes, refer to the :doc:`/book/box/indexes` pa Replicating data ---------------- +Although this topic is not directly related to ``memtx`` engine, it completes the overall picture of how Tarantool works +if you have a distributed application. Besides, replication of data means replicating WAL that ensures data persistence. +So, it is important to understand how this functionality works as well. + Replication allows multiple Tarantool instances to work on copies of the same database. The copies are kept in sync because each instance can communicate its changes to all the other instances. It is implemented via WAL replication. @@ -120,6 +133,14 @@ All the changes are being written to WAL files via the replica's WAL thread as i .. image:: memtx/replica-xlogs.svg +By default, :ref:`replication ` in Tarantool is asynchronous: if a transaction +is committed locally on a master node, it does not mean it is replicated onto any +replicas. + +:ref:`Synchronous replication ` exists to solve this problem. Synchronous transactions +are not considered committed and are not responded to a client until they are +replicated onto some number of replicas. + For more information on replication, refer to the :doc:`corresponding chapter `. .. _memtx-summary: From ee7c916c95ddd12541f990f7f6eee6c44e7de674 Mon Sep 17 00:00:00 2001 From: Patience Daur <40490252+patiencedaur@users.noreply.github.com> Date: Fri, 6 Aug 2021 14:15:05 +0300 Subject: [PATCH 07/10] Update doc/book/box/engines/memtx.rst --- doc/book/box/engines/memtx.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst index dbb0fcf1c8..99dfd36c83 100644 --- a/doc/book/box/engines/memtx.rst +++ b/doc/book/box/engines/memtx.rst @@ -95,7 +95,7 @@ What happens during the restart: corresponding to the state when the Tarantool instance stopped. 4. While reading the snapshot and WAL files, Tarantool is building the primary indexes. 5. When all the data is in memory again, Tarantool is building the secondary indexes. -6. Tarantool runs an application. +6. Tarantool runs the application. .. _memtx-indexes: From fcef8100e0c9b822ee414844ef855308792075b3 Mon Sep 17 00:00:00 2001 From: Evgeniy Osintsev Date: Tue, 17 Aug 2021 17:48:49 +0300 Subject: [PATCH 08/10] Corrections after review Part of #1632 --- doc/book/box/engines/memtx.rst | 35 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/doc/book/box/engines/memtx.rst b/doc/book/box/engines/memtx.rst index 99dfd36c83..58b8418485 100644 --- a/doc/book/box/engines/memtx.rst +++ b/doc/book/box/engines/memtx.rst @@ -3,8 +3,17 @@ Storing data with memtx ======================= -This chapter gives an overview of the ``memtx`` in-memory storage engine used in Tarantool by default. -The following topics are described with the references to the other chapters explaining the subject matter in details. +The ``memtx`` storage engine is used in Tarantool by default. It keeps all data in random-access memory (RAM), and therefore has very low read latency. + +The obvious question here is: +if all the data is stored in memory, how can you prevent the data loss in case of emergency such as outage or Tarantool instance failure? + +First of all, Tarantool persists all data changes by writing requests to the write-ahead log (WAL) that is stored on disk. +Read more about that in the :ref:`memtx-persist` section. +In case of a distributed application, there is an option of synchronous replication that ensures keeping the data consistent on a quorum of replicas. +Although replication is not directly a storage engine topic, it is a part of the answer regarding data safety. Read more in the :ref:`memtx-replication` section. + +In this chapter, the following topics are discussed in brief with the references to other chapters that explain the subject matter in details. .. contents:: :local: @@ -15,16 +24,6 @@ The following topics are described with the references to the other chapters exp Memory model ------------ -The ``memtx`` storage engine keeps all data in random-access memory (RAM), and therefore has very low read latency. - -The obvious question that can be asked here is the following: -if all the data is stored in memory, how can you prevent the data loss in case of emergency such as outage or Tarantool instance failure? - -First of all, Tarantool persists all data changes by writing them to the write-ahead log (WAL) that is stored on disk. -Read more about that in the :ref:`memtx-persist` section. -In case of a distributed application, there is an option of synchronous replication that ensures keeping the data consistent on a quorum of replicas. -Though it is not directly a memory model topic, it is a part of the answer regarding data safety. Read more in the :ref:`memtx-replication` section. - There is a fixed number of independent :ref:`execution threads `. The threads don't share state. Instead they exchange data using low-overhead message queues. While this approach limits the number of cores that the instance uses, @@ -32,6 +31,12 @@ it removes competition for the memory bus and ensures peak scalability of memory Only one thread, namely, the **transaction processor thread** (further, **TX thread**) can access the database, and there is only one TX thread for each Tarantool instance. +In this thread, transactions are executed in a strictly consecutive order. +Multi-statement transactions exist to provide isolation: +each transaction sees a consistent database state and commits all its changes atomically. +At commit time, a yield happens and all transaction changes are written to :ref:`WAL ` in a single batch. +In case of errors during transaction execution, a transaction is rolled-back completely. +Read more in the following sections: :ref:`atomic-transactions`, :ref:`atomic-transactional-manager`. Within the TX thread, there is a memory area allocated for Tarantool to store data. It's called **Arena**. @@ -40,7 +45,7 @@ Within the TX thread, there is a memory area allocated for Tarantool to store da Data is stored in :term:`spaces `. Spaces contain database records—:term:`tuples `. To access and manipulate the data stored in spaces and tuples, Tarantool builds :doc:`indexes `. -All that is managed by special `memory allocators `__ working within the Arena. +Special `allocators `__ manage memory allocations for spaces, tuples, and indexes within the Arena. The slab allocator is the main allocator used to store tuples. Tarantool has a built-in module called ``box.slab`` which provides the slab allocator statistics that can be used to monitor the total memory usage and memory fragmentation. @@ -118,9 +123,7 @@ For detailed information about indexes, refer to the :doc:`/book/box/indexes` pa Replicating data ---------------- -Although this topic is not directly related to ``memtx`` engine, it completes the overall picture of how Tarantool works -if you have a distributed application. Besides, replication of data means replicating WAL that ensures data persistence. -So, it is important to understand how this functionality works as well. +Although this topic is not directly related to the ``memtx`` engine, it completes the overall picture of how Tarantool works in case of a distributed application. Replication allows multiple Tarantool instances to work on copies of the same database. The copies are kept in sync because each instance can communicate its changes to all the other instances. From 6cc698ec133f6a8e1b2a7cc270b00262be3f4917 Mon Sep 17 00:00:00 2001 From: ainoneko Date: Sun, 22 Aug 2021 01:57:04 +0000 Subject: [PATCH 09/10] Update translations --- locale/ru/LC_MESSAGES/book/box/data_model.po | 122 +- .../ru/LC_MESSAGES/book/box/engines/index.po | 1561 +---------------- .../ru/LC_MESSAGES/book/box/engines/memtx.po | 372 ++++ .../ru/LC_MESSAGES/book/box/engines/vinyl.po | 1474 ++++++++++++++++ .../contributing/docs/localization.po | 638 +------ .../docs/localization/glossaries.po | 537 ++++++ .../contributing/docs/localization/guide.po | 240 +++ .../docs/localization/locstate.po | 105 ++ .../ru/LC_MESSAGES/contributing/docs/terms.po | 2 +- .../reference/interactive_console.po | 6 +- locale/ru/LC_MESSAGES/release.po | 79 +- locale/ru/LC_MESSAGES/release/2.2.1.po | 146 +- locale/ru/LC_MESSAGES/release/policy.po | 735 ++++++-- 13 files changed, 3528 insertions(+), 2489 deletions(-) create mode 100644 locale/ru/LC_MESSAGES/book/box/engines/memtx.po create mode 100644 locale/ru/LC_MESSAGES/book/box/engines/vinyl.po create mode 100644 locale/ru/LC_MESSAGES/contributing/docs/localization/glossaries.po create mode 100644 locale/ru/LC_MESSAGES/contributing/docs/localization/guide.po create mode 100644 locale/ru/LC_MESSAGES/contributing/docs/localization/locstate.po diff --git a/locale/ru/LC_MESSAGES/book/box/data_model.po b/locale/ru/LC_MESSAGES/book/box/data_model.po index 0231a52506..b9a4ac1a1a 100644 --- a/locale/ru/LC_MESSAGES/book/box/data_model.po +++ b/locale/ru/LC_MESSAGES/book/box/data_model.po @@ -658,6 +658,125 @@ msgstr "" " :ref:`Описание типов индексированных полей " "`." +msgid "Field type name string" +msgstr "Имя типа поля" + +msgid "Field type |br|" +msgstr "Тип поля |br|" + +msgid "Index type" +msgstr "Тип индекса" + +msgid "``'boolean'``" +msgstr "``'boolean'``" + +msgid ":ref:`boolean `" +msgstr ":ref:`boolean `" + +msgid ":ref:`TREE or HASH `" +msgstr ":ref:`TREE или HASH `" + +msgid "``'integer'`` (may also be called ‘int’)" +msgstr "``'integer'`` (также может называться ‘int’)" + +msgid ":ref:`integer `, which may include unsigned values" +msgstr "" +":ref:`integer `, может включать в себя значения unsigned " +"(без знака)" + +msgid "TREE or HASH" +msgstr "TREE или HASH" + +msgid "" +"``'unsigned'`` (may also be called ``'uint'`` or ``'num'``, but ``'num'`` is" +" deprecated)" +msgstr "" +"``'unsigned'`` (без знака, также может называться ``'uint'`` или ``'num'``, " +"но ``'num'`` объявлен устаревшим)" + +msgid ":ref:`unsigned `" +msgstr ":ref:`unsigned `" + +msgid "TREE, BITSET, or HASH" +msgstr "TREE, BITSET или HASH" + +msgid "``'double'``" +msgstr "``'double'``" + +msgid ":ref:`double `" +msgstr ":ref:`double `" + +msgid "``'number'``" +msgstr "``'number'``" + +msgid "" +":ref:`number `, which may include :ref:`integer ` or :ref:`double ` values" +msgstr "" +":ref:`number `, может включать в себя значения типа " +":ref:`integer ` или :ref:`double `" + +msgid "``'decimal'``" +msgstr "``'decimal'``" + +msgid ":ref:`decimal `" +msgstr ":ref:`decimal `" + +msgid "``'string'`` (may also be called ``'str'``)" +msgstr "``'string'`` (строка, также может называться ``'str'``)" + +msgid ":ref:`string `" +msgstr ":ref:`string `" + +msgid "``'varbinary'``" +msgstr "``'varbinary'``" + +msgid ":ref:`varbinary `" +msgstr ":ref:`varbinary `" + +msgid "TREE, HASH, or BITSET (since version 2.7)" +msgstr "TREE, HASH или BITSET (с версии 2.7)" + +msgid "``'uuid'``" +msgstr "``'uuid'``" + +msgid ":ref:`uuid `" +msgstr ":ref:`uuid `" + +msgid "``'array'``" +msgstr "``'array'``" + +msgid ":ref:`array `" +msgstr ":ref:`array `" + +msgid ":ref:`RTREE `" +msgstr ":ref:`RTREE `" + +msgid "``'scalar'``" +msgstr "``'scalar'``" + +msgid "" +"may include :ref:`nil `, :ref:`boolean `, " +":ref:`integer `, :ref:`unsigned `, " +":ref:`number `, :ref:`decimal `, " +":ref:`string `, :ref:`varbinary `, or " +":ref:`uuid ` values" +msgstr "" +"может содержать значения :ref:`nil `, :ref:`boolean `, :ref:`integer `, :ref:`unsigned `, :ref:`number `, :ref:`decimal `, :ref:`string ` или :ref:`varbinary `" + +msgid "" +"When a scalar field contains values of different underlying types, the key " +"order is: nils, then booleans, then numbers, then strings, then varbinaries," +" then uuids." +msgstr "" +"Когда поле типа scalar содержит значения различных базовых типов, то порядок" +" ключей следующий: nil, затем boolean, затем number, затем string, затем " +"varbinary, затем uuid." + msgid "Collations" msgstr "Сортировка" @@ -1486,9 +1605,6 @@ msgstr "" "больше нужно оперативной памяти, но количество низкоуровневых шагов остается" " примерно тем же." -msgid "Index type" -msgstr "Тип индекса" - msgid "" "Typically, a HASH index is faster than a TREE index if the number of tuples " "in the space is greater than one." diff --git a/locale/ru/LC_MESSAGES/book/box/engines/index.po b/locale/ru/LC_MESSAGES/book/box/engines/index.po index 37a874258e..cd5b874343 100644 --- a/locale/ru/LC_MESSAGES/book/box/engines/index.po +++ b/locale/ru/LC_MESSAGES/book/box/engines/index.po @@ -3,75 +3,46 @@ msgid "Storage engines" msgstr "Движки базы данных" msgid "" -"A storage engine is a set of very-low-level routines which actually store " -"and retrieve tuple values. Tarantool offers a choice of two storage engines:" +"A storage engine is a set of low-level routines which actually store and " +"retrieve :term:`tuple ` values. Tarantool offers a choice of two " +"storage engines:" msgstr "" -"Движок базы данных представляет собой набор очень низкоуровневых процессов, " -"которые фактически хранят и получают значения в кортежах. Tarantool " -"предлагает два движка базы данных на выбор:" +"Движок базы данных — это набор низкоуровневых процессов, которые фактически " +"хранят и получают значения :term:`кортежей `. Tarantool предлагает " +"выбор из двух движков базы данных:" -msgid "" -"memtx (the in-memory storage engine) is the default and was the first to " -"arrive." -msgstr "" -"memtx (in-memory движок базы данных) используется по умолчанию, который был " -"первым." - -msgid "" -"vinyl (the on-disk storage engine) is a working key-value engine and will " -"especially appeal to users who like to see data go directly to disk, so that" -" recovery time might be shorter and database size might be larger." -msgstr "" -"vinyl (движок для хранения данных на диске) -- это рабочий движок на основе " -"пар ключ-значение, который особенно понравится пользователям, предпочитающим" -" записывать данные напрямую на диск, чтобы сократить время восстановления и " -"увеличить размер базы данных." - -msgid "" -"On the other hand, vinyl lacks some functions and options that are available" -" with memtx. Where that is the case, the relevant description in this manual" -" contains a note beginning with the words \"Note re storage engine\"." +msgid ":doc:`memtx ` is the in-memory storage engine used by default." msgstr "" -"С другой стороны, vinyl'у не хватает некоторых функций и параметров, " -"доступных в memtx'е. В соответствующих случаях дается дополнительное " -"описание в виде примечания, которое начинается со слов **Примечание про " -"движок базы данных**." +":doc:`memtx ` — in-memory движок базы данных, используемый по " +"умолчанию." -msgid "" -"Further in this section we discuss the details of storing data using the " -"vinyl storage engine." -msgstr "" -"Далее в разделе рассмотрим подробнее метод хранения данных с помощью движка " -"базы данных vinyl." +msgid ":doc:`vinyl ` is the on-disk storage engine." +msgstr ":doc:`vinyl ` — дисковый движок базы данных." msgid "" -"To specify that the engine should be vinyl, add the clause ``engine = " -"'vinyl'`` when creating a space, for example:" +"Below you can find comparing of the two engines in brief. All the details on" +" how each engine works you can find in the dedicated sections:" msgstr "" -"Чтобы указать, что следует использовать именно vinyl, необходимо при " -"создании спейса добавить оператор ``engine = 'vinyl'``, например:" - -msgid "space = box.schema.space.create('name', {engine='vinyl'})" -msgstr "space = box.schema.space.create('name', {engine='vinyl'})" +"Ниже вы можете найти краткое сравнение этих двух движков. Все подробности о " +"том, как работает каждый движок, вы можете найти в следующих разделах:" -msgid "Differences between memtx and vinyl storage engines" -msgstr "Различия между движками memtx и vinyl" +msgid "Difference between memtx and vinyl storage engines" +msgstr "Различие между движками memtx и vinyl" msgid "" -"The primary difference between memtx and vinyl is that memtx is an \"in-" -"memory\" engine while vinyl is an \"on-disk\" engine. An in-memory storage " -"engine is generally faster (each query is usually run under 1 ms), and the " -"memtx engine is justifiably the default for Tarantool, but on-disk engine " -"such as vinyl is preferable when the database is larger than the available " -"memory and adding more memory is not a realistic option." +"The primary difference between memtx and vinyl is that memtx is an in-memory" +" engine while vinyl is an on-disk engine. An in-memory storage engine is " +"generally faster (each query is usually run under 1 ms), and the memtx " +"engine is justifiably the default for Tarantool. But on-disk engine such as " +"vinyl is preferable when the database is larger than the available memory, " +"and adding more memory is not a realistic option." msgstr "" -"Основным различием между движками memtx и vinyl является то, что memtx " -"представляет собой \"in-memory\" движок, тогда как vinyl -- это \"дисковый\"" -" движок. Как правило, in-memory движок быстрее (каждый запрос обычно " -"выполняется меньше, чем за 1 мс), и движок memtx по праву используется в " -"Tarantool по умолчанию, но если база данных больше объема доступной памяти, " -"а добавление дополнительной памяти не представляется возможным, " -"рекомендуется использовать дисковый движок, то есть vinyl." +"Основное различие между движками memtx и vinyl в том, что memtx — in-memory " +"движок, тогда как vinyl — это дисковый движок. Обычно in-memory движок " +"быстрее: время выполнения запроса, как правило, менее 1 мс. Поэтому движок " +"memtx используется в Tarantool по умолчанию. Однако если база данных не " +"помещается в доступную память, а дополнительную память добавить невозможно, " +"то лучше использовать дисковый движок, в данном случае vinyl." msgid "Option" msgstr "Характеристика" @@ -151,1477 +122,3 @@ msgstr "" msgid "Yields on the select requests or on its equivalents: get() or pairs()" msgstr "" "Передает управление на запросах выборки или аналогичных: get() или pairs()" - -msgid "Storing data with vinyl" -msgstr "Хранение данных с помощью vinyl" - -msgid "" -"Tarantool is a transactional and persistent DBMS that maintains 100% of its " -"data in RAM. The greatest advantages of in-memory databases are their speed " -"and ease of use: they demonstrate consistently high performance, but you " -"never need to tune them." -msgstr "" -"Tarantool -- это транзакционная, персистентная СУБД, которая хранит 100% " -"данных в оперативной памяти. Основными преимущества хранения данных " -"оперативной памяти являются скорость и простота использования: нет " -"необходимости в оптимизации, однако производительность остается стабильно " -"высокой." - -msgid "" -"A few years ago we decided to extend the product by implementing a classical" -" storage engine similar to those used by regular DBMSs: it uses RAM for " -"caching, while the bulk of its data is stored on disk. We decided to make it" -" possible to set a storage engine independently for each table in the " -"database, which is the same way that MySQL approaches it, but we also wanted" -" to support transactions from the very beginning." -msgstr "" -"Несколько лет назад мы решили расширить продукт путем реализации " -"классической технологии хранения как в обычных СУБД: в оперативной памяти " -"хранится лишь кэш данных, а основной объем данных находится на диске. Мы " -"решили, что движок хранения можно будет выбирать независимо для каждой " -"таблицы, как это реализовано в MySQL, но при этом с самого начала будет " -"реализована поддержка транзакций." - -msgid "" -"The first question we needed to answer was whether to create our own storage" -" engine or use an existing library. The open-source community offered a few " -"viable solutions. The RocksDB library was the fastest growing open-source " -"library and is currently one of the most prominent out there. There were " -"also several lesser-known libraries to consider, such as WiredTiger, " -"ForestDB, NestDB, and LMDB." -msgstr "" -"Первый вопрос, на который нужен был ответ: создавать свой движок или " -"использовать уже существующую библиотеку? Сообщество разработчиков открытого" -" ПО предлагает готовые библиотеки на выбор. Активнее всего развивалась " -"библиотека RocksDB, которая к настоящему времени стала одной из самых " -"популярных. Есть также несколько менее известных библиотек: WiredTiger, " -"ForestDB, NestDB, LMDB." - -msgid "" -"Nevertheless, after studying the source code of existing libraries and " -"considering the pros and cons, we opted for our own storage engine. One " -"reason is that the existing third-party libraries expected requests to come " -"from multiple operating system threads and thus contained complex " -"synchronization primitives for controlling parallel data access. If we had " -"decided to embed one of these in Tarantool, we would have made our users " -"bear the overhead of a multithreaded application without getting anything in" -" return. The thing is, Tarantool has an actor-based architecture. The way it" -" processes transactions in a dedicated thread allows it to do away with the " -"unnecessary locks, interprocess communication, and other overhead that " -"accounts for up to 80% of processor time in multithreaded DBMSs." -msgstr "" -"Тем не менее, изучив исходный код существующих библиотек и взвесив все " -"\"за\" и \"против\", мы решили написать свой движок. Одна из причин -- все " -"существующие сторонние библиотеки предполагают, что запросы к данным могут " -"поступать из множества потоков операционной системы, и поэтому содержат " -"сложные примитивы синхронизации для управления одновременным доступом к " -"данным. Если бы мы решили встраивать одну из них в Tarantool, то " -"пользователи были бы вынуждены нести издержки многопоточных приложений, не " -"получая ничего взамен. Дело в том, что в основе Tarantool лежит архитектура " -"на основе акторов. Обработка транзакций в выделенном потоке позволяет " -"обойтись без лишних блокировок, межпроцессного взаимодействия и других " -"затрат ресурсов, которые забирают до 80% процессорного времени в " -"многопоточных СУБД." - -msgid "*The Tarantool process consists of a fixed number of \"actor\" threads*" -msgstr "*Процесс в Tarantool состоит из заданного количества потоков*" - -msgid "" -"If you design a database engine with cooperative multitasking in mind right " -"from the start, it not only significantly speeds up the development process," -" but also allows the implementation of certain optimization tricks that " -"would be too complex for multithreaded engines. In short, using a third-" -"party solution wouldn’t have yielded the best result." -msgstr "" -"Если изначально проектировать движок с учетом кооперативной многозадачности," -" можно не только существенно ускорить работу, но и реализовать приемы " -"оптимизации, слишком сложные для многопоточных движков. В общем, " -"использование стороннего решения не привело бы к лучшему результату." - -msgid "Algorithm" -msgstr "Алгоритм" - -msgid "" -"Once the idea of using an existing library was off the table, we needed to " -"pick an architecture to build upon. There are two competing approaches to " -"on-disk data storage: the older one relies on B-trees and their variations; " -"the newer one advocates the use of log-structured merge-trees, or \"LSM\" " -"trees. MySQL, PostgreSQL, and Oracle use B-trees, while Cassandra, MongoDB, " -"and CockroachDB have adopted LSM trees." -msgstr "" -"Отказавшись от идеи внедрения существующих библиотек, необходимо было " -"выбрать архитектуру для использования в качестве основы. Есть два " -"альтернативных подхода к хранению данных на диске: старая модель с " -"использованием B-деревьев и их разновидностей и новая -- на основе " -"журнально-структурированных деревьев со слиянием, или LSM-деревьев (Log " -"Structured Merge Tree). MySQL, PostgreSQL и Oracle используют B-деревья, а " -"Cassandra, MongoDB и CockroachDB уже используют LSM-деревья." - -msgid "" -"B-trees are considered better suited for reads and LSM trees—for writes. " -"However, with SSDs becoming more widespread and the fact that SSDs have read" -" throughput that’s several times greater than write throughput, the " -"advantages of LSM trees in most scenarios was more obvious to us." -msgstr "" -"Считается, что B-деревья более эффективны для чтения, а LSM-деревья -- для " -"записи. Тем не менее, с распространением SSD-дисков, у которых в несколько " -"раз выше производительность чтения по сравнению с производительностью " -"записи, преимущества LSM-деревьев стали очевидны в большинстве сценариев." - -msgid "" -"Before dissecting LSM trees in Tarantool, let’s take a look at how they " -"work. To do that, we’ll begin by analyzing a regular B-tree and the issues " -"it faces. A B-tree is a balanced tree made up of blocks, which contain " -"sorted lists of key- value pairs. (Topics such as filling and balancing a " -"B-tree or splitting and merging blocks are outside of the scope of this " -"article and can easily be found on Wikipedia). As a result, we get a " -"container sorted by key, where the smallest element is stored in the " -"leftmost node and the largest one in the rightmost node. Let’s have a look " -"at how insertions and searches in a B-tree happen." -msgstr "" -"Прежде чем разбираться с LSM-деревьями в Tarantool'е, посмотрим, как они " -"работают. Для этого разберем устройство обычного B-дерева и связанные с ним " -"проблемы. \"B\" в слове B-tree означает \"Block\", то есть это " -"сбалансированное дерево, состоящее из блоков, которые содержат " -"отсортированные списки пар ключ-значение. Вопросы наполнения дерева, " -"балансировки, разбиения и слияния блоков выходят за рамки данной статьи, " -"подробности вы сможете прочитать в Википедии. В итоге мы получаем " -"отсортированный по возрастанию ключа контейнер, минимальный элемент которого" -" хранится в крайнем левом узле, а максимальный -- в крайнем правом. " -"Посмотрим, как в B-дереве осуществляется поиск и вставка данных." - -msgid "*Classical B-tree*" -msgstr "*Классическое B-дерево*" - -msgid "" -"If you need to find an element or check its membership, the search starts at" -" the root, as usual. If the key is found in the root block, the search " -"stops; otherwise, the search visits the rightmost block holding the largest " -"element that’s not larger than the key being searched (recall that elements " -"at each level are sorted). If the first level yields no results, the search " -"proceeds to the next level. Finally, the search ends up in one of the leaves" -" and probably locates the needed key. Blocks are stored and read into RAM " -"one by one, meaning the algorithm reads :math:`logB(N)` blocks in a single " -"search, where N is the number of elements in the B-tree. In the simplest " -"case, writes are done similarly: the algorithm finds the block that holds " -"the necessary element and updates (inserts) its value." -msgstr "" -"Если необходимо найти элемент или проверить его наличие, поиск начинается, " -"как обычно, с вершины. Если ключ обнаружен в корневом блоке, поиск " -"заканчивается; в противном случае, переходим в блок с наибольшим меньшим " -"ключом, то есть в самый правый блок, в котором еще есть элементы меньше " -"искомого (элементы на всех уровнях расположены по возрастанию). Если и там " -"элемент не найден, снова переходим на уровень ниже. В конце концов окажемся " -"в одном из листьев и, возможно, обнаружим искомый элемент. Блоки дерева " -"хранятся на диске и читаются в оперативную память по одному, то есть в " -"рамках одного поиска алгоритм считывает :math:`logB(N)` блоков, где N -- это" -" количество элементов в B-дереве. Запись в самом простом случае " -"осуществляется аналогично: алгоритм находит блок, который содержит " -"необходимый элемент, и обновляет (вставляет) его значение." - -msgid "" -"To better understand the data structure, let’s consider a practical example:" -" say we have a B-tree with 100,000,000 nodes, a block size of 4096 bytes, " -"and an element size of 100 bytes. Thus each block will hold up to 40 " -"elements (all overhead considered), and the B-tree will consist of around " -"2,570,000 blocks and 5 levels: the first four will have a size of 256 Mb, " -"while the last one will grow up to 10 Gb. Obviously, any modern computer " -"will be able to store all of the levels except the last one in filesystem " -"cache, so read requests will require just a single I/O operation." -msgstr "" -"Чтобы наглядно представить себе эту структуру данных, возьмем B-дерево на " -"100 000 000 узлов и предположим, что размер блока равен 4096 байтов, а " -"размер элемента -- 100 байтов. Таким образом, в каждом блоке можно будет " -"разместить до 40 элементов с учетом накладных расходов, а в B-дереве будет " -"около 2 570 000 блоков, пять уровней, при этом первые четыре займут по 256 " -"МБ, а последний -- до 10 ГБ. Очевидно, что на любом современном компьютере " -"все уровни, кроме последнего, успешно попадут в кэш файловой системы, и " -"фактически любая операция чтения будет требовать не более одной операции " -"ввода-вывода." - -msgid "" -"But if we change our perspective —B-trees don’t look so good anymore. " -"Suppose we need to update a single element. Since working with B-trees " -"involves reading and writing whole blocks, we would have to read in one " -"whole block, change our 100 bytes out of 4096, and then write the whole " -"updated block to disk. In other words,we were forced to write 40 times more " -"data than we actually modified!" -msgstr "" -"Ситуация выглядит существенно менее радужно при смене точки зрения. " -"Предположим, что необходимо обновить один элемент дерева. Так как операции с" -" B-деревьями работают через чтение и запись целых блоков, приходится " -"прочитать 1 блок в память, изменить 100 байт из 4096, а затем записать " -"обновленный блок на диск. Таким образом, нам пришлось записать в 40 раз " -"больше, чем реальный объем измененных данных!" - -msgid "" -"If you take into account the fact that an SSD block has a size of 64 Kb+ and" -" not every modification changes a whole element, the extra disk workload can" -" be greater still." -msgstr "" -"Принимая во внимание, что внутренний размер блока в SSD-дисках может быть 64" -" КБ и больше, и не любое изменение элемента меняет его целиком, объем " -"\"паразитной\" нагрузки на диск может быть еще выше." - -msgid "" -"Authors of specialized literature and blogs dedicated to on-disk data " -"storage have coined two terms for these phenomena: extra reads are referred " -"to as \"read amplification\" and writes as \"write amplification\"." -msgstr "" -"Феномен таких \"паразитных\" чтений в литературе и блогах, посвященных " -"хранению на диске, называется read amplification (усложнение чтения), а " -"феномен \"паразитной\" записи -- write amplification (усложнение записи)." - -msgid "" -"The amplification factor (multiplication coefficient) is calculated as the " -"ratio of the size of actual read (or written) data to the size of data " -"needed (or actually changed). In our B-tree example, the amplification " -"factor would be around 40 for both reads and writes." -msgstr "" -"Коэффициент усложнения, то есть коэффициент умножения, вычисляется как " -"отношение размера фактически прочитанных (или записанных) данных к реально " -"необходимому (или измененному) размеру. В нашем примере с B-деревом " -"коэффициент составит около 40 как для чтения, так и для записи." - -msgid "" -"The huge number of extra I/O operations associated with updating data is one" -" of the main issues addressed by LSM trees. Let’s see how they work." -msgstr "" -"Объем \"паразитных\" операций ввода-вывода при обновлении данных является " -"одной из основных проблем, которую решают LSM-деревья. Рассмотрим, как это " -"работает." - -msgid "" -"The key difference between LSM trees and regular B-trees is that LSM trees " -"don’t just store data (keys and values), but also data operations: " -"insertions and deletions." -msgstr "" -"Ключевое отличие LSM-деревьев от классических B-деревьев заключается в том, " -"что LSM-деревья не просто хранят данные (ключи и значения), а также операции" -" с данными: вставки и удаления." - -msgid "|br|" -msgstr "|br|" - -msgid "LSM tree:" -msgstr "LSM-дерево:" - -msgid "Stores statements, not values:" -msgstr "Хранит операторы, а не значения:" - -msgid "REPLACE" -msgstr "REPLACE" - -msgid "DELETE" -msgstr "DELETE" - -msgid "UPSERT" -msgstr "UPSERT" - -msgid "" -"Every statement is marked by LSN Append-only files, garbage is collected " -"after a checkpoint" -msgstr "" -"Для каждого оператора назначается LSN Обновление файлов происходит только " -"путем присоединения новых записей, сборка мусора проводится после " -"контрольной точки" - -msgid "Transactional log of all filesystem changes: vylog" -msgstr "Журнал транзакций при любых изменениях в системе: vylog" - -msgid "" -"For example, an element corresponding to an insertion operation has, apart " -"from a key and a value, an extra byte with an operation code (\"REPLACE\" in" -" the image above). An element representing the deletion operation contains a" -" key (since storing a value is unnecessary) and the corresponding operation " -"code—\"DELETE\". Also, each LSM tree element has a log sequence number " -"(LSN), which is the value of a monotonically increasing sequence that " -"uniquely identifies each operation. The whole tree is first ordered by key " -"in ascending order, and then, within a single key scope, by LSN in " -"descending order." -msgstr "" -"Например, элемент для операции вставки, помимо ключа и значения, содержит " -"дополнительный байт с кодом операции -- обозначенный выше как REPLACE. " -"Элемент для операции удаления содержит ключ элемента (хранить значение нет " -"необходимости) и соответствующий код операции -- DELETE. Также каждый " -"элемент LSM-дерева содержит порядковый номер операции (log sequence number " -"-- LSN), то есть значение монотонно возрастающей последовательности, которое" -" уникально идентифицирует каждую операцию. Таким образом, всё дерево " -"упорядочено сначала по возрастанию ключа, а в пределах одного ключа -- по " -"убыванию LSN." - -msgid "*A single level of an LSM tree*" -msgstr "*Один уровень LSM-дерева*" - -msgid "Filling an LSM tree" -msgstr "Наполнение LSM-дерева" - -msgid "" -"Unlike a B-tree, which is stored completely on disk and can be partly cached" -" in RAM, when using an LSM tree, memory is explicitly separated from disk " -"right from the start. The issue of volatile memory and data persistence is " -"beyond the scope of the storage algorithm and can be solved in various " -"ways—for example, by logging changes." -msgstr "" -"В отличие от B-дерева, которое полностью хранится на диске и может частично " -"кэшироваться в оперативной памяти, в LSM-дереве разделение между памятью и " -"диском явно присутствует с самого начала. При этом проблема сохранности " -"данных, расположенных в энергозависимой памяти, выносится за рамки алгоритма" -" хранения: ее можно решить разными способами, например, журналированием " -"изменений." - -msgid "" -"The part of an LSM tree that’s stored in RAM is called L0 (level zero). The " -"size of RAM is limited, so L0 is allocated a fixed amount of memory. For " -"example, in Tarantool, the L0 size is controlled by the ``vinyl_memory`` " -"parameter. Initially, when an LSM tree is empty, operations are written to " -"L0. Recall that all elements are ordered by key in ascending order, and then" -" within a single key scope, by LSN in descending order, so when a new value " -"associated with a given key gets inserted, it’s easy to locate the older " -"value and delete it. L0 can be structured as any container capable of " -"storing a sorted sequence of elements. For example, in Tarantool, L0 is " -"implemented as a B+*-tree. Lookups and insertions are standard operations " -"for the data structure underlying L0, so I won’t dwell on those." -msgstr "" -"Часть дерева, расположенную в оперативной памяти, называют L0 (level zero --" -" уровень ноль). Объем оперативной памяти ограничен, поэтому для L0 отводится" -" фиксированная область. В конфигурации Tarantool'а, например, размер L0 " -"задается с помощью параметра ``vinyl_memory``. В начале, когда LSM-дерево не" -" содержит элементов, операции записываются в L0. Следует отметить, что " -"элементы в дереве упорядочены по возрастанию ключа, а затем по убыванию LSN," -" так что в случае вставки нового значения по данному ключу легко обнаружить " -"и удалить предыдущее значение. L0 может быть представлен любым контейнером, " -"который сохраняет упорядоченность элементов. Например, для хранения L0 " -"Tarantool использует B+*-дерево. Операции поиска и вставки -- это " -"стандартные операции структуры данных, используемой для представления L0, и " -"мы их подробно рассматривать не будем." - -msgid "" -"Sooner or later the number of elements in an LSM tree exceeds the L0 size " -"and that’s when L0 gets written to a file on disk (called a \"run\") and " -"then cleared for storing new elements. This operation is called a \"dump\"." -msgstr "" -"Рано или поздно количество элементов в дереве превысит размер L0. Тогда L0 " -"записывается в файл на диске (который называется забегом -- \"run\") и " -"освобождается под новые элементы. Эта операция называется \"дамп\" (dump)." - -msgid "" -"Dumps on disk form a sequence ordered by LSN: LSN ranges in different runs " -"don’t overlap, and the leftmost runs (at the head of the sequence) hold " -"newer operations. Think of these runs as a pyramid, with the newest ones " -"closer to the top. As runs keep getting dumped, the pyramid grows higher. " -"Note that newer runs may contain deletions or replacements for existing " -"keys. To remove older data, it’s necessary to perform garbage collection " -"(this process is sometimes called \"merge\" or \"compaction\") by combining " -"several older runs into a new one. If two versions of the same key are " -"encountered during a compaction, only the newer one is retained; however, if" -" a key insertion is followed by a deletion, then both operations can be " -"discarded." -msgstr "" -"Все дампы на диске образуют последовательность, упорядоченную по LSN: " -"диапазоны LSN в файлах не пересекаются, а ближе к началу последовательности " -"находятся файлы с более новыми операциями. Представим эти файлы в виде " -"пирамиды, где новые файлы расположены вверху, а старые внизу. По мере " -"появления новых файлов забегов, высота пирамиды растет. При этом более " -"свежие файлы могут содержать операции удаления или замены для существующих " -"ключей. Для удаления старых данных необходимо производиться сборку мусора " -"(этот процесс иногда называется \"слияние\" -- в английском языке \"merge\" " -"или \"compaction\"), объединяя нескольких старых файлов в новый. Если при " -"слиянии мы встречаем две версии одного и того же ключа, то достаточно " -"оставить только более новую версию, а если после вставки ключа он был " -"удален, то из результата можно исключить обе операции." - -msgid "" -"The key choices determining an LSM tree’s efficiency are which runs to " -"compact and when to compact them. Suppose an LSM tree stores a monotonically" -" increasing sequence of keys (1, 2, 3, ...,) with no deletions. In this " -"case, compacting runs would be useless: all of the elements are sorted, the " -"tree doesn’t have any garbage, and the location of any key can unequivocally" -" be determined. On the other hand, if an LSM tree contains many deletions, " -"doing a compaction would free up some disk space. However, even if there are" -" no deletions, but key ranges in different runs overlap a lot, compacting " -"such runs could speed up lookups as there would be fewer runs to scan. In " -"this case, it might make sense to compact runs after each dump. But keep in " -"mind that a compaction causes all data stored on disk to be overwritten, so " -"with few reads it’s recommended to perform it less often." -msgstr "" -"Ключевым фактором эффективности LSM-дерева является то, в какой момент и для" -" каких файлов делается слияние. Представим, что LSM-дерево в качестве ключей" -" хранит монотонную последовательность вида 1, 2, 3 …, и операций удаления " -"нет. В этом случае слияние будет бесполезным -- все элементы уже " -"отсортированы, дерево не содержит мусор и можно однозначно определить, в " -"каком файле находится каждый ключ. Напротив, если LSM-дерево содержит много " -"операций удаления, слияние позволит освободить место на диске. Но даже если " -"удалений нет, а диапазоны ключей в разных файлах сильно пересекаются, " -"слияние может ускорить поиск, так как сократит число просматриваемых файлов." -" В этом случае имеет смысл выполнять слияние после каждого дампа. Однако " -"следует отметить, что такое слияние приведет к перезаписи всех данных на " -"диске, поэтому если чтений мало, то лучше делать слияния реже." - -msgid "" -"To ensure it’s optimally configurable for any of the scenarios above, an LSM" -" tree organizes all runs into a pyramid: the newer the data operations, the " -"higher up the pyramid they are located. During a compaction, the algorithm " -"picks two or more neighboring runs of approximately equal size, if possible." -msgstr "" -"Для оптимальной конфигурации под любой из описанных выше сценариев в LSM-" -"дереве все файлы организованы в пирамиду: чем новее операции с данными, тем " -"выше они находятся в пирамиде. При этом в слиянии участвуют два или " -"несколько соседних файлов в пирамиде; по возможности выбираются файлы " -"примерно одинакового размера." - -msgid "Multi-level compaction can span any number of levels" -msgstr "Многоуровневое слияние может охватить любое количество уровней" - -msgid "A level can contain multiple runs" -msgstr "Уровень может содержать несколько файлов" - -msgid "" -"All of the neighboring runs of approximately equal size constitute an LSM " -"tree level on disk. The ratio of run sizes at different levels determines " -"the pyramid’s proportions, which allows optimizing the tree for write-" -"intensive or read-intensive scenarios." -msgstr "" -"Все соседние файлы примерно одинакового размера составляют уровень LSM-" -"дерева на диске. Соотношение размеров файлов на различных уровнях определяет" -" пропорции пирамиды, что позволяет оптимизировать дерево под интенсивные " -"вставки, либо интенсивные чтения." - -msgid "" -"Suppose the L0 size is 100 Mb, the ratio of run sizes at each level (the " -"``vinyl_run_size_ratio`` parameter) is 5, and there can be no more than 2 " -"runs per level (the ``vinyl_run_count_per_level`` parameter). After the " -"first 3 dumps, the disk will contain 3 runs of 100 Mb each—which constitute " -"L1 (level one). Since 3 > 2, the runs will be compacted into a single 300 Mb" -" run, with the older ones being deleted. After 2 more dumps, there will be " -"another compaction, this time of 2 runs of 100 Mb each and the 300 Mb run, " -"which will produce one 500 Mb run. It will be moved to L2 (recall that the " -"run size ratio is 5), leaving L1 empty. The next 10 dumps will result in L2 " -"having 3 runs of 500 Mb each, which will be compacted into a single 1500 Mb " -"run. Over the course of 10 more dumps, the following will happen: 3 runs of " -"100 Mb each will be compacted twice, as will two 100 Mb runs and one 300 Mb " -"run, which will yield 2 new 500 Mb runs in L2. Since L2 now has 3 runs, they" -" will also be compacted: two 500 Mb runs and one 1500 Mb run will produce a " -"2500 Mb run that will be moved to L3, given its size." -msgstr "" -"Предположим, что размер L0 составляет 100 МБ, а соотношение размеров файлов " -"на каждом уровне (параметр ``vinyl_run_size_ratio``) равно 5, и на каждом " -"уровне может быть не более 2 файлов (параметр " -"``vinyl_run_count_per_level``). После первых трех дампов на диске появятся 3" -" файла по 100 МБ, эти файлы образуют уровень L1. Так как 3 > 2, запустится " -"слияние файлов в новый файл размером 300 МБ, а старые будут удалены. Спустя " -"еще 2 дампа снова запустится слияние, на этот раз файлов в 100, 100 и 300 " -"МБ, в результате файл размером 500 МБ переместится на уровень L2 (вспомним, " -"что соотношение размеров уровней равно 5), а уровень L1 останется пустым. " -"Пройдут еще 10 дампов, и получим 3 файла по 500 МБ на уровне L2, в " -"результате чего будет создан один файл размером 1500 МБ. Спустя еще 10 " -"дампов произойдет следующее: 2 раза произведем слияние 3 файлов по 100 МБ, а" -" также 2 раза слияние файлов по 100, 100 и 300 МБ, что приведет к созданию " -"двух файлов на уровне L2 по 500 МБ. Поскольку на уровне L2 уже есть три " -"файла, запустится слияние двух файлов по 500 МБ и одного файла в 1500 МБ. " -"Полученный в результате файл в 2500 МБ, в силу своего размера, переедет на " -"уровень L3." - -msgid "" -"This can go on infinitely, but if an LSM tree contains lots of deletions, " -"the resulting compacted run can be moved not only down, but also up the " -"pyramid due to its size being smaller than the sizes of the original runs " -"that were compacted. In other words, it’s enough to logically track which " -"level a certain run belongs to, based on the run size and the smallest and " -"greatest LSN among all of its operations." -msgstr "" -"Процесс может продолжаться до бесконечности, а если в потоке операций с LSM-" -"деревом будет много удалений, образовавшийся в результате слияния файл может" -" переместиться не только вниз по пирамиде, но и вверх, так как окажется " -"меньше исходных файлов, использовавшихся при слиянии. Иными словами, " -"принадлежность файла к уровню достаточно отслеживать логически на основе " -"размера файла и минимального и максимального LSN среди всех хранящихся в нем" -" операций." - -msgid "Controlling the form of an LSM tree" -msgstr "Управление формой LSM-дерева" - -msgid "" -"If it’s necessary to reduce the number of runs for lookups, then the run " -"size ratio can be increased, thus bringing the number of levels down. If, on" -" the other hand, you need to minimize the compaction-related overhead, then " -"the run size ratio can be decreased: the pyramid will grow higher, and even " -"though runs will be compacted more often, they will be smaller, which will " -"reduce the total amount of work done. In general, write amplification in an " -"LSM tree is described by this formula: :math:`log_{x}(\\frac {N} {L0}) × x` " -"or, alternatively, :math:`x × \\frac {ln (\\frac {N} {C0})} {ln(x)}`, where " -"N is the total size of all tree elements, L0 is the level zero size, and x " -"is the level size ratio (the ``level_size_ratio`` parameter). At " -":math:`\\frac {N} {C0}` = 40 (the disk-to- memory ratio), the plot would " -"look something like this:" -msgstr "" -"Если число файлов для поиска нужно уменьшить, то соотношение размеров файлов" -" на разных уровнях можно увеличить, и, как следствие, уменьшается число " -"уровней. Если, напротив, необходимо снизить затраты ресурсов, вызванные " -"слиянием, то можно уменьшить соотношение размеров уровней: пирамида будет " -"более высокой, а слияние хотя и выполняется чаще, но работает в среднем с " -"файлами меньшего размера, за счет чего суммарно выполняет меньше работы. В " -"целом, \"паразитная запись\" в LSM-дереве описывается формулой " -":math:`log_{x}(\\\\frac {N} {L0}) × x` или :math:`x × \\\\frac {ln (\\\\frac" -" {N} {C0})} {ln(x)}`, где N -- это общий размер всех элементов дерева, L0 --" -" это размер уровня ноль, а x -- это соотношение размеров уровней (параметр " -"``level_size_ratio``). Если :math:`\\\\frac {N} {C0}` = 40 (соотношение " -"диск-память), график выглядит примерно вот так:" - -msgid "" -"As for read amplification, it’s proportional to the number of levels. The " -"lookup cost at each level is no greater than that for a B-tree. Getting back" -" to the example of a tree with 100,000,000 elements: given 256 Mb of RAM and" -" the default values of ``vinyl_run_size_ratio`` and " -"``vinyl_run_count_per_level``, write amplification would come out to about " -"13, while read amplification could be as high as 150. Let’s try to figure " -"out why this happens." -msgstr "" -"\"Паразитное\" чтение при этом пропорционально количеству уровней. Стоимость" -" поиска на каждом уровне не превышает стоимости поиска в B-дереве. " -"Возвращаясь к нашему примеру дерева в 100 000 000 элементов: при наличии 256" -" МБ оперативной памяти и стандартных значений параметров " -"``vinyl_run_size_ratio`` и ``vinyl_run_count_per_level``, получим " -"коэффициент \"паразитной\" записи равным примерно 13, коэффициент " -"\"паразитной\" записи может доходить до 150. Разберемся, почему это " -"происходит." - -msgid "Search" -msgstr "Поиск" - -msgid "" -"When doing a lookup in an LSM tree, what we need to find is not the element " -"itself, but the most recent operation associated with it. If it’s a " -"deletion, then the tree doesn’t contain this element. If it’s an insertion, " -"we need to grab the topmost value in the pyramid, and the search can be " -"stopped after finding the first matching key. In the worst-case scenario, " -"that is if the tree doesn’t hold the needed element, the algorithm will have" -" to sequentially visit all of the levels, starting from L0." -msgstr "" -"При поиске в LSM-дереве нам необходимо найти не сам элемент, а последнюю " -"операцию с ним. Если это операция удаления, искомый элемент отсутствует в " -"дереве. Если это операция вставки, то искомому элементу соответствует самое " -"верхнее значение в LSM-пирамиде, и поиск можно остановить при первом " -"совпадении ключа. В худшем случае значение в дереве изначально " -"отсутствовало. Тогда поиск вынужден последовательно перебрать все уровни " -"дерева, начиная с L0." - -msgid "" -"Unfortunately, this scenario is quite common in real life. For example, when" -" inserting a value into a tree, it’s necessary to make sure there are no " -"duplicates among primary/unique keys. So to speed up membership checks, LSM " -"trees use a probabilistic data structure called a \"Bloom filter\", which " -"will be covered a bit later, in a section on how vinyl works under the hood." -msgstr "" -"К сожалению, на практике этот худший случай довольно распространен. " -"Например, при вставке в дерево необходимо убедиться в отсутствии дубликатов " -"для первичного или уникального ключа. Поэтому для ускорения поиска " -"несуществующих значений в LSM-деревьях применяется вероятностная структура " -"данных, которая называется \"фильтр Блума\". О нем мы поговорим более " -"детально в разделе, посвященном внутреннему устройству vinyl." - -msgid "Range searching" -msgstr "Поиск по диапазону" - -msgid "" -"In the case of a single-key search, the algorithm stops after encountering " -"the first match. However, when searching within a certain key range (for " -"example, looking for all the users with the last name \"Ivanov\"), it’s " -"necessary to scan all tree levels." -msgstr "" -"Если при поиске по одному ключу алгоритм завершается после первого " -"совпадения, то для поиска всех значений в диапазоне (например, всех " -"пользователей с фамилией \"Иванов\") необходимо просматривать все уровни " -"дерева." - -msgid "*Searching within a range of [24,30)*" -msgstr "*Поиск по диапазону [24,30)*" - -msgid "" -"The required range is formed the same way as when compacting several runs: " -"the algorithm picks the key with the largest LSN out of all the sources, " -"ignoring the other associated operations, then moves on to the next key and " -"repeats the procedure." -msgstr "" -"Формирование искомого диапазона при этом происходит так же, как и при " -"слиянии нескольких файлов: из всех источников алгоритм выбирает ключ с " -"максимальным LSN, отбрасывает остальные операции по этому ключу, сдвигает " -"позицию поиска на следующий ключ и повторяет процедуру." - -msgid "Deletion" -msgstr "Удаление" - -msgid "" -"Why would one store deletions? And why doesn’t it lead to a tree overflow in" -" the case of for i=1,10000000 put(i) delete(i) end?" -msgstr "" -"Зачем вообще хранить операции удаления? И почему это не приводит к " -"переполнению дерева, например, в сценарии for i=1,10000000 put(i) delete(i) " -"end?" - -msgid "" -"With regards to lookups, deletions signal the absence of a value being " -"searched; with compactions, they clear the tree of \"garbage\" records with " -"older LSNs." -msgstr "" -"Роль операций удаления при поиске -- сообщать об отсутствии искомого " -"значения, а при слиянии -- очищать дерево от \"мусорных\" записей с более " -"старыми LSN." - -msgid "" -"While the data is in RAM only, there’s no need to store deletions. " -"Similarly, you don’t need to keep them following a compaction if they " -"affect, among other things, the lowest tree level, which contains the oldest" -" dump. Indeed, if a value can’t be found at the lowest level, then it " -"doesn’t exist in the tree." -msgstr "" -"Пока данные хранятся только в оперативной памяти, нет необходимости хранить " -"операции удаления. Также нет необходимости сохранять операции удаления после" -" слияния, если оно затрагивает в том числе самый нижний уровень дерева -- на" -" нем находятся данные самого старого дампа. Действительно, отсутствие " -"значения на последнем уровне означает, что оно отсутствует в дереве." - -msgid "We can't delete from append-only files" -msgstr "" -"Нельзя производить удаление из файлов, которые обновляются только путем " -"присоединения новых записей" - -msgid "Tombstones (delete markers) are inserted into L0 instead" -msgstr "" -"Вместо этого на уровень L0 вносятся маркеры удаленных записей (tombstones)" - -msgid "*Deletion, step 1: a tombstone is inserted into L0*" -msgstr "*Удаление, шаг 1: вставка удаленной записи в L0*" - -msgid "*Deletion, step 2: the tombstone passes through intermediate levels*" -msgstr "" -"*Удаление, шаг 2: удаленная запись проходит через промежуточные уровни*" - -msgid "" -"*Deletion, step 3: in the case of a major compaction, the tombstone is " -"removed from the tree*" -msgstr "" -"*Удаление, шаг 3: при значительном слиянии удаленная запись удаляется из " -"дерева*" - -msgid "" -"If a deletion is known to come right after the insertion of a unique value, " -"which is often the case when modifying a value in a secondary index, then " -"the deletion can safely be filtered out while compacting intermediate tree " -"levels. This optimization is implemented in vinyl." -msgstr "" -"Если мы знаем, что удаление следует сразу за вставкой уникального значения " -"-- а это частый случай при изменении значения во вторичном индексе -- то " -"операцию удаления можно отфильтровывать уже при слиянии промежуточных " -"уровней. Эта оптимизация реализована в vinyl'е." - -msgid "Advantages of an LSM tree" -msgstr "Преимущества LSM-дерева" - -msgid "" -"Apart from decreasing write amplification, the approach that involves " -"periodically dumping level L0 and compacting levels L1-Lk has a few " -"advantages over the approach to writes adopted by B-trees:" -msgstr "" -"Помимо снижения \"паразитной\" записи, подход с периодическими дампами " -"уровня L0 и слиянием уровней L1-Lk имеет ряд преимуществ перед подходом к " -"записи, используемым в B-деревьях:" - -msgid "" -"Dumps and compactions write relatively large files: typically, the L0 size " -"is 50-100 Mb, which is thousands of times larger than the size of a B-tree " -"block." -msgstr "" -"При дампах и слиянии создаются относительно большие файлы: стандартный " -"размер L0 составляет 50-100 MБ, что в тысячи раз превышает размер блока " -"B-дерева." - -msgid "" -"This large size allows efficiently compressing data before writing it. " -"Tarantool compresses data automatically, which further decreases write " -"amplification." -msgstr "" -"Большой размер позволяет эффективно сжимать данные перед записью. В " -"Tarantool'е сжатие происходит автоматически, что позволяет еще больше " -"уменьшить \"паразитную\" запись." - -msgid "" -"There is no fragmentation overhead, since there’s no padding/empty space " -"between the elements inside a run." -msgstr "" -"Издержки фрагментации отсутствуют, потому что в файле элементы следуют друг " -"за другом без пустот/заполнений." - -msgid "" -"All operations create new runs instead of modifying older data in place. " -"This allows avoiding those nasty locks that everyone hates so much. Several " -"operations can run in parallel without causing any conflicts. This also " -"simplifies making backups and moving data to replicas." -msgstr "" -"Все операции создают новые файлы, а не заменяют старые данные. Это позволяет" -" избавиться от столь ненавистных нам блокировок, при этом несколько операций" -" могут идти параллельно, не приводя к конфликтам. Это также упрощает " -"создание резервных копий и перенос данных на реплику." - -msgid "" -"Storing older versions of data allows for the efficient implementation of " -"transaction support by using multiversion concurrency control." -msgstr "" -"Хранение старых версий данных позволяет эффективно реализовать поддержку " -"транзакций, используя подход управления параллельным доступом с помощью " -"многоверсионности." - -msgid "Disadvantages of an LSM tree and how to deal with them" -msgstr "Недостатки LSM-дерева и их устранение" - -msgid "" -"One of the key advantages of the B-tree as a search data structure is its " -"predictability: all operations take no longer than :math:`log_{B}(N)` to " -"run. Conversely, in a classical LSM tree, both read and write speeds can " -"differ by a factor of hundreds (best case scenario) or even thousands (worst" -" case scenario). For example, adding just one element to L0 can cause it to " -"overflow, which can trigger a chain reaction in levels L1, L2, and so on. " -"Lookups may find the needed element in L0 or may need to scan all of the " -"tree levels. It’s also necessary to optimize reads within a single level to " -"achieve speeds comparable to those of a B-tree. Fortunately, most " -"disadvantages can be mitigated or even eliminated with additional algorithms" -" and data structures. Let’s take a closer look at these disadvantages and " -"how they’re dealt with in Tarantool." -msgstr "" -"Одним из ключевых преимуществ B-дерева как структуры данных для поиска " -"является предсказуемость: любая операция занимает не более чем " -":math:`log_{B}(N)`. В классическом LSM-дереве скорость как чтения, так и " -"записи могут может отличаться в лучшем и худшем случае в сотни и тысячи раз." -" Например, добавление всего лишь одного элемента в L0 может привести к его " -"переполнению, что в свою очередь, может привести к переполнению L1, L2 и " -"т.д. Процесс чтения может обнаружить исходный элемент в L0, а может " -"задействовать все уровни. Чтение в пределах одного уровня также необходимо " -"оптимизировать, чтобы добиться скорости, сравнимой с B-деревом. К счастью, " -"многие недостатки можно скрасить или полностью устранить с помощью " -"вспомогательных алгоритмов и структур данных. Систематизируем эти недостатки" -" и опишем способы борьбы с ними, используемые в Tarantool'е." - -msgid "Unpredictable write speed" -msgstr "Непредсказуемая скорость записи" - -msgid "" -"In an LSM tree, insertions almost always affect L0 only. How do you avoid " -"idle time when the memory area allocated for L0 is full?" -msgstr "" -"Вставка данных в LSM-дерево почти всегда задействует исключительно L0. Как " -"избежать простоя, если заполнена область оперативной памяти, отведенная под " -"L0?" - -msgid "" -"Clearing L0 involves two lengthy operations: writing to disk and memory " -"deallocation. To avoid idle time while L0 is being dumped, Tarantool uses " -"writeaheads. Suppose the L0 size is 256 Mb. The disk write speed is 10 Mbps." -" Then it would take 26 seconds to dump L0. The insertion speed is 10,000 " -"RPS, with each key having a size of 100 bytes. While L0 is being dumped, " -"it’s necessary to reserve 26 Mb of RAM, effectively slicing the L0 size down" -" to 230 Mb." -msgstr "" -"Освобождение L0 подразумевает две долгих операции: запись на диск и " -"освобождение памяти. Чтобы избежать простоя во время записи L0 на диск, " -"Tarantool использует упреждающую запись. Допустим, размер L0 составляет 256 " -"MБ. Скорость записи на диск составляет 10 МБ/с. Тогда для записи L0 на диск " -"понадобится 26 секунд. Скорость вставки данных составляет 10 000 запросов в " -"секунду, а размер одного ключа -- 100 байтов. На время записи необходимо " -"зарезервировать около 26 MБ доступной оперативной памяти, сократив реальный " -"полезный размер L0 до 230 MБ." - -msgid "" -"Tarantool does all of these calculations automatically, constantly updating " -"the rolling average of the DBMS workload and the histogram of the disk " -"speed. This allows using L0 as efficiently as possible and it prevents write" -" requests from timing out. But in the case of workload surges, some wait " -"time is still possible. That’s why we also introduced an insertion timeout " -"(the ``vinyl_timeout`` parameter), which is set to 60 seconds by default. " -"The write operation itself is executed in dedicated threads. The number of " -"these threads (2 by default) is controlled by the ``vinyl_write_threads`` " -"parameter. The default value of 2 allows doing dumps and compactions in " -"parallel, which is also necessary for ensuring system predictability." -msgstr "" -"Все эти расчеты Tarantool делает автоматически, постоянно поддерживая " -"скользящее среднее значение нагрузки на СУБД и гистограмму скорости работы " -"диска. Это позволяет максимально эффективно использовать L0 и избежать " -"истечения времени ожидания доступной памяти для операций записи. При резком " -"всплеске нагрузки ожидание все же возможно, поэтому также существует время " -"ожидания операции вставки (параметр ``vinyl_timeout``), значение которого по" -" умолчанию составляет 60 секунд. Сама запись осуществляется в выделенных " -"потоках, число которых (2 по умолчанию) задается в параметре " -"``vinyl_write_threads``. Используемое по умолчанию значение 2 позволяет " -"выполнять дамп параллельно со слиянием, что также необходимо для " -"предсказуемой работы системы." - -msgid "" -"In Tarantool, compactions are always performed independently of dumps, in a " -"separate execution thread. This is made possible by the append-only nature " -"of an LSM tree: after dumps runs are never changed, and compactions simply " -"create new runs." -msgstr "" -"Слияния в Tarantool'е всегда выполняются независимо от дампов, в отдельном " -"потоке выполнения. Это возможно благодаря природе LSM-дерева -- после записи" -" файлы в дереве никогда не меняются, а слияние лишь создает новый файл." - -msgid "" -"Delays can also be caused by L0 rotation and the deallocation of memory " -"dumped to disk: during a dump, L0 memory is owned by two operating system " -"threads, a transaction processing thread and a write thread. Even though no " -"elements are being added to the rotated L0, it can still be used for " -"lookups. To avoid read locks when doing lookups, the write thread doesn’t " -"deallocate the dumped memory, instead delegating this task to the " -"transaction processor thread. Following a dump, memory deallocation itself " -"happens instantaneously: to achieve this, L0 uses a special allocator that " -"deallocates all of the memory with a single operation." -msgstr "" -"К задержкам также может приводить ротация L0 и освобождение памяти, " -"записанной на диск: в процессе записи памятью L0 владеют два потока " -"операционной системы -- поток обработки транзакций и поток записи. Хотя в L0" -" во время ротации элементы не добавляются, он может участвовать в поиске. " -"Чтобы избежать блокировок на чтение во время поиска, поток записи не " -"освобождает записанную память, а оставляет эту задачу потоку обработки " -"транзакций. Само освобождение после завершения дампа происходит мгновенно: " -"для этого в L0 используется специализированный механизм распределения, " -"позволяющий освободить всю память за одну операцию." - -msgid "anticipatory dump" -msgstr "упреждающий дамп" - -msgid "throttling" -msgstr "загрузка" - -msgid "" -"The dump is performed from the so-called \"shadow\" L0 without blocking new " -"insertions and lookups" -msgstr "" -"Дамп происходит из так называемого \"теневого\" L0, не блокируя новые " -"вставки и чтения" - -msgid "Unpredictable read speed" -msgstr "Непредсказуемая скорость чтений" - -msgid "" -"Optimizing reads is the most difficult optimization task with regards to LSM" -" trees. The main complexity factor here is the number of levels: any " -"optimization causes not only much slower lookups, but also tends to require " -"significantly larger RAM resources. Fortunately, the append-only nature of " -"LSM trees allows us to address these problems in ways that would be " -"nontrivial for traditional data structures." -msgstr "" -"Чтение -- самая сложная задача для оптимизации в LSM-деревьях. Главным " -"фактором сложности является большое количество уровней: это не только " -"значительно замедляет поиск, но и потенциально значительно увеличивает " -"требования к оперативной памяти при почти любых попытках оптимизации. К " -"счастью, природа LSM-деревьев, где файлы обновляются только путем " -"присоединения новых записей, позволяет решать эти проблемы нестандартными " -"для традиционных структур данных способами." - -msgid "page index" -msgstr "постраничный индекс" - -msgid "bloom filters" -msgstr "фильтры Блума" - -msgid "tuple range cache" -msgstr "кэш диапазона кортежей" - -msgid "multi-level compaction" -msgstr "многоуровневое слияние" - -msgid "Compression and page index" -msgstr "Сжатие и постраничный индекс" - -msgid "" -"In B-trees, data compression is either the hardest problem to crack or a " -"great marketing tool—rather than something really useful. In LSM trees, " -"compression works as follows:" -msgstr "" -"Сжатие данных в B-деревьях -- это либо сложнейшая в реализации задача, либо " -"больше средство маркетинга, чем действительно полезный инструмент. Сжатие в " -"LSM-деревьях работает следующим образом:" - -msgid "" -"During a dump or compaction all of the data within a single run is split " -"into pages. The page size (in bytes) is controlled by the " -"``vinyl_page_size`` parameter and can be set separately for each index. A " -"page doesn’t have to be exactly of ``vinyl_page_size`` size—depending on the" -" data it holds, it can be a little bit smaller or larger. Because of this, " -"pages never have any empty space inside." -msgstr "" -"При любом дампе или слиянии мы разбиваем все данные в одном файле на " -"страницы. Размер страницы в байтах задается в параметре ``vinyl_page_size``," -" который можно менять отдельно для каждого индекса. Страница не обязана " -"занимать строго то количество байт, которое прописано ``vinyl_page_size`` --" -" она может быть чуть больше или чуть меньше, в зависимости от хранящихся в " -"ней данных. Благодаря этому страница никогда не содержит пустот." - -msgid "" -"Data is compressed by `Facebook’s streaming algorithm " -"`_ called \"zstd\". The first key of each " -"page, along with the page offset, is added to a \"page index\", which is a " -"separate file that allows the quick retrieval of any page. After a dump or " -"compaction, the page index of the created run is also written to disk." -msgstr "" -"Для сжатия используется `потоковый алгоритм Facebook " -"`_ под названием \"zstd\". Первый ключ " -"каждой страницы и смещение страницы в файле добавляются в так называемый " -"постраничный индекс (page index) -- отдельный файл, который позволяет быстро" -" найти нужную страницу. После дампа или слияния постраничный индекс " -"созданного файла также записывается на диск." - -msgid "" -"All `.index` files are cached in RAM, which allows finding the necessary " -"page with a single lookup in a `.run` file (in vinyl, this is the extension " -"of files resulting from a dump or compaction). Since data within a page is " -"sorted, after it’s read and decompressed, the needed key can be found using " -"a regular binary search. Decompression and reads are handled by separate " -"threads, and are controlled by the ``vinyl_read_threads`` parameter." -msgstr "" -"Все файлы типа `.index` кэшируются в оперативной памяти, что позволяет " -"найти нужную страницу за одно чтение из файла `.run` (такое расширение имени" -" файла используется в vinyl'е для файлов, полученных в результате дампа или " -"слияния). Поскольку данные в странице отсортированы, после чтения и " -"декомпрессии нужный ключ можно найти с помощью простого бинарного поиска. За" -" чтение и декомпрессию отвечают отдельные потоки, их количество определяется" -" в параметре ``vinyl_read_threads``." - -msgid "" -"Tarantool uses a universal file format: for example, the format of a `.run` " -"file is no different from that of an `.xlog` file (log file). This " -"simplifies backup and recovery as well as the usage of external tools." -msgstr "" -"Tarantool использует единый формат файлов: например, формат данных в файле " -"`.run` ничем не отличается от формата файла `.xlog` (файл журнала). Это " -"упрощает резервное копирование и восстановление, а также работу внешних " -"инструментов." - -msgid "Bloom filters" -msgstr "Фильтры Блума" - -msgid "" -"Even though using a page index enables scanning fewer pages per run when " -"doing a lookup, it’s still necessary to traverse all of the tree levels. " -"There’s a special case, which involves checking if particular data is absent" -" when scanning all of the tree levels and it’s unavoidable: I’m talking " -"about insertions into a unique index. If the data being inserted already " -"exists, then inserting the same data into a unique index should lead to an " -"error. The only way to throw an error in an LSM tree before a transaction is" -" committed is to do a search before inserting the data. Such reads form a " -"class of their own in the DBMS world and are called \"hidden\" or " -"\"parasitic\" reads." -msgstr "" -"Хотя постраничный индекс позволяет уменьшить количество страниц, " -"просматриваемых при поиске в одном файле, он не отменяет необходимости " -"искать на всех уровнях дерева. Есть важный частный случай, когда необходимо " -"проверить отсутствие данных, и тогда просмотр всех уровней неизбежен: " -"вставка в уникальный индекс. Если данные уже существуют, то вставка в " -"уникальный индекс должна завершиться с ошибкой. Единственный способ вернуть " -"ошибку до завершения транзакции в LSM-дереве -- произвести поиск перед " -"вставкой. Такого рода чтения в СУБД образуют целый класс, называемый " -"\"скрытыми\" или \"паразитными\" чтениями." - -msgid "" -"Another operation leading to hidden reads is updating a value in a field on " -"which a secondary index is defined. Secondary keys are regular LSM trees " -"that store differently ordered data. In most cases, in order not to have to " -"store all of the data in all of the indexes, a value associated with a given" -" key is kept in whole only in the primary index (any index that stores both " -"a key and a value is called \"covering\" or \"clustered\"), whereas the " -"secondary index only stores the fields on which a secondary index is " -"defined, and the values of the fields that are part of the primary index. " -"Thus, each time a change is made to a value in a field on which a secondary " -"index is defined, it’s necessary to first remove the old key from the " -"secondary index—and only then can the new key be inserted. At update time, " -"the old value is unknown, and it is this value that needs to be read in from" -" the primary key \"under the hood\"." -msgstr "" -"Другая операция, приводящая к скрытым чтениям, -- обновление значения, по " -"которому построен вторичный индекс. Вторичные ключи представляют собой " -"обычные LSM-деревья, в которых данные хранятся в другом порядке. Чаще всего," -" чтобы не хранить все данные во всех индексах, значение, соответствующее " -"данному ключу, целиком сохраняется только в первичном индексе (любой индекс," -" хранящий и ключ, и значение, называется покрывающим или кластерным), а во " -"вторичном индексе сохраняются лишь поля, по которым построен вторичный " -"индекс, и значения полей, участвующих в первичном индексе. Тогда при любом " -"изменении значения, по которому построен вторичный ключ, приходится сначала " -"удалять из вторичного индекса старый ключ, и только потом вставлять новый. " -"Старое значение во время обновления неизвестно -- именно его и нужно читать " -"из первичного ключа с точки зрения внутреннего устройства." - -msgid "For example:" -msgstr "Например:" - -msgid "update t1 set city=’Moscow’ where id=1" -msgstr "update t1 set city=’Moscow’ where id=1" - -msgid "" -"To minimize the number of disk reads, especially for nonexistent data, " -"nearly all LSM trees use probabilistic data structures, and Tarantool is no " -"exception. A classical Bloom filter is made up of several (usually 3-to-5) " -"bit arrays. When data is written, several hash functions are calculated for " -"each key in order to get corresponding array positions. The bits at these " -"positions are then set to 1. Due to possible hash collisions, some bits " -"might be set to 1 twice. We’re most interested in the bits that remain 0 " -"after all keys have been added. When looking for an element within a run, " -"the same hash functions are applied to produce bit positions in the arrays. " -"If any of the bits at these positions is 0, then the element is definitely " -"not in the run. The probability of a false positive in a Bloom filter is " -"calculated using Bayes’ theorem: each hash function is an independent random" -" variable, so the probability of a collision simultaneously occurring in all" -" of the bit arrays is infinitesimal." -msgstr "" -"Чтобы уменьшить количество чтений с диска, особенно для несуществующих " -"значений, практически все LSM-деревья используют вероятностные структуры " -"данных. Tarantool не исключение. Классический фильтр Блума -- это набор из " -"нескольких (обычно 3-5) битовых массивов. При записи для каждого ключа " -"вычисляется несколько хеш-функций, и в каждом массиве выставляется бит, " -"соответствующий значению хеша. При хешировании могут возникнуть коллизии, " -"поэтому некоторые биты могут быть проставлены дважды. Интерес представляют " -"биты, которые оказались не проставлены после записи всех ключей. При поиске " -"также вычисляются выбранные хеш-функции. Если хотя бы в одном из битовых " -"массивов бит не стоит, то значение в файле отсутствует. Вероятность " -"срабатывания фильтра Блума определяется теоремой Байеса: каждая хеш-функция " -"представляет собой независимую случайную величину, благодаря чему " -"вероятность того, что во всех битовых массивах одновременно произойдет " -"коллизия, очень мала." - -msgid "" -"The key advantage of Bloom filters in Tarantool is that they’re easily " -"configurable. The only parameter that can be specified separately for each " -"index is called ``vinyl_bloom_fpr`` (FPR stands for \"false positive " -"ratio\") and it has the default value of 0.05, which translates to a 5% FPR." -" Based on this parameter, Tarantool automatically creates Bloom filters of " -"the optimal size for partial- key and full-key searches. The Bloom filters " -"are stored in the `.index` file, along with the page index, and are cached " -"in RAM." -msgstr "" -"Ключевым преимуществом реализации фильтров Блума в Tarantool'е является " -"простота настройки. Единственный параметр, который можно менять независимо " -"для каждого индекса, называется ``vinyl_bloom_fpr`` (FPR в данном случае " -"означает сокращение от \"false positive ratio\" -- коэффициент " -"ложноположительного срабатывания), который по умолчанию равен 0,05, или 5%. " -"На основе этого параметра Tarantool автоматически строит фильтры Блума " -"оптимального размера для поиска как по полному ключу, так и по компонентам " -"ключа. Сами фильтры Блума хранятся вместе с постраничным индексом в файле " -"`.index` и кэшируются в оперативной памяти." - -msgid "Caching" -msgstr "Кэширование" - -msgid "" -"A lot of people think that caching is a silver bullet that can help with any" -" performance issue. \"When in doubt, add more cache\". In vinyl, caching is " -"viewed rather as a means of reducing the overall workload and consequently, " -"of getting a more stable response time for those requests that don’t hit the" -" cache. vinyl boasts a unique type of cache among transactional systems " -"called a \"range tuple cache\". Unlike, say, RocksDB or MySQL, this cache " -"doesn’t store pages, but rather ranges of index values obtained from disk, " -"after having performed a compaction spanning all tree levels. This allows " -"the use of caching for both single-key and key-range searches. Since this " -"method of caching stores only hot data and not, say, pages (you may need " -"only some data from a page), RAM is used in the most efficient way possible." -" The cache size is controlled by the ``vinyl_cache`` parameter." -msgstr "" -"Многие привыкли считать кэширование панацеей от всех проблем с " -"производительностью: \"В любой непонятной ситуации добавляй кэш\". В vinyl'е" -" мы смотрим на кэш скорее как на средство снижения общей нагрузки на диск, " -"и, как следствие, получения более предсказуемого времени ответов на запросы," -" которые не попали в кэш. В vinyl'е реализован уникальный для транзакционных" -" систем вид кэша под названием \"кэш диапазона кортежей\" (range tuple " -"cache). В отличие от RocksDB, например, или MySQL, этот кэш хранит не " -"страницы, а уже готовые диапазоны значений индекса, после их чтения с диска " -"и слияния всех уровней. Это позволяет использовать кэш для запросов как по " -"одному ключу, так и по диапазону ключей. Поскольку в кэше хранятся только " -"горячие данные, а не, скажем, страницы (в странице может быть востребована " -"лишь часть данных), оперативная память используется наиболее оптимально. " -"Размер кэша задается в параметре ``vinyl_cache``." - -msgid "Garbage collection control" -msgstr "Управление сборкой мусора" - -msgid "" -"Chances are that by now you’ve started losing focus and need a well-deserved" -" dopamine reward. Feel free to take a break, since working through the rest " -"of the article is going to take some serious mental effort." -msgstr "" -"Возможно, добравшись до этого места вы уже начали терять концентрацию и " -"нуждаетесь в заслуженной дозе допамина. Самое время сделать перерыв, так как" -" для того, чтобы разобраться с оставшейся частью, понадобятся серьезные " -"усилия." - -msgid "" -"An LSM tree in vinyl is just a small piece of the puzzle. Even with a single" -" table (or so-called \"space\"), vinyl creates and maintains several LSM " -"trees, one for each index. But even a single index can be comprised of " -"dozens of LSM trees. Let’s try to understand why this might be necessary." -msgstr "" -"В vinyl'е устройство одного LSM-дерева -- это лишь фрагмент мозаики. Vinyl " -"создает и обслуживает несколько LSM-деревьев даже для одной таблицы (так " -"называемого спейса) -- по одному дереву на каждый индекс. Но даже один " -"единственный индекс может состоять из десятков LSM-деревьев. Попробуем " -"разобраться, зачем." - -msgid "" -"Recall our example with a tree containing 100,000,000 records, 100 bytes " -"each. As time passes, the lowest LSM level may end up holding a 10 Gb run. " -"During compaction, a temporary run of approximately the same size will be " -"created. Data at intermediate levels takes up some space as well, since the " -"tree may store several operations associated with a single key. In total, " -"storing 10 Gb of actual data may require up to 30 Gb of free space: 10 Gb " -"for the last tree level, 10 Gb for a temporary run, and 10 Gb for the " -"remaining data. But what if the data size is not 10 Gb, but 1 Tb? Requiring " -"that the available disk space always be several times greater than the " -"actual data size is financially unpractical, not to mention that it may take" -" dozens of hours to create a 1 Tb run. And in the case of an emergency " -"shutdown or system restart, the process would have to be started from " -"scratch." -msgstr "" -"Рассмотрим наш стандартный пример: 100 000 000 записей по 100 байтов каждая." -" Через некоторое время на самом нижнем уровне LSM у нас может оказаться файл" -" размером 10 ГБ. Во время слияния последнего уровня мы создадим временный " -"файл, который также будет занимать около 10 ГБ. Данные на промежуточных " -"уровнях тоже занимают место: по одному и тому же ключу дерево может хранить " -"несколько операций. Суммарно для хранения 10 ГБ полезных данных нам может " -"потребоваться до 30 ГБ свободного места: 10 ГБ на последний уровень, 10 ГБ " -"на временный файл и 10 ГБ на всё остальное. А если данных не 1 ГБ, а 1 ТБ? " -"Требовать, чтобы количество свободного места на диске всегда в несколько раз" -" превышало объем полезных данных, экономически нецелесообразно, да и " -"создание файла в 1ТБ может занимать десятки часов. При любой аварии или " -"перезапуске системы операцию придется начинать заново." - -msgid "" -"Here’s another scenario. Suppose the primary key is a monotonically " -"increasing sequence—for example, a time series. In this case, most " -"insertions will fall into the right part of the key range, so it wouldn’t " -"make much sense to do a compaction just to append a few million more records" -" to an already huge run." -msgstr "" -"Рассмотрим другую проблему. Представим, что первичный ключ дерева -- это " -"монотонная последовательность, например, временной ряд. В этом случае " -"основные вставки будут приходиться на правую часть диапазона ключей. Нет " -"смысла заново производить слияние лишь для того, чтобы дописать в конец и " -"без того огромного файла еще несколько миллионов записей." - -msgid "" -"But what if writes predominantly occur in a particular region of the key " -"range, whereas most reads take place in a different region? How do you " -"optimize the form of the LSM tree in this case? If it’s too high, read " -"performance is impacted; if it’s too low—write speed is reduced." -msgstr "" -"А если вставки происходят, в основном, в одну часть диапазона ключей, а " -"чтения -- из другой части? Как в этом случае оптимизировать форму дерева? " -"Если оно будет слишком высоким, пострадают чтения, если слишком низким -- " -"запись." - -msgid "" -"Tarantool \"factorizes\" this problem by creating multiple LSM trees for " -"each index. The approximate size of each subtree may be controlled by the " -":ref:`vinyl_range_size ` configuration " -"parameter. We call such subtrees \"ranges\"." -msgstr "" -"Tarantool \"факторизует\" проблему, создавая не одно, а множество LSM-" -"деревьев для каждого индекса. Примерный размер каждого поддерева можно " -"задать в конфигурационном параметре ``vinyl_range_size``. Такие поддеревья " -"называется диапазонами (\"range\")." - -msgid "Factorizing large LSM trees via ranging" -msgstr "Факторизация больших LSM-деревьев с помощью диапазонов" - -msgid "Ranges reflect a static layout of sorted runs" -msgstr "Диапазоны отражают статичную структуру упорядоченных файлов" - -msgid "Slices connect a sorted run into a range" -msgstr "Срезы объединяют упорядоченный файл в диапазон" - -msgid "" -"Initially, when the index has few elements, it consists of a single range. " -"As more elements are added, its total size may exceed :ref:`the maximum " -"range size `. In that case a special operation" -" called \"split\" divides the tree into two equal parts. The tree is split " -"at the middle element in the range of keys stored in the tree. For example, " -"if the tree initially stores the full range of -inf…+inf, then after " -"splitting it at the middle key X, we get two subtrees: one that stores the " -"range of -inf...X, and the other storing the range of X…+inf. With this " -"approach, we always know which subtree to use for writes and which one for " -"reads. If the tree contained deletions and each of the neighboring ranges " -"grew smaller as a result, the opposite operation called \"coalesce\" " -"combines two neighboring trees into one." -msgstr "" -"Изначально, пока в индексе мало элементов, он состоит из одного диапазона. " -"По мере добавления элементов суммарный объем может превысить " -":ref:`максимальный размер диапазона `. В таком" -" случае выполняется операция под названием \"разделение\" (split), которая " -"делит дерево на две равные части. Разделение происходит по срединному " -"элементу диапазона ключей, хранящихся в дереве. Например, если изначально " -"дерево хранит полный диапазон -inf… +inf, то после разделения по срединному " -"ключу X получим два поддерева: одно будет хранить все ключи от -inf до X, " -"другое -- от X до +inf. Таким образом, при вставке или чтении мы однозначно " -"знаем, к какому поддереву обращаться. Если в дереве были удаления и каждый " -"из соседних диапазонов уменьшился, выполняется обратная операция под " -"названием \"объединение\" (coalesce). Она объединяет два соседних дерева в " -"одно." - -msgid "" -"Split and coalesce don’t entail a compaction, the creation of new runs, or " -"other resource-intensive operations. An LSM tree is just a collection of " -"runs. vinyl has a special metadata log that helps keep track of which run " -"belongs to which subtree(s). This has the `.vylog` extension and its format " -"is compatible with an .xlog file. Similarly to an `.xlog` file, the metadata" -" log gets rotated at each checkpoint. To avoid the creation of extra runs " -"with split and coalesce, we have also introduced an auxiliary entity called " -"\"slice\". It’s a reference to a run containing a key range and it’s stored " -"only in the metadata log. Once the reference counter drops to zero, the " -"corresponding file gets removed. When it’s necessary to perform a split or " -"to coalesce, Tarantool creates slice objects for each new tree, removes " -"older slices, and writes these operations to the metadata log, which " -"literally stores records that look like this: ```` or " -"````." -msgstr "" -"Разделение и объединение не приводят к слиянию, созданию новых файлов и " -"прочим тяжеловесным операциям. LSM-дерево -- это лишь набор файлов. В " -"vinyl'е мы реализовали специальный журнал метаданных, позволяющий легко " -"отслеживать, какой файл принадлежит какому поддереву или поддеревьям. Журнал" -" имеет расширение `.vylog`, по формату он совместим с файлом `.xlog`. Как и " -"файл `.xlog`, происходит автоматическая ротация файла при каждой контрольной" -" точке. Чтобы избежать повторного создания файлов при разделении и " -"объединении, мы ввели промежуточную сущность -- срез (slice). Это ссылка на " -"файл с указанием диапазона значений ключа, которая хранится исключительно в " -"журнале метаданных. Когда число ссылок на файл становится равным нулю, файл " -"удаляется. А когда необходимо произвести разделение или объединение, " -"Tarantool создает срезы для каждого нового дерева, старые срезы удаляет, и " -"записывает эти операции в журнал метаданных. Буквально, журнал метаданных " -"хранит записи вида <идентификатор дерева, идентификатор среза> или " -"<идентификатор среза, идентификатор файла, мин, макс>." - -msgid "" -"This way all of the heavy lifting associated with splitting a tree into two " -"subtrees is postponed until a compaction and then is performed " -"automatically. A huge advantage of dividing all of the keys into ranges is " -"the ability to independently control the L0 size as well as the dump and " -"compaction processes for each subtree, which makes these processes " -"manageable and predictable. Having a separate metadata log also simplifies " -"the implementation of both \"truncate\" and \"drop\". In vinyl, they’re " -"processed instantly, since they only work with the metadata log, while " -"garbage collection is done in the background." -msgstr "" -"Таким образом, непосредственно тяжелая работа по разбиению дерева на два поддерева, откладывается до слияния и выполняется автоматически.\n" -"Огромным преимуществом подхода с разделением всего диапазона ключей на диапазоны является возможность независимо управлять размером L0, а также процессом создания дампов и слиянием для каждого поддерева. В результате эти процессы являются управляемыми и предсказуемыми. Наличие отдельного журнала метаданных также упрощает выполнение таких операций, как усечение и удаление -- в vinyl'е они обрабатываются мгновенно, потому что работают исключительно с журналом метаданных, а удаление мусора выполняется в фоне." - -msgid "Advanced features of vinyl" -msgstr "Расширенные возможности vinyl'а" - -msgid "Upsert" -msgstr "Upsert (обновление и вставка)" - -msgid "" -"In the previous sections, we mentioned only two operations stored by an LSM " -"tree: deletion and replacement. Let’s take a look at how all of the other " -"operations can be represented. An insertion can be represented via a " -"replacement—you just need to make sure there are no other elements with the " -"specified key. To perform an update, it’s necessary to read the older value " -"from the tree, so it’s easier to represent this operation as a replacement " -"as well—this speeds up future read requests by the key. Besides, an update " -"must return the new value, so there’s no avoiding hidden reads." -msgstr "" -"В предыдущих разделах упоминались лишь две операции, которые хранит LSM-" -"дерево: удаление и замена. Давайте рассмотрим, как представлены все " -"остальные. Вставку можно представить с помощью замены -- необходимо лишь " -"предварительно убедиться в отсутствии элемента указанным ключом. Для " -"выполнения обновления необходимо предварительно считывать старое значение из" -" дерева, так что и эту операцию проще записать в дерево как замену -- это " -"ускорит будущие чтения по этому ключу. Кроме того, обновление должно вернуть" -" новое значение, так что скрытых чтений никак не избежать." - -msgid "" -"In B-trees, the cost of hidden reads is negligible: to update a block, it " -"first needs to be read from disk anyway. Creating a special update operation" -" for an LSM tree that doesn’t cause any hidden reads is really tempting." -msgstr "" -"В B-деревьях скрытые чтения почти ничего не стоят: чтобы обновить блок, его " -"в любом случае необходимо прочитать с диска. Для LSM-деревьев идея создания " -"специальной операции обновления, которая не приводила бы к скрытым чтениям, " -"выглядит очень заманчивой." - -msgid "" -"Such an operation must contain not only a default value to be inserted if a " -"key has no value yet, but also a list of update operations to perform if a " -"value does exist." -msgstr "" -"Такая операция должна содержать как значение по умолчанию, которое нужно " -"вставить, если данных по ключу еще нет, так и список операций обновления, " -"которые нужно выполнить, если значение существует." - -msgid "" -"At transaction execution time, Tarantool just saves the operation in an LSM " -"tree, then \"executes\" it later, during a compaction." -msgstr "" -"На этапе выполнения транзакции Tarantool лишь сохраняет всю операцию в LSM-" -"дереве, а \"выполняет\" ее уже только во время слияния." - -msgid "The upsert operation:" -msgstr "Операция обновления и вставки:" - -msgid "space:upsert(tuple, {{operator, field, value}, ... })" -msgstr "space:upsert(tuple, {{operator, field, value}, ... })" - -msgid "Non-reading update or insert" -msgstr "Обновление без чтения или вставка" - -msgid "Delayed execution" -msgstr "Отложенное выполнение" - -msgid "Background upsert squashing prevents upserts from piling up" -msgstr "" -"Фоновое сжатие операций обновления и вставки предотвращает накапливание " -"операций" - -msgid "" -"Unfortunately, postponing the operation execution until a compaction doesn’t" -" leave much leeway in terms of error handling. That’s why Tarantool tries to" -" validate upserts as fully as possible before writing them to an LSM tree. " -"However, some checks are only possible with older data on hand, for example " -"when the update operation is trying to add a number to a string or to remove" -" a field that doesn’t exist." -msgstr "" -"К сожалению, если откладывать выполнение операции на этап слияния, " -"возможностей для обработки ошибок не остается. Поэтому Tarantool стремится " -"максимально проверять операции обновления и вставки upsert перед записью в " -"дерево. Тем не менее, некоторые проверки можно выполнить лишь имея старые " -"данные на руках. Например, если обновление прибавляет число к строке или " -"удаляет несуществующее поле." - -msgid "" -"A semantically similar operation exists in many products including " -"PostgreSQL and MongoDB. But anywhere you look, it’s just syntactic sugar " -"that combines the update and replace operations without avoiding hidden " -"reads. Most probably, the reason is that LSM trees as data storage " -"structures are relatively new." -msgstr "" -"Операция с похожей семантикой присутствует во многих продуктах, в том числе " -"в PostgreSQL и MongoDB. Но везде она представляет собой лишь синтаксический " -"сахар, объединяющий обновление и вставку, не избавляя СУБД от необходимости " -"выполнять скрытые чтения. Скорее всего, причиной этого является " -"относительная новизна LSM-деревьев в качестве структур данных для хранения." - -msgid "" -"Even though an upsert is a very important optimization and implementing it " -"cost us a lot of blood, sweat, and tears, we must admit that it has limited " -"applicability. If a table contains secondary keys or triggers, hidden reads " -"can’t be avoided. But if you have a scenario where secondary keys are not " -"required and the update following the transaction completion will certainly " -"not cause any errors, then the operation is for you." -msgstr "" -"Хотя обновление и вставка upsert представляет собой очень важную " -"оптимизацию, и ее реализация стоила нам долгой напряженной работы, следует " -"признать, что ее применимость ограничена. Если в таблице есть вторичные " -"ключи или триггеры, скрытых чтений не избежать. А если у вас есть сценарии, " -"для которых не нужны вторичные ключи и обновление после завершения " -"транзакции однозначно не приведет к ошибкам -- эта операция для вас." - -msgid "" -"I’d like to tell you a short story about an upsert. It takes place back when" -" vinyl was only beginning to \"mature\" and we were using an upsert in " -"production for the first time. We had what seemed like an ideal environment " -"for it: we had tons of keys, the current time was being used as values; " -"update operations were inserting keys or modifying the current time; and we " -"had few reads. Load tests yielded great results." -msgstr "" -"Небольшая история, связанная с этим оператором: vinyl только начинал " -"\"взрослеть\", и мы впервые запустили операцию обновления и вставки upsert " -"на рабочие серверы. Казалось бы, идеальные условия: огромный набор ключей, " -"текущее время в качестве значения, операции обновления либо вставляют ключ, " -"либо обновляют текущее время, редкие операции чтения. Нагрузочные тесты " -"показали отличные результаты." - -msgid "" -"Nevertheless, after a couple of days, the Tarantool process started eating " -"up 100% of our CPU, and the system performance dropped close to zero." -msgstr "" -"Тем не менее, после пары дней работы процесс Tarantool'а начал потреблять " -"100 % CPU, а производительность системы упала практически до нуля." - -msgid "" -"We started digging into the issue and found out that the distribution of " -"requests across keys was significantly different from what we had seen in " -"the test environment. It was...well, quite nonuniform. Most keys were " -"updated once or twice a day, so the database was idle for the most part, but" -" there were much hotter keys with tens of thousands of updates per day. " -"Tarantool handled those just fine. But in the case of lookups by key with " -"tens of thousands of upserts, things quickly went downhill. To return the " -"most recent value, Tarantool had to read and \"replay\" the whole history " -"consisting of all of the upserts. When designing upserts, we had hoped this " -"would happen automatically during a compaction, but the process never even " -"got to that stage: the L0 size was more than enough, so there were no dumps." -msgstr "" -"Начали подробно изучать проблему. Оказалось, что распределение запросов по " -"ключам существенно отличалось от того, что мы видели в тестовом окружении. " -"Оно было… очень неравномерное. Большая часть ключей обновлялась 1-2 раза за " -"сутки, и база для них не была нагружена. Но были ключи гораздо более горячие" -" -- десятки тысяч обновлений в сутки. Tarantool прекрасно справлялся с этим " -"потоком обновлений. А вот когда по ключу с десятком тысяч операций " -"обновления и вставки upsert происходило чтение, всё шло под откос. Чтобы " -"вернуть последнее значение, Tarantool'у приходилось каждый раз прочитать и " -"\"проиграть\" историю из десятков тысяч команд обновления и вставки upsert. " -"На стадии проекта мы надеялись, что это произойдет автоматически во время " -"слияния уровней, но до слияния дело даже не доходило: памяти L0 было " -"предостаточно, и дампы не создавались." - -msgid "" -"We solved the problem by adding a background process that performed " -"readaheads on any keys that had more than a few dozen upserts piled up, so " -"all those upserts were squashed and substituted with the read value." -msgstr "" -"Решили мы проблему добавлением фонового процесса, осуществляющего " -"упреждающие чтения для ключей, по которым накопилось больше нескольких " -"десятков операций обновления и вставки upsert с последующей заменой на " -"прочитанное значение." - -msgid "Secondary keys" -msgstr "Вторичные ключи" - -msgid "" -"Update is not the only operation where optimizing hidden reads is critical. " -"Even the replace operation, given secondary keys, has to read the older " -"value: it needs to be independently deleted from the secondary indexes, and " -"inserting a new element might not do this, leaving some garbage behind." -msgstr "" -"Не только для операции обновления остро стоит проблема оптимизации скрытых " -"чтений. Даже операция замены при наличии вторичных ключей вынуждена читать " -"старое значение: его нужно независимо удалить из вторичных индексов, а " -"вставка нового элемента может этого не сделать, оставив в индексе мусор." - -msgid "" -"If secondary indexes are not unique, then collecting \"garbage\" from them " -"can be put off until a compaction, which is what we do in Tarantool. The " -"append-only nature of LSM trees allowed us to implement full-blown " -"serializable transactions in vinyl. Read-only requests use older versions of" -" data without blocking any writes. The transaction manager itself is fairly " -"simple for now: in classical terms, it implements the MVTO (multiversion " -"timestamp ordering) class, whereby the winning transaction is the one that " -"finished earlier. There are no locks and associated deadlocks. Strange as it" -" may seem, this is a drawback rather than an advantage: with parallel " -"execution, you can increase the number of successful transactions by simply " -"holding some of them on lock when necessary. We’re planning to improve the " -"transaction manager soon. In the current release, we focused on making the " -"algorithm behave 100% correctly and predictably. For example, our " -"transaction manager is one of the few on the NoSQL market that supports so-" -"called \"gap locks\"." -msgstr "" -"Если вторичные индексы не уникальны, то удаление из них \"мусора\" также " -"можно перенести в фазу слияния, что мы и делаем в Tarantool'е. Природа LSM-" -"дерева, в котором файлы обновляются путем присоединения новых записей, " -"позволила нам реализовать в vinyl'е полноценные сериализуемые транзакции. " -"Запросы только для чтения при этом используют старые версии данных и не " -"блокируют запись. Сам менеджер транзакций пока довольно простой: в " -"традиционной классификации он реализует класс MVTO (multiversion timestamp " -"ordering -- упорядочение временных меток на основе многоверсионности), при " -"этом в конфликте побеждает та транзакция, что завершилась первой. Блокировок" -" и свойственных им взаимоблокировок нет. Как ни странно, это скорее " -"недостаток, чем преимущество: при параллельном выполнении можно повысить " -"количество успешных транзакций, задерживая некоторые из них в нужный момент " -"на блокировке. Развитие менеджера транзакций в наших ближайших планах. В " -"текущей версии мы сфокусировались на том, чтобы сделать алгоритм корректным " -"и предсказуемым на 100%. Например, наш менеджер транзакций -- один из " -"немногих в NoSQL-среде, поддерживающих так называемые \"блокировки " -"разрывов\" (gap locks)." diff --git a/locale/ru/LC_MESSAGES/book/box/engines/memtx.po b/locale/ru/LC_MESSAGES/book/box/engines/memtx.po new file mode 100644 index 0000000000..308c09dfdc --- /dev/null +++ b/locale/ru/LC_MESSAGES/book/box/engines/memtx.po @@ -0,0 +1,372 @@ + +msgid "Storing data with memtx" +msgstr "Хранение данных с помощью memtx" + +msgid "" +"The ``memtx`` storage engine is used in Tarantool by default. It keeps all " +"data in random-access memory (RAM), and therefore has very low read latency." +msgstr "" +"Движок базы данных ``memtx`` используется в Tarantool по умолчанию. Он " +"хранит все данные в оперативной памяти (RAM), поэтому значение задержки " +"чтения у него очень низкое." + +msgid "" +"The obvious question here is: if all the data is stored in memory, how can " +"you prevent the data loss in case of emergency such as outage or Tarantool " +"instance failure?" +msgstr "" +"Очевидный вопрос: если все данные хранятся в памяти, как можно предотвратить" +" их потерю в случае чрезвычайной ситуации, например при отключении " +"электропитания или сбое экземпляра Tarantool?" + +msgid "" +"First of all, Tarantool persists all data changes by writing requests to the" +" write-ahead log (WAL) that is stored on disk. Read more about that in the " +":ref:`memtx-persist` section. In case of a distributed application, there is" +" an option of synchronous replication that ensures keeping the data " +"consistent on a quorum of replicas. Although replication is not directly a " +"storage engine topic, it is a part of the answer regarding data safety. Read" +" more in the :ref:`memtx-replication` section." +msgstr "" +"Прежде всего, Tarantool сохраняет все изменения данных, записывая запросы в " +"журнал упреждающей записи (WAL), хранящийся на диске. Подробнее это описано " +"в разделе :ref:`memtx-persist`. В случае распределенного приложения возможна" +" синхронная репликация, которая обеспечивают согласованность данных в " +"кворуме реплик. Хотя репликация напрямую не относится к механизму хранения, " +"она отчасти способствует безопасности данных. Подробности можно найти в " +"разделе :ref:`memtx-replication`." + +msgid "" +"In this chapter, the following topics are discussed in brief with the " +"references to other chapters that explain the subject matter in details." +msgstr "" +"Ниже указаны темы, которые обсуждаются в этой главе. В тексте вы также " +"найдете ссылки на главы с подробными сведениями по каждой из тем." + +msgid "Memory model" +msgstr "Модель памяти" + +msgid "" +"There is a fixed number of independent :ref:`execution threads `. The threads don't share state. Instead they " +"exchange data using low-overhead message queues. While this approach limits " +"the number of cores that the instance uses, it removes competition for the " +"memory bus and ensures peak scalability of memory access and network " +"throughput." +msgstr "" +"Есть фиксированное количество независимых :ref:`потоков выполнения `. У этих потоков нет общего состояния. Вместо этого " +"они обмениваются данными через очереди сообщений с низкими накладными " +"расходами. Хотя такой подход ограничивает количество ядер, которое может " +"использовать экземпляр, он устраняет конкуренцию за шину памяти и " +"обеспечивает максимальную масштабируемость доступа к памяти и пропускной " +"способности сети." + +msgid "" +"Only one thread, namely, the **transaction processor thread** (further, **TX" +" thread**) can access the database, and there is only one TX thread for each" +" Tarantool instance. In this thread, transactions are executed in a strictly" +" consecutive order. Multi-statement transactions exist to provide isolation:" +" each transaction sees a consistent database state and commits all its " +"changes atomically. At commit time, a yield happens and all transaction " +"changes are written to :ref:`WAL ` in a single batch. In case" +" of errors during transaction execution, a transaction is rolled-back " +"completely. Read more in the following sections: :ref:`atomic-transactions`," +" :ref:`atomic-transactional-manager`." +msgstr "" +"Обращаться к базе данных может только **поток обработчика транзакций** " +"(далее — **поток TX**). В каждом экземпляре Tarantool есть только один такой" +" поток. Транзакции в этом потоке выполняются строго последовательно. " +"Транзакции, состоящие из нескольких инструкций, обеспечивают изоляцию: " +"каждая транзакция видит согласованное состояние базы данных и применяет " +"коммит со всеми своими изменениями атомарно. Во время коммита происходит " +"передача управления, и все изменения транзакции записываются в :ref:`WAL-" +"файл ` одним пакетом. Если во время выполнения транзакции " +"произошли ошибки, она полностью отменяется. Подробности можно найти в " +"следующих разделах: :ref:`atomic-transactions`, :ref:`atomic-transactional-" +"manager`." + +msgid "" +"Within the TX thread, there is a memory area allocated for Tarantool to " +"store data. It's called **Arena**." +msgstr "" +"Внутри потока TX есть область памяти, в которой Tarantool хранит данные. Эта" +" область называется **Arena**." + +msgid "" +"Data is stored in :term:`spaces `. Spaces contain database " +"records—:term:`tuples `. To access and manipulate the data stored in " +"spaces and tuples, Tarantool builds :doc:`indexes `." +msgstr "" +"Данные хранятся в :term:`спейсах `. Спейсы содержат записи базы " +"данных — :term:`кортежи `. Чтобы обращаться к данным, хранящимся в " +"спейсах и кортежах, и изменять их, Tarantool создаёт :doc:`индексы " +"`." + +msgid "" +"Special `allocators `__ manage memory " +"allocations for spaces, tuples, and indexes within the Arena. The slab " +"allocator is the main allocator used to store tuples. Tarantool has a built-" +"in module called ``box.slab`` which provides the slab allocator statistics " +"that can be used to monitor the total memory usage and memory fragmentation." +" For details, see the ``box.slab`` module :doc:`reference " +"`." +msgstr "" +"Распределением памяти для спейсов, кортежей и индексов внутри области Arena " +"управляют специальные `аллокаторы `__. " +"Для хранения кортежей главным образом используется аллокатор slab. В " +"Tarantool встроен модуль под названием ``box.slab``, предоставляющий " +"статистику распределения slab. С помощью этой статистики можно отслеживать " +"общее использование памяти и ее фрагментацию. Подробности см. в :doc:` " +"руководстве ` по модулю ``box.slab``." + +msgid "" +"Also inside the TX thread, there is an event loop. Within the event loop, " +"there are a number of :ref:`fibers `. Fibers are cooperative " +"primitives that allows interaction with spaces, that is, reading and " +"writting the data. Fibers can interact with the event loop and between each " +"other directly or by using special primitives called channels. Due to the " +"usage of fibers and :ref:`cooperative multitasking `, the ``memtx`` engine is lock-free in typical " +"situations." +msgstr "" +"Внутри потока TX также есть цикл событий. Этот цикл содержит несколько " +":ref:`файберов ` — кооперативных примитивов, позволяющих " +"взаимодействовать со спейсами, то есть читать и записывать данные. Файберы " +"могут обращаться к циклу событий и друг к другу как напрямую, так и " +"посредством специальных примитивов, называемых каналами. Благодаря " +"использованию файберов и :ref:`кооперативной многозадачности ` движок ``memtx``, как правило, свободен от " +"блокировок." + +msgid "" +"To interact with external users, there is a separate :ref:`network thread " +"` also called the **iproto thread**. The " +"iproto thread receives a request from the network, parses and checks the " +"statement, and transforms it into a special structure—a message containing " +"an executable statement and its options. Then the iproto thread ships this " +"message to the TX thread and runs the user's request in a separate fiber." +msgstr "" +"Чтобы взаимодействовать с внешними пользователями, используется отдельный " +":ref:`сетевой поток `, называемый также " +"**поток iproto**. Поток iproto получает запрос из сети, разбирает и " +"проверяет инструкцию из него, а затем преобразует ее в специальную структуру" +" — сообщение, содержащее исполнимую инструкцию с параметрами. Затем iproto " +"доставляет это сообщение в поток TX и исполняет запрос пользователя в " +"отдельном файбере." + +msgid "Data persistence" +msgstr "Персистентность данных" + +msgid "" +"To ensure :ref:`data persistence `, Tarantool does " +"two things." +msgstr "" +"Чтобы обеспечить :ref:`персистентность данных `, " +"Tarantool выполняет следующие действия." + +msgid "" +"After executing data change requests in memory, Tarantool writes each such " +"request to the :ref:`write-ahead log (WAL) ` files " +"(``.xlog``) that are stored on disk. Tarantool does this via a separate " +"thread called the **WAL thread**." +msgstr "" +"Исполнив в памяти запросы на изменение данных, Tarantool записывает все эти " +"запросы в файлы :ref:`журнала упреждающей записи (WAL) ` (с " +"расширением ``.xlog``), хранящиеся на диске. Это делается в отдельном " +"потоке, называемом **поток WAL**." + +msgid "" +"Tarantool periodically takes the entire :doc:`database snapshot " +"` and saves it on disk. It is " +"necessary for accelerating instance's restart because when there are too " +"many WAL files, it can be difficult for Tarantool to restart quickly." +msgstr "" +"Tarantool периодически делает :doc:`снимок всей базы данных " +"` и сохраняет его на диск. Это " +"необходимо для ускорения перезапуска экземпляра, так как если файлов WAL " +"слишком много, то Tarantool не сможет быстро перезапуститься." + +msgid "" +"To save a snapshot, there is a special fiber called the **snapshot daemon**." +" It reads the consistent content of the entire Arena and writes it on disk " +"into a snapshot file (``.snap``). Due of the cooperative multitasking, " +"Tarantool cannot write directly on disk because it is a locking operation. " +"That is why Tarantool interacts with disk via a separate pool of threads " +"from the :doc:`fio ` library." +msgstr "" +"Специальный файбер под названием **демон снимков** (**snapshot daemon**) " +"позволяет сохранять снимки. Он читает консистентное содержимое всей области " +"Arena и записывает его на диск в файл снимка (с расширением ``.snap``). Из-" +"за кооперативной многозадачности Tarantool не может записывать данные " +"непосредственно на диск, так как это блокирующая операция. Поэтому Tarantool" +" взаимодействует с диском через отдельный пул потоков из библиотеки " +":doc:`fio `." + +msgid "" +"So, even in emergency situations such as an outage or a Tarantool instance " +"failure, when the in-memory database is lost, the data can be restored fully" +" during Tarantool restart." +msgstr "" +"Таким образом, при перезапуске Tarantool данные можно полностью восстановить" +" даже в аварийных ситуациях, например при отключении питания или падении " +"экземпляра Tarantool, когда хранящаяся в оперативной памяти база данных " +"утеряна." + +msgid "What happens during the restart:" +msgstr "Что происходит при перезапуске:" + +msgid "Tarantool finds the latest snapshot file and reads it." +msgstr "Tarantool находит и читает последний файл снимка." + +msgid "" +"Tarantool finds all the WAL files created after that snapshot and reads them" +" as well." +msgstr "" +"Tarantool также находит и читает все файлы WAL, созданные после этого " +"снимка." + +msgid "" +"When the snapshot and WAL files have been read, there is a fully recovered " +"in-memory data set corresponding to the state when the Tarantool instance " +"stopped." +msgstr "" +"Как только снимок и файлы WAL будут прочитаны, набор данных в памяти будет " +"полностью восстановлен. Он будет соответствовать состоянию экземпляра " +"Tarantool на момент, когда тот прекратил работу." + +msgid "" +"While reading the snapshot and WAL files, Tarantool is building the primary " +"indexes." +msgstr "" +"Во время чтения снимка и файлов WAL Tarantool строит первичные индексы." + +msgid "" +"When all the data is in memory again, Tarantool is building the secondary " +"indexes." +msgstr "Когда все данные снова в памяти, Tarantool строит вторичные индексы." + +msgid "Tarantool runs the application." +msgstr "Tarantool запускает приложение." + +msgid "Accessing data" +msgstr "Доступ к данным" + +msgid "" +"To access and manipulate the data stored in memory, Tarantool builds " +"indexes. Indexes are also stored in memory within the Arena." +msgstr "" +"Чтобы обращаться к данным, хранящимся в оперативной памяти, и работать с " +"ними, Tarantool строит индексы, которые хранятся внутри области памяти " +"Arena." + +msgid "" +"Tarantool supports a number of :ref:`index types ` intended for" +" different usage scenarios. The possible types are TREE, HASH, BITSET, and " +"RTREE." +msgstr "" +"Tarantool поддерживает несколько :ref:`типов индексов `: TREE, " +"HASH, BITSET, RTREE. Все они предназначены для разных сценариев " +"использования." + +msgid "" +"Select query are possible against secondary index keys as well as primary " +"keys. Indexes can have multi-part keys." +msgstr "" +"Можно выполнять SELECT-запросы как по первичным, так и по вторичным ключам " +"индекса. Ключи могут быть составными." + +msgid "" +"For detailed information about indexes, refer to the " +":doc:`/book/box/indexes` page." +msgstr "" +"Подробности про индексы можно найти на странице :doc:`/book/box/indexes`." + +msgid "Replicating data" +msgstr "Репликация данных" + +msgid "" +"Although this topic is not directly related to the ``memtx`` engine, it " +"completes the overall picture of how Tarantool works in case of a " +"distributed application." +msgstr "" +"Хотя эта тема не имеет прямого отношения к движку ``memtx``, она дополняет " +"общую картину того, как работает Tarantool, когда приложение распределенное." + +msgid "" +"Replication allows multiple Tarantool instances to work on copies of the " +"same database. The copies are kept in sync because each instance can " +"communicate its changes to all the other instances. It is implemented via " +"WAL replication." +msgstr "" +"Репликация позволяет нескольким экземплярам Tarantool работать с копиями " +"одной и той же базы данных. Эти копии остаются синхронизированными благодаря" +" тому, что каждый экземпляр может сообщать другим экземплярам о совершенных " +"им изменениях. Для этого используется WAL-репликация." + +msgid "" +"To send data to a replica, Tarantool runs another thread called **relay**. " +"Its purpose is to read the WAL files and send them to replicas. On a " +"replica, the fiber called **applier** is run. It receives the changes from a" +" remote node and applies them to the replica's Arena. All the changes are " +"being written to WAL files via the replica's WAL thread as if they are done " +"locally." +msgstr "" +"Чтобы отправить данные на реплику, Tarantool запускает еще один поток, " +"называемый **relay**. Этот поток читает файлы WAL и отправляет их репликам. " +"На каждой реплике выполняется файбер под названием **applier**. Он получает " +"изменения от удаленного узла и применяет их к области Arena реплики. Все " +"изменения записываются в файлы WAL через поток WAL реплики так же, как если " +"бы они были сделаны локально." + +msgid "" +"By default, :ref:`replication ` in Tarantool is " +"asynchronous: if a transaction is committed locally on a master node, it " +"does not mean it is replicated onto any replicas." +msgstr "" +"В Tarantool :ref:`репликация ` по умолчанию " +"асинхронна: то, что транзакция проходит коммит локально на главном узле, не " +"означает, что она отправляется на какие-то другие реплики." + +msgid "" +":ref:`Synchronous replication ` exists to solve this problem. " +"Synchronous transactions are not considered committed and are not responded " +"to a client until they are replicated onto some number of replicas." +msgstr "" +"Эту проблему решает :ref:`синхронная репликация `. Каждая " +"синхронная транзакция проходит коммит лишь после репликации на некотором " +"количестве экземпляров, и только тогда клиенту приходит ответ о завершении " +"транзакции." + +msgid "" +"For more information on replication, refer to the :doc:`corresponding " +"chapter `." +msgstr "" +"Более подробные сведения вы найдете в :doc:`главе о репликации " +"`." + +msgid "Summary" +msgstr "Ключевые сведения" + +msgid "" +"The main key points describing how the in-memory storage engine works can be" +" summarized in the following way:" +msgstr "Вот главные принципы, по которым работает движок:" + +msgid "All data is in RAM." +msgstr "Все данные находятся в оперативной памяти." + +msgid "Access to data is from one thread." +msgstr "Доступ к данным производится только из одного потока." + +msgid "Tarantool writes all data change requests in WAL." +msgstr "Tarantool записывает все изменения данных в файлы WAL." + +msgid "Data snapshots are taken periodically." +msgstr "Периодически создаются снимки данных." + +msgid "Indexes are build to access the data." +msgstr "Для доступа к данным создаются индексы." + +msgid "WAL can be replicated." +msgstr "Файлы WAL можно реплицировать." diff --git a/locale/ru/LC_MESSAGES/book/box/engines/vinyl.po b/locale/ru/LC_MESSAGES/book/box/engines/vinyl.po new file mode 100644 index 0000000000..4395c2ed1a --- /dev/null +++ b/locale/ru/LC_MESSAGES/book/box/engines/vinyl.po @@ -0,0 +1,1474 @@ + +msgid "Storing data with vinyl" +msgstr "Хранение данных с помощью vinyl" + +msgid "" +"Tarantool is a transactional and persistent DBMS that maintains 100% of its " +"data in RAM. The greatest advantages of in-memory databases are their speed " +"and ease of use: they demonstrate consistently high performance, but you " +"never need to tune them." +msgstr "" +"Tarantool -- это транзакционная, персистентная СУБД, которая хранит 100% " +"данных в оперативной памяти. Основными преимущества хранения данных " +"оперативной памяти являются скорость и простота использования: нет " +"необходимости в оптимизации, однако производительность остается стабильно " +"высокой." + +msgid "" +"A few years ago we decided to extend the product by implementing a classical" +" storage engine similar to those used by regular DBMSs: it uses RAM for " +"caching, while the bulk of its data is stored on disk. We decided to make it" +" possible to set a storage engine independently for each table in the " +"database, which is the same way that MySQL approaches it, but we also wanted" +" to support transactions from the very beginning." +msgstr "" +"Несколько лет назад мы решили расширить продукт путем реализации " +"классической технологии хранения как в обычных СУБД: в оперативной памяти " +"хранится лишь кэш данных, а основной объем данных находится на диске. Мы " +"решили, что движок хранения можно будет выбирать независимо для каждой " +"таблицы, как это реализовано в MySQL, но при этом с самого начала будет " +"реализована поддержка транзакций." + +msgid "" +"The first question we needed to answer was whether to create our own storage" +" engine or use an existing library. The open-source community offered a few " +"viable solutions. The RocksDB library was the fastest growing open-source " +"library and is currently one of the most prominent out there. There were " +"also several lesser-known libraries to consider, such as WiredTiger, " +"ForestDB, NestDB, and LMDB." +msgstr "" +"Первый вопрос, на который нужен был ответ: создавать свой движок или " +"использовать уже существующую библиотеку? Сообщество разработчиков открытого" +" ПО предлагает готовые библиотеки на выбор. Активнее всего развивалась " +"библиотека RocksDB, которая к настоящему времени стала одной из самых " +"популярных. Есть также несколько менее известных библиотек: WiredTiger, " +"ForestDB, NestDB, LMDB." + +msgid "" +"Nevertheless, after studying the source code of existing libraries and " +"considering the pros and cons, we opted for our own storage engine. One " +"reason is that the existing third-party libraries expected requests to come " +"from multiple operating system threads and thus contained complex " +"synchronization primitives for controlling parallel data access. If we had " +"decided to embed one of these in Tarantool, we would have made our users " +"bear the overhead of a multithreaded application without getting anything in" +" return. The thing is, Tarantool has an actor-based architecture. The way it" +" processes transactions in a dedicated thread allows it to do away with the " +"unnecessary locks, interprocess communication, and other overhead that " +"accounts for up to 80% of processor time in multithreaded DBMSs." +msgstr "" +"Тем не менее, изучив исходный код существующих библиотек и взвесив все " +"\"за\" и \"против\", мы решили написать свой движок. Одна из причин -- все " +"существующие сторонние библиотеки предполагают, что запросы к данным могут " +"поступать из множества потоков операционной системы, и поэтому содержат " +"сложные примитивы синхронизации для управления одновременным доступом к " +"данным. Если бы мы решили встраивать одну из них в Tarantool, то " +"пользователи были бы вынуждены нести издержки многопоточных приложений, не " +"получая ничего взамен. Дело в том, что в основе Tarantool лежит архитектура " +"на основе акторов. Обработка транзакций в выделенном потоке позволяет " +"обойтись без лишних блокировок, межпроцессного взаимодействия и других " +"затрат ресурсов, которые забирают до 80% процессорного времени в " +"многопоточных СУБД." + +msgid "*The Tarantool process consists of a fixed number of \"actor\" threads*" +msgstr "*Процесс в Tarantool состоит из заданного количества потоков*" + +msgid "" +"If you design a database engine with cooperative multitasking in mind right " +"from the start, it not only significantly speeds up the development process," +" but also allows the implementation of certain optimization tricks that " +"would be too complex for multithreaded engines. In short, using a third-" +"party solution wouldn’t have yielded the best result." +msgstr "" +"Если изначально проектировать движок с учетом кооперативной многозадачности," +" можно не только существенно ускорить работу, но и реализовать приемы " +"оптимизации, слишком сложные для многопоточных движков. В общем, " +"использование стороннего решения не привело бы к лучшему результату." + +msgid "Algorithm" +msgstr "Алгоритм" + +msgid "" +"Once the idea of using an existing library was off the table, we needed to " +"pick an architecture to build upon. There are two competing approaches to " +"on-disk data storage: the older one relies on B-trees and their variations; " +"the newer one advocates the use of log-structured merge-trees, or \"LSM\" " +"trees. MySQL, PostgreSQL, and Oracle use B-trees, while Cassandra, MongoDB, " +"and CockroachDB have adopted LSM trees." +msgstr "" +"Отказавшись от идеи внедрения существующих библиотек, необходимо было " +"выбрать архитектуру для использования в качестве основы. Есть два " +"альтернативных подхода к хранению данных на диске: старая модель с " +"использованием B-деревьев и их разновидностей и новая -- на основе " +"журнально-структурированных деревьев со слиянием, или LSM-деревьев (Log " +"Structured Merge Tree). MySQL, PostgreSQL и Oracle используют B-деревья, а " +"Cassandra, MongoDB и CockroachDB уже используют LSM-деревья." + +msgid "" +"B-trees are considered better suited for reads and LSM trees—for writes. " +"However, with SSDs becoming more widespread and the fact that SSDs have read" +" throughput that’s several times greater than write throughput, the " +"advantages of LSM trees in most scenarios was more obvious to us." +msgstr "" +"Считается, что B-деревья более эффективны для чтения, а LSM-деревья -- для " +"записи. Тем не менее, с распространением SSD-дисков, у которых в несколько " +"раз выше производительность чтения по сравнению с производительностью " +"записи, преимущества LSM-деревьев стали очевидны в большинстве сценариев." + +msgid "" +"Before dissecting LSM trees in Tarantool, let’s take a look at how they " +"work. To do that, we’ll begin by analyzing a regular B-tree and the issues " +"it faces. A B-tree is a balanced tree made up of blocks, which contain " +"sorted lists of key- value pairs. (Topics such as filling and balancing a " +"B-tree or splitting and merging blocks are outside of the scope of this " +"article and can easily be found on Wikipedia). As a result, we get a " +"container sorted by key, where the smallest element is stored in the " +"leftmost node and the largest one in the rightmost node. Let’s have a look " +"at how insertions and searches in a B-tree happen." +msgstr "" +"Прежде чем разбираться с LSM-деревьями в Tarantool'е, посмотрим, как они " +"работают. Для этого разберем устройство обычного B-дерева и связанные с ним " +"проблемы. \"B\" в слове B-tree означает \"Block\", то есть это " +"сбалансированное дерево, состоящее из блоков, которые содержат " +"отсортированные списки пар ключ-значение. Вопросы наполнения дерева, " +"балансировки, разбиения и слияния блоков выходят за рамки данной статьи, " +"подробности вы сможете прочитать в Википедии. В итоге мы получаем " +"отсортированный по возрастанию ключа контейнер, минимальный элемент которого" +" хранится в крайнем левом узле, а максимальный -- в крайнем правом. " +"Посмотрим, как в B-дереве осуществляется поиск и вставка данных." + +msgid "*Classical B-tree*" +msgstr "*Классическое B-дерево*" + +msgid "" +"If you need to find an element or check its membership, the search starts at" +" the root, as usual. If the key is found in the root block, the search " +"stops; otherwise, the search visits the rightmost block holding the largest " +"element that’s not larger than the key being searched (recall that elements " +"at each level are sorted). If the first level yields no results, the search " +"proceeds to the next level. Finally, the search ends up in one of the leaves" +" and probably locates the needed key. Blocks are stored and read into RAM " +"one by one, meaning the algorithm reads :math:`logB(N)` blocks in a single " +"search, where N is the number of elements in the B-tree. In the simplest " +"case, writes are done similarly: the algorithm finds the block that holds " +"the necessary element and updates (inserts) its value." +msgstr "" +"Если необходимо найти элемент или проверить его наличие, поиск начинается, " +"как обычно, с вершины. Если ключ обнаружен в корневом блоке, поиск " +"заканчивается; в противном случае, переходим в блок с наибольшим меньшим " +"ключом, то есть в самый правый блок, в котором еще есть элементы меньше " +"искомого (элементы на всех уровнях расположены по возрастанию). Если и там " +"элемент не найден, снова переходим на уровень ниже. В конце концов окажемся " +"в одном из листьев и, возможно, обнаружим искомый элемент. Блоки дерева " +"хранятся на диске и читаются в оперативную память по одному, то есть в " +"рамках одного поиска алгоритм считывает :math:`logB(N)` блоков, где N -- это" +" количество элементов в B-дереве. Запись в самом простом случае " +"осуществляется аналогично: алгоритм находит блок, который содержит " +"необходимый элемент, и обновляет (вставляет) его значение." + +msgid "" +"To better understand the data structure, let’s consider a practical example:" +" say we have a B-tree with 100,000,000 nodes, a block size of 4096 bytes, " +"and an element size of 100 bytes. Thus each block will hold up to 40 " +"elements (all overhead considered), and the B-tree will consist of around " +"2,570,000 blocks and 5 levels: the first four will have a size of 256 Mb, " +"while the last one will grow up to 10 Gb. Obviously, any modern computer " +"will be able to store all of the levels except the last one in filesystem " +"cache, so read requests will require just a single I/O operation." +msgstr "" +"Чтобы наглядно представить себе эту структуру данных, возьмем B-дерево на " +"100 000 000 узлов и предположим, что размер блока равен 4096 байтов, а " +"размер элемента -- 100 байтов. Таким образом, в каждом блоке можно будет " +"разместить до 40 элементов с учетом накладных расходов, а в B-дереве будет " +"около 2 570 000 блоков, пять уровней, при этом первые четыре займут по 256 " +"МБ, а последний -- до 10 ГБ. Очевидно, что на любом современном компьютере " +"все уровни, кроме последнего, успешно попадут в кэш файловой системы, и " +"фактически любая операция чтения будет требовать не более одной операции " +"ввода-вывода." + +msgid "" +"But if we change our perspective —B-trees don’t look so good anymore. " +"Suppose we need to update a single element. Since working with B-trees " +"involves reading and writing whole blocks, we would have to read in one " +"whole block, change our 100 bytes out of 4096, and then write the whole " +"updated block to disk. In other words,we were forced to write 40 times more " +"data than we actually modified!" +msgstr "" +"Ситуация выглядит существенно менее радужно при смене точки зрения. " +"Предположим, что необходимо обновить один элемент дерева. Так как операции с" +" B-деревьями работают через чтение и запись целых блоков, приходится " +"прочитать 1 блок в память, изменить 100 байт из 4096, а затем записать " +"обновленный блок на диск. Таким образом, нам пришлось записать в 40 раз " +"больше, чем реальный объем измененных данных!" + +msgid "" +"If you take into account the fact that an SSD block has a size of 64 Kb+ and" +" not every modification changes a whole element, the extra disk workload can" +" be greater still." +msgstr "" +"Принимая во внимание, что внутренний размер блока в SSD-дисках может быть 64" +" КБ и больше, и не любое изменение элемента меняет его целиком, объем " +"\"паразитной\" нагрузки на диск может быть еще выше." + +msgid "" +"Authors of specialized literature and blogs dedicated to on-disk data " +"storage have coined two terms for these phenomena: extra reads are referred " +"to as \"read amplification\" and writes as \"write amplification\"." +msgstr "" +"Феномен таких \"паразитных\" чтений в литературе и блогах, посвященных " +"хранению на диске, называется read amplification (усложнение чтения), а " +"феномен \"паразитной\" записи -- write amplification (усложнение записи)." + +msgid "" +"The amplification factor (multiplication coefficient) is calculated as the " +"ratio of the size of actual read (or written) data to the size of data " +"needed (or actually changed). In our B-tree example, the amplification " +"factor would be around 40 for both reads and writes." +msgstr "" +"Коэффициент усложнения, то есть коэффициент умножения, вычисляется как " +"отношение размера фактически прочитанных (или записанных) данных к реально " +"необходимому (или измененному) размеру. В нашем примере с B-деревом " +"коэффициент составит около 40 как для чтения, так и для записи." + +msgid "" +"The huge number of extra I/O operations associated with updating data is one" +" of the main issues addressed by LSM trees. Let’s see how they work." +msgstr "" +"Объем \"паразитных\" операций ввода-вывода при обновлении данных является " +"одной из основных проблем, которую решают LSM-деревья. Рассмотрим, как это " +"работает." + +msgid "" +"The key difference between LSM trees and regular B-trees is that LSM trees " +"don’t just store data (keys and values), but also data operations: " +"insertions and deletions." +msgstr "" +"Ключевое отличие LSM-деревьев от классических B-деревьев заключается в том, " +"что LSM-деревья не просто хранят данные (ключи и значения), а также операции" +" с данными: вставки и удаления." + +msgid "|br|" +msgstr "|br|" + +msgid "LSM tree:" +msgstr "LSM-дерево:" + +msgid "Stores statements, not values:" +msgstr "Хранит операторы, а не значения:" + +msgid "REPLACE" +msgstr "REPLACE" + +msgid "DELETE" +msgstr "DELETE" + +msgid "UPSERT" +msgstr "UPSERT" + +msgid "" +"Every statement is marked by LSN Append-only files, garbage is collected " +"after a checkpoint" +msgstr "" +"Для каждого оператора назначается LSN Обновление файлов происходит только " +"путем присоединения новых записей, сборка мусора проводится после " +"контрольной точки" + +msgid "Transactional log of all filesystem changes: vylog" +msgstr "Журнал транзакций при любых изменениях в системе: vylog" + +msgid "" +"For example, an element corresponding to an insertion operation has, apart " +"from a key and a value, an extra byte with an operation code (\"REPLACE\" in" +" the image above). An element representing the deletion operation contains a" +" key (since storing a value is unnecessary) and the corresponding operation " +"code—\"DELETE\". Also, each LSM tree element has a log sequence number " +"(LSN), which is the value of a monotonically increasing sequence that " +"uniquely identifies each operation. The whole tree is first ordered by key " +"in ascending order, and then, within a single key scope, by LSN in " +"descending order." +msgstr "" +"Например, элемент для операции вставки, помимо ключа и значения, содержит " +"дополнительный байт с кодом операции -- обозначенный выше как REPLACE. " +"Элемент для операции удаления содержит ключ элемента (хранить значение нет " +"необходимости) и соответствующий код операции -- DELETE. Также каждый " +"элемент LSM-дерева содержит порядковый номер операции (log sequence number " +"-- LSN), то есть значение монотонно возрастающей последовательности, которое" +" уникально идентифицирует каждую операцию. Таким образом, всё дерево " +"упорядочено сначала по возрастанию ключа, а в пределах одного ключа -- по " +"убыванию LSN." + +msgid "*A single level of an LSM tree*" +msgstr "*Один уровень LSM-дерева*" + +msgid "Filling an LSM tree" +msgstr "Наполнение LSM-дерева" + +msgid "" +"Unlike a B-tree, which is stored completely on disk and can be partly cached" +" in RAM, when using an LSM tree, memory is explicitly separated from disk " +"right from the start. The issue of volatile memory and data persistence is " +"beyond the scope of the storage algorithm and can be solved in various " +"ways—for example, by logging changes." +msgstr "" +"В отличие от B-дерева, которое полностью хранится на диске и может частично " +"кэшироваться в оперативной памяти, в LSM-дереве разделение между памятью и " +"диском явно присутствует с самого начала. При этом проблема сохранности " +"данных, расположенных в энергозависимой памяти, выносится за рамки алгоритма" +" хранения: ее можно решить разными способами, например, журналированием " +"изменений." + +msgid "" +"The part of an LSM tree that’s stored in RAM is called L0 (level zero). The " +"size of RAM is limited, so L0 is allocated a fixed amount of memory. For " +"example, in Tarantool, the L0 size is controlled by the ``vinyl_memory`` " +"parameter. Initially, when an LSM tree is empty, operations are written to " +"L0. Recall that all elements are ordered by key in ascending order, and then" +" within a single key scope, by LSN in descending order, so when a new value " +"associated with a given key gets inserted, it’s easy to locate the older " +"value and delete it. L0 can be structured as any container capable of " +"storing a sorted sequence of elements. For example, in Tarantool, L0 is " +"implemented as a B+*-tree. Lookups and insertions are standard operations " +"for the data structure underlying L0, so I won’t dwell on those." +msgstr "" +"Часть дерева, расположенную в оперативной памяти, называют L0 (level zero --" +" уровень ноль). Объем оперативной памяти ограничен, поэтому для L0 отводится" +" фиксированная область. В конфигурации Tarantool'а, например, размер L0 " +"задается с помощью параметра ``vinyl_memory``. В начале, когда LSM-дерево не" +" содержит элементов, операции записываются в L0. Следует отметить, что " +"элементы в дереве упорядочены по возрастанию ключа, а затем по убыванию LSN," +" так что в случае вставки нового значения по данному ключу легко обнаружить " +"и удалить предыдущее значение. L0 может быть представлен любым контейнером, " +"который сохраняет упорядоченность элементов. Например, для хранения L0 " +"Tarantool использует B+*-дерево. Операции поиска и вставки -- это " +"стандартные операции структуры данных, используемой для представления L0, и " +"мы их подробно рассматривать не будем." + +msgid "" +"Sooner or later the number of elements in an LSM tree exceeds the L0 size " +"and that’s when L0 gets written to a file on disk (called a \"run\") and " +"then cleared for storing new elements. This operation is called a \"dump\"." +msgstr "" +"Рано или поздно количество элементов в дереве превысит размер L0. Тогда L0 " +"записывается в файл на диске (который называется забегом -- \"run\") и " +"освобождается под новые элементы. Эта операция называется \"дамп\" (dump)." + +msgid "" +"Dumps on disk form a sequence ordered by LSN: LSN ranges in different runs " +"don’t overlap, and the leftmost runs (at the head of the sequence) hold " +"newer operations. Think of these runs as a pyramid, with the newest ones " +"closer to the top. As runs keep getting dumped, the pyramid grows higher. " +"Note that newer runs may contain deletions or replacements for existing " +"keys. To remove older data, it’s necessary to perform garbage collection " +"(this process is sometimes called \"merge\" or \"compaction\") by combining " +"several older runs into a new one. If two versions of the same key are " +"encountered during a compaction, only the newer one is retained; however, if" +" a key insertion is followed by a deletion, then both operations can be " +"discarded." +msgstr "" +"Все дампы на диске образуют последовательность, упорядоченную по LSN: " +"диапазоны LSN в файлах не пересекаются, а ближе к началу последовательности " +"находятся файлы с более новыми операциями. Представим эти файлы в виде " +"пирамиды, где новые файлы расположены вверху, а старые внизу. По мере " +"появления новых файлов забегов, высота пирамиды растет. При этом более " +"свежие файлы могут содержать операции удаления или замены для существующих " +"ключей. Для удаления старых данных необходимо производиться сборку мусора " +"(этот процесс иногда называется \"слияние\" -- в английском языке \"merge\" " +"или \"compaction\"), объединяя нескольких старых файлов в новый. Если при " +"слиянии мы встречаем две версии одного и того же ключа, то достаточно " +"оставить только более новую версию, а если после вставки ключа он был " +"удален, то из результата можно исключить обе операции." + +msgid "" +"The key choices determining an LSM tree’s efficiency are which runs to " +"compact and when to compact them. Suppose an LSM tree stores a monotonically" +" increasing sequence of keys (1, 2, 3, ...,) with no deletions. In this " +"case, compacting runs would be useless: all of the elements are sorted, the " +"tree doesn’t have any garbage, and the location of any key can unequivocally" +" be determined. On the other hand, if an LSM tree contains many deletions, " +"doing a compaction would free up some disk space. However, even if there are" +" no deletions, but key ranges in different runs overlap a lot, compacting " +"such runs could speed up lookups as there would be fewer runs to scan. In " +"this case, it might make sense to compact runs after each dump. But keep in " +"mind that a compaction causes all data stored on disk to be overwritten, so " +"with few reads it’s recommended to perform it less often." +msgstr "" +"Ключевым фактором эффективности LSM-дерева является то, в какой момент и для" +" каких файлов делается слияние. Представим, что LSM-дерево в качестве ключей" +" хранит монотонную последовательность вида 1, 2, 3 …, и операций удаления " +"нет. В этом случае слияние будет бесполезным -- все элементы уже " +"отсортированы, дерево не содержит мусор и можно однозначно определить, в " +"каком файле находится каждый ключ. Напротив, если LSM-дерево содержит много " +"операций удаления, слияние позволит освободить место на диске. Но даже если " +"удалений нет, а диапазоны ключей в разных файлах сильно пересекаются, " +"слияние может ускорить поиск, так как сократит число просматриваемых файлов." +" В этом случае имеет смысл выполнять слияние после каждого дампа. Однако " +"следует отметить, что такое слияние приведет к перезаписи всех данных на " +"диске, поэтому если чтений мало, то лучше делать слияния реже." + +msgid "" +"To ensure it’s optimally configurable for any of the scenarios above, an LSM" +" tree organizes all runs into a pyramid: the newer the data operations, the " +"higher up the pyramid they are located. During a compaction, the algorithm " +"picks two or more neighboring runs of approximately equal size, if possible." +msgstr "" +"Для оптимальной конфигурации под любой из описанных выше сценариев в LSM-" +"дереве все файлы организованы в пирамиду: чем новее операции с данными, тем " +"выше они находятся в пирамиде. При этом в слиянии участвуют два или " +"несколько соседних файлов в пирамиде; по возможности выбираются файлы " +"примерно одинакового размера." + +msgid "Multi-level compaction can span any number of levels" +msgstr "Многоуровневое слияние может охватить любое количество уровней" + +msgid "A level can contain multiple runs" +msgstr "Уровень может содержать несколько файлов" + +msgid "" +"All of the neighboring runs of approximately equal size constitute an LSM " +"tree level on disk. The ratio of run sizes at different levels determines " +"the pyramid’s proportions, which allows optimizing the tree for write-" +"intensive or read-intensive scenarios." +msgstr "" +"Все соседние файлы примерно одинакового размера составляют уровень LSM-" +"дерева на диске. Соотношение размеров файлов на различных уровнях определяет" +" пропорции пирамиды, что позволяет оптимизировать дерево под интенсивные " +"вставки, либо интенсивные чтения." + +msgid "" +"Suppose the L0 size is 100 Mb, the ratio of run sizes at each level (the " +"``vinyl_run_size_ratio`` parameter) is 5, and there can be no more than 2 " +"runs per level (the ``vinyl_run_count_per_level`` parameter). After the " +"first 3 dumps, the disk will contain 3 runs of 100 Mb each—which constitute " +"L1 (level one). Since 3 > 2, the runs will be compacted into a single 300 Mb" +" run, with the older ones being deleted. After 2 more dumps, there will be " +"another compaction, this time of 2 runs of 100 Mb each and the 300 Mb run, " +"which will produce one 500 Mb run. It will be moved to L2 (recall that the " +"run size ratio is 5), leaving L1 empty. The next 10 dumps will result in L2 " +"having 3 runs of 500 Mb each, which will be compacted into a single 1500 Mb " +"run. Over the course of 10 more dumps, the following will happen: 3 runs of " +"100 Mb each will be compacted twice, as will two 100 Mb runs and one 300 Mb " +"run, which will yield 2 new 500 Mb runs in L2. Since L2 now has 3 runs, they" +" will also be compacted: two 500 Mb runs and one 1500 Mb run will produce a " +"2500 Mb run that will be moved to L3, given its size." +msgstr "" +"Предположим, что размер L0 составляет 100 МБ, а соотношение размеров файлов " +"на каждом уровне (параметр ``vinyl_run_size_ratio``) равно 5, и на каждом " +"уровне может быть не более 2 файлов (параметр " +"``vinyl_run_count_per_level``). После первых трех дампов на диске появятся 3" +" файла по 100 МБ, эти файлы образуют уровень L1. Так как 3 > 2, запустится " +"слияние файлов в новый файл размером 300 МБ, а старые будут удалены. Спустя " +"еще 2 дампа снова запустится слияние, на этот раз файлов в 100, 100 и 300 " +"МБ, в результате файл размером 500 МБ переместится на уровень L2 (вспомним, " +"что соотношение размеров уровней равно 5), а уровень L1 останется пустым. " +"Пройдут еще 10 дампов, и получим 3 файла по 500 МБ на уровне L2, в " +"результате чего будет создан один файл размером 1500 МБ. Спустя еще 10 " +"дампов произойдет следующее: 2 раза произведем слияние 3 файлов по 100 МБ, а" +" также 2 раза слияние файлов по 100, 100 и 300 МБ, что приведет к созданию " +"двух файлов на уровне L2 по 500 МБ. Поскольку на уровне L2 уже есть три " +"файла, запустится слияние двух файлов по 500 МБ и одного файла в 1500 МБ. " +"Полученный в результате файл в 2500 МБ, в силу своего размера, переедет на " +"уровень L3." + +msgid "" +"This can go on infinitely, but if an LSM tree contains lots of deletions, " +"the resulting compacted run can be moved not only down, but also up the " +"pyramid due to its size being smaller than the sizes of the original runs " +"that were compacted. In other words, it’s enough to logically track which " +"level a certain run belongs to, based on the run size and the smallest and " +"greatest LSN among all of its operations." +msgstr "" +"Процесс может продолжаться до бесконечности, а если в потоке операций с LSM-" +"деревом будет много удалений, образовавшийся в результате слияния файл может" +" переместиться не только вниз по пирамиде, но и вверх, так как окажется " +"меньше исходных файлов, использовавшихся при слиянии. Иными словами, " +"принадлежность файла к уровню достаточно отслеживать логически на основе " +"размера файла и минимального и максимального LSN среди всех хранящихся в нем" +" операций." + +msgid "Controlling the form of an LSM tree" +msgstr "Управление формой LSM-дерева" + +msgid "" +"If it’s necessary to reduce the number of runs for lookups, then the run " +"size ratio can be increased, thus bringing the number of levels down. If, on" +" the other hand, you need to minimize the compaction-related overhead, then " +"the run size ratio can be decreased: the pyramid will grow higher, and even " +"though runs will be compacted more often, they will be smaller, which will " +"reduce the total amount of work done. In general, write amplification in an " +"LSM tree is described by this formula: :math:`log_{x}(\\frac {N} {L0}) × x` " +"or, alternatively, :math:`x × \\frac {ln (\\frac {N} {C0})} {ln(x)}`, where " +"N is the total size of all tree elements, L0 is the level zero size, and x " +"is the level size ratio (the ``level_size_ratio`` parameter). At " +":math:`\\frac {N} {C0}` = 40 (the disk-to- memory ratio), the plot would " +"look something like this:" +msgstr "" +"Если число файлов для поиска нужно уменьшить, то соотношение размеров файлов" +" на разных уровнях можно увеличить, и, как следствие, уменьшается число " +"уровней. Если, напротив, необходимо снизить затраты ресурсов, вызванные " +"слиянием, то можно уменьшить соотношение размеров уровней: пирамида будет " +"более высокой, а слияние хотя и выполняется чаще, но работает в среднем с " +"файлами меньшего размера, за счет чего суммарно выполняет меньше работы. В " +"целом, \"паразитная запись\" в LSM-дереве описывается формулой " +":math:`log_{x}(\\\\frac {N} {L0}) × x` или :math:`x × \\\\frac {ln (\\\\frac" +" {N} {C0})} {ln(x)}`, где N -- это общий размер всех элементов дерева, L0 --" +" это размер уровня ноль, а x -- это соотношение размеров уровней (параметр " +"``level_size_ratio``). Если :math:`\\\\frac {N} {C0}` = 40 (соотношение " +"диск-память), график выглядит примерно вот так:" + +msgid "" +"As for read amplification, it’s proportional to the number of levels. The " +"lookup cost at each level is no greater than that for a B-tree. Getting back" +" to the example of a tree with 100,000,000 elements: given 256 Mb of RAM and" +" the default values of ``vinyl_run_size_ratio`` and " +"``vinyl_run_count_per_level``, write amplification would come out to about " +"13, while read amplification could be as high as 150. Let’s try to figure " +"out why this happens." +msgstr "" +"\"Паразитное\" чтение при этом пропорционально количеству уровней. Стоимость" +" поиска на каждом уровне не превышает стоимости поиска в B-дереве. " +"Возвращаясь к нашему примеру дерева в 100 000 000 элементов: при наличии 256" +" МБ оперативной памяти и стандартных значений параметров " +"``vinyl_run_size_ratio`` и ``vinyl_run_count_per_level``, получим " +"коэффициент \"паразитной\" записи равным примерно 13, коэффициент " +"\"паразитной\" записи может доходить до 150. Разберемся, почему это " +"происходит." + +msgid "Search" +msgstr "Поиск" + +msgid "" +"When doing a lookup in an LSM tree, what we need to find is not the element " +"itself, but the most recent operation associated with it. If it’s a " +"deletion, then the tree doesn’t contain this element. If it’s an insertion, " +"we need to grab the topmost value in the pyramid, and the search can be " +"stopped after finding the first matching key. In the worst-case scenario, " +"that is if the tree doesn’t hold the needed element, the algorithm will have" +" to sequentially visit all of the levels, starting from L0." +msgstr "" +"При поиске в LSM-дереве нам необходимо найти не сам элемент, а последнюю " +"операцию с ним. Если это операция удаления, искомый элемент отсутствует в " +"дереве. Если это операция вставки, то искомому элементу соответствует самое " +"верхнее значение в LSM-пирамиде, и поиск можно остановить при первом " +"совпадении ключа. В худшем случае значение в дереве изначально " +"отсутствовало. Тогда поиск вынужден последовательно перебрать все уровни " +"дерева, начиная с L0." + +msgid "" +"Unfortunately, this scenario is quite common in real life. For example, when" +" inserting a value into a tree, it’s necessary to make sure there are no " +"duplicates among primary/unique keys. So to speed up membership checks, LSM " +"trees use a probabilistic data structure called a \"Bloom filter\", which " +"will be covered a bit later, in a section on how vinyl works under the hood." +msgstr "" +"К сожалению, на практике этот худший случай довольно распространен. " +"Например, при вставке в дерево необходимо убедиться в отсутствии дубликатов " +"для первичного или уникального ключа. Поэтому для ускорения поиска " +"несуществующих значений в LSM-деревьях применяется вероятностная структура " +"данных, которая называется \"фильтр Блума\". О нем мы поговорим более " +"детально в разделе, посвященном внутреннему устройству vinyl." + +msgid "Range searching" +msgstr "Поиск по диапазону" + +msgid "" +"In the case of a single-key search, the algorithm stops after encountering " +"the first match. However, when searching within a certain key range (for " +"example, looking for all the users with the last name \"Ivanov\"), it’s " +"necessary to scan all tree levels." +msgstr "" +"Если при поиске по одному ключу алгоритм завершается после первого " +"совпадения, то для поиска всех значений в диапазоне (например, всех " +"пользователей с фамилией \"Иванов\") необходимо просматривать все уровни " +"дерева." + +msgid "*Searching within a range of [24,30)*" +msgstr "*Поиск по диапазону [24,30)*" + +msgid "" +"The required range is formed the same way as when compacting several runs: " +"the algorithm picks the key with the largest LSN out of all the sources, " +"ignoring the other associated operations, then moves on to the next key and " +"repeats the procedure." +msgstr "" +"Формирование искомого диапазона при этом происходит так же, как и при " +"слиянии нескольких файлов: из всех источников алгоритм выбирает ключ с " +"максимальным LSN, отбрасывает остальные операции по этому ключу, сдвигает " +"позицию поиска на следующий ключ и повторяет процедуру." + +msgid "Deletion" +msgstr "Удаление" + +msgid "" +"Why would one store deletions? And why doesn’t it lead to a tree overflow in" +" the case of for i=1,10000000 put(i) delete(i) end?" +msgstr "" +"Зачем вообще хранить операции удаления? И почему это не приводит к " +"переполнению дерева, например, в сценарии for i=1,10000000 put(i) delete(i) " +"end?" + +msgid "" +"With regards to lookups, deletions signal the absence of a value being " +"searched; with compactions, they clear the tree of \"garbage\" records with " +"older LSNs." +msgstr "" +"Роль операций удаления при поиске -- сообщать об отсутствии искомого " +"значения, а при слиянии -- очищать дерево от \"мусорных\" записей с более " +"старыми LSN." + +msgid "" +"While the data is in RAM only, there’s no need to store deletions. " +"Similarly, you don’t need to keep them following a compaction if they " +"affect, among other things, the lowest tree level, which contains the oldest" +" dump. Indeed, if a value can’t be found at the lowest level, then it " +"doesn’t exist in the tree." +msgstr "" +"Пока данные хранятся только в оперативной памяти, нет необходимости хранить " +"операции удаления. Также нет необходимости сохранять операции удаления после" +" слияния, если оно затрагивает в том числе самый нижний уровень дерева -- на" +" нем находятся данные самого старого дампа. Действительно, отсутствие " +"значения на последнем уровне означает, что оно отсутствует в дереве." + +msgid "We can't delete from append-only files" +msgstr "" +"Нельзя производить удаление из файлов, которые обновляются только путем " +"присоединения новых записей" + +msgid "Tombstones (delete markers) are inserted into L0 instead" +msgstr "" +"Вместо этого на уровень L0 вносятся маркеры удаленных записей (tombstones)" + +msgid "*Deletion, step 1: a tombstone is inserted into L0*" +msgstr "*Удаление, шаг 1: вставка удаленной записи в L0*" + +msgid "*Deletion, step 2: the tombstone passes through intermediate levels*" +msgstr "" +"*Удаление, шаг 2: удаленная запись проходит через промежуточные уровни*" + +msgid "" +"*Deletion, step 3: in the case of a major compaction, the tombstone is " +"removed from the tree*" +msgstr "" +"*Удаление, шаг 3: при значительном слиянии удаленная запись удаляется из " +"дерева*" + +msgid "" +"If a deletion is known to come right after the insertion of a unique value, " +"which is often the case when modifying a value in a secondary index, then " +"the deletion can safely be filtered out while compacting intermediate tree " +"levels. This optimization is implemented in vinyl." +msgstr "" +"Если мы знаем, что удаление следует сразу за вставкой уникального значения " +"-- а это частый случай при изменении значения во вторичном индексе -- то " +"операцию удаления можно отфильтровывать уже при слиянии промежуточных " +"уровней. Эта оптимизация реализована в vinyl'е." + +msgid "Advantages of an LSM tree" +msgstr "Преимущества LSM-дерева" + +msgid "" +"Apart from decreasing write amplification, the approach that involves " +"periodically dumping level L0 and compacting levels L1-Lk has a few " +"advantages over the approach to writes adopted by B-trees:" +msgstr "" +"Помимо снижения \"паразитной\" записи, подход с периодическими дампами " +"уровня L0 и слиянием уровней L1-Lk имеет ряд преимуществ перед подходом к " +"записи, используемым в B-деревьях:" + +msgid "" +"Dumps and compactions write relatively large files: typically, the L0 size " +"is 50-100 Mb, which is thousands of times larger than the size of a B-tree " +"block." +msgstr "" +"При дампах и слиянии создаются относительно большие файлы: стандартный " +"размер L0 составляет 50-100 MБ, что в тысячи раз превышает размер блока " +"B-дерева." + +msgid "" +"This large size allows efficiently compressing data before writing it. " +"Tarantool compresses data automatically, which further decreases write " +"amplification." +msgstr "" +"Большой размер позволяет эффективно сжимать данные перед записью. В " +"Tarantool'е сжатие происходит автоматически, что позволяет еще больше " +"уменьшить \"паразитную\" запись." + +msgid "" +"There is no fragmentation overhead, since there’s no padding/empty space " +"between the elements inside a run." +msgstr "" +"Издержки фрагментации отсутствуют, потому что в файле элементы следуют друг " +"за другом без пустот/заполнений." + +msgid "" +"All operations create new runs instead of modifying older data in place. " +"This allows avoiding those nasty locks that everyone hates so much. Several " +"operations can run in parallel without causing any conflicts. This also " +"simplifies making backups and moving data to replicas." +msgstr "" +"Все операции создают новые файлы, а не заменяют старые данные. Это позволяет" +" избавиться от столь ненавистных нам блокировок, при этом несколько операций" +" могут идти параллельно, не приводя к конфликтам. Это также упрощает " +"создание резервных копий и перенос данных на реплику." + +msgid "" +"Storing older versions of data allows for the efficient implementation of " +"transaction support by using multiversion concurrency control." +msgstr "" +"Хранение старых версий данных позволяет эффективно реализовать поддержку " +"транзакций, используя подход управления параллельным доступом с помощью " +"многоверсионности." + +msgid "Disadvantages of an LSM tree and how to deal with them" +msgstr "Недостатки LSM-дерева и их устранение" + +msgid "" +"One of the key advantages of the B-tree as a search data structure is its " +"predictability: all operations take no longer than :math:`log_{B}(N)` to " +"run. Conversely, in a classical LSM tree, both read and write speeds can " +"differ by a factor of hundreds (best case scenario) or even thousands (worst" +" case scenario). For example, adding just one element to L0 can cause it to " +"overflow, which can trigger a chain reaction in levels L1, L2, and so on. " +"Lookups may find the needed element in L0 or may need to scan all of the " +"tree levels. It’s also necessary to optimize reads within a single level to " +"achieve speeds comparable to those of a B-tree. Fortunately, most " +"disadvantages can be mitigated or even eliminated with additional algorithms" +" and data structures. Let’s take a closer look at these disadvantages and " +"how they’re dealt with in Tarantool." +msgstr "" +"Одним из ключевых преимуществ B-дерева как структуры данных для поиска " +"является предсказуемость: любая операция занимает не более чем " +":math:`log_{B}(N)`. В классическом LSM-дереве скорость как чтения, так и " +"записи могут может отличаться в лучшем и худшем случае в сотни и тысячи раз." +" Например, добавление всего лишь одного элемента в L0 может привести к его " +"переполнению, что в свою очередь, может привести к переполнению L1, L2 и " +"т.д. Процесс чтения может обнаружить исходный элемент в L0, а может " +"задействовать все уровни. Чтение в пределах одного уровня также необходимо " +"оптимизировать, чтобы добиться скорости, сравнимой с B-деревом. К счастью, " +"многие недостатки можно скрасить или полностью устранить с помощью " +"вспомогательных алгоритмов и структур данных. Систематизируем эти недостатки" +" и опишем способы борьбы с ними, используемые в Tarantool'е." + +msgid "Unpredictable write speed" +msgstr "Непредсказуемая скорость записи" + +msgid "" +"In an LSM tree, insertions almost always affect L0 only. How do you avoid " +"idle time when the memory area allocated for L0 is full?" +msgstr "" +"Вставка данных в LSM-дерево почти всегда задействует исключительно L0. Как " +"избежать простоя, если заполнена область оперативной памяти, отведенная под " +"L0?" + +msgid "" +"Clearing L0 involves two lengthy operations: writing to disk and memory " +"deallocation. To avoid idle time while L0 is being dumped, Tarantool uses " +"writeaheads. Suppose the L0 size is 256 Mb. The disk write speed is 10 Mbps." +" Then it would take 26 seconds to dump L0. The insertion speed is 10,000 " +"RPS, with each key having a size of 100 bytes. While L0 is being dumped, " +"it’s necessary to reserve 26 Mb of RAM, effectively slicing the L0 size down" +" to 230 Mb." +msgstr "" +"Освобождение L0 подразумевает две долгих операции: запись на диск и " +"освобождение памяти. Чтобы избежать простоя во время записи L0 на диск, " +"Tarantool использует упреждающую запись. Допустим, размер L0 составляет 256 " +"MБ. Скорость записи на диск составляет 10 МБ/с. Тогда для записи L0 на диск " +"понадобится 26 секунд. Скорость вставки данных составляет 10 000 запросов в " +"секунду, а размер одного ключа -- 100 байтов. На время записи необходимо " +"зарезервировать около 26 MБ доступной оперативной памяти, сократив реальный " +"полезный размер L0 до 230 MБ." + +msgid "" +"Tarantool does all of these calculations automatically, constantly updating " +"the rolling average of the DBMS workload and the histogram of the disk " +"speed. This allows using L0 as efficiently as possible and it prevents write" +" requests from timing out. But in the case of workload surges, some wait " +"time is still possible. That’s why we also introduced an insertion timeout " +"(the ``vinyl_timeout`` parameter), which is set to 60 seconds by default. " +"The write operation itself is executed in dedicated threads. The number of " +"these threads (2 by default) is controlled by the ``vinyl_write_threads`` " +"parameter. The default value of 2 allows doing dumps and compactions in " +"parallel, which is also necessary for ensuring system predictability." +msgstr "" +"Все эти расчеты Tarantool делает автоматически, постоянно поддерживая " +"скользящее среднее значение нагрузки на СУБД и гистограмму скорости работы " +"диска. Это позволяет максимально эффективно использовать L0 и избежать " +"истечения времени ожидания доступной памяти для операций записи. При резком " +"всплеске нагрузки ожидание все же возможно, поэтому также существует время " +"ожидания операции вставки (параметр ``vinyl_timeout``), значение которого по" +" умолчанию составляет 60 секунд. Сама запись осуществляется в выделенных " +"потоках, число которых (2 по умолчанию) задается в параметре " +"``vinyl_write_threads``. Используемое по умолчанию значение 2 позволяет " +"выполнять дамп параллельно со слиянием, что также необходимо для " +"предсказуемой работы системы." + +msgid "" +"In Tarantool, compactions are always performed independently of dumps, in a " +"separate execution thread. This is made possible by the append-only nature " +"of an LSM tree: after dumps runs are never changed, and compactions simply " +"create new runs." +msgstr "" +"Слияния в Tarantool'е всегда выполняются независимо от дампов, в отдельном " +"потоке выполнения. Это возможно благодаря природе LSM-дерева -- после записи" +" файлы в дереве никогда не меняются, а слияние лишь создает новый файл." + +msgid "" +"Delays can also be caused by L0 rotation and the deallocation of memory " +"dumped to disk: during a dump, L0 memory is owned by two operating system " +"threads, a transaction processing thread and a write thread. Even though no " +"elements are being added to the rotated L0, it can still be used for " +"lookups. To avoid read locks when doing lookups, the write thread doesn’t " +"deallocate the dumped memory, instead delegating this task to the " +"transaction processor thread. Following a dump, memory deallocation itself " +"happens instantaneously: to achieve this, L0 uses a special allocator that " +"deallocates all of the memory with a single operation." +msgstr "" +"К задержкам также может приводить ротация L0 и освобождение памяти, " +"записанной на диск: в процессе записи памятью L0 владеют два потока " +"операционной системы -- поток обработки транзакций и поток записи. Хотя в L0" +" во время ротации элементы не добавляются, он может участвовать в поиске. " +"Чтобы избежать блокировок на чтение во время поиска, поток записи не " +"освобождает записанную память, а оставляет эту задачу потоку обработки " +"транзакций. Само освобождение после завершения дампа происходит мгновенно: " +"для этого в L0 используется специализированный механизм распределения, " +"позволяющий освободить всю память за одну операцию." + +msgid "anticipatory dump" +msgstr "упреждающий дамп" + +msgid "throttling" +msgstr "загрузка" + +msgid "" +"The dump is performed from the so-called \"shadow\" L0 without blocking new " +"insertions and lookups" +msgstr "" +"Дамп происходит из так называемого \"теневого\" L0, не блокируя новые " +"вставки и чтения" + +msgid "Unpredictable read speed" +msgstr "Непредсказуемая скорость чтений" + +msgid "" +"Optimizing reads is the most difficult optimization task with regards to LSM" +" trees. The main complexity factor here is the number of levels: any " +"optimization causes not only much slower lookups, but also tends to require " +"significantly larger RAM resources. Fortunately, the append-only nature of " +"LSM trees allows us to address these problems in ways that would be " +"nontrivial for traditional data structures." +msgstr "" +"Чтение -- самая сложная задача для оптимизации в LSM-деревьях. Главным " +"фактором сложности является большое количество уровней: это не только " +"значительно замедляет поиск, но и потенциально значительно увеличивает " +"требования к оперативной памяти при почти любых попытках оптимизации. К " +"счастью, природа LSM-деревьев, где файлы обновляются только путем " +"присоединения новых записей, позволяет решать эти проблемы нестандартными " +"для традиционных структур данных способами." + +msgid "page index" +msgstr "постраничный индекс" + +msgid "bloom filters" +msgstr "фильтры Блума" + +msgid "tuple range cache" +msgstr "кэш диапазона кортежей" + +msgid "multi-level compaction" +msgstr "многоуровневое слияние" + +msgid "Compression and page index" +msgstr "Сжатие и постраничный индекс" + +msgid "" +"In B-trees, data compression is either the hardest problem to crack or a " +"great marketing tool—rather than something really useful. In LSM trees, " +"compression works as follows:" +msgstr "" +"Сжатие данных в B-деревьях -- это либо сложнейшая в реализации задача, либо " +"больше средство маркетинга, чем действительно полезный инструмент. Сжатие в " +"LSM-деревьях работает следующим образом:" + +msgid "" +"During a dump or compaction all of the data within a single run is split " +"into pages. The page size (in bytes) is controlled by the " +"``vinyl_page_size`` parameter and can be set separately for each index. A " +"page doesn’t have to be exactly of ``vinyl_page_size`` size—depending on the" +" data it holds, it can be a little bit smaller or larger. Because of this, " +"pages never have any empty space inside." +msgstr "" +"При любом дампе или слиянии мы разбиваем все данные в одном файле на " +"страницы. Размер страницы в байтах задается в параметре ``vinyl_page_size``," +" который можно менять отдельно для каждого индекса. Страница не обязана " +"занимать строго то количество байт, которое прописано ``vinyl_page_size`` --" +" она может быть чуть больше или чуть меньше, в зависимости от хранящихся в " +"ней данных. Благодаря этому страница никогда не содержит пустот." + +msgid "" +"Data is compressed by `Facebook’s streaming algorithm " +"`_ called \"zstd\". The first key of each " +"page, along with the page offset, is added to a \"page index\", which is a " +"separate file that allows the quick retrieval of any page. After a dump or " +"compaction, the page index of the created run is also written to disk." +msgstr "" +"Для сжатия используется `потоковый алгоритм Facebook " +"`_ под названием \"zstd\". Первый ключ " +"каждой страницы и смещение страницы в файле добавляются в так называемый " +"постраничный индекс (page index) -- отдельный файл, который позволяет быстро" +" найти нужную страницу. После дампа или слияния постраничный индекс " +"созданного файла также записывается на диск." + +msgid "" +"All `.index` files are cached in RAM, which allows finding the necessary " +"page with a single lookup in a `.run` file (in vinyl, this is the extension " +"of files resulting from a dump or compaction). Since data within a page is " +"sorted, after it’s read and decompressed, the needed key can be found using " +"a regular binary search. Decompression and reads are handled by separate " +"threads, and are controlled by the ``vinyl_read_threads`` parameter." +msgstr "" +"Все файлы типа `.index` кэшируются в оперативной памяти, что позволяет " +"найти нужную страницу за одно чтение из файла `.run` (такое расширение имени" +" файла используется в vinyl'е для файлов, полученных в результате дампа или " +"слияния). Поскольку данные в странице отсортированы, после чтения и " +"декомпрессии нужный ключ можно найти с помощью простого бинарного поиска. За" +" чтение и декомпрессию отвечают отдельные потоки, их количество определяется" +" в параметре ``vinyl_read_threads``." + +msgid "" +"Tarantool uses a universal file format: for example, the format of a `.run` " +"file is no different from that of an `.xlog` file (log file). This " +"simplifies backup and recovery as well as the usage of external tools." +msgstr "" +"Tarantool использует единый формат файлов: например, формат данных в файле " +"`.run` ничем не отличается от формата файла `.xlog` (файл журнала). Это " +"упрощает резервное копирование и восстановление, а также работу внешних " +"инструментов." + +msgid "Bloom filters" +msgstr "Фильтры Блума" + +msgid "" +"Even though using a page index enables scanning fewer pages per run when " +"doing a lookup, it’s still necessary to traverse all of the tree levels. " +"There’s a special case, which involves checking if particular data is absent" +" when scanning all of the tree levels and it’s unavoidable: I’m talking " +"about insertions into a unique index. If the data being inserted already " +"exists, then inserting the same data into a unique index should lead to an " +"error. The only way to throw an error in an LSM tree before a transaction is" +" committed is to do a search before inserting the data. Such reads form a " +"class of their own in the DBMS world and are called \"hidden\" or " +"\"parasitic\" reads." +msgstr "" +"Хотя постраничный индекс позволяет уменьшить количество страниц, " +"просматриваемых при поиске в одном файле, он не отменяет необходимости " +"искать на всех уровнях дерева. Есть важный частный случай, когда необходимо " +"проверить отсутствие данных, и тогда просмотр всех уровней неизбежен: " +"вставка в уникальный индекс. Если данные уже существуют, то вставка в " +"уникальный индекс должна завершиться с ошибкой. Единственный способ вернуть " +"ошибку до завершения транзакции в LSM-дереве -- произвести поиск перед " +"вставкой. Такого рода чтения в СУБД образуют целый класс, называемый " +"\"скрытыми\" или \"паразитными\" чтениями." + +msgid "" +"Another operation leading to hidden reads is updating a value in a field on " +"which a secondary index is defined. Secondary keys are regular LSM trees " +"that store differently ordered data. In most cases, in order not to have to " +"store all of the data in all of the indexes, a value associated with a given" +" key is kept in whole only in the primary index (any index that stores both " +"a key and a value is called \"covering\" or \"clustered\"), whereas the " +"secondary index only stores the fields on which a secondary index is " +"defined, and the values of the fields that are part of the primary index. " +"Thus, each time a change is made to a value in a field on which a secondary " +"index is defined, it’s necessary to first remove the old key from the " +"secondary index—and only then can the new key be inserted. At update time, " +"the old value is unknown, and it is this value that needs to be read in from" +" the primary key \"under the hood\"." +msgstr "" +"Другая операция, приводящая к скрытым чтениям, -- обновление значения, по " +"которому построен вторичный индекс. Вторичные ключи представляют собой " +"обычные LSM-деревья, в которых данные хранятся в другом порядке. Чаще всего," +" чтобы не хранить все данные во всех индексах, значение, соответствующее " +"данному ключу, целиком сохраняется только в первичном индексе (любой индекс," +" хранящий и ключ, и значение, называется покрывающим или кластерным), а во " +"вторичном индексе сохраняются лишь поля, по которым построен вторичный " +"индекс, и значения полей, участвующих в первичном индексе. Тогда при любом " +"изменении значения, по которому построен вторичный ключ, приходится сначала " +"удалять из вторичного индекса старый ключ, и только потом вставлять новый. " +"Старое значение во время обновления неизвестно -- именно его и нужно читать " +"из первичного ключа с точки зрения внутреннего устройства." + +msgid "For example:" +msgstr "Например:" + +msgid "update t1 set city=’Moscow’ where id=1" +msgstr "update t1 set city=’Moscow’ where id=1" + +msgid "" +"To minimize the number of disk reads, especially for nonexistent data, " +"nearly all LSM trees use probabilistic data structures, and Tarantool is no " +"exception. A classical Bloom filter is made up of several (usually 3-to-5) " +"bit arrays. When data is written, several hash functions are calculated for " +"each key in order to get corresponding array positions. The bits at these " +"positions are then set to 1. Due to possible hash collisions, some bits " +"might be set to 1 twice. We’re most interested in the bits that remain 0 " +"after all keys have been added. When looking for an element within a run, " +"the same hash functions are applied to produce bit positions in the arrays. " +"If any of the bits at these positions is 0, then the element is definitely " +"not in the run. The probability of a false positive in a Bloom filter is " +"calculated using Bayes’ theorem: each hash function is an independent random" +" variable, so the probability of a collision simultaneously occurring in all" +" of the bit arrays is infinitesimal." +msgstr "" +"Чтобы уменьшить количество чтений с диска, особенно для несуществующих " +"значений, практически все LSM-деревья используют вероятностные структуры " +"данных. Tarantool не исключение. Классический фильтр Блума -- это набор из " +"нескольких (обычно 3-5) битовых массивов. При записи для каждого ключа " +"вычисляется несколько хеш-функций, и в каждом массиве выставляется бит, " +"соответствующий значению хеша. При хешировании могут возникнуть коллизии, " +"поэтому некоторые биты могут быть проставлены дважды. Интерес представляют " +"биты, которые оказались не проставлены после записи всех ключей. При поиске " +"также вычисляются выбранные хеш-функции. Если хотя бы в одном из битовых " +"массивов бит не стоит, то значение в файле отсутствует. Вероятность " +"срабатывания фильтра Блума определяется теоремой Байеса: каждая хеш-функция " +"представляет собой независимую случайную величину, благодаря чему " +"вероятность того, что во всех битовых массивах одновременно произойдет " +"коллизия, очень мала." + +msgid "" +"The key advantage of Bloom filters in Tarantool is that they’re easily " +"configurable. The only parameter that can be specified separately for each " +"index is called ``vinyl_bloom_fpr`` (FPR stands for \"false positive " +"ratio\") and it has the default value of 0.05, which translates to a 5% FPR." +" Based on this parameter, Tarantool automatically creates Bloom filters of " +"the optimal size for partial- key and full-key searches. The Bloom filters " +"are stored in the `.index` file, along with the page index, and are cached " +"in RAM." +msgstr "" +"Ключевым преимуществом реализации фильтров Блума в Tarantool'е является " +"простота настройки. Единственный параметр, который можно менять независимо " +"для каждого индекса, называется ``vinyl_bloom_fpr`` (FPR в данном случае " +"означает сокращение от \"false positive ratio\" -- коэффициент " +"ложноположительного срабатывания), который по умолчанию равен 0,05, или 5%. " +"На основе этого параметра Tarantool автоматически строит фильтры Блума " +"оптимального размера для поиска как по полному ключу, так и по компонентам " +"ключа. Сами фильтры Блума хранятся вместе с постраничным индексом в файле " +"`.index` и кэшируются в оперативной памяти." + +msgid "Caching" +msgstr "Кэширование" + +msgid "" +"A lot of people think that caching is a silver bullet that can help with any" +" performance issue. \"When in doubt, add more cache\". In vinyl, caching is " +"viewed rather as a means of reducing the overall workload and consequently, " +"of getting a more stable response time for those requests that don’t hit the" +" cache. vinyl boasts a unique type of cache among transactional systems " +"called a \"range tuple cache\". Unlike, say, RocksDB or MySQL, this cache " +"doesn’t store pages, but rather ranges of index values obtained from disk, " +"after having performed a compaction spanning all tree levels. This allows " +"the use of caching for both single-key and key-range searches. Since this " +"method of caching stores only hot data and not, say, pages (you may need " +"only some data from a page), RAM is used in the most efficient way possible." +" The cache size is controlled by the ``vinyl_cache`` parameter." +msgstr "" +"Многие привыкли считать кэширование панацеей от всех проблем с " +"производительностью: \"В любой непонятной ситуации добавляй кэш\". В vinyl'е" +" мы смотрим на кэш скорее как на средство снижения общей нагрузки на диск, " +"и, как следствие, получения более предсказуемого времени ответов на запросы," +" которые не попали в кэш. В vinyl'е реализован уникальный для транзакционных" +" систем вид кэша под названием \"кэш диапазона кортежей\" (range tuple " +"cache). В отличие от RocksDB, например, или MySQL, этот кэш хранит не " +"страницы, а уже готовые диапазоны значений индекса, после их чтения с диска " +"и слияния всех уровней. Это позволяет использовать кэш для запросов как по " +"одному ключу, так и по диапазону ключей. Поскольку в кэше хранятся только " +"горячие данные, а не, скажем, страницы (в странице может быть востребована " +"лишь часть данных), оперативная память используется наиболее оптимально. " +"Размер кэша задается в параметре ``vinyl_cache``." + +msgid "Garbage collection control" +msgstr "Управление сборкой мусора" + +msgid "" +"Chances are that by now you’ve started losing focus and need a well-deserved" +" dopamine reward. Feel free to take a break, since working through the rest " +"of the article is going to take some serious mental effort." +msgstr "" +"Возможно, добравшись до этого места вы уже начали терять концентрацию и " +"нуждаетесь в заслуженной дозе допамина. Самое время сделать перерыв, так как" +" для того, чтобы разобраться с оставшейся частью, понадобятся серьезные " +"усилия." + +msgid "" +"An LSM tree in vinyl is just a small piece of the puzzle. Even with a single" +" table (or so-called \"space\"), vinyl creates and maintains several LSM " +"trees, one for each index. But even a single index can be comprised of " +"dozens of LSM trees. Let’s try to understand why this might be necessary." +msgstr "" +"В vinyl'е устройство одного LSM-дерева -- это лишь фрагмент мозаики. Vinyl " +"создает и обслуживает несколько LSM-деревьев даже для одной таблицы (так " +"называемого спейса) -- по одному дереву на каждый индекс. Но даже один " +"единственный индекс может состоять из десятков LSM-деревьев. Попробуем " +"разобраться, зачем." + +msgid "" +"Recall our example with a tree containing 100,000,000 records, 100 bytes " +"each. As time passes, the lowest LSM level may end up holding a 10 Gb run. " +"During compaction, a temporary run of approximately the same size will be " +"created. Data at intermediate levels takes up some space as well, since the " +"tree may store several operations associated with a single key. In total, " +"storing 10 Gb of actual data may require up to 30 Gb of free space: 10 Gb " +"for the last tree level, 10 Gb for a temporary run, and 10 Gb for the " +"remaining data. But what if the data size is not 10 Gb, but 1 Tb? Requiring " +"that the available disk space always be several times greater than the " +"actual data size is financially unpractical, not to mention that it may take" +" dozens of hours to create a 1 Tb run. And in the case of an emergency " +"shutdown or system restart, the process would have to be started from " +"scratch." +msgstr "" +"Рассмотрим наш стандартный пример: 100 000 000 записей по 100 байтов каждая." +" Через некоторое время на самом нижнем уровне LSM у нас может оказаться файл" +" размером 10 ГБ. Во время слияния последнего уровня мы создадим временный " +"файл, который также будет занимать около 10 ГБ. Данные на промежуточных " +"уровнях тоже занимают место: по одному и тому же ключу дерево может хранить " +"несколько операций. Суммарно для хранения 10 ГБ полезных данных нам может " +"потребоваться до 30 ГБ свободного места: 10 ГБ на последний уровень, 10 ГБ " +"на временный файл и 10 ГБ на всё остальное. А если данных не 1 ГБ, а 1 ТБ? " +"Требовать, чтобы количество свободного места на диске всегда в несколько раз" +" превышало объем полезных данных, экономически нецелесообразно, да и " +"создание файла в 1ТБ может занимать десятки часов. При любой аварии или " +"перезапуске системы операцию придется начинать заново." + +msgid "" +"Here’s another scenario. Suppose the primary key is a monotonically " +"increasing sequence—for example, a time series. In this case, most " +"insertions will fall into the right part of the key range, so it wouldn’t " +"make much sense to do a compaction just to append a few million more records" +" to an already huge run." +msgstr "" +"Рассмотрим другую проблему. Представим, что первичный ключ дерева -- это " +"монотонная последовательность, например, временной ряд. В этом случае " +"основные вставки будут приходиться на правую часть диапазона ключей. Нет " +"смысла заново производить слияние лишь для того, чтобы дописать в конец и " +"без того огромного файла еще несколько миллионов записей." + +msgid "" +"But what if writes predominantly occur in a particular region of the key " +"range, whereas most reads take place in a different region? How do you " +"optimize the form of the LSM tree in this case? If it’s too high, read " +"performance is impacted; if it’s too low—write speed is reduced." +msgstr "" +"А если вставки происходят, в основном, в одну часть диапазона ключей, а " +"чтения -- из другой части? Как в этом случае оптимизировать форму дерева? " +"Если оно будет слишком высоким, пострадают чтения, если слишком низким -- " +"запись." + +msgid "" +"Tarantool \"factorizes\" this problem by creating multiple LSM trees for " +"each index. The approximate size of each subtree may be controlled by the " +":ref:`vinyl_range_size ` configuration " +"parameter. We call such subtrees \"ranges\"." +msgstr "" +"Tarantool \"факторизует\" проблему, создавая не одно, а множество LSM-" +"деревьев для каждого индекса. Примерный размер каждого поддерева можно " +"задать в конфигурационном параметре ``vinyl_range_size``. Такие поддеревья " +"называется диапазонами (\"range\")." + +msgid "Factorizing large LSM trees via ranging" +msgstr "Факторизация больших LSM-деревьев с помощью диапазонов" + +msgid "Ranges reflect a static layout of sorted runs" +msgstr "Диапазоны отражают статичную структуру упорядоченных файлов" + +msgid "Slices connect a sorted run into a range" +msgstr "Срезы объединяют упорядоченный файл в диапазон" + +msgid "" +"Initially, when the index has few elements, it consists of a single range. " +"As more elements are added, its total size may exceed :ref:`the maximum " +"range size `. In that case a special operation" +" called \"split\" divides the tree into two equal parts. The tree is split " +"at the middle element in the range of keys stored in the tree. For example, " +"if the tree initially stores the full range of -inf…+inf, then after " +"splitting it at the middle key X, we get two subtrees: one that stores the " +"range of -inf...X, and the other storing the range of X…+inf. With this " +"approach, we always know which subtree to use for writes and which one for " +"reads. If the tree contained deletions and each of the neighboring ranges " +"grew smaller as a result, the opposite operation called \"coalesce\" " +"combines two neighboring trees into one." +msgstr "" +"Изначально, пока в индексе мало элементов, он состоит из одного диапазона. " +"По мере добавления элементов суммарный объем может превысить " +":ref:`максимальный размер диапазона `. В таком" +" случае выполняется операция под названием \"разделение\" (split), которая " +"делит дерево на две равные части. Разделение происходит по срединному " +"элементу диапазона ключей, хранящихся в дереве. Например, если изначально " +"дерево хранит полный диапазон -inf… +inf, то после разделения по срединному " +"ключу X получим два поддерева: одно будет хранить все ключи от -inf до X, " +"другое -- от X до +inf. Таким образом, при вставке или чтении мы однозначно " +"знаем, к какому поддереву обращаться. Если в дереве были удаления и каждый " +"из соседних диапазонов уменьшился, выполняется обратная операция под " +"названием \"объединение\" (coalesce). Она объединяет два соседних дерева в " +"одно." + +msgid "" +"Split and coalesce don’t entail a compaction, the creation of new runs, or " +"other resource-intensive operations. An LSM tree is just a collection of " +"runs. vinyl has a special metadata log that helps keep track of which run " +"belongs to which subtree(s). This has the `.vylog` extension and its format " +"is compatible with an .xlog file. Similarly to an `.xlog` file, the metadata" +" log gets rotated at each checkpoint. To avoid the creation of extra runs " +"with split and coalesce, we have also introduced an auxiliary entity called " +"\"slice\". It’s a reference to a run containing a key range and it’s stored " +"only in the metadata log. Once the reference counter drops to zero, the " +"corresponding file gets removed. When it’s necessary to perform a split or " +"to coalesce, Tarantool creates slice objects for each new tree, removes " +"older slices, and writes these operations to the metadata log, which " +"literally stores records that look like this: ```` or " +"````." +msgstr "" +"Разделение и объединение не приводят к слиянию, созданию новых файлов и " +"прочим тяжеловесным операциям. LSM-дерево -- это лишь набор файлов. В " +"vinyl'е мы реализовали специальный журнал метаданных, позволяющий легко " +"отслеживать, какой файл принадлежит какому поддереву или поддеревьям. Журнал" +" имеет расширение `.vylog`, по формату он совместим с файлом `.xlog`. Как и " +"файл `.xlog`, происходит автоматическая ротация файла при каждой контрольной" +" точке. Чтобы избежать повторного создания файлов при разделении и " +"объединении, мы ввели промежуточную сущность -- срез (slice). Это ссылка на " +"файл с указанием диапазона значений ключа, которая хранится исключительно в " +"журнале метаданных. Когда число ссылок на файл становится равным нулю, файл " +"удаляется. А когда необходимо произвести разделение или объединение, " +"Tarantool создает срезы для каждого нового дерева, старые срезы удаляет, и " +"записывает эти операции в журнал метаданных. Буквально, журнал метаданных " +"хранит записи вида <идентификатор дерева, идентификатор среза> или " +"<идентификатор среза, идентификатор файла, мин, макс>." + +msgid "" +"This way all of the heavy lifting associated with splitting a tree into two " +"subtrees is postponed until a compaction and then is performed " +"automatically. A huge advantage of dividing all of the keys into ranges is " +"the ability to independently control the L0 size as well as the dump and " +"compaction processes for each subtree, which makes these processes " +"manageable and predictable. Having a separate metadata log also simplifies " +"the implementation of both \"truncate\" and \"drop\". In vinyl, they’re " +"processed instantly, since they only work with the metadata log, while " +"garbage collection is done in the background." +msgstr "" +"Таким образом, непосредственно тяжелая работа по разбиению дерева на два поддерева, откладывается до слияния и выполняется автоматически.\n" +"Огромным преимуществом подхода с разделением всего диапазона ключей на диапазоны является возможность независимо управлять размером L0, а также процессом создания дампов и слиянием для каждого поддерева. В результате эти процессы являются управляемыми и предсказуемыми. Наличие отдельного журнала метаданных также упрощает выполнение таких операций, как усечение и удаление -- в vinyl'е они обрабатываются мгновенно, потому что работают исключительно с журналом метаданных, а удаление мусора выполняется в фоне." + +msgid "Advanced features of vinyl" +msgstr "Расширенные возможности vinyl'а" + +msgid "Upsert" +msgstr "Upsert (обновление и вставка)" + +msgid "" +"In the previous sections, we mentioned only two operations stored by an LSM " +"tree: deletion and replacement. Let’s take a look at how all of the other " +"operations can be represented. An insertion can be represented via a " +"replacement—you just need to make sure there are no other elements with the " +"specified key. To perform an update, it’s necessary to read the older value " +"from the tree, so it’s easier to represent this operation as a replacement " +"as well—this speeds up future read requests by the key. Besides, an update " +"must return the new value, so there’s no avoiding hidden reads." +msgstr "" +"В предыдущих разделах упоминались лишь две операции, которые хранит LSM-" +"дерево: удаление и замена. Давайте рассмотрим, как представлены все " +"остальные. Вставку можно представить с помощью замены -- необходимо лишь " +"предварительно убедиться в отсутствии элемента указанным ключом. Для " +"выполнения обновления необходимо предварительно считывать старое значение из" +" дерева, так что и эту операцию проще записать в дерево как замену -- это " +"ускорит будущие чтения по этому ключу. Кроме того, обновление должно вернуть" +" новое значение, так что скрытых чтений никак не избежать." + +msgid "" +"In B-trees, the cost of hidden reads is negligible: to update a block, it " +"first needs to be read from disk anyway. Creating a special update operation" +" for an LSM tree that doesn’t cause any hidden reads is really tempting." +msgstr "" +"В B-деревьях скрытые чтения почти ничего не стоят: чтобы обновить блок, его " +"в любом случае необходимо прочитать с диска. Для LSM-деревьев идея создания " +"специальной операции обновления, которая не приводила бы к скрытым чтениям, " +"выглядит очень заманчивой." + +msgid "" +"Such an operation must contain not only a default value to be inserted if a " +"key has no value yet, but also a list of update operations to perform if a " +"value does exist." +msgstr "" +"Такая операция должна содержать как значение по умолчанию, которое нужно " +"вставить, если данных по ключу еще нет, так и список операций обновления, " +"которые нужно выполнить, если значение существует." + +msgid "" +"At transaction execution time, Tarantool just saves the operation in an LSM " +"tree, then \"executes\" it later, during a compaction." +msgstr "" +"На этапе выполнения транзакции Tarantool лишь сохраняет всю операцию в LSM-" +"дереве, а \"выполняет\" ее уже только во время слияния." + +msgid "The upsert operation:" +msgstr "Операция обновления и вставки:" + +msgid "space:upsert(tuple, {{operator, field, value}, ... })" +msgstr "space:upsert(tuple, {{operator, field, value}, ... })" + +msgid "Non-reading update or insert" +msgstr "Обновление без чтения или вставка" + +msgid "Delayed execution" +msgstr "Отложенное выполнение" + +msgid "Background upsert squashing prevents upserts from piling up" +msgstr "" +"Фоновое сжатие операций обновления и вставки предотвращает накапливание " +"операций" + +msgid "" +"Unfortunately, postponing the operation execution until a compaction doesn’t" +" leave much leeway in terms of error handling. That’s why Tarantool tries to" +" validate upserts as fully as possible before writing them to an LSM tree. " +"However, some checks are only possible with older data on hand, for example " +"when the update operation is trying to add a number to a string or to remove" +" a field that doesn’t exist." +msgstr "" +"К сожалению, если откладывать выполнение операции на этап слияния, " +"возможностей для обработки ошибок не остается. Поэтому Tarantool стремится " +"максимально проверять операции обновления и вставки upsert перед записью в " +"дерево. Тем не менее, некоторые проверки можно выполнить лишь имея старые " +"данные на руках. Например, если обновление прибавляет число к строке или " +"удаляет несуществующее поле." + +msgid "" +"A semantically similar operation exists in many products including " +"PostgreSQL and MongoDB. But anywhere you look, it’s just syntactic sugar " +"that combines the update and replace operations without avoiding hidden " +"reads. Most probably, the reason is that LSM trees as data storage " +"structures are relatively new." +msgstr "" +"Операция с похожей семантикой присутствует во многих продуктах, в том числе " +"в PostgreSQL и MongoDB. Но везде она представляет собой лишь синтаксический " +"сахар, объединяющий обновление и вставку, не избавляя СУБД от необходимости " +"выполнять скрытые чтения. Скорее всего, причиной этого является " +"относительная новизна LSM-деревьев в качестве структур данных для хранения." + +msgid "" +"Even though an upsert is a very important optimization and implementing it " +"cost us a lot of blood, sweat, and tears, we must admit that it has limited " +"applicability. If a table contains secondary keys or triggers, hidden reads " +"can’t be avoided. But if you have a scenario where secondary keys are not " +"required and the update following the transaction completion will certainly " +"not cause any errors, then the operation is for you." +msgstr "" +"Хотя обновление и вставка upsert представляет собой очень важную " +"оптимизацию, и ее реализация стоила нам долгой напряженной работы, следует " +"признать, что ее применимость ограничена. Если в таблице есть вторичные " +"ключи или триггеры, скрытых чтений не избежать. А если у вас есть сценарии, " +"для которых не нужны вторичные ключи и обновление после завершения " +"транзакции однозначно не приведет к ошибкам -- эта операция для вас." + +msgid "" +"I’d like to tell you a short story about an upsert. It takes place back when" +" vinyl was only beginning to \"mature\" and we were using an upsert in " +"production for the first time. We had what seemed like an ideal environment " +"for it: we had tons of keys, the current time was being used as values; " +"update operations were inserting keys or modifying the current time; and we " +"had few reads. Load tests yielded great results." +msgstr "" +"Небольшая история, связанная с этим оператором: vinyl только начинал " +"\"взрослеть\", и мы впервые запустили операцию обновления и вставки upsert " +"на рабочие серверы. Казалось бы, идеальные условия: огромный набор ключей, " +"текущее время в качестве значения, операции обновления либо вставляют ключ, " +"либо обновляют текущее время, редкие операции чтения. Нагрузочные тесты " +"показали отличные результаты." + +msgid "" +"Nevertheless, after a couple of days, the Tarantool process started eating " +"up 100% of our CPU, and the system performance dropped close to zero." +msgstr "" +"Тем не менее, после пары дней работы процесс Tarantool'а начал потреблять " +"100 % CPU, а производительность системы упала практически до нуля." + +msgid "" +"We started digging into the issue and found out that the distribution of " +"requests across keys was significantly different from what we had seen in " +"the test environment. It was...well, quite nonuniform. Most keys were " +"updated once or twice a day, so the database was idle for the most part, but" +" there were much hotter keys with tens of thousands of updates per day. " +"Tarantool handled those just fine. But in the case of lookups by key with " +"tens of thousands of upserts, things quickly went downhill. To return the " +"most recent value, Tarantool had to read and \"replay\" the whole history " +"consisting of all of the upserts. When designing upserts, we had hoped this " +"would happen automatically during a compaction, but the process never even " +"got to that stage: the L0 size was more than enough, so there were no dumps." +msgstr "" +"Начали подробно изучать проблему. Оказалось, что распределение запросов по " +"ключам существенно отличалось от того, что мы видели в тестовом окружении. " +"Оно было… очень неравномерное. Большая часть ключей обновлялась 1-2 раза за " +"сутки, и база для них не была нагружена. Но были ключи гораздо более горячие" +" -- десятки тысяч обновлений в сутки. Tarantool прекрасно справлялся с этим " +"потоком обновлений. А вот когда по ключу с десятком тысяч операций " +"обновления и вставки upsert происходило чтение, всё шло под откос. Чтобы " +"вернуть последнее значение, Tarantool'у приходилось каждый раз прочитать и " +"\"проиграть\" историю из десятков тысяч команд обновления и вставки upsert. " +"На стадии проекта мы надеялись, что это произойдет автоматически во время " +"слияния уровней, но до слияния дело даже не доходило: памяти L0 было " +"предостаточно, и дампы не создавались." + +msgid "" +"We solved the problem by adding a background process that performed " +"readaheads on any keys that had more than a few dozen upserts piled up, so " +"all those upserts were squashed and substituted with the read value." +msgstr "" +"Решили мы проблему добавлением фонового процесса, осуществляющего " +"упреждающие чтения для ключей, по которым накопилось больше нескольких " +"десятков операций обновления и вставки upsert с последующей заменой на " +"прочитанное значение." + +msgid "Secondary keys" +msgstr "Вторичные ключи" + +msgid "" +"Update is not the only operation where optimizing hidden reads is critical. " +"Even the replace operation, given secondary keys, has to read the older " +"value: it needs to be independently deleted from the secondary indexes, and " +"inserting a new element might not do this, leaving some garbage behind." +msgstr "" +"Не только для операции обновления остро стоит проблема оптимизации скрытых " +"чтений. Даже операция замены при наличии вторичных ключей вынуждена читать " +"старое значение: его нужно независимо удалить из вторичных индексов, а " +"вставка нового элемента может этого не сделать, оставив в индексе мусор." + +msgid "" +"If secondary indexes are not unique, then collecting \"garbage\" from them " +"can be put off until a compaction, which is what we do in Tarantool. The " +"append-only nature of LSM trees allowed us to implement full-blown " +"serializable transactions in vinyl. Read-only requests use older versions of" +" data without blocking any writes. The transaction manager itself is fairly " +"simple for now: in classical terms, it implements the MVTO (multiversion " +"timestamp ordering) class, whereby the winning transaction is the one that " +"finished earlier. There are no locks and associated deadlocks. Strange as it" +" may seem, this is a drawback rather than an advantage: with parallel " +"execution, you can increase the number of successful transactions by simply " +"holding some of them on lock when necessary. We’re planning to improve the " +"transaction manager soon. In the current release, we focused on making the " +"algorithm behave 100% correctly and predictably. For example, our " +"transaction manager is one of the few on the NoSQL market that supports so-" +"called \"gap locks\"." +msgstr "" +"Если вторичные индексы не уникальны, то удаление из них \"мусора\" также " +"можно перенести в фазу слияния, что мы и делаем в Tarantool'е. Природа LSM-" +"дерева, в котором файлы обновляются путем присоединения новых записей, " +"позволила нам реализовать в vinyl'е полноценные сериализуемые транзакции. " +"Запросы только для чтения при этом используют старые версии данных и не " +"блокируют запись. Сам менеджер транзакций пока довольно простой: в " +"традиционной классификации он реализует класс MVTO (multiversion timestamp " +"ordering -- упорядочение временных меток на основе многоверсионности), при " +"этом в конфликте побеждает та транзакция, что завершилась первой. Блокировок" +" и свойственных им взаимоблокировок нет. Как ни странно, это скорее " +"недостаток, чем преимущество: при параллельном выполнении можно повысить " +"количество успешных транзакций, задерживая некоторые из них в нужный момент " +"на блокировке. Развитие менеджера транзакций в наших ближайших планах. В " +"текущей версии мы сфокусировались на том, чтобы сделать алгоритм корректным " +"и предсказуемым на 100%. Например, наш менеджер транзакций -- один из " +"немногих в NoSQL-среде, поддерживающих так называемые \"блокировки " +"разрывов\" (gap locks)." diff --git a/locale/ru/LC_MESSAGES/contributing/docs/localization.po b/locale/ru/LC_MESSAGES/contributing/docs/localization.po index 5a6f917244..22d83b84a6 100644 --- a/locale/ru/LC_MESSAGES/contributing/docs/localization.po +++ b/locale/ru/LC_MESSAGES/contributing/docs/localization.po @@ -2,641 +2,11 @@ msgid "Localization" msgstr "" -msgid "State of localization" -msgstr "" - -msgid "Repository" -msgstr "" - -msgid "State" -msgstr "" - -msgid "Volume, words" -msgstr "" - -msgid "Tarantool Community" -msgstr "" - -msgid "|doc|" -msgstr "" - -msgid "352 000" -msgstr "" - -msgid "Cartridge" -msgstr "" - -msgid "|cartridge|" -msgstr "" - -msgid "14 000" -msgstr "" - -msgid "Tarantool Ansible Role" -msgstr "" - -msgid "|tarantool-ansible-role|" -msgstr "" - -msgid "11 000" -msgstr "" - -msgid "Cartridge CLI" -msgstr "" - -msgid "|cartridge-cli|" -msgstr "" - -msgid "6 500" -msgstr "" - -msgid "Tarantool Enterprise" -msgstr "" - -msgid "|tarantool-enterprise|" -msgstr "" - -msgid "6 000" -msgstr "" - -msgid "Tarantool Data Grid" -msgstr "" - -msgid "|tarantool-data-grid|" -msgstr "" - -msgid "4 000" -msgstr "" - -msgid "Tarantool Metrics" -msgstr "" - -msgid "|tarantool-metrics|" -msgstr "" - -msgid "Tarantool C++ Driver" -msgstr "" - -msgid "|tarantool-cpp|" -msgstr "" - -msgid "Tarantool Kubernetes Operator" -msgstr "" - -msgid "|tarantool-kubernetes-operator|" -msgstr "" - -msgid "2 750" -msgstr "" - -msgid "Tarantool Luatest" -msgstr "" - -msgid "|tarantool-luatest|" -msgstr "" - -msgid "750" -msgstr "" - -msgid "Tarantool Graphana Dashboard" -msgstr "" - -msgid "|tarantool-graphana-dashboard|" -msgstr "" - -msgid "500" -msgstr "" - -msgid "Glossaries" -msgstr "" - -msgid "Tarantool Core" -msgstr "" - -msgid "Term [en]" -msgstr "" - -msgid "Term [ru]" -msgstr "" - -msgid "Description [en]" -msgstr "" - -msgid "Description [ru]" -msgstr "" - -msgid "space" -msgstr "" - -msgid "спейс" -msgstr "" - -msgid "A space is a container for tuples." -msgstr "" - -msgid "https://www.tarantool.io/en/doc/latest/book/box/data_model/#spaces\"" -msgstr "" - -msgid "NOUN" -msgstr "" - -msgid "tuple" -msgstr "" - -msgid "кортеж" -msgstr "" - msgid "" -"A tuple plays the same role as a “row” or a “record”. The number of tuples " -"in a space is unlimited. Tuples in Tarantool are stored as MsgPack arrays. " -"https://www.tarantool.io/en/doc/latest/book/box/data_model/#tuples" -msgstr "" - -msgid "Tarantool" -msgstr "" - -msgid "НЕ ПЕРЕВОДИТЬ" -msgstr "" - -msgid "primary index" -msgstr "" - -msgid "первичный индекс" -msgstr "" - -msgid "" -"The first index defined on a space is called the primary key index, and it " -"must be unique. All other indexes are called secondary indexes, and they may" -" be non-unique. " -"https://www.tarantool.io/en/doc/latest/book/box/data_model/#indexes" -msgstr "" - -msgid "fiber" -msgstr "" - -msgid "файбер" -msgstr "" - -msgid "" -"A fiber is a set of instructions which are executed with cooperative " -"multitasking. Fibers managed by the fiber module are associated with a user-" -"supplied function called the fiber function. " -"https://www.tarantool.io/en/doc/latest/reference/reference_lua/fiber/#fibers" -msgstr "" - -msgid "Tarantool garbage collector" -msgstr "" - -msgid "сборщик мусора в Tarantool" -msgstr "" - -msgid "" -"A garbage collector fiber runs in the background on the master storages of " -"each replica set. It starts deleting the contents of the bucket in the " -"GARBAGE state part by part. Once the bucket is empty, its record is deleted " -"from the _bucket system space. " -"https://www.tarantool.io/en/doc/latest/reference/reference_rock/vshard/vshard_admin/#garbage-" -"collector" -msgstr "" - -msgid "Lua garbage collector" -msgstr "" - -msgid "сборщик мусора на Lua" -msgstr "" - -msgid "" -"Lua manages memory automatically by running a garbage collector from time to" -" time to collect all dead objects (that is, objects that are no longer " -"accessible from Lua). https://www.lua.org/manual/5.1/manual.html#2.10" -msgstr "" - -msgid "storage engine" -msgstr "" - -msgid "движок базы данных" -msgstr "" - -msgid "" -"A storage engine is a set of very-low-level routines which actually store " -"and retrieve tuple values. " -"https://www.tarantool.io/en/doc/latest/book/box/engines/" -msgstr "" - -msgid "thread" -msgstr "" - -msgid "поток" -msgstr "" - -msgid "" -"A thread of execution is the smallest sequence of programmed instructions " -"that can be managed independently by a scheduler, which is typically a part " -"of the operating system." -msgstr "" - -msgid "Lua application" -msgstr "" - -msgid "Lua-приложение, приложение на языке Lua" -msgstr "" - -msgid "Tarantool’s native language for writing applications is Lua." -msgstr "" - -msgid "memtx" -msgstr "" - -msgid "instance" -msgstr "" - -msgid "экземпляр" -msgstr "" - -msgid "implicit casting" -msgstr "" - -msgid "неявное приведение типов" -msgstr "" - -msgid "database" -msgstr "" - -msgid "база данных" -msgstr "" - -msgid "Release policy" -msgstr "" - -msgid "Релизная политика" -msgstr "" - -msgid "" -"A set of rules for releasing and naming new distributions of Tarantool: " -"where we add new features and where we don't, how we give them numbers, what" -" versions are suitable to use in production." -msgstr "" - -msgid "field" -msgstr "" - -msgid "поле" -msgstr "" - -msgid "" -"Fields are distinct data values, contained in a tuple. They play the same " -"role as «row columns» or «record fields» in relational databases." -msgstr "" - -msgid "https://www.tarantool.io/ru/doc/latest/book/box/data_model/#term-field\"" -msgstr "" - -msgid "leader election" -msgstr "" - -msgid "выборы лидера" -msgstr "" - -msgid "(in a replica set, by the Raft algorithm)" -msgstr "" - -msgid "replica set" -msgstr "" - -msgid "набор реплик" -msgstr "" - -msgid "heartbeat" -msgstr "" - -msgid "контрольный сигнал" -msgstr "" - -msgid "functionality" -msgstr "" - -msgid "функциональность" -msgstr "" - -msgid "log" -msgstr "" - -msgid "журнал" -msgstr "" - -msgid "node" -msgstr "" - -msgid "узел" -msgstr "" - -msgid "follower" -msgstr "" - -msgid "реплика" -msgstr "" - -msgid "small allocator" -msgstr "" - -msgid "аллокатор small" -msgstr "" - -msgid "https://github.com/tarantool/small" -msgstr "" - -msgid "patch" -msgstr "" - -msgid "патч" -msgstr "" - -msgid "breaking change" -msgstr "" - -msgid "критическое изменение" -msgstr "" - -msgid "parser" -msgstr "" - -msgid "парсер" -msgstr "" - -msgid "UUID" -msgstr "" - -msgid "data type" -msgstr "" - -msgid "тип данных" -msgstr "" - -msgid "alias" -msgstr "" - -msgid "алиас" -msgstr "" - -msgid "или псевдоним?" -msgstr "" - -msgid "push" -msgstr "" - -msgid "выполнить push" -msgstr "" - -msgid "MVCC" -msgstr "" - -msgid "(механизм) MVCC" -msgstr "" - -msgid "dirty read" -msgstr "" - -msgid "\"грязное чтение\"" -msgstr "" - -msgid "в кавычках" -msgstr "" - -msgid "snapshot" -msgstr "" - -msgid "снимок (данных)" -msgstr "" - -msgid "keywords" -msgstr "" - -msgid "ключевые слова" -msgstr "" - -msgid "identifier" -msgstr "" - -msgid "имя, идентификатор" -msgstr "" - -msgid "clause" -msgstr "" - -msgid "предложение, блок" -msgstr "" - -msgid "" -"(SQL) A clause in SQL is a part of a query that lets you filter or " -"customizes how you want your data to be queried to you." -msgstr "" - -msgid "expression" -msgstr "" - -msgid "выражение" -msgstr "" - -msgid "predicate" -msgstr "" - -msgid "предикат" -msgstr "" - -msgid "" -"(SQL) Predicates, which specify conditions that can be evaluated to SQL " -"three-valued logic (3VL) (true/false/unknown) or Boolean truth values and " -"are used to limit the effects of statements and queries, or to change " -"program flow." -msgstr "" - -msgid "query" -msgstr "" - -msgid "запрос" -msgstr "" - -msgid "" -"(SQL) Queries retrieve the data based on specific criteria. A query is a " -"statement that returns a result set (possibly empty)." -msgstr "" - -msgid "result set" -msgstr "" - -msgid "результат запроса" -msgstr "" - -msgid "" -"(SQL) An SQL result set is a set of rows from a database, as well as " -"metadata about the query such as the column names, and the types and sizes " -"of each column. A result set is effectively a table." -msgstr "" - -msgid "resultset" -msgstr "" - -msgid "statement" -msgstr "" - -msgid "инструкция" -msgstr "" - -msgid "" -"(SQL) A statement is any text that the database engine recognizes as a valid" -" command." -msgstr "" - -msgid "" -"(SQL) Любой текст, который распознаётся движком БД как команда. Инструкция " -"состоит из ключевых слов и выражений языка SQL, которые предписывают " -"Tarantool выполнять какие-либо действия с базой данных." -msgstr "" - -msgid "" -"Tarantool: A statement consists of SQL-language keywords and expressions " -"that direct Tarantool to do something with a database. " -"https://www.tarantool.io/en/doc/latest/reference/reference_sql/sql_user_guide/#statements\"" -msgstr "" - -msgid "batch" -msgstr "" - -msgid "пакет (инструкций)" -msgstr "" - -msgid "" -"(SQL) A series of SQL statements sent to the server at once is called a " -"batch." -msgstr "" - -msgid "(SQL) Серия SQL-инструкций (statements), отправляемая на сервер вместе" -msgstr "" - -msgid "production configuration" -msgstr "" - -msgid "конфигурация производственной среды" -msgstr "" - -msgid "deployment" -msgstr "" - -msgid "" -"Transforming a mechanical, electrical, or computer system from a packaged to" -" an operational state. IT infrastructure deployment typically involves " -"defining the sequence of operations or steps, often referred to as a " -"deployment plan, that must be carried to deliver changes into a target " -"system environment." -msgstr "" - -msgid "roll back" -msgstr "" - -msgid "отменить" -msgstr "" - -msgid "транзакцию" -msgstr "" - -msgid "deploy to production" -msgstr "" - -msgid "" -"IT infrastructure deployment typically involves defining the sequence of " -"operations or steps, often referred to as a deployment plan, that must be " -"carried to deliver changes into a target system environment. Production " -"environment is a setting where software and other products are actually put " -"into operation for their intended uses by end users" -msgstr "" - -msgid "operations" -msgstr "" - -msgid "эксплуатация" -msgstr "" - -msgid "" -"(DevOps) Information technology operations, or IT operations, are the set of" -" all processes and services that are both provisioned by an IT staff to " -"their internal or external clients and used by themselves, to run themselves" -" as a business." -msgstr "" - -msgid "to deploy" -msgstr "" - -msgid "deployment plan" -msgstr "" - -msgid "" -"A sequence of operations or steps that must be carried to deliver changes " -"into a target system environment." -msgstr "" - -msgid "приложение на Tarantool Cartridge" -msgstr "" - -msgid "" -"Если без предлога, то теряется смысл: читается так, как будто Tarantool " -"Cartridge — это название приложения. А это не так." -msgstr "" - -msgid "Tarantool Cartridge application" -msgstr "" - -msgid "Tarantool Cartridge — это фреймворк" -msgstr "" - -msgid "на базе которого можно разработать свое приложение.\"" -msgstr "" - -msgid "production environment" -msgstr "" - -msgid "производственная среда" -msgstr "" - -msgid "" -"Production environment is a term used mostly by developers to describe the " -"setting where software and other products are actually put into operation " -"for their intended uses by end users." -msgstr "" - -msgid "failover" -msgstr "" - -msgid "восстановление после сбоев" -msgstr "" - -msgid "" -"In computing and related technologies such as networking, failover is " -"switching to a redundant or standby computer server, system, hardware " -"component or network upon the failure or abnormal termination of the " -"previously active application, server, system, hardware component, or " -"network." -msgstr "" - -msgid "replicaset" -msgstr "" - -msgid "directory" -msgstr "" - -msgid "директория" -msgstr "" - -msgid "bucket" -msgstr "" - -msgid "сегмент" -msgstr "" - -msgid "check" -msgstr "" - -msgid "выберите, выбрать" +"This section covers the specifics of localizing Tarantool into Russian. If " +"you are translating Tarantool docs into Russian, be sure to check out our " +"translation guidelines." msgstr "" -msgid "To select a checkbox" +msgid "Contents:" msgstr "" diff --git a/locale/ru/LC_MESSAGES/contributing/docs/localization/glossaries.po b/locale/ru/LC_MESSAGES/contributing/docs/localization/glossaries.po new file mode 100644 index 0000000000..3259781f40 --- /dev/null +++ b/locale/ru/LC_MESSAGES/contributing/docs/localization/glossaries.po @@ -0,0 +1,537 @@ + +msgid "Glossaries" +msgstr "" + +msgid "Tarantool Core" +msgstr "" + +msgid "Term [en]" +msgstr "" + +msgid "Term [ru]" +msgstr "" + +msgid "Description [en]" +msgstr "" + +msgid "Description [ru]" +msgstr "" + +msgid "space" +msgstr "" + +msgid "спейс" +msgstr "" + +msgid "A space is a container for tuples." +msgstr "" + +msgid "https://www.tarantool.io/en/doc/latest/book/box/data_model/#spaces\"" +msgstr "" + +msgid "NOUN" +msgstr "" + +msgid "tuple" +msgstr "" + +msgid "кортеж" +msgstr "" + +msgid "" +"A tuple plays the same role as a “row” or a “record”. The number of tuples " +"in a space is unlimited. Tuples in Tarantool are stored as MsgPack arrays. " +"https://www.tarantool.io/en/doc/latest/book/box/data_model/#tuples" +msgstr "" + +msgid "Tarantool" +msgstr "" + +msgid "НЕ ПЕРЕВОДИТЬ" +msgstr "" + +msgid "primary index" +msgstr "" + +msgid "первичный индекс" +msgstr "" + +msgid "" +"The first index defined on a space is called the primary key index, and it " +"must be unique. All other indexes are called secondary indexes, and they may" +" be non-unique. " +"https://www.tarantool.io/en/doc/latest/book/box/data_model/#indexes" +msgstr "" + +msgid "fiber" +msgstr "" + +msgid "файбер" +msgstr "" + +msgid "" +"A fiber is a set of instructions which are executed with cooperative " +"multitasking. Fibers managed by the fiber module are associated with a user-" +"supplied function called the fiber function. " +"https://www.tarantool.io/en/doc/latest/reference/reference_lua/fiber/#fibers" +msgstr "" + +msgid "Tarantool garbage collector" +msgstr "" + +msgid "сборщик мусора в Tarantool" +msgstr "" + +msgid "" +"A garbage collector fiber runs in the background on the master storages of " +"each replica set. It starts deleting the contents of the bucket in the " +"GARBAGE state part by part. Once the bucket is empty, its record is deleted " +"from the _bucket system space. " +"https://www.tarantool.io/en/doc/latest/reference/reference_rock/vshard/vshard_admin/#garbage-" +"collector" +msgstr "" + +msgid "Lua garbage collector" +msgstr "" + +msgid "сборщик мусора на Lua" +msgstr "" + +msgid "" +"Lua manages memory automatically by running a garbage collector from time to" +" time to collect all dead objects (that is, objects that are no longer " +"accessible from Lua). https://www.lua.org/manual/5.1/manual.html#2.10" +msgstr "" + +msgid "storage engine" +msgstr "" + +msgid "движок базы данных" +msgstr "" + +msgid "" +"A storage engine is a set of very-low-level routines which actually store " +"and retrieve tuple values. " +"https://www.tarantool.io/en/doc/latest/book/box/engines/" +msgstr "" + +msgid "thread" +msgstr "" + +msgid "поток" +msgstr "" + +msgid "" +"A thread of execution is the smallest sequence of programmed instructions " +"that can be managed independently by a scheduler, which is typically a part " +"of the operating system." +msgstr "" + +msgid "Lua application" +msgstr "" + +msgid "Lua-приложение, приложение на языке Lua" +msgstr "" + +msgid "Tarantool’s native language for writing applications is Lua." +msgstr "" + +msgid "memtx" +msgstr "" + +msgid "instance" +msgstr "" + +msgid "экземпляр" +msgstr "" + +msgid "implicit casting" +msgstr "" + +msgid "неявное приведение типов" +msgstr "" + +msgid "database" +msgstr "" + +msgid "база данных" +msgstr "" + +msgid "Release policy" +msgstr "" + +msgid "Релизная политика" +msgstr "" + +msgid "" +"A set of rules for releasing and naming new distributions of Tarantool: " +"where we add new features and where we don't, how we give them numbers, what" +" versions are suitable to use in production." +msgstr "" + +msgid "field" +msgstr "" + +msgid "поле" +msgstr "" + +msgid "" +"Fields are distinct data values, contained in a tuple. They play the same " +"role as «row columns» or «record fields» in relational databases." +msgstr "" + +msgid "https://www.tarantool.io/ru/doc/latest/book/box/data_model/#term-field\"" +msgstr "" + +msgid "leader election" +msgstr "" + +msgid "выборы лидера" +msgstr "" + +msgid "(in a replica set, by the Raft algorithm)" +msgstr "" + +msgid "replica set" +msgstr "" + +msgid "набор реплик" +msgstr "" + +msgid "heartbeat" +msgstr "" + +msgid "контрольный сигнал" +msgstr "" + +msgid "functionality" +msgstr "" + +msgid "функциональность" +msgstr "" + +msgid "log" +msgstr "" + +msgid "журнал" +msgstr "" + +msgid "node" +msgstr "" + +msgid "узел" +msgstr "" + +msgid "follower" +msgstr "" + +msgid "реплика" +msgstr "" + +msgid "small allocator" +msgstr "" + +msgid "аллокатор small" +msgstr "" + +msgid "https://github.com/tarantool/small" +msgstr "" + +msgid "patch" +msgstr "" + +msgid "патч" +msgstr "" + +msgid "breaking change" +msgstr "" + +msgid "критическое изменение" +msgstr "" + +msgid "parser" +msgstr "" + +msgid "парсер" +msgstr "" + +msgid "UUID" +msgstr "" + +msgid "data type" +msgstr "" + +msgid "тип данных" +msgstr "" + +msgid "alias" +msgstr "" + +msgid "алиас" +msgstr "" + +msgid "или псевдоним?" +msgstr "" + +msgid "push" +msgstr "" + +msgid "выполнить push" +msgstr "" + +msgid "MVCC" +msgstr "" + +msgid "(механизм) MVCC" +msgstr "" + +msgid "dirty read" +msgstr "" + +msgid "\"грязное чтение\"" +msgstr "" + +msgid "в кавычках" +msgstr "" + +msgid "snapshot" +msgstr "" + +msgid "снимок (данных)" +msgstr "" + +msgid "keywords" +msgstr "" + +msgid "ключевые слова" +msgstr "" + +msgid "identifier" +msgstr "" + +msgid "имя, идентификатор" +msgstr "" + +msgid "clause" +msgstr "" + +msgid "предложение, блок" +msgstr "" + +msgid "" +"(SQL) A clause in SQL is a part of a query that lets you filter or " +"customizes how you want your data to be queried to you." +msgstr "" + +msgid "expression" +msgstr "" + +msgid "выражение" +msgstr "" + +msgid "predicate" +msgstr "" + +msgid "предикат" +msgstr "" + +msgid "" +"(SQL) Predicates, which specify conditions that can be evaluated to SQL " +"three-valued logic (3VL) (true/false/unknown) or Boolean truth values and " +"are used to limit the effects of statements and queries, or to change " +"program flow." +msgstr "" + +msgid "query" +msgstr "" + +msgid "запрос" +msgstr "" + +msgid "" +"(SQL) Queries retrieve the data based on specific criteria. A query is a " +"statement that returns a result set (possibly empty)." +msgstr "" + +msgid "result set" +msgstr "" + +msgid "результат запроса" +msgstr "" + +msgid "" +"(SQL) An SQL result set is a set of rows from a database, as well as " +"metadata about the query such as the column names, and the types and sizes " +"of each column. A result set is effectively a table." +msgstr "" + +msgid "resultset" +msgstr "" + +msgid "statement" +msgstr "" + +msgid "инструкция" +msgstr "" + +msgid "" +"(SQL) A statement is any text that the database engine recognizes as a valid" +" command." +msgstr "" + +msgid "" +"(SQL) Любой текст, который распознаётся движком БД как команда. Инструкция " +"состоит из ключевых слов и выражений языка SQL, которые предписывают " +"Tarantool выполнять какие-либо действия с базой данных." +msgstr "" + +msgid "" +"Tarantool: A statement consists of SQL-language keywords and expressions " +"that direct Tarantool to do something with a database. " +"https://www.tarantool.io/en/doc/latest/reference/reference_sql/sql_user_guide/#statements\"" +msgstr "" + +msgid "batch" +msgstr "" + +msgid "пакет (инструкций)" +msgstr "" + +msgid "" +"(SQL) A series of SQL statements sent to the server at once is called a " +"batch." +msgstr "" + +msgid "(SQL) Серия SQL-инструкций (statements), отправляемая на сервер вместе" +msgstr "" + +msgid "production configuration" +msgstr "" + +msgid "конфигурация производственной среды" +msgstr "" + +msgid "deployment" +msgstr "" + +msgid "" +"Transforming a mechanical, electrical, or computer system from a packaged to" +" an operational state. IT infrastructure deployment typically involves " +"defining the sequence of operations or steps, often referred to as a " +"deployment plan, that must be carried to deliver changes into a target " +"system environment." +msgstr "" + +msgid "roll back" +msgstr "" + +msgid "отменить" +msgstr "" + +msgid "транзакцию" +msgstr "" + +msgid "deploy to production" +msgstr "" + +msgid "" +"IT infrastructure deployment typically involves defining the sequence of " +"operations or steps, often referred to as a deployment plan, that must be " +"carried to deliver changes into a target system environment. Production " +"environment is a setting where software and other products are actually put " +"into operation for their intended uses by end users" +msgstr "" + +msgid "operations" +msgstr "" + +msgid "эксплуатация" +msgstr "" + +msgid "" +"(DevOps) Information technology operations, or IT operations, are the set of" +" all processes and services that are both provisioned by an IT staff to " +"their internal or external clients and used by themselves, to run themselves" +" as a business." +msgstr "" + +msgid "to deploy" +msgstr "" + +msgid "deployment plan" +msgstr "" + +msgid "" +"A sequence of operations or steps that must be carried to deliver changes " +"into a target system environment." +msgstr "" + +msgid "Cartridge" +msgstr "" + +msgid "приложение на Tarantool Cartridge" +msgstr "" + +msgid "" +"Если без предлога, то теряется смысл: читается так, как будто Tarantool " +"Cartridge — это название приложения. А это не так." +msgstr "" + +msgid "Tarantool Cartridge application" +msgstr "" + +msgid "Tarantool Cartridge — это фреймворк" +msgstr "" + +msgid "на базе которого можно разработать свое приложение.\"" +msgstr "" + +msgid "production environment" +msgstr "" + +msgid "производственная среда" +msgstr "" + +msgid "" +"Production environment is a term used mostly by developers to describe the " +"setting where software and other products are actually put into operation " +"for their intended uses by end users." +msgstr "" + +msgid "failover" +msgstr "" + +msgid "восстановление после сбоев" +msgstr "" + +msgid "" +"In computing and related technologies such as networking, failover is " +"switching to a redundant or standby computer server, system, hardware " +"component or network upon the failure or abnormal termination of the " +"previously active application, server, system, hardware component, or " +"network." +msgstr "" + +msgid "replicaset" +msgstr "" + +msgid "directory" +msgstr "" + +msgid "директория" +msgstr "" + +msgid "bucket" +msgstr "" + +msgid "сегмент" +msgstr "" + +msgid "check" +msgstr "" + +msgid "выберите, выбрать" +msgstr "" + +msgid "To select a checkbox" +msgstr "" diff --git a/locale/ru/LC_MESSAGES/contributing/docs/localization/guide.po b/locale/ru/LC_MESSAGES/contributing/docs/localization/guide.po new file mode 100644 index 0000000000..c2931b4069 --- /dev/null +++ b/locale/ru/LC_MESSAGES/contributing/docs/localization/guide.po @@ -0,0 +1,240 @@ + +msgid "Tarantool Translation Guidelines" +msgstr "" + +msgid "Use this guide when localizing Tarantool into Russian." +msgstr "" + +msgid "Tone of voice" +msgstr "" + +msgid "General voice" +msgstr "" + +msgid "" +"We address IT specialists fairly knowledgeable in their respective fields. " +"The goal of our translations is to help these people understand how to use " +"Tarantool. Think of us as their colleagues and address them as such. Be " +"professional but friendly. Don’t command or patronize. Use colloquial speech" +" but avoid being too familiar. It’s all about the golden mean." +msgstr "" + +msgid "Modal verbs" +msgstr "" + +msgid "" +"Think twice when translating modal verbs. Avoid using expressions like «вы " +"должны», because they sound like a demand in Russian, and «вам придётся», " +"because it implies that our readers will face a lot of trouble. Be careful " +"with «нельзя». Make it easy for the user to read the documentation." +msgstr "" + +msgid "Gender neutrality" +msgstr "" + +msgid "" +"Use gender-neutral expressions like «сделать самостоятельно» instead of " +"«сделать самому», etc." +msgstr "" + +msgid "Term choice" +msgstr "" + +msgid "" +"Though not all of our readers may be fluent in English, they write in " +"English-based programming languages and are used to seeing error messages in" +" English. Therefore, if they see an unfamiliar and/or more archaic Russian " +"term for a familiar concept, they might have trouble correlating them." +msgstr "" + +msgid "" +"We don’t want our audience to feel confused, so we prefer newer terms. We " +"also provide the English equivalent for a term if it is used in the article " +"for the first time." +msgstr "" + +msgid "" +"If you feel like the older Russian term may sound more familiar for a part " +"of the audience (for example, those with a math background), consider adding" +" it in parentheses along with the English equivalent. Don’t repeat the " +"parentheses throughout the text. A similar rule applies to :ref:`introducing" +" terms in Tarantool documentation `." +msgstr "" + +msgid "Term choice examples" +msgstr "" + +msgid "First time" +msgstr "" + +msgid "All following times" +msgstr "" + +msgid "state machine" +msgstr "" + +msgid "машина состояний (конечный автомат, state machine)" +msgstr "" + +msgid "машина состояний" +msgstr "" + +msgid "write-ahead log; WAL" +msgstr "" + +msgid "журнал упреждающей записи (write-ahead log, WAL)" +msgstr "" + +msgid "журнал упреждающей записи; WAL; журнал WAL *(using a descriptor)*" +msgstr "" + +msgid "Best practices" +msgstr "" + +msgid "Be creative" +msgstr "" + +msgid "" +"Please avoid word-for-word translations. Let the resulting text sound as " +"though it was originally written in Russian." +msgstr "" + +msgid "Less is more" +msgstr "" + +msgid "" +"Be concise and don't repeat yourself. Fewer words are the best option most " +"of the time." +msgstr "" + +msgid "Don't" +msgstr "" + +msgid "Do" +msgstr "" + +msgid "" +"Профиль доступа можно назначить для любой роли пользователя, созданной " +"администратором. А к ролям по умолчанию привязать профили доступа не " +"получится, поскольку такие роли редактировать нельзя." +msgstr "" + +msgid "" +"Профиль доступа можно назначить для любой роли пользователя, созданной " +"администратором. Исключение составляют роли по умолчанию, поскольку их " +"нельзя редактировать." +msgstr "" + +msgid "Topic and focus" +msgstr "" + +msgid "Avoid English word order." +msgstr "" + +msgid "" +"The Russian speech is structured with topic and focus (`тема и рема " +"`_). The " +"topic is the given in the sentence, something we already know. The focus is " +"whatever new/important information is provided in the sentence about the " +"topic. In written Russian, the focus most often stands at the end of the " +"sentence, while in English, sentences may start with it." +msgstr "" + +msgid "" +"It is recommended to use `systemd` for managing the application instances " +"and accessing log entries." +msgstr "" + +msgid "" +"Для управления экземплярами приложения и доступа к записям журнала " +"рекомендуется использовать `systemd`." +msgstr "" + +msgid "" +"Do not specify working directories of the instances in this configuration." +msgstr "" + +msgid "Не указывайте в этой конфигурации рабочие директории экземпляров." +msgstr "" + +msgid "No bureaucratese" +msgstr "" + +msgid "" +"Avoid overly formal, bureaucratic language whenever possible. Prefer verbs " +"over verbal nouns, and don’t use «являться» and «осуществляться» unless it’s" +" absolutely necessary." +msgstr "" + +msgid "" +"To learn how to clear your Russian texts of bureaucratese, check `Timur " +"Anikin's training The Writing Dead " +"`_." +msgstr "" + +msgid "Сообщение исчезнет, как только вы покинете данную страницу." +msgstr "" + +msgid "Сообщение исчезнет, как только вы покинете страницу." +msgstr "" + +msgid "Проверка истечения срока действия паролей производится раз в 30 минут." +msgstr "" + +msgid "Система раз в 30 минут проверяет, не истек ли срок действия паролей." +msgstr "" + +msgid "Consistency" +msgstr "" + +msgid "" +"Use one term for one concept throughout the article. For example, only " +"translate production as «производственная среда» and not as " +"«эксплуатационная среда» throughout your article. It’s not about synonyms, " +"but about terms: we don’t want people to get confused." +msgstr "" + +msgid "Avoid elliptical sentences" +msgstr "" + +msgid "Defaults to `root`." +msgstr "" + +msgid "По умолчанию --- `root`." +msgstr "" + +msgid "Значение по умолчанию --- `root`." +msgstr "" + +msgid "Pronoun collocations" +msgstr "" + +msgid "Do all the pronouns point to the exact nouns you want them to?" +msgstr "" + +msgid "" +"**Example (how not to):** Прежде чем добавить запись в конфигурацию, укажите" +" к ней путь." +msgstr "" + +msgid "" +"In the example, it is not quite clear what «к ней» means---to the record or " +"to the configuration. For more on this issue, check out `the writers' " +"reference at «Ошибкариум» `_." +msgstr "" + +msgid "Be critical towards your text" +msgstr "" + +msgid "" +"Don't forget to proofread your translation. Check your text at least twice." +msgstr "" + +msgid "Be nice to your peers" +msgstr "" + +msgid "" +"If you review others’ translations, be gentle and kind. Everyone makes " +"mistakes, and nobody likes to be punished for them. You can use phrasings " +"like \"I suggest\" or \"it's a good idea to... .\"" +msgstr "" diff --git a/locale/ru/LC_MESSAGES/contributing/docs/localization/locstate.po b/locale/ru/LC_MESSAGES/contributing/docs/localization/locstate.po new file mode 100644 index 0000000000..cb5c41ca59 --- /dev/null +++ b/locale/ru/LC_MESSAGES/contributing/docs/localization/locstate.po @@ -0,0 +1,105 @@ + +msgid "State of localization" +msgstr "" + +msgid "Repository" +msgstr "" + +msgid "State" +msgstr "" + +msgid "Volume, words" +msgstr "" + +msgid "Tarantool Community" +msgstr "" + +msgid "|doc|" +msgstr "" + +msgid "352 000" +msgstr "" + +msgid "Cartridge" +msgstr "" + +msgid "|cartridge|" +msgstr "" + +msgid "14 000" +msgstr "" + +msgid "Tarantool Ansible Role" +msgstr "" + +msgid "|tarantool-ansible-role|" +msgstr "" + +msgid "11 000" +msgstr "" + +msgid "Cartridge CLI" +msgstr "" + +msgid "|cartridge-cli|" +msgstr "" + +msgid "6 500" +msgstr "" + +msgid "Tarantool Enterprise" +msgstr "" + +msgid "|tarantool-enterprise|" +msgstr "" + +msgid "6 000" +msgstr "" + +msgid "Tarantool Data Grid" +msgstr "" + +msgid "|tarantool-data-grid|" +msgstr "" + +msgid "4 000" +msgstr "" + +msgid "Tarantool Metrics" +msgstr "" + +msgid "|tarantool-metrics|" +msgstr "" + +msgid "Tarantool C++ Driver" +msgstr "" + +msgid "|tarantool-cpp|" +msgstr "" + +msgid "Tarantool Kubernetes Operator" +msgstr "" + +msgid "|tarantool-kubernetes-operator|" +msgstr "" + +msgid "2 750" +msgstr "" + +msgid "Tarantool Luatest" +msgstr "" + +msgid "|tarantool-luatest|" +msgstr "" + +msgid "750" +msgstr "" + +msgid "Tarantool Graphana Dashboard" +msgstr "" + +msgid "|tarantool-graphana-dashboard|" +msgstr "" + +msgid "500" +msgstr "" diff --git a/locale/ru/LC_MESSAGES/contributing/docs/terms.po b/locale/ru/LC_MESSAGES/contributing/docs/terms.po index 4aea8c4750..484d0753ce 100644 --- a/locale/ru/LC_MESSAGES/contributing/docs/terms.po +++ b/locale/ru/LC_MESSAGES/contributing/docs/terms.po @@ -67,7 +67,7 @@ msgstr "" msgid "" "For example, in Tarantool, we don't use the term \"[database] segmentation\"" " to denote what we call \"database sharding.\" Although, other authors could" -" do so. Also, there is a term \"[database] partitioning\" that we use to " +" do so. Also, there is the term \"[database] partitioning\" that we use to " "denote a wider concept, which includes sharding and other things." msgstr "" diff --git a/locale/ru/LC_MESSAGES/reference/interactive_console.po b/locale/ru/LC_MESSAGES/reference/interactive_console.po index 5a66698254..a475a7dfe7 100644 --- a/locale/ru/LC_MESSAGES/reference/interactive_console.po +++ b/locale/ru/LC_MESSAGES/reference/interactive_console.po @@ -92,13 +92,13 @@ msgid ":code:`1`" msgstr "" msgid ":code:`---`" -msgstr ":code:`---`" +msgstr "" msgid ":code:`- 1`" -msgstr ":code:`- 1`" +msgstr "" msgid ":code:`...`" -msgstr ":code:`...`" +msgstr "" msgid ":code:`\\x01`" msgstr "" diff --git a/locale/ru/LC_MESSAGES/release.po b/locale/ru/LC_MESSAGES/release.po index 03405ef98e..36d4aaa76f 100644 --- a/locale/ru/LC_MESSAGES/release.po +++ b/locale/ru/LC_MESSAGES/release.po @@ -2,50 +2,36 @@ msgid "Release notes" msgstr "Примечания к версиям" -msgid "Tarantool version numbers consist of three parts:" -msgstr "Номер версии Tarantool состоит из трех частей:" - -msgid "MAJOR_VERSION.RELEASE_SERIES.RELEASE" -msgstr "ОСНОВНАЯ_ВЕРСИЯ.СЕРИЯ_ВЫПУСКОВ.ВЫПУСК" - msgid "" -"The third number distinguishes between alpha, beta and release versions:" +"Since version 2.10, there's a :doc:`new release policy for Tarantool " +"`. In short, Tarantool version numbers consist of three " +"parts:" msgstr "" -"Третья часть номера указывает, альфа-версия ли это, бета-версия или релизная" -" версия:" +"Для Tarantool 2.10 и последующих версий действует :doc:`новая релизная " +"политика `. Номер версии Tarantool состоит из трех чисел:" -msgid "" -"``x.y.0`` is an **alpha version**, just a base for adding new features. We " -"use alpha versions internally and don't release them as distributions." -msgstr "" -"``x.y.0`` — это **альфа-версия**, просто база для добавления новых функций. " -"Мы используем альфа-версии внутри компании и не выпускаем их в виде " -"дистрибутивов." +msgid "MAJOR.MINOR.PATCH" +msgstr "MAJOR.MINOR.PATCH" msgid "" -"``x.y.1`` is a **beta version**, where we add most new features. Beta " -"versions are good for trying new features, but not suitable for production " -"usage." +"Any version without extra prefixes is a release version. If you need a " +"version for production use, pick the latest release. For evaluation and " +"development, you can use beta versions. They are marked with ``-betaN`` " +"suffixes." msgstr "" -"``x.y.1`` — это **бета-версия**, в которую мы добавляем большинство новых " -"функций. Бета-версии полезны для тестирования новых функций, но не подходят " -"для использования в производстве." +"Релизные версии не имеют префиксов в названии. Для производственной " +"эксплуатации выбирайте последний релиз. Для пробного использования и " +"разработке выбирайте бета-версии. Они обозначены суффиксами вида ``-betaN``." msgid "" -"``x.y.2``, ``x.y.3`` and later are **release versions**, where we fix bugs " -"and polish newly added features." +"Before 2.10.0, version numbers were subject to the :doc:`legacy versioning " +"policy `:" msgstr "" -"``x.y.2``, ``x.y.3`` и выше — **релизные версии**, в которых исправлены " -"ошибки и проработаны новые функции." +"Версии Tarantool до 2.10.0 нумеровались согласно :doc:`старой политике " +"версионирования `:" -msgid "" -"If you want to use Tarantool in production, pick the one of the latest " -"release versions, such as 2.6.2 or 2.5.3. To learn more about the meaning of" -" version numbers, read the :doc:`/release/policy`." -msgstr "" -"Если вы хотите использовать Tarantool в рабочей среде, выберите одну из " -"последних релизных версий, например 2.6.2 или 2.5.3. Чтобы узнать больше о " -"значении номеров версий, см. :doc:`/release/policy`." +msgid "MAJOR_VERSION.RELEASE_SERIES.RELEASE" +msgstr "ОСНОВНАЯ_ВЕРСИЯ.СЕРИЯ_ВЫПУСКОВ.ВЫПУСК" msgid "" "Below is the table listing all Tarantool versions starting from 1.10.0 up to" @@ -68,17 +54,29 @@ msgstr "Бета" msgid "Release" msgstr "Выпуск" +msgid "2.10" +msgstr "2.10" + +msgid "n/a" +msgstr "--" + +msgid "2.10.0-beta1" +msgstr "2.10.0-beta1" + +msgid "not released yet" +msgstr "выпуск еще не состоялся" + msgid "2.8" -msgstr "" +msgstr "2.8" msgid "2.8.0" -msgstr "" +msgstr "2.8.0" msgid ":doc:`2.8.1 `" msgstr ":doc:`2.8.1 `" -msgid "not released yet" -msgstr "выпуск еще не состоялся" +msgid "2.8.2" +msgstr "2.8.2" msgid "2.7" msgstr "2.7" @@ -168,6 +166,11 @@ msgid "" "`, :doc:`1.10.9 `, :doc:`1.10.10 " "`" msgstr "" +":ref:`1.10.2 `, :ref:`1.10.3 `, :ref:`1.10.4" +" `, :doc:`1.10.5 `, :doc:`1.10.6 " +"`, :doc:`1.10.7 `, :doc:`1.10.8 " +"`, :doc:`1.10.9 `, :doc:`1.10.10 " +"`" msgid "" "For smaller feature changes and bug fixes, see closed `milestones " diff --git a/locale/ru/LC_MESSAGES/release/2.2.1.po b/locale/ru/LC_MESSAGES/release/2.2.1.po index 7e3ce2de3d..f3314e052b 100644 --- a/locale/ru/LC_MESSAGES/release/2.2.1.po +++ b/locale/ru/LC_MESSAGES/release/2.2.1.po @@ -2,47 +2,12 @@ msgid "Tarantool 2.2.1" msgstr "" -msgid "Release: :tarantool-release:`2.2.1`" -msgstr "" - -msgid "" -"Tarantool 2.x is backward compatible with Tarantool 1.10.x in binary data " -"layout, client-server protocol and replication protocol. You can " -":ref:`upgrade ` using the ``box.schema.upgrade()`` " -"procedure." -msgstr "" -"Tarantool 2.x обратно совместим с Tarantool 1.10.x в том, что касается " -"структуры бинарных данных, клиент-серверного протокола и протокола " -"репликации. :ref:`Обновление ` можно произвести с помощью " -"процедуры ``box.schema.upgrade()``." - -msgid "**Release 2.4.1**" -msgstr "**Версия 2.4.1**" - -msgid "Deprecations" -msgstr "Устаревшие функции" - -msgid "(SQL) SESSION will be a reserved word so objects named SESSION will" -msgstr "" - -msgid "be illegal. Part of (:tarantool-issue:`4711`)." -msgstr "" - -msgid "In :ref:`box.session.push() ` the use of the" -msgstr "" - msgid "" -"``sync`` parameter will cause a warning in version 2.4.1 and will cause an " -"error in later versions. Part of (:tarantool-issue:`4689`)." +"Release: :tarantool-release:`2.2.1`. Release type: beta. Release date: " +"2019-08-02." msgstr "" -msgid "**Release 2.2.1**" -msgstr "**Версия 2.2.1**" - -msgid "Release type: beta. Release date: 2019-08-02." -msgstr "" - -msgid "Release: :tarantool-release:`2.2.1.`" +msgid "Overview" msgstr "" msgid "" @@ -56,8 +21,22 @@ msgid "" "feature set, and improve integration with the core." msgstr "" -msgid "Functionality added or changed:" -msgstr "Изменения или добавления функциональности:" +msgid "Compatibility" +msgstr "" + +msgid "" +"Tarantool 2.x is backward compatible with Tarantool 1.10.x in binary data " +"layout, client-server protocol and replication protocol. You can " +":ref:`upgrade ` using the ``box.schema.upgrade()`` " +"procedure." +msgstr "" +"Tarantool 2.x обратно совместим с Tarantool 1.10.x в том, что касается " +"структуры бинарных данных, клиент-серверного протокола и протокола " +"репликации. :ref:`Обновление ` можно произвести с помощью " +"процедуры ``box.schema.upgrade()``." + +msgid "Functionality added or changed" +msgstr "" msgid "(SQL) ALTER now allows to add a constraint:" msgstr "" @@ -67,10 +46,9 @@ msgid "" "ALTER TABLE t2 ADD CONSTRAINT ck CHECK(id > 0);" msgstr "" -msgid "(SQL) CHECK constraints are validated during DML operations performed" -msgstr "" - -msgid "from the Lua land:" +msgid "" +"(SQL) CHECK constraints are validated during DML operations performed from " +"the Lua land:" msgstr "" msgid "" @@ -87,35 +65,28 @@ msgid "" "..." msgstr "" -msgid "(SQL) New :ref:`SQL types ` introduced:" -msgstr "" - -msgid "VARBINARY, UNSIGNED, and `BOOLEAN`." -msgstr "" - msgid "" -"(SQL) CREATE TABLE statement (and all other data definition statements)" +"(SQL) New :ref:`SQL types ` introduced: VARBINARY," +" UNSIGNED, and `BOOLEAN`." msgstr "" -msgid "are now truly transactional." +msgid "" +"(SQL) CREATE TABLE statement (and all other data definition statements) are " +"now truly transactional." msgstr "" msgid "" "(SQL) SQL now uses Tarantool diagnostics API to set errors, so error " -"reporting" -msgstr "" - -msgid "now provides an error code in addition to error message." +"reporting now provides an error code in addition to error message." msgstr "" msgid "" "(SQL) Multiple improvements to the type system to make it more consistent." msgstr "" -msgid "(SQL) Added aliases for LENGTH() from ANSI SQL:" -msgstr "" - -msgid "CHAR_LENGTH() and CHARACTER_LENGTH()." +msgid "" +"(SQL) Added aliases for LENGTH() from ANSI SQL: CHAR_LENGTH() and " +"CHARACTER_LENGTH()." msgstr "" msgid "(SQL) It is possible to use HAVING without GROUP BY." @@ -201,7 +172,7 @@ msgid "" "tarantool> box.func.summarize:call({1, 2})\n" "---\n" "- 3\n" -".. ." +"..." msgstr "" msgid "(Server) Functional indexes implemented:" @@ -285,46 +256,34 @@ msgstr "" msgid "" "(Engines) New protocol (called :ref:`SWIM `) implemented to " -"keep" -msgstr "" - -msgid "a table of cluster members." +"keep a table of cluster members." msgstr "" msgid "(Engines) Removed yields from Vinyl DDL on commit triggers." msgstr "" -msgid "(Engines) Improved performance of SELECT-s on memtx spaces." -msgstr "" - msgid "" -"The drawback is that now every memtx-tree tuple consumes extra 8 bytes for a" -" search hint." -msgstr "" - -msgid "(Engines) Indexes of memtx spaces are now built in background fibers." +"(Engines) Improved performance of SELECT-s on memtx spaces. The drawback is " +"that now every memtx-tree tuple consumes extra 8 bytes for a search hint." msgstr "" msgid "" -"This means that we do not block the event loop during index build anymore." -msgstr "" - -msgid "Replication applier now can apply transactions which were concurrent" +"(Engines) Indexes of memtx spaces are now built in background fibers. This " +"means that we do not block the event loop during index build anymore." msgstr "" msgid "" -"on the master concurrently on replica. This dramatically improves " -"replication peak performance, from ~50K writes per second to 200K writes per" -" second and higher on a single instance." -msgstr "" - -msgid "Transaction boundaries introduced to replication protocol." +"Replication applier now can apply transactions which were concurrent on the " +"master concurrently on replica. This dramatically improves replication peak " +"performance, from ~50K writes per second to 200K writes per second and " +"higher on a single instance." msgstr "" msgid "" -"This means that Tarantool replication is now transaction-safe, and also " -"reduces load on replica write ahead log in case the master uses a lot of " -"multi-statement transactions." +"Transaction boundaries introduced to replication protocol. This means that " +"Tarantool replication is now transaction-safe, and also reduces load on " +"replica write ahead log in case the master uses a lot of multi-statement " +"transactions." msgstr "" msgid "Tuple access by field name for ``net.box``:" @@ -344,16 +303,13 @@ msgstr "" msgid "Cluster id check is now the slave’s responsibility." msgstr "" -msgid "It is now possible to set the output format to Lua instead of YAML" -msgstr "" - -msgid "in the :ref:`interactive console `." -msgstr "" - -msgid "Multiple new collations added." +msgid "" +"It is now possible to set the output format to Lua instead of YAML in the " +":ref:`interactive console `." msgstr "" -msgid "New collations follow this naming pattern:" +msgid "" +"Multiple new collations added. New collations follow this naming pattern:" msgstr "" msgid "unicode__" @@ -372,7 +328,7 @@ msgid "Tertiary - \"s3\"" msgstr "" msgid "" -"The following list contains so-called \"stable\" collations - the ones whose" +"The following list contains so-called \"stable\" collations---the ones whose" " sort order doesn't depend on the ICU version:" msgstr "" diff --git a/locale/ru/LC_MESSAGES/release/policy.po b/locale/ru/LC_MESSAGES/release/policy.po index f7529dd8b2..3065e0250e 100644 --- a/locale/ru/LC_MESSAGES/release/policy.po +++ b/locale/ru/LC_MESSAGES/release/policy.po @@ -2,260 +2,629 @@ msgid "Tarantool Release Policy" msgstr "Принципы выпуска версий Tarantool" +msgid "Summary" +msgstr "Введение" + +msgid "" +"The Tarantool release policy is changing to become more clear and intuitive." +" The new policy uses a `SemVer-like `__ versioning " +"format, and introduces a new version lifecycle with more long-time support " +"series. This document explains the new release policy, versioning rules, and" +" :term:`release series` lifecycle." +msgstr "" +"Релизная политика Tarantool меняется, чтобы стать более понятной. Вводится " +"новый формат версионирования, похожий на `семантическое версионирование " +"(SemVer) `__, а также новый жизненный цикл " +"версий, предполагающий больше серий с долгосрочной поддержкой. В этом " +"документе подробно рассказано о новой релизной политике, правилах " +"версионирования и жизненном цикле :term:`релизных серий `." + +msgid "" +"The new release policy replaces :doc:`the legacy policy ` for:" +msgstr "" +"Новая релизная политика заменяет :doc:`старую ` для " +"следующих серий:" + +msgid "" +"The ``2.x.y`` series since the ``2.10.0`` release. Development for this new " +"release starts with version ``2.10.0-beta1``." +msgstr "" +"``2.x.y``, начиная с ``2.10.0``. Первая версия в этой серии --- " +"``2.10.0-beta1``." + +msgid "The future ``3.0.0`` series." +msgstr "В будущем --- ``3.0.0``." + +msgid "Here are the most significant changes from the legacy release policy:" +msgstr "Вот самые важные нововведения:" + +msgid "" +"The third number in the version label doesn't distinguish between pre-" +"release (alpha and beta) and release versions. Instead, it is used for patch" +" (bugfix-only) releases. Pre-release versions have suffixes, like " +"``3.0.0-alpha1``." +msgstr "" +"Третья часть номера версии больше не указывает на тип версии (альфа-, бета- " +"или релизная). Если это число отлично от нуля, то версия является патчем и " +"содержит только исправление ошибок. На конце номеров предварительных версий " +"теперь есть соответствующие суффиксы, например: ``3.0.0-alpha1``." + +msgid "" +"In the legacy release policy, ``1.10`` was a long-term support (LTS) series," +" while ``2.x.y`` had stable releases, but wasn't an LTS series. Now both " +"series are long-term supported." +msgstr "" +"Согласно старой релизной политике ``1.10`` была серией с долгосрочной " +"поддержкой (long-term support, LTS), а серия ``2.x.y`` — нет, хоть и " +"содержала стабильные релизы. Теперь долгосрочной поддержкой пользуются обе " +"серии." + +msgid "The topics below describe the new versioning policy in more detail." +msgstr "Ниже вы найдете подробные сведения о новой политике версионирования." + +msgid "Versioning policy" +msgstr "Политика версионирования" + +msgid "Release series and versions" +msgstr "Релизные серии и версии" + msgid "" -"A Tarantool release is identified by three digits, for example, 2.6.2 or " -"1.10.9:" -msgstr "Версия Tarantool состоит из трех чисел, например 2.6.2 или 1.10.9:" +"The new Tarantool release policy is based on having several release series, " +"each with its own lifecycle, pre-release and release versions." +msgstr "" +"В основе новой релизной политики Tarantool лежит поддержка нескольких " +"релизных серий. У каждой серии свой жизненный цикл, и в нее входят как " +"предварительные, так и релизные версии." + +msgid "Release series" +msgstr "Что такое релизная серия?" msgid "" -"The first digit stands for a MAJOR release series that introduces some " -"*major changes*. Up to now, there has been only one major release jump when " -"we delivered the 2.x release series with the SQL support." +"Release series is a sequence of development and production-ready versions " +"with linear evolution toward a defined roadmap. A series has a distinct " +"lifecycle and certain compatibility guarantees within itself and with other " +"series. The intended support time for each series is at least two years " +"since the first release." msgstr "" -"Первое число обозначает серию ОСНОВНЫХ версий, в которой вводятся некоторые " -"*значительные изменения*. Пока был только один переход на новую серию, когда" -" мы выпустили серию 2.x с поддержкой SQL." +"Релизная серия — это ряд версий для разработки и производственной " +"эксплуатации. Эта последовательность версий линейно развивается по " +"определенному плану. У каждой серии свой жизненный цикл, а версии в ней " +"обладают некоторой гарантией совместимости друг с другом и с версиями других" +" серий. Срок поддержки каждой серии — минимум два года с выхода первого " +"релиза." msgid "" -"The second digit stands for a MINOR release series that is used for " -"introducing new *features*. :ref:`Backward incompatible changes ` are possible between these release series." +"At the moment when this document is published, there are two release series:" +" series ``1.10`` and series ``2``." msgstr "" -"Второе число обозначает серию ПРОМЕЖУТОЧНЫХ версий, которые используются для" -" введения новых *функций*. Эти версии могут быть :ref:`обратно несовместимы " -"` между собой." +"На момент публикации этого документа существует две релизных серии " +"Tarantool: ``1.10`` и ``2``." + +msgid "Release version" +msgstr "Что такое релизная версия?" msgid "" -"The third digit is for PATCH releases by which we reflect how stable the " -"MINOR release series is:" +"Release version is a Tarantool distribution which is thoroughly tested and " +"ready for production usage. It is bound to a certain commit. Release version" +" label consists of three numbers:" +msgstr "" +"Релизная версия, или релиз — это тщательно протестированный и готовый к " +"производственной эксплуатации дистрибутив Tarantool, привязанный к " +"определенному коммиту. Номер релиза состоит из трех частей:" + +msgid "MAJOR.MINOR.PATCH" +msgstr "MAJOR.MINOR.PATCH" + +msgid "These numbers correspond to the three types of release versions:" msgstr "" -"Третье число используется для обозначения ПАТЧ-версий, которые отражают " -"стабильность ПРОМЕЖУТОЧНЫХ версий:" +"Каждое число соответствует одному из трех типов релизных версий, о чем " +"подробно рассказано ниже." -msgid "``0`` meaning **alpha**" -msgstr "``0`` — **альфа**" +msgid "Major release" +msgstr "Мажорный релиз" -msgid "``1`` meaning **beta**" -msgstr "``1`` — **бета**" +msgid "" +"Major release is the first :term:`release version ` of its " +"own :term:`release series `. It introduces new features and " +"can have a few backward-incompatible changes. Such release changes the first" +" version number:" +msgstr "" +"Мажорная релизная версия — это первый :term:`релиз ` в " +"своей :term:`релизной серии `. Релиз включает в себя новую " +"функциональность и может нарушать обратную совместимость с прежними " +"версиями. Каждый следующий мажорный релиз получает номер, в котором изменено" +" первое число:" -msgid "``2`` and above meaning **release** (earlier known as **stable**)." +msgid "" +"MAJOR.0.0\n" +"\n" +"3.0.0" msgstr "" -"``2`` и выше — **релизная версия** (раньше называлась **стабильная**)." +"MAJOR.0.0\n" +"\n" +"3.0.0" + +msgid "Minor release" +msgstr "Минорный релиз" msgid "" -"So, each MINOR release series goes through a development-maturity life cycle" -" as follows:" +"Minor release introduces a few new features, but guarantees backward " +"compatibility. There can be a few bugs fixed as well. Such release changes " +"the second version number:" msgstr "" -"Таким образом, разработка каждой ПРОМЕЖУТОЧНОЙ версии проходит жизненный " -"цикл следующим образом:" +"В минорном релизе могут вводиться новые функциональные возможности. Тем не " +"менее он гарантированно будет совместим с более ранними версиями серии. " +"Могут быть также исправлены ошибки. Каждый следующий минорный релиз получает" +" номер, в котором изменено второе число:" msgid "" -"**Alpha**. Once a quarter, we start off with a new alpha version, such as " -"2.3.0, 2.4.0, and so on. This is not what an alpha release usually means in " -"the typical software release life cycle but rather the current trunk version" -" which is under heavy development and can be unstable. The current alpha " -"version always lives in the master branch." +"MAJOR.MINOR.0\n" +"\n" +"3.1.0\n" +"3.2.0" msgstr "" -"**Альфа-версия**. Раз в квартал мы начинаем разработку новой альфа-версии, " -"например 2.3.0, 2.4.0 и так далее. Это не совсем альфа-версия, как в " -"типичном жизненном цикле выпуска программного обеспечения, а скорее текущая " -"основная версия, которая находится в процессе интенсивной разработки и может" -" быть нестабильной. Текущая альфа-версия всегда живет в основной ветви " -"разработки." +"MAJOR.MINOR.0\n" +"\n" +"3.1.0\n" +"3.2.0" + +msgid "Patch release" +msgstr "Патч" msgid "" -"**Beta**. When all the features planned are implemented, we fork a new " -"branch from the master branch and tag it as a new beta version. It contains " -"``1`` for the PATCH digit, e.g., 2.3.1, 2.4.1, and so on. This version " -"cannot be called stable yet (feature freeze has just been done) although " -"there are no known critical regressions in it since the last stable release." +"Patch release fixes bugs from an earlier release, but doesn't introduce new " +"features. Such release changes the third version number:" msgstr "" -"**Бета-версия**. Когда все запланированные функции реализованы, мы отделяем " -"новую ветвь от основной и помечаем ее как новую бета-версию с ``1`` в конце " -"для обозначения ПАТЧА, например, 2.3.1, 2.4.1 и так далее. Эту версию пока " -"нельзя назвать стабильной (только что перестали добавлять функциональные " -"возможности), хотя с момента последнего стабильного выпуска в ней нет " -"известных критических регрессионных ошибок." +"Патч (patch release) исправляет ошибки предыдущих версий, но не добавляет " +"новую функциональность. Каждый следующий патч получает номер, в котором " +"изменено третье число:" msgid "" -"**Release** (earlier known as **stable**). Finally, after we see our beta " -"version runs successfully in a production or development environment during " -"another quarter while we fix incoming bugs, we declare this version stable. " -"It is tagged with ``2`` for the PATCH digit, e.g., 2.3.2, 2.4.2, and so on." +"MAJOR.MINOR.PATCH\n" +"\n" +"3.0.1\n" +"3.0.2" msgstr "" -"**Релизная версия** (раньше называлась **стабильная**). Когда мы видим, что " -"бета-версия успешно работает в течение еще одного квартала в рабочей среде " -"или в среде разработки, пока мы исправляем обнаруженные ошибки, мы объявляем" -" эту версию стабильной. ПАТЧ помечается цифрой ``2``, например, 2.3.2, 2.4.2" -" и так далее." +"MAJOR.MINOR.PATCH\n" +"\n" +"3.0.1\n" +"3.0.2" + +msgid "Release versions conform to a set of requirements:" +msgstr "Релизы отвечают ряду требований:" msgid "" -"We support such version for 3 months while making another stable release by " -"fixing all bugs found. We release it in a quarter. This last tag contains " -"``3`` for the PATCH digit, e.g., 2.3.3, 2.4.3, and so on. After the tag is " -"set, no new changes are allowed to the release branch, and it is declared " -"deprecated and superseded by a newer MINOR version." +"The release has gone through pre-release testing and adoption in the " +"internal projects until there were no doubts regarding its stability." +msgstr "" +"Каждый релиз предварительно тестировался и обкатывался во внутренних " +"проектах, пока не исчезли все сомнения в его стабильности." + +msgid "There are no known bugs in the typical usage scenarios." msgstr "" -"Мы поддерживаем такую версию в течение 3 месяцев, параллельно работая над " -"еще одной стабильной версией, в которой исправляем все найденные ошибки. " -"Через три месяца мы выпускаем ее, обозначая ПАТЧ цифрой ``3``, например, " -"2.3.3, 2.4.3 и так далее. После установки этого тега никакие новые изменения" -" в релизную ветвь не вносим, объявляем ее устаревшей и заменяем ее новой " -"ПРОМЕЖУТОЧНОЙ версией." +"Исправлены все обнаруженные ошибки в стандартных сценариях использования." msgid "" -"Release versions don't receive any new features and only get backward " -"compatible fixes." +"There are no degradations from the previous release or release series, in " +"case of a major release." msgstr "" -"В релизные версии мы не добавляем никакие новые функциональные возможности, " -"а только обратно совместимые исправления." +"Нет регрессии, то есть нет новых ошибок в функциональности из прошлых " +"релизов. В случае мажорного релиза, нет регрессии в функциональности из " +"предыдущей серии." msgid "" -"Like Ubuntu, in terms of support, we distinguish between two kinds of stable" -" release series:" +"Backwards compatibility is guaranteed between all versions in the same " +"release series. It is also appreciated, but not guaranteed between different" +" release series (major number changes). A detailed description of " +"compatibility guarantees will be published later." msgstr "" -"Как в Ubuntu, у нас есть две категории стабильных версий в плане поддержки:" +"Обратная совместимость между всеми версиями одной релизной серии " +"гарантирована. Между разными сериями (у которых различается первая часть " +"номера) обратная совместимость приветствуется, но не гарантируется. " +"Подробная информация о гарантиях совместимости будет опубликована позже." + +msgid "Pre-release versions" +msgstr "Предварительные версии" + +msgid "Pre-release version" +msgstr "Что такое предварительная версия?" msgid "" -"**LTS (Long Term Support)** is a release series that is supported for 3 " -"years (community) and up to 5 years (paying customers). Current LTS release " -"series is 1.10, and it receives only PATCH level releases." +"Pre-release versions are the ones published for testing and evaluation, and " +"not intended for production use. Such versions use the same pattern with an " +"additional suffix:" msgstr "" -"**LTS-версии (долгосрочная поддержка, long term support)** — это выпуски, " -"которые поддерживаются 3 года для сообщества и 5 лет для платящих клиентов. " -"Текущая серия LTS-версий — 1.10, для нее выпускаются только версии уровня " -"ПАТЧ." +"Предварительными называются версии, опубликованные для тестирования и " +"обкатки, но не предназначенные для производственной эксплуатации. Эти версии" +" нумеруются по тому же принципу, что и релизы, но имеют суффикс:" + +msgid "MAJOR.MINOR.PATCH-suffix" +msgstr "MAJOR.MINOR.PATCH-suffix" + +msgid "There are a few types of pre-release versions:" +msgstr "Ниже подробно рассказывается о четырех типах предварительных версий." + +msgid "Development build" +msgstr "Dev-сборка" msgid "" -"**Standard** is a release series that is supported only for a few months " -"until the next release series enters the stable state." +"Development builds reflect the state of current development process. They're" +" used entirely for development and testing, and not intended for any " +"external use." msgstr "" -"**Обычные версии** — это серия выпусков, которая поддерживается только в " -"течение нескольких месяцев до выхода следующей стабильной серии." +"Dev-сборка (development build) отражает определенный этап разработки " +"продукта. Такие сборки используются только в процессе разработки и " +"внутреннего тестирования." msgid "" -"Below is a diagram that illustrates the release sequence issuing described " -"above by an example of some latest releases and release series:" +"Development builds have suffixes made with ``$(git describe --always " +"--long)-dev``:" msgstr "" -"Ниже представлена схема, которая иллюстрирует вышеописанную " -"последовательность выпуска версий на примере некоторых последних версий и " -"серий:" +"Dev-сборки обозначаются суффиксом, полученным командой ``$(git describe " +"--always --long)-dev``:" msgid "" -"1.10 series -- 1.10.4 -- 1.10.5 -- 1.10.6 -- 1.10.7\n" -"(LTS)\n" +"MAJOR.MINOR.PATCH-describe-dev\n" "\n" -"....\n" +"2.10.2-149-g1575f3c07-dev\n" +"3.0.0-alpha1-14-gxxxxxxxxx-dev\n" +"3.0.0-entrypoint-17-gxxxxxxxxx-dev\n" +"3.1.2-5-gxxxxxxxxx-dev" +msgstr "" +"MAJOR.MINOR.PATCH-describe-dev\n" "\n" -"2.2 series --- 2.2.1 --- 2.2.2 --- 2.2.3 (end of support)\n" -" |\n" -" V\n" -"2.3 series ... 2.3.0 --- 2.3.1 --- 2.3.2 --- 2.3.3 (end of support)\n" -" |\n" -" V\n" -"2.4 series ............. 2.4.0 --- 2.4.1 --- 2.4.2\n" -" |\n" -" V\n" -"2.5 series ....................... 2.5.0 --- 2.5.1\n" -" |\n" -" V\n" -"2.6 series ................................. 2.6.0\n" +"2.10.2-149-g1575f3c07-dev\n" +"3.0.0-alpha1-14-gxxxxxxxxx-dev\n" +"3.0.0-entrypoint-17-gxxxxxxxxx-dev\n" +"3.1.2-5-gxxxxxxxxx-dev" + +msgid "Alpha version" +msgstr "Альфа-версия" + +msgid "" +"Alpha version has some of the features planned in the release series. It can" +" be incomplete or unstable, and can break the backwards compatibility with " +"the previous release series." +msgstr "" +"В альфа-версию (alpha version) включена часть функциональных возможностей, " +"запланированных в релизной серии. Альфа-версия может быть неполной или " +"нестабильной, а также не обладать обратной совместимостью с предыдущей " +"серией." + +msgid "" +"Alpha versions are published for early adopters and developers of dependent " +"components, such as connectors and modules." +msgstr "" +"Альфа-версии предназначены для пользователей, готовых попробовать новую " +"серию на раннем этапе, а также для тех, кто разрабатывает зависимые " +"компоненты — коннекторы и модули." + +msgid "" +"MAJOR.MINOR.PATCH-alphaN\n" "\n" -"-----------------|---------|---------|---------|------> (time)\n" -" 1/4 yr. 1/4 yr. 1/4 yr." +"3.0.0-alpha1\n" +"3.0.0-alpha2" msgstr "" -"серия 1.10 -- 1.10.4 -- 1.10.5 -- 1.10.6 -- 1.10.7\n" -"(LTS)\n" +"MAJOR.MINOR.PATCH-alphaN\n" "\n" -"....\n" +"3.0.0-alpha1\n" +"3.0.0-alpha2" + +msgid "Beta version" +msgstr "Бета-версия" + +msgid "" +"Beta version has all the features which are planned for the release series. " +"It is a good choice to start developing a new application." +msgstr "" +"В бета-версию (beta version) включены все функциональные " +"возможности, запланированные в релизной серии. Бета-версия подходит, чтобы " +"начать разработку нового приложения." + +msgid "" +"Readiness of a feature can be checked in a beta version to decide whether to" +" remove the feature, finish it later, or replace it with something else. A " +"beta version can still have a known bug in the new functionality, or a known" +" degradation since the previous release series that affects a common use " +"case." +msgstr "" +"Бета-версия позволяет проверить, насколько готова к выпуску та или иная " +"функциональная возможность. На основании этого принимается решение, " +"доработать ли эту возможность, удалить или заменить. Бета-версия может " +"содержать известные ошибки новой функциональности, а также регрессионные " +"ошибки в распространенных сценариях использования." + +msgid "" +"MAJOR.MINOR.PATCH-betaN\n" "\n" -"серия 2.2 --- 2.2.1 --- 2.2.2 --- 2.2.3 (окончание поддержки)\n" -" |\n" -" V\n" -"серия 2.3 ... 2.3.0 --- 2.3.1 --- 2.3.2 --- 2.3.3 (окончание поддержки)\n" -" |\n" -" V\n" -"серия 2.4 ............. 2.4.0 --- 2.4.1 --- 2.4.2\n" -" |\n" -" V\n" -"серия 2.5 ....................... 2.5.0 --- 2.5.1\n" -" |\n" -" V\n" -"серия 2.6 ................................. 2.6.0\n" +"3.0.0-beta1\n" +"3.0.0-beta2" +msgstr "" +"MAJOR.MINOR.PATCH-betaN\n" "\n" -"-----------------|---------|---------|---------|------> (время)\n" -" 1/4 г. 1/4 г. 1/4 г." +"3.0.0-beta1\n" +"3.0.0-beta2" msgid "" -"*Support* means that we continue fixing bugs. We add bug fixes " -"simultaneously into the following release series: LTS, last stable, beta, " -"and alpha. If we look at the release diagram above, it means that the bug " -"fixes are to be added into 1.10, 2.4, 2.5, and 2.6 release series." +"Note that the development of ``2.10.0``, the first release under the new " +"policy, starts with version ``2.10.0-beta1``." msgstr "" -"*Поддержка* означает, что мы продолжаем исправлять ошибки. Мы также " -"добавляем исправления ошибок в следующие серии версий: LTS, последнюю " -"стабильную, бета и альфа. Если посмотреть на схему выпуска версий выше, — " -"это означает, что исправления ошибок будут добавлены в серии 1.10, 2.4, 2.5 " -"и 2.6." + +msgid "Release candidate" +msgstr "Релиз-кандидат" msgid "" -"To sum it up, once a quarter we release (see the release diagram above for " -"reference):" +"Release candidate is used to fix bugs, mature the functionality, and collect" +" feedback before an upcoming release. Release candidate has the same feature" +" set as the preceding beta version and doesn't have known bugs in typical " +"usage scenarios or degradations from the previous release series." msgstr "" -"Итак, раз в квартал выходят (см. вышеприведенную схему выпуска версий):" +"В релиз-кандидате (release candidate, RC) исправляются ошибки и " +"совершенствуется функциональность. Он также помогает собирать отзывы перед " +"публикацией релиза. Набор функциональных возможностей в релиз-кандидате " +"такой же, как в бета-версии. Известные ошибки в типичных сценариях " +"использования устранены, регрессионных ошибок нет." -msgid "next LTS release, e.g., 1.10.9" -msgstr "очередная LTS-версия, например 1.10.9" +msgid "Release candidate is a good choice to set up a staging server." +msgstr "" +"Релиз-кандидат подходит для использования в предпроизводственной среде " +"(staging)." -msgid "two stable releases, e.g., 2.5.3 and 2.6.2" -msgstr "две стабильные версии, например 2.5.3 и 2.6.2" +msgid "" +"MAJOR.MINOR.PATCH-rcN\n" +"\n" +"3.0.0-rc1\n" +"3.0.0-rc2\n" +"3.0.1-rc1" +msgstr "" +"MAJOR.MINOR.PATCH-rcN\n" +"\n" +"3.0.0-rc1\n" +"3.0.0-rc2\n" +"3.0.1-rc1" -msgid "beta version of the next release series, e.g., 2.7.1." -msgstr "бета-версия следующей серии, например 2.7.1." +msgid "Release series lifecycle" +msgstr "Жизненный цикл релизной серии" + +msgid "Every release series goes through the following stages:" +msgstr "Каждая релизная серия проходит три стадии:" + +msgid "Early development" +msgstr "Ранняя разработка" + +msgid "" +"The early development stage goes on until the first :term:`major release " +"`. Alpha, beta, and release candidate versions are published " +"at this stage." +msgstr "" +"Стадия ранней разработки (early development) продолжается до выхода " +":term:`мажорного релиза `. На этой стадии публикуются альфа- " +"и бета-версии, а также релиз-кандидаты." + +msgid "The stage splits into two phases:" +msgstr "Стадия разделена на два этапа:" + +msgid "" +"Development of a new functionality through alpha and beta versions. Features" +" can be added and, sometimes, removed in this phase." +msgstr "" +"Разработка и проверка новой функциональности в альфа- и бета-версиях. На " +"этом этапе функциональные возможности могут добавляться и в некоторых " +"случаях удаляться." + +msgid "" +"Stabilization starts with the first release candidate version. Feature set " +"doesn't change in this phase." +msgstr "" +"Стабилизация. С момента выхода первого релиз-кандидата набор функциональных " +"возможностей не меняется." + +msgid "Support" +msgstr "Поддержка" + +msgid "" +"The stage starts when the first release is published. The release series now" +" is an object of only backward compatible changes." +msgstr "" +"Эта стадия начинается, когда выходит первый релиз. Теперь в релизной серии " +"могут появляться только изменения, не нарушающие обратную совместимость." + +msgid "" +"At this stage, all known security problems and all found degradations since " +"the previous series are being fixed." +msgstr "" +"На этой стадии устраняются известные проблемы безопасности и исправляются " +"регрессионные ошибки, возникшие в серии." + +msgid "" +"The series receives degradation fixes and other bugfixes during the support " +"stage and until the series transitions into the end of life (EOL) stage." +msgstr "" +"Патчи для регрессионных и других ошибок выпускаются, пока серия не перейдет " +"со стадии поддержки на стадию прекращения поддержки (end of life, EOL)." + +msgid "" +"The decision of whether to fix a particular problem in a particular release " +"series depends on the impact of the problem, risks around backward " +"compatibility, and the complexity of backporting a fix." +msgstr "" +"Решение о том, исправить ли конкретную ошибку в релизной серии, принимается " +"в зависимости от того, насколько проблема серьезна, сложно ли будет ее " +"устранить в предыдущих версиях и нарушит ли исправление обратную " +"совместимость." + +msgid "" +"The release series might receive new features at this stage, but only in a " +"backward compatible manner. Also, a release candidate may be published to " +"collect feedback before the release version." +msgstr "" +"На этой стадии в релизной серии могут выпускаться новые функциональные " +"возможности, но все они будут обратно совместимы с предыдущими версиями. " +"Кроме того, может быть выпущен релиз-кандидат, чтобы собрать отзывы " +"пользователей перед выходом релиза." msgid "" -"In all supported releases, when we find and fix an outstanding " -"CVE/vulnerability, we deliver a patch for that but do not tag a new PATCH " -"level version. Users will be informed about such critical patches via the " -"official Tarantool news channel (`tarantool_news " -"`_)." +"During the support period a release series receives new versions of " +"supported Linux distributives to build infrastructure." msgstr "" -"Когда мы находим и исправляем известную уязвимость (CVE) в любой " -"поддерживаемой версии, мы выпускаем для этого патч, но не проставляем тег " -"уровня ПАТЧ. Пользователи узнают о таких критических патчах из официального " -"новостного канала Tarantool (`tarantool_news " -"`_)." +"В течение периода поддержки в релизной серии выпускаются обновления для " +"новых версий дистрибутивов Linux." msgid "" -"We also publish nightly builds, and use the fourth slot in the version " -"identifier to designate the nightly build number." +"The intended duration of the support period for each series is at least two " +"years." +msgstr "Срок поддержки для каждой серии — как минимум два года." + +msgid "End of life" +msgstr "Прекращение поддержки" + +msgid "" +"A series reaches the end of life (EOL) when the last release in the series " +"is published. The series will not receive updates anymore." msgstr "" -"Мы также публикуем ночные сборки и используем четвертый слот в " -"идентификаторе версии для обозначения номера ночной сборки." +"Стадия прекращения поддержки (end of life, EOL) для серии наступает, когда " +"опубликован последний релиз в этой серии. После этого серия прекращает " +"обновляться." msgid "" -"A release series may introduce backward incompatible changes in a sense that" -" existing Lua, SQL or C code that are run on a current release series may " -"not be run with the same effect on a future series. However, we don't " -"exploit this rule and don't make incompatible changes without appropriate " -"reason. We usually deliver information how mature a functionality is via " -"release notes." +"In modules, connectors and tools, we don't guarantee support of any release " +"series that reaches EOL." msgstr "" -"В новой серии релизов могут быть обратно несовместимые изменения — это " -"значит, что код на Lua, SQL или C, выполняемый в текущей серии версий, может" -" не выполняться в следующей серии версий. Тем не менее, мы не злоупотребляем" -" этим правилом и не вносим несовместимые изменения без причины. Обычно мы " -"предоставляем информацию о том, насколько сформирована функциональность, в " -"примечаниях к версии." +"Для серий, достигших этой стадии, поддержка не гарантируется. Скорее всего, " +"для них не будут выходить обновления, связанные с работой модулей, " +"коннекторов и инструментов." + +msgid "" +"A release series cannot reach EOL until the vast majority of production " +"environments, for which we have commitments and SLAs, is updated to a newer " +"series." +msgstr "" +"Стадия прекращения поддержки для релизной серии может наступить только " +"тогда, когда большинство производственных сред, с которыми Tarantool " +"работает по SLA и другим соглашениям, обновится до более новой серии." + +msgid "Versions per lifecycle stage" +msgstr "Версии по стадиям жизненного цикла" + +msgid "Stage" +msgstr "Стадия" + +msgid "Version types" +msgstr "Типы версий" + +msgid "Examples" +msgstr "Примеры" + +msgid "Alpha, beta, release candidate" +msgstr "Альфа, бета, релиз-кандидат" + +msgid "" +"3.0.0-alpha1\n" +"3.0.0-beta1\n" +"3.0.0-rc1\n" +"3.0.0-dev" +msgstr "" +"3.0.0-alpha1\n" +"3.0.0-beta1\n" +"3.0.0-rc1\n" +"3.0.0-dev" + +msgid "Release candidate, release" +msgstr "Релиз-кандидат, релиз" + +msgid "" +"3.0.0\n" +"3.0.1-rc1\n" +"3.0.1-dev" +msgstr "" +"3.0.0\n" +"3.0.1-rc1\n" +"3.0.1-dev" + +msgid "None" +msgstr "–" + +msgid "N/A" +msgstr "–" + +msgid "Example of a release series" +msgstr "Пример релизной серии" + +msgid "" +"A release series in an early development stage can have the following " +"version sequence:" +msgstr "" +"На стадии ранней разработки последовательность версий в релизной серии может" +" быть такой:" + +msgid "" +"3.0.0-alpha1\n" +"3.0.0-alpha2\n" +"...\n" +"3.0.0-alpha7\n" +"\n" +"3.0.0-beta1\n" +"...\n" +"3.0.0-beta5\n" +"\n" +"3.0.0-rc1\n" +"...\n" +"3.0.0-rc4\n" +"\n" +"3.0.0 (release)" +msgstr "" +"3.0.0-alpha1\n" +"3.0.0-alpha2\n" +"...\n" +"3.0.0-alpha7\n" +"\n" +"3.0.0-beta1\n" +"...\n" +"3.0.0-beta5\n" +"\n" +"3.0.0-rc1\n" +"...\n" +"3.0.0-rc4\n" +"\n" +"3.0.0 (релиз)" + +msgid "" +"Since the first release version, the series comes into a support stage. Then" +" it can proceed with a version sequence like the following:" +msgstr "" +"Как только выпущен первый релиз, серия переходит на стадию поддержки. " +"Дальнейшие версии могут быть опубликованы в такой последовательности:" + +msgid "" +"3.0.0 (release of a new major version)\n" +"\n" +"3.0.1-rc1\n" +"...\n" +"3.0.1-rc4\n" +"3.0.1 (release with some bugs fixed but no new features)\n" +"\n" +"3.1.0-rc1\n" +"...\n" +"3.1.0-rc6\n" +"3.1.0 (release with new features and, possibly, extra fixed bugs)" +msgstr "" +"3.0.0 (релиз новой основной версии)\n" +"\n" +"3.0.1-rc1\n" +"...\n" +"3.0.1-rc4\n" +"3.0.1 (релиз с исправлением ошибок, но без функциональных изменений)\n" +"\n" +"3.1.0-rc1\n" +"...\n" +"3.1.0-rc6\n" +"3.1.0 (релиз с новыми функциональными возможностями и, вероятно, дополнительными исправлениями)" msgid "" -"Please note that binary data layout is always compatible with the previous " -"series as well as with the LTS series (an instance of ``X.Y`` version can be" -" started on top of ``X.(Y+1)`` or ``1.10.z`` data); binary protocol is " -"compatible too (client-server as well as replication protocol)." +"Eventually, the support stage stops and the release series comes to the end " +"of life (EOL) stage. No new versions are released since then." msgstr "" -"Обратите внимание, что структура бинарных данных всегда совместима с " -"предыдущими сериями, а также с сериями LTS (экземпляр версии ``X.Y`` может " -"быть запущен на основе данных ``X.(Y+1)`` или ``1.10.z``). Бинарный протокол" -" также обратно совместим (как клиент-серверный протокол, так и протокол " -"репликации)." +"Со временем стадия поддержки подходит к концу, и релизная серия выходит на " +"стадию прекращения поддержки (end of life, EOL). С этого момента новые " +"версии не выпускаются." From 3be7390fc1c90f6ead43dd7138edb5048922fc14 Mon Sep 17 00:00:00 2001 From: patiencedaur Date: Sun, 22 Aug 2021 05:31:19 +0000 Subject: [PATCH 10/10] Update translations --- locale/ru/LC_MESSAGES/release.po | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/locale/ru/LC_MESSAGES/release.po b/locale/ru/LC_MESSAGES/release.po index ed6c08d628..36d4aaa76f 100644 --- a/locale/ru/LC_MESSAGES/release.po +++ b/locale/ru/LC_MESSAGES/release.po @@ -1,6 +1,6 @@ msgid "Release notes" -msgstr "Описания версий" +msgstr "Примечания к версиям" msgid "" "Since version 2.10, there's a :doc:`new release policy for Tarantool " @@ -31,18 +31,19 @@ msgstr "" "версионирования `:" msgid "MAJOR_VERSION.RELEASE_SERIES.RELEASE" -msgstr "MAJOR_VERSION.RELEASE_SERIES.RELEASE" +msgstr "ОСНОВНАЯ_ВЕРСИЯ.СЕРИЯ_ВЫПУСКОВ.ВЫПУСК" msgid "" "Below is the table listing all Tarantool versions starting from 1.10.0 up to" " the current latest versions. Each link leads to the release notes page of " "the corresponding version:" msgstr "" -"В таблице ниже перечислены все версии Tarantool с 1.10.0 до последних " -"актуальных. Каждая ссылка ведёт на страницу описания соответствующей версии." +"Ниже приводится таблица, в которой перечислены все версии Tarantool, начиная" +" с версии 1.10.0 и заканчивая действующими последними версиями. Каждая " +"ссылка ведёт на страницу примечаний к соответствующей версии:" msgid "Release Series" -msgstr "Серия" +msgstr "Серия выпусков" msgid "Alpha" msgstr "Альфа" @@ -51,19 +52,7 @@ msgid "Beta" msgstr "Бета" msgid "Release" -msgstr "Релиз" - -msgid "2.10" -msgstr "2.10" - -msgid "n/a" -msgstr "--" - -msgid "2.10.0-beta1" -msgstr "2.10.0-beta1" - -msgid "not released yet" -msgstr "еще не состоялся" +msgstr "Выпуск" msgid "2.10" msgstr "2.10" @@ -194,7 +183,7 @@ msgstr "" "GitHub." msgid "Release notes for series before 1.10 are also available:" -msgstr "Также доступны описания серий ранее 1.10:" +msgstr "Также доступны примечания к версиям ниже 1.10:" msgid ":doc:`release/1.9`" msgstr ":doc:`release/1.9`"