From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladimir Davydov Subject: [PATCH 3/8] vinyl: do not use column mask as trigger for turning REPLACE into INSERT Date: Sun, 14 Oct 2018 21:16:47 +0300 Message-Id: <96c69e742bf2292aea97f64ab8d84de6e1d3ad08.1539539421.git.vdavydov.dev@gmail.com> In-Reply-To: References: In-Reply-To: References: To: kostja@tarantool.org Cc: tarantool-patches@freelists.org List-ID: 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. --- src/box/vinyl.c | 3 +++ src/box/vy_stmt.c | 8 ++++++++ src/box/vy_stmt.h | 11 ++++++++++- src/box/vy_write_iterator.c | 5 ++--- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 869c4140..be21d9d9 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -1723,6 +1723,9 @@ vy_perform_update(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, if (vy_check_is_unique(env, tx, space, stmt->new_tuple) != 0) return -1; + + vy_stmt_set_flags(stmt->new_tuple, VY_STMT_UPDATE); + if (vy_tx_set(tx, pk, stmt->new_tuple) != 0) return -1; if (space->index_count == 1) diff --git a/src/box/vy_stmt.c b/src/box/vy_stmt.c index ebe64300..bb9e1edb 100644 --- a/src/box/vy_stmt.c +++ b/src/box/vy_stmt.c @@ -61,6 +61,14 @@ static inline uint8_t vy_stmt_persistent_flags(const struct tuple *stmt, bool is_primary) { uint8_t mask = VY_STMT_FLAGS_ALL; + + /* + * This flag is only used by the write iterator to turn + * in-memory REPLACEs into INSERTs on dump so no need to + * persist it. + */ + mask &= ~VY_STMT_UPDATE; + if (!is_primary) { /* * Do not store VY_STMT_DEFERRED_DELETE flag in diff --git a/src/box/vy_stmt.h b/src/box/vy_stmt.h index 73e18ca7..4a67b3c7 100644 --- a/src/box/vy_stmt.h +++ b/src/box/vy_stmt.h @@ -98,9 +98,18 @@ enum { */ VY_STMT_SKIP_READ = 1 << 1, /** + * This flag is set for those REPLACE statements that were + * generated by UPDATE operations. It is used by the write + * iterator to turn such REPLACEs into INSERTs in secondary + * indexes so that they can get annihilated with DELETEs on + * compaction. It is never written to disk. + */ + VY_STMT_UPDATE = 1 << 2, + /** * Bit mask of all statement flags. */ - VY_STMT_FLAGS_ALL = VY_STMT_DEFERRED_DELETE | VY_STMT_SKIP_READ, + VY_STMT_FLAGS_ALL = (VY_STMT_DEFERRED_DELETE | VY_STMT_SKIP_READ | + VY_STMT_UPDATE), }; /** diff --git a/src/box/vy_write_iterator.c b/src/box/vy_write_iterator.c index 17b80685..0b6ab0a8 100644 --- a/src/box/vy_write_iterator.c +++ b/src/box/vy_write_iterator.c @@ -694,14 +694,13 @@ vy_write_iterator_build_history(struct vy_write_iterator *stream, *is_first_insert = vy_stmt_type(src->tuple) == IPROTO_INSERT; if (!stream->is_primary && - vy_stmt_type(src->tuple) == IPROTO_REPLACE) { + (vy_stmt_flags(src->tuple) & VY_STMT_UPDATE) != 0) { /* * If a REPLACE stored in a secondary index was * generated by an update operation, it can be * turned into an INSERT. */ - if (vy_stmt_column_mask(src->tuple) != UINT64_MAX) - *is_first_insert = true; + *is_first_insert = true; } /* -- 2.11.0