Skip to content

Commit

Permalink
This is patch for the https://jira.mariadb.org/browse/MDEV-9519 issue:
Browse files Browse the repository at this point in the history
If we have a 2+ node cluster which is replicating from an async master
and the binlog_format is set to STATEMENT and multi-row inserts are executed
on a table with an auto_increment column such that values are automatically
generated by MySQL, then the server node generates wrong auto_increment
values, which are different from what was generated on the async master.

The causes and fixes:

1. We need to improve processing of changing the auto-increment values
after changing the cluster size.

2. If wsrep auto_increment_control switched on during operation of
the node, then we should immediately update the auto_increment_increment
and auto_increment_offset global variables, without waiting of the next
invocation of the wsrep_view_handler_cb() callback. In the current version
these variables retain its initial values if wsrep_auto_increment_control
is switched on during operation of the node, which leads to inconsistent
results on the different nodes in some scenarios.

3. If wsrep auto_increment_control switched off during operation of the node,
then we must return the original values of the auto_increment_increment and
auto_increment_offset global variables, as the user has set. To make this
possible, we need to add a "shadow copies" of these variables (which stores
the latest values set by the user).
  • Loading branch information
sysprg authored and Jan Lindström committed Aug 15, 2018
1 parent 5960815 commit 75dfd4a
Show file tree
Hide file tree
Showing 11 changed files with 677 additions and 30 deletions.
147 changes: 147 additions & 0 deletions mysql-test/suite/galera/r/galera_binlog_stmt_autoinc.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
SET GLOBAL wsrep_forced_binlog_format='STATEMENT';
SET GLOBAL wsrep_forced_binlog_format='STATEMENT';
CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into t1(i) values(null);
select * from t1;
i c
1 dummy_text
insert into t1(i) values(null), (null), (null);
select * from t1;
i c
1 dummy_text
3 dummy_text
5 dummy_text
7 dummy_text
select * from t1;
i c
1 dummy_text
3 dummy_text
5 dummy_text
7 dummy_text
SET GLOBAL wsrep_forced_binlog_format='none';
SET GLOBAL wsrep_forced_binlog_format='none';
drop table t1;
SET SESSION binlog_format='STATEMENT';
show variables like 'binlog_format';
Variable_name Value
binlog_format STATEMENT
SET GLOBAL wsrep_auto_increment_control='OFF';
SET SESSION auto_increment_increment = 3;
SET SESSION auto_increment_offset = 1;
CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into t1(i) values(null);
select * from t1;
i c
1 dummy_text
insert into t1(i) values(null), (null), (null);
select * from t1;
i c
1 dummy_text
4 dummy_text
7 dummy_text
10 dummy_text
select * from t1;
i c
1 dummy_text
4 dummy_text
7 dummy_text
10 dummy_text
SET GLOBAL wsrep_auto_increment_control='ON';
SET SESSION binlog_format='ROW';
show variables like 'binlog_format';
Variable_name Value
binlog_format ROW
show variables like '%auto_increment%';
Variable_name Value
auto_increment_increment 2
auto_increment_offset 1
wsrep_auto_increment_control ON
SET GLOBAL wsrep_auto_increment_control='OFF';
show variables like '%auto_increment%';
Variable_name Value
auto_increment_increment 3
auto_increment_offset 1
wsrep_auto_increment_control OFF
SET GLOBAL wsrep_auto_increment_control='ON';
drop table t1;
SET GLOBAL wsrep_forced_binlog_format='ROW';
SET GLOBAL wsrep_forced_binlog_format='ROW';
CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into t1(i) values(null);
select * from t1;
i c
1 dummy_text
insert into t1(i) values(null), (null), (null);
select * from t1;
i c
1 dummy_text
3 dummy_text
5 dummy_text
7 dummy_text
select * from t1;
i c
1 dummy_text
3 dummy_text
5 dummy_text
7 dummy_text
SET GLOBAL wsrep_forced_binlog_format='none';
SET GLOBAL wsrep_forced_binlog_format='none';
drop table t1;
SET SESSION binlog_format='ROW';
show variables like 'binlog_format';
Variable_name Value
binlog_format ROW
SET GLOBAL wsrep_auto_increment_control='OFF';
SET SESSION auto_increment_increment = 3;
SET SESSION auto_increment_offset = 1;
CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
insert into t1(i) values(null);
select * from t1;
i c
1 dummy_text
insert into t1(i) values(null), (null), (null);
select * from t1;
i c
1 dummy_text
4 dummy_text
7 dummy_text
10 dummy_text
select * from t1;
i c
1 dummy_text
4 dummy_text
7 dummy_text
10 dummy_text
SET GLOBAL wsrep_auto_increment_control='ON';
show variables like 'binlog_format';
Variable_name Value
binlog_format ROW
show variables like '%auto_increment%';
Variable_name Value
auto_increment_increment 2
auto_increment_offset 1
wsrep_auto_increment_control ON
SET GLOBAL wsrep_auto_increment_control='OFF';
show variables like '%auto_increment%';
Variable_name Value
auto_increment_increment 3
auto_increment_offset 1
wsrep_auto_increment_control OFF
SET GLOBAL wsrep_auto_increment_control='ON';
drop table t1;
223 changes: 223 additions & 0 deletions mysql-test/suite/galera/t/galera_binlog_stmt_autoinc.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
##
## Tests the auto-increment with binlog in STATEMENT mode.
##

