<HTML><BODY><div> </div><div> </div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">Понедельник, 9 августа 2021, 13:40 +03:00 от Vladimir Davydov <vdavydov@tarantool.org>:<br> <div id=""><div class="js-helper js-readmsg-msg"><div><div id="style_16285056300428434684_BODY">To apply a client request, we only need to know its type and body. All<br>the meta information, such as LSN, TSN, or replica id, must be set by<br>WAL. Currently, however, it isn't necessarily true: iproto leaves a<br>request header received over iproto as is, and tx will reuse the header<br>instead of allocating a new one in this case, which is needed to process<br>replication requests, see txn_add_redo().<br><br>Unless a client actually sets one of those meta fields, this causes no<br>problems. However, if we added transaction support to the replication<br>protocol, reusing the header would result in broken xlog, because<br>currently, all requests received over iproto have the is_commit field<br>set in xrow_header for the lack of TSN, while is_commit must only be set<br>for the final statement in a transaction. One way to fix it would be<br>clearing is_commit explicitly in iproto, but ignoring the whole header<br>received over iproto looks more logical and error-proof.<br><br>Needed for #5860<br>---<br><a href="https://github.com/tarantool/tarantool/tree/vdavydov/iproto-clear-request-header" target="_blank">https://github.com/tarantool/tarantool/tree/vdavydov/iproto-clear-request-header</a><br><br> src/box/iproto.cc | 6 ++++++<br> src/box/xrow.h | 2 +-<br> 2 files changed, 7 insertions(+), 1 deletion(-)<br><br>diff --git a/src/box/iproto.cc b/src/box/iproto.cc<br>index 5cc69b77ff93..dcf60e1be099 100644<br>--- a/src/box/iproto.cc<br>+++ b/src/box/iproto.cc<br>@@ -1264,6 +1264,12 @@ iproto_msg_decode(struct iproto_msg *msg, const char **pos, const char *reqend,<br>  if (xrow_decode_dml(&msg->header, &msg->dml,<br>  dml_request_key_map(type)))<br>  goto error;<br>+ /*<br>+ * In contrast to replication requests, for a client request<br>+ * the xrow header is set by WAL, which generates LSNs and sets<br>+ * replica id. Ignore the header received over network.<br>+ */<br>+ msg->dml.header = NULL;<br>  assert(type < sizeof(iproto_thread->dml_route) /<br>  sizeof(*(iproto_thread->dml_route)));<br>  cmsg_init(&msg->base, iproto_thread->dml_route[type]);<br>diff --git a/src/box/xrow.h b/src/box/xrow.h<br>index 0f2fcf94acfc..48b8b55f5e9b 100644<br>--- a/src/box/xrow.h<br>+++ b/src/box/xrow.h<br>@@ -163,7 +163,7 @@ struct request {<br>  /*<br>  * Either log row, or network header, or NULL, depending<br>  * on where this packet originated from: the write ahead<br>- * log/snapshot, client request, or a Lua request.<br>+ * log/snapshot, repliation, or a client request.<br>  */<br>  struct xrow_header *header;<br>  /**<br>--<br>2.25.1</div></div></div></div></blockquote><div>LGTM</div></BODY></HTML>