← Back to team overview

maria-developers team mailing list archive

Re: MDEV-5914

 

Jan Lindström <jplindst@xxxxxxxxxxx> writes:

> Here is necessary changes. I have run whole mysql-test-run and I did not see
> any failures, thus is is mostly safe. I say mostly,
> because we really do not have much test cases that would use multimaster setup
> and try to get conflicting transactions
> generated from local clients against slave thread.

Thanks a lot!

I will try to come up with some test cases for this, with replication and
external transactions that conflict and show the problem.

In parallel, I tried running the parallel replication slaves with READ
COMMITTED; that also seems to work and can get Elena able to continue
testing. But this change is potentially more correct; I will let you know when
I have some test results.

 - Kristian.

> =================================
>
> jan@jan-GE70-0NC-0ND ~/mysql/10.0-mdev5914 $ bzr diff
> === modified file 'include/mysql/plugin.h'
> --- include/mysql/plugin.h    2014-02-26 14:28:07 +0000
> +++ include/mysql/plugin.h    2014-03-21 09:05:58 +0000
> @@ -617,6 +617,7 @@
>  int thd_in_lock_tables(const MYSQL_THD thd);
>  int thd_tablespace_op(const MYSQL_THD thd);
>  long long thd_test_options(const MYSQL_THD thd, long long test_options);
> +unsigned long long thd_group_commit_id(const MYSQL_THD thd);
>  int thd_sql_command(const MYSQL_THD thd);
>  void **thd_ha_data(const MYSQL_THD thd, const struct handlerton *hton);
>  void thd_storage_lock_wait(MYSQL_THD thd, long long value);
>
> === modified file 'include/mysql/plugin_audit.h.pp'
> --- include/mysql/plugin_audit.h.pp    2013-12-22 16:11:20 +0000
> +++ include/mysql/plugin_audit.h.pp    2014-03-21 09:06:17 +0000
> @@ -298,6 +298,7 @@
>  int thd_in_lock_tables(const void* thd);
>  int thd_tablespace_op(const void* thd);
>  long long thd_test_options(const void* thd, long long test_options);
> +unsigned long long thd_group_commit_id(const void* thd);
>  int thd_sql_command(const void* thd);
>  void **thd_ha_data(const void* thd, const struct handlerton *hton);
>  void thd_storage_lock_wait(void* thd, long long value);
>
> === modified file 'include/mysql/plugin_auth.h.pp'
> --- include/mysql/plugin_auth.h.pp    2013-12-22 16:11:20 +0000
> +++ include/mysql/plugin_auth.h.pp    2014-03-21 09:06:35 +0000
> @@ -298,6 +298,7 @@
>  int thd_in_lock_tables(const void* thd);
>  int thd_tablespace_op(const void* thd);
>  long long thd_test_options(const void* thd, long long test_options);
> +unsigned long long thd_group_commit_id(const void* thd);
>  int thd_sql_command(const void* thd);
>  void **thd_ha_data(const void* thd, const struct handlerton *hton);
>  void thd_storage_lock_wait(void* thd, long long value);
>
> === modified file 'include/mysql/plugin_ftparser.h.pp'
> --- include/mysql/plugin_ftparser.h.pp    2013-12-22 16:11:20 +0000
> +++ include/mysql/plugin_ftparser.h.pp    2014-03-21 09:06:59 +0000
> @@ -251,6 +251,7 @@
>  int thd_in_lock_tables(const void* thd);
>  int thd_tablespace_op(const void* thd);
>  long long thd_test_options(const void* thd, long long test_options);
> +unsigned long long thd_group_commit_id(const void* thd);
>  int thd_sql_command(const void* thd);
>  void **thd_ha_data(const void* thd, const struct handlerton *hton);
>  void thd_storage_lock_wait(void* thd, long long value);
>
> === modified file 'sql/sql_class.cc'
> --- sql/sql_class.cc    2014-03-20 14:36:45 +0000
> +++ sql/sql_class.cc    2014-03-21 09:07:12 +0000
> @@ -675,6 +675,12 @@
>  }
>  
>  extern "C"
> +unsigned long long thd_group_commit_id(const THD *thd)
> +{
> +  return thd->rpl_group_commit_id;
> +}
> +
> +extern "C"
>  int thd_sql_command(const THD *thd)
>  {
>    return (int) thd->lex->sql_command;
>
> === modified file 'storage/innobase/handler/ha_innodb.cc'
> --- storage/innobase/handler/ha_innodb.cc    2014-02-26 18:36:33 +0000
> +++ storage/innobase/handler/ha_innodb.cc    2014-03-20 15:42:27 +0000
> @@ -2048,6 +2048,8 @@
>      trx->check_unique_secondary = !thd_test_options(
>          thd, OPTION_RELAXED_UNIQUE_CHECKS);
>  
> +    trx->group_commit_id = thd_group_commit_id(thd);
> +
>      DBUG_VOID_RETURN;
>  }
>  
>
> === modified file 'storage/innobase/include/trx0trx.h'
> --- storage/innobase/include/trx0trx.h    2014-02-26 18:36:33 +0000
> +++ storage/innobase/include/trx0trx.h    2014-03-20 15:28:19 +0000
> @@ -840,6 +840,7 @@
>                      or the state last time became
>                      TRX_STATE_ACTIVE */
>      trx_id_t    id;        /*!< transaction id */
> +    ib_uint64_t    group_commit_id;/*!< Group commit id or 0 */
>      XID        xid;        /*!< X/Open XA transaction
>                      identification to identify a
>                      transaction branch */
>
> === modified file 'storage/innobase/lock/lock0lock.cc'
> --- storage/innobase/lock/lock0lock.cc    2014-02-26 18:22:48 +0000
> +++ storage/innobase/lock/lock0lock.cc    2014-03-21 09:32:54 +0000
> @@ -1020,6 +1020,23 @@
>              return(FALSE);
>          }
>  
> +        if (trx->group_commit_id != 0 &&
> +            lock2->trx->group_commit_id != 0 &&
> +            trx->group_commit_id == lock2->trx->group_commit_id &&
> +            (type_mode & LOCK_GAP || lock_rec_get_gap(lock2))) {
> +            /* No lock request needs to wait GAP locks if
> +            transactions belong to the same group commit group.
> +            This is because we have already verified these
> +            transactions on master that they do not conflict
> +            on record locks but as they could be executed on
> +            different order on slave we should not wait for
> +            gap locks here. Note that parallel replication
> +            makes sure that transaction commits are executed
> +            in the same order in master and slave. */
> +
> +            return (FALSE);
> +        }
> +
>          return(TRUE);
>      }
>  
>
> === modified file 'storage/xtradb/handler/ha_innodb.cc'
> --- storage/xtradb/handler/ha_innodb.cc    2014-02-26 18:21:23 +0000
> +++ storage/xtradb/handler/ha_innodb.cc    2014-03-20 15:42:41 +0000
> @@ -2308,6 +2308,8 @@
>  
>      trx->fake_changes = THDVAR(thd, fake_changes);
>  
> +    trx->group_commit_id = thd_group_commit_id(thd);
> +
>  #ifdef EXTENDED_SLOWLOG
>      if (thd_log_slow_verbosity(thd) & (1ULL << SLOG_V_INNODB)) {
>          trx->take_stats = TRUE;
>
> === modified file 'storage/xtradb/include/trx0trx.h'
> --- storage/xtradb/include/trx0trx.h    2014-02-26 18:21:23 +0000
> +++ storage/xtradb/include/trx0trx.h    2014-03-20 15:28:20 +0000
> @@ -861,6 +861,7 @@
>                      or the state last time became
>                      TRX_STATE_ACTIVE */
>      trx_id_t    id;        /*!< transaction id */
> +    ib_uint64_t    group_commit_id;/*!< Group commit id or 0 */
>      XID        xid;        /*!< X/Open XA transaction
>                      identification to identify a
>                      transaction branch */
>
> === modified file 'storage/xtradb/lock/lock0lock.cc'
> --- storage/xtradb/lock/lock0lock.cc    2013-12-22 16:06:50 +0000
> +++ storage/xtradb/lock/lock0lock.cc    2014-03-21 09:32:46 +0000
> @@ -1021,6 +1021,23 @@
>              return(FALSE);
>          }
>  
> +        if (trx->group_commit_id != 0 &&
> +            lock2->trx->group_commit_id != 0 &&
> +            trx->group_commit_id == lock2->trx->group_commit_id &&
> +            (type_mode & LOCK_GAP || lock_rec_get_gap(lock2))) {
> +            /* No lock request needs to wait GAP locks if
> +            transactions belong to the same group commit group.
> +            This is because we have already verified these
> +            transactions on master that they do not conflict
> +            on record locks but as they could be executed on
> +            different order on slave we should not wait for
> +            gap locks here. Note that parallel replication
> +            makes sure that transaction commits are executed
> +            in the same order in master and slave. */
> +
> +            return (FALSE);
> +        }
> +
>          return(TRUE);
>      }