--source include/galera_cluster.inc
--source include/have_innodb.inc

--let $node_1=node_1
--let $node_2=node_2
--source include/auto_increment_offset_save.inc

##
## Verify the correct operation of the auto-increment when the binlog
## format artificially set to the 'STATEMENT' (although this mode is
## not recommended in the current version):
##

--connection node_2
SET GLOBAL wsrep_forced_binlog_format='STATEMENT';

--connection node_1
SET GLOBAL wsrep_forced_binlog_format='STATEMENT';

CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into t1(i) values(null);

select * from t1;

insert into t1(i) values(null), (null), (null);

select * from t1;

--connection node_2

select * from t1;

SET GLOBAL wsrep_forced_binlog_format='none';

--connection node_1

SET GLOBAL wsrep_forced_binlog_format='none';

drop table t1;

##
## Check the operation when the automatic control over the auto-increment
## settings is switched off, that is, when we use the increment step and
## the offset specified by the user. In the current session, the binlog
## format is set to 'STATEMENT'. It is important that the values of the
## auto-increment options does not changed on other node - it allows us
## to check the correct transmission of the auto-increment options to
## other nodes:
##

--disable_warnings
SET SESSION binlog_format='STATEMENT';
--enable_warnings

show variables like 'binlog_format';

SET GLOBAL wsrep_auto_increment_control='OFF';

SET SESSION auto_increment_increment = 3;
SET SESSION auto_increment_offset = 1;

CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into t1(i) values(null);

select * from t1;

insert into t1(i) values(null), (null), (null);

select * from t1;

--connection node_2

select * from t1;

--connection node_1

##
## Verify the return to automatic calculation of the step
## and offset of the auto-increment:
##

SET GLOBAL wsrep_auto_increment_control='ON';

SET SESSION binlog_format='ROW';

show variables like 'binlog_format';
show variables like '%auto_increment%';

##
## Verify the recovery of original user-defined values after
## stopping the automatic control over auto-increment:
##

SET GLOBAL wsrep_auto_increment_control='OFF';

show variables like '%auto_increment%';

##
## Restore original options and drop test table:
##

SET GLOBAL wsrep_auto_increment_control='ON';

drop table t1;

##
## Verify the correct operation of the auto-increment when the binlog
## format set to the 'ROW':
##

--connection node_2
SET GLOBAL wsrep_forced_binlog_format='ROW';

--connection node_1
SET GLOBAL wsrep_forced_binlog_format='ROW';

CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into t1(i) values(null);

select * from t1;

insert into t1(i) values(null), (null), (null);

select * from t1;

--connection node_2

select * from t1;

SET GLOBAL wsrep_forced_binlog_format='none';

--connection node_1

SET GLOBAL wsrep_forced_binlog_format='none';

drop table t1;

##
## Check the operation when the automatic control over the auto-increment
## settings is switched off, that is, when we use the increment step and
## the offset specified by the user. In the current session, the binlog
## format is set to 'ROW'. It is important that the values of the
## auto-increment options does not changed on other node - it allows us
## to check the correct transmission of the auto-increment options to
## other nodes:
##

SET SESSION binlog_format='ROW';

show variables like 'binlog_format';

SET GLOBAL wsrep_auto_increment_control='OFF';

SET SESSION auto_increment_increment = 3;
SET SESSION auto_increment_offset = 1;

CREATE TABLE t1 (
i int(11) NOT NULL AUTO_INCREMENT,
c char(32) DEFAULT 'dummy_text',
PRIMARY KEY (i)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

insert into t1(i) values(null);

select * from t1;

insert into t1(i) values(null), (null), (null);

select * from t1;

--connection node_2

select * from t1;

--connection node_1

##
## Verify the return to automatic calculation of the step
## and offset of the auto-increment:
##

SET GLOBAL wsrep_auto_increment_control='ON';

show variables like 'binlog_format';
show variables like '%auto_increment%';

##
## Verify the recovery of original user-defined values after
## stopping the automatic control over auto-increment:
##

SET GLOBAL wsrep_auto_increment_control='OFF';

show variables like '%auto_increment%';

##
## Restore original options and drop test table:
##

SET GLOBAL wsrep_auto_increment_control='ON';

drop table t1;

--source include/auto_increment_offset_restore.inc
Loading

0 comments on commit 75dfd4a

Please sign in to comment.