1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

MDEV-32188 make TIMESTAMP use whole 32-bit unsigned range

This patch extends the timestamp from
2038-01-19 03:14:07.999999 to 2106-02-07 06:28:15.999999
for 64 bit hardware and OS where 'long' is 64 bits.
This is true for 64 bit Linux but not for Windows.

This is done by treating the 32 bit stored int as unsigned instead of
signed.  This is safe as MariaDB has never accepted dates before the epoch
(1970).
The benefit of this approach that for normal timestamp the storage is
compatible with earlier version.

However for tables using system versioning we before stored a
timestamp with the year 2038 as the 'max timestamp', which is used to
detect current values.  This patch stores the new 2106 year max value
as the max timestamp. This means that old tables using system
versioning needs to be updated with mariadb-upgrade when moving them
to 11.4. That will be done in a separate commit.
This commit is contained in:
Monty
2023-09-11 17:58:22 +03:00
committed by Sergei Golubchik
parent ce6cce85d4
commit dfdedd46e4
90 changed files with 1227 additions and 354 deletions

View File

@@ -4,6 +4,8 @@ if (`SELECT $PS_PROTOCOL != 0`)
}
--source include/have_innodb.inc
--source include/default_optimizer_switch.inc
--source include/word_size.inc
--source suite/versioning/sys_time.inc
--let $replace_regex_tsltz6= /TIMESTAMP..WITH LOCAL TIME ZONE..'....-..-.. ..:..:..[.]......'/TIMESTAMP\/*WITH LOCAL TIME ZONE*\/'YYYY-MM-DD hh:ss:mm:.uuuuuu'/
@@ -109,7 +111,7 @@ as
)
select name from emp where emp_id in (select emp_id from ancestors for system_time as of timestamp @ts_1);
--replace_regex $replace_regex_tsltz6
--replace_regex $replace_regex_tsltz6 /$sys_time_max/SYS_TIME_MAX/
eval explain extended $q;
eval $q;

View File

@@ -67,6 +67,7 @@ select x, check_fields(x, row_start, row_end) from t2 for system_time all order
--exec $MYSQL_DUMP --databases test > $TMP/dump_no_history.sql
--exec $MYSQL_DUMP --dump-history --no-create-info --skip-comments --databases test > $TMP/dump_only_data.sql
--exec $MYSQL_DUMP --dump-history --compact test 2>&1 > $TMP/dump_history_compact.sql
--replace_result $sys_time_max_replace MAX_TIME
--cat_file $TMP/dump_history_compact.sql
--replace_result mariadb-dump.exe mariadb-dump
--error 1

View File

@@ -1,6 +1,7 @@
--source suite/versioning/common.inc
--source include/have_partition.inc
--source suite/versioning/engines.inc
--source include/word_size.inc
call mtr.add_suppression("need more HISTORY partitions");

View File

@@ -224,6 +224,7 @@ create or replace table child(
insert into parent values(1);
insert into child values(1);
-- error ER_ROW_IS_REFERENCED_2
delete from parent;
-- error ER_ROW_IS_REFERENCED_2

View File

@@ -85,7 +85,7 @@ drop table t2;
--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';
let $MAX_TIMESTAMP= $sys_time_max;
create table t1(x int primary key) with system versioning;
create table t2(y int primary key,
@@ -108,7 +108,7 @@ 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');
--error ER_WRONG_VALUE
--error ER_WRONG_VERSIONING_RANGE
insert into t3 values (5, '1980-01-02 00:00:00', '1980-01-01 00:00:01');
select x, row_start, row_end from t1 for system_time all;
@@ -132,16 +132,19 @@ insert t2 (y,row_end) values (1, '1970-01-01 00:00:00') on duplicate key update
# 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
--error ER_WRONG_VERSIONING_RANGE
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
--error ER_WRONG_VERSIONING_RANGE
insert into t1(x, row_start, row_end) values (7, '1980-01-01 00:00:11', '1980-01-01 00:00:11');
insert into t1(x, row_start) values (8, '1980-01-01 00:00:22');
--replace_regex /'202\d-\d\d-\d\d .*'/'now'/
--error ER_WRONG_VALUE
--error ER_WRONG_VERSIONING_RANGE
insert into t1(x, row_end) values (9, '1980-01-01 00:00:33');
--replace_result $MAX_TIMESTAMP MAX_TIMESTAMP
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;
--replace_result $MAX_TIMESTAMP MAX_TIMESTAMP
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
@@ -159,6 +162,7 @@ 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;
--replace_result $MAX_TIMESTAMP MAX_TIMESTAMP
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;

View File

@@ -1,4 +1,6 @@
--source include/have_innodb.inc
set @@time_zone='+00:00';
--source suite/versioning/sys_time.inc
# TRT test
@@ -64,7 +66,8 @@ create or replace table t1 (
period for system_time(s, e))
with system versioning;
insert into t1 values (1, null, null, 'foo');
select i, c, e>TIMESTAMP'2038-01-01 00:00:00' AS current_row from t1;
--replace_result $sys_time_max SYS_TIME_MAX
--eval select i, c, e>LEFT($sys_time_max, 10) AS current_row from t1;
drop table t1;
drop table t2;
@@ -84,3 +87,6 @@ create table t1 (pk int primary key, i int) with system versioning;
replace into t1 values (1,10),(1,100),(1,1000);
select pk,i,row_end > '2038-01-01' from t1 for system_time all;
drop table t1;
# Cleanup
set @@time_zone=default;

View File

@@ -1,8 +1,11 @@
--source suite/versioning/sys_time.inc
#
# simple tests that don't need to be run in multiple various combinations
#
set time_zone='+00:00';
--echo #
--echo # MDEV-29750 triggers can modify history
--echo #
@@ -11,6 +14,7 @@ create table t (a int, b int as (a+1), s timestamp(6) as row start, e timestamp(
insert into t values (1,1, '2022-01-01','2023-01-01'),(2,2, '2022-02-02','2023-02-02');
create trigger tr before insert on t for each row set new.b=1, new.s = '2022-03-03', new.e = '2023-03-03';
insert into t (a) values (3),(4);
--replace_result $sys_time_max_replace SYS_TIME_MAX
select * from t for system_time all;
drop table t;
set sql_mode=default, timestamp=default;
@@ -33,6 +37,7 @@ insert t1 (a,s,e) values (1,'2020-01-01',default), (2,'2020-02-02',ignore),(3,de
set timestamp=unix_timestamp('2010-11-11 11:11:11');
insert t1 values (5,'2020-01-01',default), (6,'2020-02-02',ignore),(7,default,'2020-03-03'), (8,ignore,'2020-04-04');
set timestamp=default;
--replace_result $sys_time_max_replace SYS_TIME_MAX
select * from t1 for system_time all;
drop table t1;

View File

@@ -179,7 +179,8 @@ set @now= now(6);
insert into t1 values (1);
set @str= concat('select x, row_start < @now as A, row_end > @now as B from t1 partition (p0)');
prepare select_p0 from @str;
set @str= concat('select x, row_start > @now as C, row_end = timestamp\'2038-01-19 03:14:07.999999\' as D from t1 partition (pn)');
--replace_result $sys_time_max SYS_TIME_MAX
--eval set @str= concat("select x, row_start > @now as C, row_end = $sys_time_max as D from t1 partition (pn)");
prepare select_pn from @str;
execute select_p0;
@@ -278,7 +279,7 @@ partition by system_time interval 6 day limit 98;
--error ER_DATA_OUT_OF_RANGE
create or replace table t1 (pk int) with system versioning
partition by system_time interval 10 year partitions 3;
partition by system_time interval 60 year partitions 3;
--echo # INTERVAL and ALTER TABLE
create or replace table t1 (i int) with system versioning
@@ -2646,11 +2647,12 @@ create table t1 (a varchar(100)) with system versioning
partition by system_time interval 1 day
starts '2021-09-30 00:00:00' partitions 3;
set system_versioning_insert_history=1;
insert into t1 (a,row_start,row_end) values
--replace_result $sys_time_max SYS_TIME_MAX
eval insert into t1 (a,row_start,row_end) values
('p0', '2021-09-30', '2021-09-30 10:00:00'),
('p1', '2021-09-30', '2021-10-01 10:00:00'),
('overflows, so also p1','2021-09-30', '2021-10-10 10:00:00'),
('pn, current', '2021-09-30', '2038-01-19 03:14:07.999999');
('pn, current', '2021-09-30', $sys_time_max);
select table_name,partition_name,partition_ordinal_position,partition_method,partition_description,table_rows
from information_schema.partitions where table_schema='test';
drop table t1;

View File

@@ -1,6 +1,7 @@
--source include/have_binlog_format_row.inc
--source include/master-slave.inc
--source include/have_innodb.inc
--source suite/versioning/sys_time.inc
--echo # MDEV-16252: MINIMAL binlog_row_image does not work for versioned tables
set @old_row_image= @@binlog_row_image;
@@ -39,6 +40,7 @@ show create table t1;
set timestamp= 12345;
--let $start_pos= query_get_value("SHOW MASTER STATUS", Position, 1)
insert t1 values (1, 1);
--replace_result $sys_timestamp_max TIMESTAMP_MAX
select *, unix_timestamp(row_start) as row_start, unix_timestamp(row_end) as row_end from t1;
--let $stop_pos= query_get_value("SHOW MASTER STATUS", Position, 1)
set timestamp= default;
@@ -46,6 +48,7 @@ set timestamp= default;
# NOTE: pipe grep is not Windows-compatible
--let grep_file= $TMP/out.txt
--let grep_regex= ^###
--let grep_filter=s{$sys_timestamp_max}{MAX_TIMESTAMP};
--exec $MYSQL_BINLOG -v -j $start_pos --stop-position=$stop_pos -o 3 $MYSQLD_DATADIR/master-bin.000001 > $grep_file
--source include/grep.inc
--sync_slave_with_master

View File

@@ -186,13 +186,15 @@ create or replace table t1(x int) with system versioning;
select * from (t1 as r left join t1 as u using (x)), t1;
# @end should be max
set @@time_zone="+00:00";
create or replace table t1 (a int) with system versioning;
insert into t1 values (1);
create trigger read_end after update on t1
for each row set @end = old.row_end;
update t1 set a=2;
--replace_result 18446744073709551615 MAX_RESULT "2038-01-19 03:14:07.999999" MAX_RESULT
--replace_result 18446744073709551615 MAX_RESULT $sys_time_max_replace MAX_RESULT
select @end;
set @@time_zone=default;
create or replace table t1 (a int) with system versioning;
create or replace table t2 (b int) with system versioning;
@@ -223,6 +225,7 @@ create or replace table t1 (a int) with system versioning;
insert into t1 values (1);
insert into t1 values (2);
insert into t1 values (3);
--replace_result $sys_time_max SYS_TIME_MAX
explain extended
select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
@@ -377,6 +380,7 @@ select f1 from t1 join t2 left join t3 left join t4 on f3 = f4 on f3 = f2;
insert t2 values (1),(2);
insert t3 values (1),(2);
insert t4 values (1),(2);
--replace_result $sys_time_max SYS_TIME_MAX
explain extended
select f1 from t1 join t2 left join t3 left join t4 on f3 = f4 on f3 = f2;

View File

@@ -160,7 +160,7 @@ insert into t1 values (1);
create trigger read_end after update on t1
for each row set @end = old.row_end;
update t1 set a=2;
--replace_result 18446744073709551615 MAX_RESULT "2038-01-19 03:14:07.999999" MAX_RESULT
--replace_result 18446744073709551615 MAX_RESULT $sys_time_max_replace MAX_RESULT
select @end;
create or replace table t1 (a int) with system versioning;

View File

@@ -440,8 +440,8 @@ DELIMITER ;$$
--echo # String literals resolve to TIMESTAMP
--echo #
SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00';
SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2038-12-30 00:00:00';
SELECT * FROM t1 FOR SYSTEM_TIME AS OF '2107-12-30 00:00:00';
SELECT * FROM t2 FOR SYSTEM_TIME AS OF '2107-12-30 00:00:00';
DROP TABLE t1, t2;

View File

@@ -56,7 +56,7 @@ select * from vt1;
--echo # VIEW with parameters [tempesta-tech/mariadb#151]
create or replace table t1 (x int) with system versioning;
create or replace view vt1(c) as select x from t1;
--replace_result 18446744073709551615 MAX_RESULT "TIMESTAMP'2038-01-19 03:14:07.999999'" MAX_RESULT
--replace_result 18446744073709551615 MAX_RESULT $sys_time_max_replace MAX_RESULT
show create view vt1;
--echo # VIEW over JOIN of versioned tables [tempesta-tech/mariadb#153]