- Oct 26, 2018
-
-
Vladimir Davydov authored
-
Georgy Kirichenko authored
In some cases luajit does not collect cdata objects which were transformed with ffi.cast as tuple_bless does. In consequence, internal table with gc callback overflows and then lua crashes. There might be an internal luajit issue because it fires only for jitted code. But assigning a gc callback before transformation fixes the problem. Closes #3751
-
Vladimir Davydov authored
Back when bloom filters were introduced, neither box.info.memory() nor box.stat.vinyl().memory didn't exist so bloom filters were accounted to box.runtime.info().used for lack of a better place. Now, there's no point to account them there. In fact, it's confusing, because bloom filters are allocated with malloc(), not from the runtime arena, so let's drop it.
-
Vladimir Davydov authored
If a tuple read from a run by a slice stream happens to be out of the slice bounds, it will never be freed. Fix it. The leak was introduced by commit c174c985 ("vinyl: implement new simple write iterator").
-
- Oct 25, 2018
-
-
Alexander Turenko authored
-
Alexander Turenko authored
-
Alexander Turenko authored
-
Alexander Turenko authored
Upload tarballs of alpha and beta tarantool versions (*.0 and *.1 branches) into 2x (3x, 4x...) buckets. See more details about the release process in the documentation: [1]. [1]: https://tarantool.io/en/doc/2.0/dev_guide/release_management/
-
Serge Petrenko authored
This patch adds logging amount of rows received by applier during the join stage, the same way that recovery has it. Closes #3165
-
Kirill Yukhin authored
Remove function which deletes from cache, making replace more general: it might be used for both insertions, deletions and replaces. Also, put assert on equality of space pointer found in cache to old one into replace routine.
-
Vladimir Davydov authored
Now if the WAL thread fails to preallocate disk space needed to commit a transaction, it will delete old WAL files until it succeeds or it deletes all files that are not needed for local recovery from the oldest checkpoint. After it deletes a file, it notifies the garbage collector via the WAL watcher interface. The latter then deactivates consumers that would need deleted files. The user doesn't see a ENOSPC error if the WAL thread successfully allocates disk space after deleting old files. Here's what's printed to the log when this happens: wal/101/main C> ran out of disk space, try to delete old WAL files wal/101/main I> removed /home/vlad/src/tarantool/test/var/001_replication/master/00000000000000000005.xlog wal/101/main I> removed /home/vlad/src/tarantool/test/var/001_replication/master/00000000000000000006.xlog wal/101/main I> removed /home/vlad/src/tarantool/test/var/001_replication/master/00000000000000000007.xlog main/105/main C> deactivated WAL consumer replica 82d0fa3f-6881-4bc5-a2c0-a0f5dcf80120 at {1: 5} main/105/main C> deactivated WAL consumer replica 98dce0a8-1213-4824-b31e-c7e3c4eaf437 at {1: 7} Closes #3397
-
Vladimir Davydov authored
In order to implement WAL auto-deletion, we need a notification channel through which the WAL thread could notify TX that a WAL file was deleted so that the latter can shoot off stale replicas. We will reuse existing wal_watcher API for this. Currently, wal_watcher invokes the registered callback on each WAL write so using it as is would be inefficient. To avoid that, let's allow the caller to specify events of interest when registering a wal_watcher. Needed for #3397
-
Vladimir Davydov authored
We will add another event bitmap to wal_watcher. To avoid confusion between them, let's rename wal_watcher->events.
-
Vladimir Davydov authored
This should make it easier to pass some extra information along with the event mask. For example, we will use it to pass the vclock of the oldest stored WAL, which is needed for WAL auto-deletion. Needed for #3397
-
Alexander Turenko authored
Updated the test case for #2780 to check a last snapshot file modification time instead of search log messages. The test was flaky, because of small timeouts on Linux, but now we spinning on a condition check to achieve both stable results and fast execution. Follows up #2780. Fixes #3684.
-
Alexander Turenko authored
* added more details about hung tests (#107); * added show_reproduce_content option (#113); * fixed inspector error reporting for a failed app test; * expand action of use_unix_socket option to non-default servers; * updated tarantool-python submodule (#126); * added test_run:wait_cond() and test_run:wail_log(). Updated box-py/call.test.py result file, because tarantool-python now uses CALL 1.7 convention by default and slightly changed yaml output formatting. See [1] and [3] for more information. Updated replication-py/cluster.test.py, because of changed tarantool-python internals, see commit [2]. Updated box-py/iproto.test.py because it uses tarantool-python internals that was rewritten in [2]. Updated its result file according to CALL 1.7 response format that was set as default with [1] and yaml output formatting changed within [3]. Updated replication-py/swap.test.py result file, because of yaml output formatting that was slightly changed within [3]. [1]: https://github.com/tarantool/tarantool-python/issues/82 [2]: https://github.com/tarantool/tarantool-python/commit/4639d9ae1c48f1608bd599c6d93ed6bfca48fbf9 [3]: https://github.com/tarantool/tarantool-python/issues/90
-
Vladimir Davydov authored
This function introduces a new xlog method xlog_fallocate() that makes sure that the requested amount of disk space is available at the current write position. It does that with posix_fallocate(). The new method is called before writing anything to WAL, see wal_fallocate(). In order not to invoke the system call too often, wal_fallocate() allocates disk space in big chunks (1 MB). The reason why I'm doing this is that I want to have a single and clearly defined point in the code to handle ENOSPC errors, where I could delete old WALs and retry (this is what #3397 is about). Needed for #3397
-
Vladimir Davydov authored
Memory allocated for vy_write_iterator::src_heap is never freed. Fix it. The leak was introduced by commit c174c985 ("vinyl: implement new simple write iterator").
-
- Oct 24, 2018
-
-
Vladimir Davydov authored
So that we can add more flags.
-
Vladimir Davydov authored
This patch adds a new entry to per index statistics reported by index.stat(): disk.statement inserts replaces deletes upserts It shows the number of statements of each type stored in run files. The new statistics are persisted in index files. We will need this information so that we can force major compaction when there are too many DELETE statements accumulated in run files. Needed for #3225
-
Vladimir Davydov authored
Local variable total_size equals total_stmt_count.bytes_compressed so we don't really need it.
-
Vladimir Davydov authored
tuple_extra() allows to store arbitrary metadata inside tuples. To use it, one should set extra_size when creating a tuple_format. It was introduced for storing UPSERT counter or column mask inside vinyl statements. Turned out that it wasn't really needed as UPSERT counter can be stored on lsregion while column mask doesn't need to be stored at all. Actually, the whole idea of tuple_extra() is rather crooked: why would we need it if we can inherit struct tuple instead, as we do in case of memtx_tuple and vy_stmt? Accessing an inherited struct is much more convenient than using tuple_extra(). So this patch gets rid of tuple_extra(). To do that, it partially reverts the following commits: 6c0842e0 vinyl: refactor vy_stmt_alloc() 74ff46d8 vinyl: add special format for tuples with column mask 11eb7816 Add extra size to tuple_format->field_map_size
-
Vladimir Davydov authored
This function was only used for creating a format for tuples with column mask in vinyl. Not needed anymore and can be removed. Anyway, it doesn't make much sense to duplciate a tuple format, because it can be referenced instead. Besides, once JSON indexes are introcued, duplicating a tuple format will be really painful. One more reason to drop it now.
-
Vladimir Davydov authored
Finally, these atrocities are not used anywhere and can be removed.
-
Vladimir Davydov authored
This patch is a preparation for removing vy_stmt_column_mask.
-
Vladimir Davydov authored
This patch is a preparation for removing vy_stmt_column_mask.
-
Vladimir Davydov authored
If a REPLACE statement was generated by an UPDATE operation that updated a column indexed by a secondary key, we can turn it into INSERT when the secondary index is dumped, because there can't be an older statement with the same key other than DELETE. Currently, we use the statement column mask to detect such REPLACEs in the write iterator, but I'm planning to get rid of vy_stmt_column_mask so let's instead introduce a new statement flag to mark such REPLACEs.
-
Vladimir Davydov authored
This patch introduces a helper function vy_perform_update() that performs operations common for UPDATE and UPSERT, namely replaces a tuple in a transaction write set.
-
Vladimir Davydov authored
An UPDATE operation is written as DELETE + REPLACE to secondary indexes. We write those statements to the memory level even if the UPDATE doesn't actually update columns indexed by a secondary key. We filter them out in the write iterator when the memory level is dumped. That's what we use vy_stmt_column_mask for. Actually, there's no point to keep those statements until dump - we could as well filter them out when the transaction is committed. This would even save some memory. This wouldn't hurt read operations, because point lookup doesn't work for secondary indexes by design and so we have to read all sources, including disk, on every read from a secondary index. That said, let's move update optimization from the write iterator to vy_tx_commit. This is a step towards removing vy_stmt_column_mask.
-
- Oct 23, 2018
-
-
Alexander Turenko authored
The behaviour change was introduced in cda3cb55: sync_is_async option was forgotten to be updated from xdir; sync_interval was forgotten too, but was restored in 1900c58b. The commit fixes the performance regression around 6-14% for average RPS on default nosqlbench workload with 30 seconds duration. The additional information about benchmarking can be found in #3747. Thanks to Vladimir Davydov (@locker) for the investigation of the cda3cb55 changes. Closes #3747 (cherry picked from commit cd9cc4c5)
-
- Oct 13, 2018
-
-
Vladimir Davydov authored
During SUBSCRIBE the master sends only those rows originating from the subscribed replica that aren't present on the replica. Such rows may appear after a sudden power loss in case the replica doesn't issue fdatasync() after each WAL write, which is the default behavior. This means that a replica can write some rows to WAL, relay them to another replica, then stop without syncing WAL file. If this happens we expect the replica to read its own rows from other members of the cluster upon restart. For more details see commit eae84efb ("replication: recover missing local data from replica"). Obviously, this feature only makes sense for SUBSCRIBE. During JOIN we must relay all rows. This is how it initially worked, but commit adc28591 ("replication: do not delete relay on applier disconnect"), witlessly removed the corresponding check from relay_send_row() so that now we don't send any rows originating from the joined replica: @@ -595,8 +630,7 @@ relay_send_row(struct xstream *stream, struct xrow_header *packet) * it). In the latter case packet's LSN is less than or equal to * local master's LSN at the moment it received 'SUBSCRIBE' request. */ - if (relay->replica == NULL || - packet->replica_id != relay->replica->id || + if (packet->replica_id != relay->replica->id || packet->lsn <= vclock_get(&relay->local_vclock_at_subscribe, packet->replica_id)) { relay_send(relay, packet); (relay->local_vclock_at_subscribe is initialized to 0 on JOIN) This only affects the case of rebootstrap, automatic or manual, because when a new replica joins a cluster there can't be any rows on the master originating from it. On manual rebootstrap, i.e. when the replica files are deleted by the user and the replica is restarted from an empty directory with the same UUID (set via box.cfg.instance_uuid), this isn't critical - the replica will still receive those rows it should have received during JOIN once it subscribes. However, in case of automatic rebootstrap this can result in broken order of xlog/snap files, because the replica directory still contains old xlog/snap files created before rebootstrap. The rebootstrap logic expects them to have strictly less vclocks than new files, but if JOIN stops prematurely, this condition may not hold, leading to a crash when the vclock of a new xlog/snap is inserted into the corresponding xdir. This patch fixes this issue by restoring pre eae84efb behavior: now we create a new relay for FINAL JOIN instead of reusing the one attached to the joined replica so that relay_send_row() can detect JOIN phase and relay all rows in this case. It also adds a comment so that we don't make such a mistake in future. Apart from fixing the issue, this patch also fixes a relay leak in relay_initial_join() in case engine_join_xc() fails, which was also introduced by the above mentioned commit. A note about xlog/panic_on_broken_lsn test. Now the relay status isn't reported by box.info.replication if FINAL JOIN failed and the replica never subscribed (this is how it worked before commit eae84efb) so we need to tweak the test a bit to handle this. Closes #3740
-
- Oct 12, 2018
-
-
Kirill Yukhin authored
-
Vladimir Davydov authored
If the rate at which transactions are ready to write to the database is greater than the dump bandwidth, memory will get depleted before the previously scheduled dump is complete and all newer transactions will have to wait, which may take seconds or even minutes: W> waited for 555 bytes of vinyl memory quota for too long: 15.750 sec This patch set implements basic transaction throttling that is supposed to help avoid unpredictably long stalls. Now the transaction write rate is always capped by the observed dump bandwidth, because it doesn't make sense to consume memory at a greater rate than it can be freed. On top of that, when a dump begins, we estimate the amount of time it is going to take and limit the transaction write rate accordingly. Note, this patch doesn't take into account compaction when setting the rate limit so compaction threads may still fail to keep up with dumps, increasing the read amplification. It will be addressed later. Closes #1862
-
Vladimir Davydov authored
vy_quota_signal() doesn't wake up a consumer if it won't be able to proceed because of the memory limit. This is OK, but it doesn't attempt to trigger memory dump in this case either. As a result, it may occur that dump isn't triggered and all waiting consumers are aborted by timeout. E.g. this happens if memory dump releases no memory, which is possible because memory is allocated and freed in 16 MB chunks. This results in occasional vinyl/quota_tmeout test failures. Fix this by moving the dump trigger right in vy_quota_may_use() so that it's called whenever we consider a consumer for wakeup.
-
Vladimir Davydov authored
Small dumps (e.g. triggered by box.snapshot) have too high overhead associated with file creation so taking them into account for bandwidth estimation may result in erroneous transaction throttling. Let's ignore dumps of size less than 1 MB. Needed for #1862
-
Vladimir Davydov authored
This is pointless since trigger_dump_cb callback will return right away in such a case. Let's wrap trigger_dump_cb in vy_regulator_trigger_dump method, which will actulally invoke the callback only if the previous dump has already completed (i.e. vy_regulator_dump_complete was called). This also gives us a definite place in code where we can adjust the rate limit so as to guarantee that a triggered memory dump will finish before we hit the hard memory limit (this will be done later). Needed for #1862
-
Vladimir Davydov authored
When the format of a space is altered, we walk over all tuples stored in the primary index and check them against the new format. This doesn't guarantee that all *statements* stored in the primary index conform to the new format though, because the check isn't performed for deleted or overwritten statements, e.g. s = box.schema.space.create('test', {engine = 'vinyl'}) s:create_index('primary') s:insert{1} box.snapshot() s:delete{1} -- The following command will succeed, because the space is empty, -- however one of the runs contains REPLACE{1}, which doesn't conform -- to the new format. s:create_index('secondary', {parts = {2, 'unsigned'}}) This is OK as we will never return such overwritten statements to the user, however we may still need to read them. Currently, this leads either to an assertion failure or to a read error in vy_stmt_decode vy_stmt_new_with_ops tuple_init_field_map We could probably force major compaction of the primary index to purge such statements, but it is complicated as there may be a read view preventing the write iterator from squashing such a statement, and currently there's no way to force destruction of a read view. So this patch simply disables format validation for all tuples loaded from disk (actually we already skip format validation for all secondary index statements and for DELETE statements in primary indexes so this isn't as bad as it may seem). To do that, it adds a boolean parameter to tuple_init_field_map() that disables format validation, and then makes vy_stmt_new_with_ops(), which is used for constructing vinyl statements, set it to false. This is OK as all statements inserted into a vinyl space are validated explicitly with tuple_validate() anyway. This is rather a workaround for the lack of a better solution. Closes #3540
-
Vladimir Davydov authored
For some reason this test uses 555 for space id, which may be taken by a previously created space: Test failed! Result content mismatch: --- box/sql.result Fri Oct 5 17:23:25 2018 +++ box/sql.reject Fri Oct 12 19:38:51 2018 @@ -12,12 +12,14 @@ ... _ = box.schema.space.create('test1', { id = 555 }) --- +- error: Duplicate key exists in unique index 'primary' in space '_space' ... Reproduce file: --- - [box/rtree_point.test.lua, null] - [box/transaction.test.lua, null] - [box/tree_pk.test.lua, null] - [box/access.test.lua, null] - [box/cfg.test.lua, null] - [box/admin.test.lua, null] - [box/lua.test.lua, null] - [box/bitset.test.lua, null] - [box/role.test.lua, null] - [box/sql.test.lua, null] ... Remove { id = 555 } to make sure it never happens.
-
Alexander Turenko authored
Replaced targets generation using a matrix expansion + exclusion list with the explicit targets list. Gave meagingful names for targets. Fixes #3673.
-
Vladimir Davydov authored
- xlog_rename() doesn't strip xlog->filename of inprogress suffix so write errors will mistakenly report the filename as inprogress. - xlog_create() uses a name without inprogress suffix for error reporting while it actually creates an inprogress file.
-