From 303f0c6342c7728059a23eaf7c0e72eb1c40777e Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Thu, 13 Aug 2015 00:32:59 +0300 Subject: [PATCH] gh-916: (limit of statements in transaction) review fixes - update comments - fix the logic of partial write recovery (still needs a test) --- src/box/wal.cc | 14 +++++++------- src/fio.c | 13 ++++++++----- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/box/wal.cc b/src/box/wal.cc index 79fb5985a3..444028ec67 100644 --- a/src/box/wal.cc +++ b/src/box/wal.cc @@ -327,22 +327,22 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer, /* * This code tries to write queued requests (=transactions) using as - * less as possible I/O syscalls and memory copies. For this reason + * few I/O syscalls and memory copies as possible. For this reason * writev(2) and `struct iovec[]` are used (see `struct fio_batch`). * * For each request (=transaction) each request row (=statement) is * added to iov `batch`. A row can contain up to XLOG_IOVMAX iovecs. * A request can have an **unlimited** number of rows. Since OS has - * hardcoded limit up to `sysconf(_SC_IOV_MAX)` iovecs (usually 1024), - * a single batch can't fit huge transactions. Therefore, it is not - * possible to "atomically" write an entire transaction using the - * single writev(2) call. + * a hard coded limit up to `sysconf(_SC_IOV_MAX)` iovecs (usually + * 1024), a huge transaction may not fit into a single batch. + * Therefore, it is not possible to "atomically" write an entire + * transaction using a single writev(2) call. * * Request boundaries and batch boundaries are not connected at all * in this code. Batches flushed to disk as soon as they are full. * In order to guarantee that a transaction is either fully written * to file or isn't written at all, ftruncate(2) is used to shrink - * file to the last fuly written request. The absolute position + * the file to the last fully written request. The absolute position * of request in xlog file is stored inside `struct wal_request`. */ @@ -400,7 +400,7 @@ wal_write_to_disk(struct recovery_state *r, struct wal_writer *writer, /* Flush remaining data in batch (if any) */ if (fio_batch_size(batch) > 0) { ssize_t nwr = wal_fio_batch_write(batch, fileno(wal->f)); - if (nwr >= 0) { + if (nwr > 0) { /* Update cached file offset */ written_bytes += nwr; } diff --git a/src/fio.c b/src/fio.c index 8561d625a4..594ca49f69 100644 --- a/src/fio.c +++ b/src/fio.c @@ -221,13 +221,16 @@ fio_batch_rotate(struct fio_batch *batch, size_t bytes_written) struct iovec *iov = batch->iov; struct iovec *iovend = iov + batch->iovcnt; - for (; bytes_written >= iov->iov_len; ++iov) + for (; iov < iovend; ++iov) { + if (iov->iov_len > bytes_written) { + iov->iov_base = (char *) iov->iov_base + bytes_written; + iov->iov_len -= bytes_written; + break; + } bytes_written -= iov->iov_len; - + } assert(iov < iovend); /* Partial write */ - iov->iov_base = (char *) iov->iov_base + bytes_written; - iov->iov_len -= bytes_written; - memmove(batch->iov, iov, iovend - iov); + memmove(batch->iov, iov, (iovend - iov) * sizeof(struct iovec)); batch->iovcnt = iovend - iov; } -- GitLab