[Tarantool-patches] [PATCH 1/2] wal: fix tx boundaries

Cyrill Gorcunov gorcunov at gmail.com
Tue May 19 12:08:15 MSK 2020


On Mon, May 18, 2020 at 03:24:04PM +0300, Serge Petrenko wrote:
...
> --- a/src/box/wal.c
> +++ b/src/box/wal.c
> @@ -956,24 +956,33 @@ wal_assign_lsn(struct vclock *vclock_diff, struct vclock *base,
>  	       struct xrow_header **end)
>  {
>  	int64_t tsn = 0;
> +	struct xrow_header **start = row;
> +	struct xrow_header **first_glob_row = end;
>  	/** Assign LSN to all local rows. */
>  	for ( ; row < end; row++) {
>  		if ((*row)->replica_id == 0) {
>  			/*
>  			 * All rows representing local space data
> -			 * manipulations are signed wth a zero
> +			 * manipulations are signed with a zero
>  			 * instance id. This is also true for
>  			 * anonymous replicas, since they are
>  			 * only capable of writing to local and
>  			 * temporary spaces.
>  			 */
> -			if ((*row)->group_id != GROUP_LOCAL)
> +			if ((*row)->group_id != GROUP_LOCAL) {
>  				(*row)->replica_id = instance_id;
> +			}
>  
>  			(*row)->lsn = vclock_inc(vclock_diff, (*row)->replica_id) +
>  				      vclock_get(base, (*row)->replica_id);
> -			/* Use lsn of the first local row as transaction id. */
> -			tsn = tsn == 0 ? (*row)->lsn : tsn;
> +			/*
> +			 * Use lsn of the first global row as
> +			 * transaction id.
> +			 */
> +			if ((*row)->group_id != GROUP_LOCAL && tsn == 0) {
> +				tsn = (*row)->lsn;
> +				first_glob_row = row;
> +			}
>  			(*row)->tsn = tsn;

1) ^^^

>  			(*row)->is_commit = row == end - 1;
>  		} else {
> @@ -993,6 +1002,15 @@ wal_assign_lsn(struct vclock *vclock_diff, struct vclock *base,
>  			}
>  		}
>  	}
> +	if (tsn == 0)
> +		tsn = (*start)->lsn;
> +	/*
> +	 * Fill transaction id for all the local rows preceding
> +	 * the first global row. tsn was yet unknown when those
> +	 * rows were processed.
> +	 */
> +	for (row = start; row < first_glob_row; row++)
> +		(*row)->tsn = tsn;
>  }

Wait, the chunk above -- lets assume we've all rows in GROUP_LOCAL thus
in (1) we already set this member to 0 and now we re-walk the entries
again and assign lsn to the first row's lsn. This is ugly as hell,
if only I didn't miss something obvious.

Can't we do something like below to eliminate needless rewalk over
all rows? Do I make a mistake?
---
diff --git a/src/box/wal.c b/src/box/wal.c
index d36d4259e..ef4d84920 100644
--- a/src/box/wal.c
+++ b/src/box/wal.c
@@ -957,7 +957,7 @@ wal_assign_lsn(struct vclock *vclock_diff, struct vclock *base,
 {
 	int64_t tsn = 0;
 	struct xrow_header **start = row;
-	struct xrow_header **first_glob_row = end;
+	struct xrow_header **first_glob_row = row;
 	/** Assign LSN to all local rows. */
 	for ( ; row < end; row++) {
 		if ((*row)->replica_id == 0) {
@@ -981,9 +981,12 @@ wal_assign_lsn(struct vclock *vclock_diff, struct vclock *base,
 			 */
 			if ((*row)->group_id != GROUP_LOCAL && tsn == 0) {
 				tsn = (*row)->lsn;
+				/*
+				 * Remember the tail being processed.
+				 */
 				first_glob_row = row;
 			}
-			(*row)->tsn = tsn;
+			(*row)->tsn = tsn == 0 ? (*start)->lsn : tsn;
 			(*row)->is_commit = row == end - 1;
 		} else {
 			int64_t diff = (*row)->lsn - vclock_get(base, (*row)->replica_id);
@@ -1002,8 +1005,7 @@ wal_assign_lsn(struct vclock *vclock_diff, struct vclock *base,
 			}
 		}
 	}
-	if (tsn == 0)
-		tsn = (*start)->lsn;
+
 	/*
 	 * Fill transaction id for all the local rows preceding
 	 * the first global row. tsn was yet unknown when those


More information about the Tarantool-patches mailing list