mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-16546 System versioning setting to allow history modification
1. system_versioning_insert_history session variable allows pseudocolumns ROW_START and ROW_END be specified in INSERT, INSERT..SELECT and LOAD DATA. 2. Cleaned up select_insert::send_data() from setting vers_write as this parameter is now set on TABLE initialization. 4. Replication of system_versioning_insert_history via option_bits in OPTIONS_WRITTEN_TO_BIN_LOG.
This commit is contained in:
committed by
Sergei Golubchik
parent
d9b0c9ad2b
commit
a2cda88631
@@ -81,4 +81,161 @@ select x, y from t2;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-16546 System versioning setting to allow history modification
|
||||
--echo #
|
||||
set @@session.time_zone='+00:00';
|
||||
let $MAX_TIMESTAMP= TIMESTAMP'2038-01-19 03:14:07.999999';
|
||||
|
||||
create table t1(x int primary key) with system versioning;
|
||||
create table t2(y int primary key,
|
||||
row_start timestamp(6) as row start invisible,
|
||||
row_end timestamp(6) as row end invisible,
|
||||
period for system_time (row_start, row_end))
|
||||
with system versioning;
|
||||
create table t3(z int primary key,
|
||||
row_start timestamp(6) as row start,
|
||||
row_end timestamp(6) as row end,
|
||||
period for system_time (row_start, row_end))
|
||||
with system versioning;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
insert into t1(x, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
insert into t2(y, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
set @@system_versioning_insert_history= 1;
|
||||
--replace_result $default_engine DEFAULT_ENGINE
|
||||
show create table t1;
|
||||
insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
insert into t2(y, row_start, row_end) values (4, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
insert into t3 values (5, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
|
||||
select x, row_start, row_end from t1 for system_time all;
|
||||
select y, row_start, row_end from t2 for system_time all;
|
||||
select z, row_start, row_end from t3 for system_time all;
|
||||
|
||||
insert into t1(x) values (1);
|
||||
insert into t2(y) values (1);
|
||||
|
||||
update t1 set x= x + 1;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
update t1 set row_start= '1971-01-01 00:00:00';
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
update t2 set row_start= '1971-01-01 00:00:00';
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
insert t1 (x) values (2) on duplicate key update x= 3, row_end= '1970-01-01 00:00:00';
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
insert t2 (y) values (1) on duplicate key update y= 3, row_end= '1970-01-01 00:00:00';
|
||||
# this should work, row_start/row_end must be mentioned explicitly:
|
||||
insert into t1 values (4);
|
||||
insert into t1 set x= 5, row_start= '1980-01-01 00:00:00', row_end= '1980-01-01 00:00:01';
|
||||
--error ER_WRONG_VALUE
|
||||
insert into t1(x, row_start, row_end) values (6, '1980-01-01 00:00:01', '1980-01-01 00:00:00');
|
||||
--error ER_WRONG_VALUE
|
||||
insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:11', '1980-01-01 00:00:11');
|
||||
--error ER_WRONG_VALUE
|
||||
insert into t1(x, row_start) values (8, '1980-01-01 00:00:22');
|
||||
# NOTE: having row_start=0 might be useful and can mean
|
||||
# "there is no information on when history was started" (an opposite to row_end=MAX_TIMESTAMP)
|
||||
--error ER_WRONG_VALUE
|
||||
insert into t1(x, row_end) values (9, '1980-01-01 00:00:33');
|
||||
--error ER_WRONG_VALUE
|
||||
eval insert into t1(x, row_end) values (10, $MAX_TIMESTAMP);
|
||||
select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x;
|
||||
eval select x, row_start, row_end from t1 for system_time all
|
||||
where x > 1 and row_end < $MAX_TIMESTAMP order by x, row_start, row_end;
|
||||
--echo # Direct insert is not possible for TRX_ID versioning
|
||||
create or replace table t2(y int primary key,
|
||||
row_start bigint unsigned as row start,
|
||||
row_end bigint unsigned as row end,
|
||||
period for system_time (row_start, row_end))
|
||||
with system versioning engine innodb;
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
insert into t2(y, row_start, row_end) values (0, 1, 2);
|
||||
set @@system_versioning_insert_history= 0;
|
||||
|
||||
--echo ## INSERT..SELECT
|
||||
create or replace table t2 like t1;
|
||||
set @@system_versioning_insert_history= 1;
|
||||
insert into t2 (x, row_start, row_end) select x, row_start, row_end from t1 for system_time all;
|
||||
select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x;
|
||||
eval select x, row_start, row_end from t2 for system_time all
|
||||
where x > 1 and row_end < $MAX_TIMESTAMP order by x, row_start, row_end;
|
||||
set @@system_versioning_insert_history= 0;
|
||||
|
||||
--echo # REPLACE / REPLACE .. SELECT
|
||||
create or replace table t2(a int primary key,
|
||||
row_start timestamp(6) as row start invisible,
|
||||
row_end timestamp(6) as row end invisible,
|
||||
period for system_time (row_start, row_end))
|
||||
with system versioning;
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
--error ER_WARNING_NON_DEFAULT_VALUE_FOR_GENERATED_COLUMN
|
||||
replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1;
|
||||
create or replace table t2 (a int primary key) with system versioning;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1;
|
||||
set @@system_versioning_insert_history= 1;
|
||||
--error ER_WRONG_VALUE
|
||||
replace into t2 (a, row_start) values (1, '1980-01-01 00:00:00');
|
||||
--error ER_WRONG_VALUE
|
||||
replace into t2 (a, row_end) values (0, '1980-01-01 00:00:00');
|
||||
replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
select a, row_start, row_end from t2 for system_time all order by a, row_start, row_end;
|
||||
--echo # Changing row_end via REPLACE is NOT possible, we just insert new row:
|
||||
# NOTE: because multiple versions of history row with a=1 may exist, so what REPLACE should change?
|
||||
replace into t2 (a, row_start, row_end) values (1, '1980-01-01 00:00:00', '1990-01-01 00:00:01');
|
||||
select a, row_start, row_end from t2 for system_time all order by a, row_start, row_end;
|
||||
--echo # But changing row_start via REPLACE is possible:
|
||||
replace into t2 (a, row_start, row_end) values (1, '1971-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
select a, row_start, row_end from t2 for system_time all order by a, row_start, row_end;
|
||||
eval replace into t2 (a, row_start, row_end) select x, row_start, row_end from t1 for system_time all
|
||||
where x > 1 and row_end < $MAX_TIMESTAMP;
|
||||
select a, row_start, row_end from t2 for system_time all order by a, row_start, row_end;
|
||||
|
||||
--echo # LOAD DATA
|
||||
--let DATAFILE= $MYSQLTEST_VARDIR/tmp/test_versioning_t3.data
|
||||
--replace_result $DATAFILE DATAFILE
|
||||
eval select x, row_start, row_end into outfile '$DATAFILE' from t1 for system_time all;
|
||||
create or replace table t3 like t1;
|
||||
--replace_result $default_engine DEFAULT_ENGINE
|
||||
show create table t3;
|
||||
set @@system_versioning_insert_history= 1;
|
||||
--replace_result $default_engine DEFAULT_ENGINE
|
||||
show create table t3;
|
||||
--replace_result $DATAFILE DATAFILE
|
||||
eval load data infile '$DATAFILE' into table t3 (x, row_start, row_end);
|
||||
select x, check_row_ts(row_start, row_end) from t3 for system_time all order by x;
|
||||
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3;
|
||||
--remove_file $DATAFILE
|
||||
|
||||
--echo # Honor secure_timestamp option
|
||||
--let $restart_parameters= --secure-timestamp=YES
|
||||
--source include/restart_mysqld.inc
|
||||
set @@system_versioning_insert_history= 1;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
insert into t1(x, row_start, row_end) values (8, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
--let $restart_parameters= --secure-timestamp=REPLICATION
|
||||
--source include/restart_mysqld.inc
|
||||
set @@system_versioning_insert_history= 1;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
insert into t1(x, row_start, row_end) values (9, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
--let $restart_parameters= --secure-timestamp=SUPER
|
||||
--source include/restart_mysqld.inc
|
||||
set @@system_versioning_insert_history= 1;
|
||||
insert into t1(x, row_start, row_end) values (10, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
create user nobody;
|
||||
change_user nobody;
|
||||
use test;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
change_user root;
|
||||
use test;
|
||||
--let $restart_parameters= --secure-timestamp=NO
|
||||
--source include/restart_mysqld.inc
|
||||
|
||||
drop tables t1, t2, t3;
|
||||
|
||||
-- source suite/versioning/common_finish.inc
|
||||
|
@@ -1,6 +1,7 @@
|
||||
--source suite/versioning/engines.inc
|
||||
--source include/have_partition.inc
|
||||
--source include/master-slave.inc
|
||||
--source suite/versioning/common.inc
|
||||
|
||||
#BUG#12662190 - COM_COMMIT IS NOT INCREMENTED FROM THE BINARY LOGS ON SLAVE, COM_BEGIN IS
|
||||
#Testing command counters -BEFORE.
|
||||
@@ -10,6 +11,7 @@ let $slave_com_commit_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_commi
|
||||
let $slave_com_insert_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_insert', Value, 1);
|
||||
let $slave_com_delete_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_delete', Value, 1);
|
||||
let $slave_com_update_before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_update', Value, 1);
|
||||
set @@session.time_zone='+00:00';
|
||||
|
||||
connection master;
|
||||
CREATE TABLE t1 (x int) with system versioning;
|
||||
@@ -296,4 +298,46 @@ alter table t drop partition p0;
|
||||
drop tables t, t2;
|
||||
set timestamp= default;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-16546 System versioning setting to allow history modification
|
||||
--echo #
|
||||
create table t1(x int) with system versioning;
|
||||
insert into t1(x) values (1);
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
insert into t1(x, row_start, row_end) values (2, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
set @@system_versioning_insert_history= 1;
|
||||
insert into t1(x, row_start, row_end) values (3, '1980-01-01 00:00:00', '1980-01-01 00:00:01');
|
||||
update t1 set x= x + 1;
|
||||
sync_slave_with_master;
|
||||
set @@session.time_zone='+00:00';
|
||||
select x, check_row_ts(row_start, row_end) from t1 for system_time all order by x;
|
||||
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t1 for system_time all where x = 3;
|
||||
|
||||
--echo ## INSERT..SELECT
|
||||
connection master;
|
||||
create or replace table t2 like t1;
|
||||
set @@system_versioning_insert_history= 1;
|
||||
insert into t2 (x, row_start, row_end) select x, row_start, row_end from t1 for system_time all;
|
||||
sync_slave_with_master;
|
||||
select x, check_row_ts(row_start, row_end) from t2 for system_time all order by x;
|
||||
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t2 for system_time all where x = 3;
|
||||
|
||||
--echo # LOAD DATA
|
||||
connection master;
|
||||
--let DATAFILE= $MYSQLTEST_VARDIR/tmp/test_versioning_t3.data
|
||||
--replace_result $DATAFILE DATAFILE
|
||||
eval select x, row_start, row_end into outfile '$DATAFILE' from t1 for system_time all;
|
||||
create or replace table t3 like t1;
|
||||
set @@system_versioning_insert_history= 1;
|
||||
--replace_result $DATAFILE DATAFILE
|
||||
eval load data infile '$DATAFILE' into table t3 (x, row_start, row_end);
|
||||
sync_slave_with_master;
|
||||
select x, check_row_ts(row_start, row_end) from t3 for system_time all order by x;
|
||||
select row_start = '1980-01-01 00:00:00', row_end = '1980-01-01 00:00:01' from t3 for system_time all where x = 3;
|
||||
--remove_file $DATAFILE
|
||||
|
||||
connection master;
|
||||
drop tables t1, t2, t3;
|
||||
|
||||
--source suite/versioning/common_finish.inc
|
||||
--source include/rpl_end.inc
|
||||
|
Reference in New Issue
Block a user