Commit a4272bf1 authored by Sergei Golubchik's avatar Sergei Golubchik

versioning: use @@timestamp

Don't use hidden system time in versioning,
but keep the system time logic in THD
to workaround low-res system clock and
replication not versioned to versioned.

This reverts MDEV-14788 (System versioning cannot
be based on local timestamps, as it is now).
Versioning is based on local timestamps again,
but timestamps are protected by MDEV-15923
(option to control who can set session @@timestamp).
parent 4203f572
...@@ -71,24 +71,6 @@ i c current_row ...@@ -71,24 +71,6 @@ i c current_row
1 foo 1 1 foo 1
drop table t1; drop table t1;
drop table t2; drop table t2;
set timestamp=1000000019;
select now() < sysdate();
now() < sysdate()
1
create table t1 (a int) with system versioning;
insert t1 values (1);
set @a=sysdate(6);
select * from t1 for system_time as of now(6);
a
select * from t1 for system_time as of sysdate(6);
a
1
update t1 set a=2;
delete from t1;
select *, row_start > @a, row_end > @a from t1 for system_time all;
a row_start > @a row_end > @a
1 0 1
2 1 1
# #
# MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger # MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger
# #
......
include/master-slave.inc
[connection master]
set timestamp=unix_timestamp('2001-02-03 10:20:30'); set timestamp=unix_timestamp('2001-02-03 10:20:30');
create or replace table t1 (i int) with system versioning create or replace table t1 (i int) with system versioning
partition by system_time interval 1 day partition by system_time interval 1 day
...@@ -10,22 +8,23 @@ insert t1 values (1); ...@@ -10,22 +8,23 @@ insert t1 values (1);
delete from t1; delete from t1;
set timestamp=unix_timestamp('2001-02-04 10:20:50'); set timestamp=unix_timestamp('2001-02-04 10:20:50');
insert t1 values (2); insert t1 values (2);
Warnings:
Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
delete from t1; delete from t1;
connection slave; Warnings:
Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
subpartition_name partition_description table_rows subpartition_name partition_description table_rows
p1sp0 2001-02-04 10:20:30 1 p1sp0 2001-02-04 10:20:30 1
p1sp1 2001-02-04 10:20:30 1 p1sp1 2001-02-04 10:20:30 1
pnsp0 CURRENT 0 pnsp0 CURRENT 0
pnsp1 CURRENT 0 pnsp1 CURRENT 0
connection master;
set timestamp=unix_timestamp('2001-02-04 10:20:55'); set timestamp=unix_timestamp('2001-02-04 10:20:55');
alter table t1 add partition (partition p0 history, partition p2 history); alter table t1 add partition (partition p0 history, partition p2 history);
set timestamp=unix_timestamp('2001-02-04 10:30:00'); set timestamp=unix_timestamp('2001-02-04 10:30:00');
insert t1 values (4),(5); insert t1 values (4),(5);
set timestamp=unix_timestamp('2001-02-04 10:30:10'); set timestamp=unix_timestamp('2001-02-04 10:30:10');
update t1 set i=6 where i=5; update t1 set i=6 where i=5;
connection slave;
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
subpartition_name partition_description table_rows subpartition_name partition_description table_rows
p1sp0 2001-02-04 10:20:30 1 p1sp0 2001-02-04 10:20:30 1
...@@ -56,6 +55,4 @@ i ...@@ -56,6 +55,4 @@ i
explain partitions select * from t1 for system_time all where row_end = @ts; explain partitions select * from t1 for system_time all where row_end = @ts;
id select_type table partitions type possible_keys key key_len ref rows Extra id select_type table partitions type possible_keys key key_len ref rows Extra
1 SIMPLE t1 p1_p1sp0,p1_p1sp1 # NULL NULL NULL NULL # # 1 SIMPLE t1 p1_p1sp0,p1_p1sp1 # NULL NULL NULL NULL # #
connection master;
drop table t1; drop table t1;
include/rpl_end.inc
...@@ -69,24 +69,6 @@ select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1; ...@@ -69,24 +69,6 @@ select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1;
drop table t1; drop table t1;
drop table t2; drop table t2;
#
# MDEV-14788 System versioning cannot be based on local timestamps, as it is now
#
set timestamp=1000000019;
select now() < sysdate();
create table t1 (a int) with system versioning;
insert t1 values (1);
--source suite/versioning/wait_system_clock.inc
set @a=sysdate(6);
select * from t1 for system_time as of now(6);
select * from t1 for system_time as of sysdate(6);
update t1 set a=2;
delete from t1;
--sorted_result
select *, row_start > @a, row_end > @a from t1 for system_time all;
--echo # --echo #
--echo # MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger --echo # MDEV-14871 Server crashes in fill_record / fill_record_n_invoke_before_triggers upon inserting into versioned table with trigger
--echo # --echo #
......
--source include/have_partition.inc --source include/have_partition.inc
--source include/have_binlog_format_statement.inc
--source include/master-slave.inc
#
# The test below isn't a replication test as such,
# but it uses replication to get custom timestamps and repeatable
# behavior into versioning.
#
# #
# partition rotation # partition rotation
# #
disable_warnings;
set timestamp=unix_timestamp('2001-02-03 10:20:30'); set timestamp=unix_timestamp('2001-02-03 10:20:30');
create or replace table t1 (i int) with system versioning create or replace table t1 (i int) with system versioning
partition by system_time interval 1 day partition by system_time interval 1 day
...@@ -21,17 +12,16 @@ set timestamp=unix_timestamp('2001-02-03 10:20:40'); ...@@ -21,17 +12,16 @@ set timestamp=unix_timestamp('2001-02-03 10:20:40');
insert t1 values (1); delete from t1; insert t1 values (1); delete from t1;
set timestamp=unix_timestamp('2001-02-04 10:20:50'); set timestamp=unix_timestamp('2001-02-04 10:20:50');
insert t1 values (2); delete from t1; insert t1 values (2); delete from t1;
enable_warnings;
sync_slave_with_master;
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
connection master;
set timestamp=unix_timestamp('2001-02-04 10:20:55'); set timestamp=unix_timestamp('2001-02-04 10:20:55');
alter table t1 add partition (partition p0 history, partition p2 history); alter table t1 add partition (partition p0 history, partition p2 history);
set timestamp=unix_timestamp('2001-02-04 10:30:00'); set timestamp=unix_timestamp('2001-02-04 10:30:00');
insert t1 values (4),(5); insert t1 values (4),(5);
set timestamp=unix_timestamp('2001-02-04 10:30:10'); set timestamp=unix_timestamp('2001-02-04 10:30:10');
update t1 set i=6 where i=5; update t1 set i=6 where i=5;
sync_slave_with_master;
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1'; select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
--echo ## pruning check --echo ## pruning check
...@@ -47,7 +37,4 @@ select * from t1 for system_time all where row_end = @ts; ...@@ -47,7 +37,4 @@ select * from t1 for system_time all where row_end = @ts;
--replace_column 5 # 10 # 11 # --replace_column 5 # 10 # 11 #
explain partitions select * from t1 for system_time all where row_end = @ts; explain partitions select * from t1 for system_time all where row_end = @ts;
connection master;
drop table t1; drop table t1;
--source include/rpl_end.inc
...@@ -859,7 +859,7 @@ void partition_info::vers_set_hist_part(THD *thd) ...@@ -859,7 +859,7 @@ void partition_info::vers_set_hist_part(THD *thd)
if (vers_info->interval.is_set()) if (vers_info->interval.is_set())
{ {
if (vers_info->hist_part->range_value > thd->systime()) if (vers_info->hist_part->range_value > thd->query_start())
return; return;
partition_element *next= NULL; partition_element *next= NULL;
...@@ -870,7 +870,7 @@ void partition_info::vers_set_hist_part(THD *thd) ...@@ -870,7 +870,7 @@ void partition_info::vers_set_hist_part(THD *thd)
while ((next= it++) != vers_info->now_part) while ((next= it++) != vers_info->now_part)
{ {
vers_info->hist_part= next; vers_info->hist_part= next;
if (next->range_value > thd->systime()) if (next->range_value > thd->query_start())
return; return;
} }
goto warn; goto warn;
......
...@@ -3437,16 +3437,13 @@ class THD :public Statement, ...@@ -3437,16 +3437,13 @@ class THD :public Statement,
{ query_start_sec_part_used=1; return start_time_sec_part; } { query_start_sec_part_used=1; return start_time_sec_part; }
MYSQL_TIME query_start_TIME(); MYSQL_TIME query_start_TIME();
private:
struct { struct {
my_hrtime_t start; my_hrtime_t start;
my_time_t sec; my_time_t sec;
ulong sec_part; ulong sec_part;
} system_time; } system_time;
ulong systime_sec_part() { query_start_sec_part_used=1; return system_time.sec_part; }
my_time_t systime() { return system_time.sec; }
private:
void set_system_time() void set_system_time()
{ {
my_hrtime_t hrtime= my_hrtime(); my_hrtime_t hrtime= my_hrtime();
...@@ -3471,29 +3468,9 @@ class THD :public Statement, ...@@ -3471,29 +3468,9 @@ class THD :public Statement,
} }
} }
void set_system_time_from_user_time(bool with_sec_part)
{
if (with_sec_part)
{
system_time.sec= start_time;
system_time.sec_part= start_time_sec_part;
}
else
{
if (system_time.sec == start_time)
system_time.sec_part++;
else
{
system_time.sec= start_time;
system_time.sec_part= 0;
}
}
}
public: public:
inline void set_start_time() inline void set_start_time()
{ {
set_system_time();
if (user_time.val) if (user_time.val)
{ {
start_time= hrtime_to_my_time(user_time); start_time= hrtime_to_my_time(user_time);
...@@ -3501,6 +3478,7 @@ class THD :public Statement, ...@@ -3501,6 +3478,7 @@ class THD :public Statement,
} }
else else
{ {
set_system_time();
start_time= system_time.sec; start_time= system_time.sec;
start_time_sec_part= system_time.sec_part; start_time_sec_part= system_time.sec_part;
} }
...@@ -3511,6 +3489,7 @@ class THD :public Statement, ...@@ -3511,6 +3489,7 @@ class THD :public Statement,
set_start_time(); set_start_time();
start_utime= utime_after_lock= microsecond_interval_timer(); start_utime= utime_after_lock= microsecond_interval_timer();
} }
/* only used in SET @@timestamp=... */
inline void set_time(my_hrtime_t t) inline void set_time(my_hrtime_t t)
{ {
user_time= t; user_time= t;
...@@ -3525,14 +3504,23 @@ class THD :public Statement, ...@@ -3525,14 +3504,23 @@ class THD :public Statement,
if (opt_secure_timestamp > (slave_thread ? SECTIME_REPL : SECTIME_SUPER)) if (opt_secure_timestamp > (slave_thread ? SECTIME_REPL : SECTIME_SUPER))
set_time(); // note that BINLOG itself requires SUPER set_time(); // note that BINLOG itself requires SUPER
else else
{
if (sec_part <= TIME_MAX_SECOND_PART)
{
start_time= system_time.sec= t;
start_time_sec_part= system_time.sec_part= sec_part;
}
else if (t != system_time.sec)
{
start_time= system_time.sec= t;
start_time_sec_part= system_time.sec_part= 0;
}
else
{ {
start_time= t; start_time= t;
start_time_sec_part= sec_part > TIME_MAX_SECOND_PART ? 0 : sec_part; start_time_sec_part= ++system_time.sec_part;
}
user_time.val= hrtime_from_time(start_time) + start_time_sec_part; user_time.val= hrtime_from_time(start_time) + start_time_sec_part;
if (slave_thread)
set_system_time_from_user_time(sec_part <= TIME_MAX_SECOND_PART);
else // BINLOG command
set_system_time();
PSI_CALL_set_thread_start_time(start_time); PSI_CALL_set_thread_start_time(start_time);
start_utime= utime_after_lock= microsecond_interval_timer(); start_utime= utime_after_lock= microsecond_interval_timer();
} }
......
...@@ -1571,7 +1571,7 @@ static bool check_vers_constants(THD *thd, partition_info *part_info) ...@@ -1571,7 +1571,7 @@ static bool check_vers_constants(THD *thd, partition_info *part_info)
my_tz_OFFSET0->TIME_to_gmt_sec(&ltime, &error); my_tz_OFFSET0->TIME_to_gmt_sec(&ltime, &error);
if (error) if (error)
goto err; goto err;
if (vers_info->hist_part->range_value <= thd->systime()) if (vers_info->hist_part->range_value <= thd->query_start())
vers_info->hist_part= el; vers_info->hist_part= el;
} }
return 0; return 0;
...@@ -5310,7 +5310,7 @@ that are reorganised. ...@@ -5310,7 +5310,7 @@ that are reorganised.
if (*fast_alter_table && tab_part_info->vers_info->interval.is_set()) if (*fast_alter_table && tab_part_info->vers_info->interval.is_set())
{ {
partition_element *hist_part= tab_part_info->vers_info->hist_part; partition_element *hist_part= tab_part_info->vers_info->hist_part;
if (hist_part->range_value <= thd->systime()) if (hist_part->range_value <= thd->query_start())
hist_part->part_state= PART_CHANGED; hist_part->part_state= PART_CHANGED;
} }
} }
......
...@@ -5907,7 +5907,7 @@ opt_versioning_rotation: ...@@ -5907,7 +5907,7 @@ opt_versioning_rotation:
opt_versioning_interval_start: opt_versioning_interval_start:
/* empty */ /* empty */
{ {
$$= thd->systime(); $$= thd->query_start();
} }
| STARTS_SYM ulong_num | STARTS_SYM ulong_num
{ {
......
...@@ -7752,8 +7752,8 @@ void TABLE::vers_update_fields() ...@@ -7752,8 +7752,8 @@ void TABLE::vers_update_fields()
{ {
if (!vers_write) if (!vers_write)
return; return;
if (vers_start_field()->store_timestamp(in_use->systime(), if (vers_start_field()->store_timestamp(in_use->query_start(),
in_use->systime_sec_part())) in_use->query_start_sec_part()))
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
else else
...@@ -7768,8 +7768,8 @@ void TABLE::vers_update_fields() ...@@ -7768,8 +7768,8 @@ void TABLE::vers_update_fields()
void TABLE::vers_update_end() void TABLE::vers_update_end()
{ {
if (vers_end_field()->store_timestamp(in_use->systime(), if (vers_end_field()->store_timestamp(in_use->query_start(),
in_use->systime_sec_part())) in_use->query_start_sec_part()))
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
...@@ -8611,9 +8611,9 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id) ...@@ -8611,9 +8611,9 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id)
if (!table && open()) if (!table && open())
return true; return true;
timeval start_time= {thd->systime(), long(thd->systime_sec_part())}; timeval start_time= {thd->query_start(), long(thd->query_start_sec_part())};
thd->set_start_time(); thd->set_start_time();
timeval end_time= {thd->systime(), long(thd->systime_sec_part())}; timeval end_time= {thd->query_start(), long(thd->query_start_sec_part())};
store(FLD_TRX_ID, start_id); store(FLD_TRX_ID, start_id);
store(FLD_COMMIT_ID, end_id); store(FLD_COMMIT_ID, end_id);
store(FLD_BEGIN_TS, start_time); store(FLD_BEGIN_TS, start_time);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment