mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
When there are E empty partitions left, auto-create N new empty partitions for SYSTEM_TIME partitioning rotated by INTERVAL/LIMIT and marked by AUTO_INCREMENT keyword. Syntax change: AUTO_INCREMENT keyword (or shorter AUTO may be used instead) after LIMIT/INTERVAL clause. CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING PARTITION BY SYSTEM_TIME LIMIT 100000 AUTO_INCREMENT; CREATE OR REPLACE TABLE t (x INT) WITH SYSTEM VERSIONING PARTITION BY SYSTEM_TIME INTERVAL 1 WEEK AUTO_INCREMENT; The current revision implements hard-coded values of 1 for E and N. As well as auto-creation threshold MinInterval = 1 hour, MinLimit = 1000. The name for newly added partition will be first chosen as "pX", where X is partition number and "p" is hard-coded name prefix. If this name is already occupied, the X will be incremented until the resulting name will be free to use. ALTER TABLE ADD PARTITION is now always fast. If there some history partition overflow occurs manual ALTER TABLE REBUILD PARTITION is needed.
This commit is contained in:
@ -154,3 +154,15 @@ select * from t1;
|
|||||||
a
|
a
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
|
||||||
|
#
|
||||||
|
# Don't auto-create new partition on DELETE HISTORY:
|
||||||
|
create or replace table t (a int)
|
||||||
|
with system versioning
|
||||||
|
partition by system_time limit 1000;
|
||||||
|
delete history from t;
|
||||||
|
select count(*) - 1 as hist_partitions from information_schema.partitions where table_name = 't' and table_schema = 'test';
|
||||||
|
hist_partitions
|
||||||
|
1
|
||||||
|
drop table t;
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
call mtr.add_suppression("need more HISTORY partitions");
|
call mtr.add_suppression("need more HISTORY partitions");
|
||||||
|
call mtr.add_suppression("Duplicate partition name");
|
||||||
|
call mtr.add_suppression("Wrong partitioning type");
|
||||||
|
call mtr.add_suppression("Table 'test.t1' doesn't exist");
|
||||||
set system_versioning_alter_history=keep;
|
set system_versioning_alter_history=keep;
|
||||||
# Check conventional partitioning on temporal tables
|
# Check conventional partitioning on temporal tables
|
||||||
create or replace table t1 (
|
create or replace table t1 (
|
||||||
@ -237,7 +240,9 @@ select @ts0 = @ts1;
|
|||||||
select @ts2 = @ts3;
|
select @ts2 = @ts3;
|
||||||
@ts2 = @ts3
|
@ts2 = @ts3
|
||||||
1
|
1
|
||||||
## rotation by LIMIT
|
#
|
||||||
|
# Rotation by LIMIT
|
||||||
|
#
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
partition by system_time limit 0 partitions 3;
|
partition by system_time limit 0 partitions 3;
|
||||||
@ -289,7 +294,37 @@ x
|
|||||||
6
|
6
|
||||||
7
|
7
|
||||||
8
|
8
|
||||||
## rotation by INTERVAL
|
# Auto-create history partitions
|
||||||
|
create or replace table t1 (x int) with system versioning
|
||||||
|
partition by system_time limit 1000 auto_increment;
|
||||||
|
lock tables t1 write;
|
||||||
|
insert into t1 values (1);
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
select state, info from information_schema.processlist where info like 'ALTER TABLE %';
|
||||||
|
state info
|
||||||
|
Waiting for table metadata lock ALTER TABLE `test`.`t1` ADD PARTITION (PARTITION `p1` HISTORY)
|
||||||
|
unlock tables;
|
||||||
|
show create table t1;
|
||||||
|
Table Create Table
|
||||||
|
t1 CREATE TABLE `t1` (
|
||||||
|
`x` int(11) DEFAULT NULL
|
||||||
|
) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||||
|
PARTITION BY SYSTEM_TIME LIMIT 1000 AUTO_INCREMENT
|
||||||
|
(PARTITION `p0` HISTORY ENGINE = DEFAULT_ENGINE,
|
||||||
|
PARTITION `p1` HISTORY ENGINE = DEFAULT_ENGINE,
|
||||||
|
PARTITION `pn` CURRENT ENGINE = DEFAULT_ENGINE)
|
||||||
|
### Test ALTER failure
|
||||||
|
set @lock_wait_timeout0= @@global.lock_wait_timeout;
|
||||||
|
set global lock_wait_timeout= 1;
|
||||||
|
create or replace table t1 (x int) with system versioning partition by system_time limit 1000;
|
||||||
|
lock tables t1 write;
|
||||||
|
insert t1 values (1);
|
||||||
|
insert t1 values (1);
|
||||||
|
unlock tables;
|
||||||
|
set global lock_wait_timeout= @lock_wait_timeout0;
|
||||||
|
#
|
||||||
|
# Rotation by INTERVAL
|
||||||
|
#
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
partition by system_time interval 0 second partitions 3;
|
partition by system_time interval 0 second partitions 3;
|
||||||
@ -302,7 +337,7 @@ partition by system_time interval 10 year partitions 3;
|
|||||||
ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL'
|
ERROR 22003: TIMESTAMP value is out of range in 'INTERVAL'
|
||||||
# INTERVAL and ALTER TABLE
|
# INTERVAL and ALTER TABLE
|
||||||
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 hour;
|
partition by system_time interval 59 minute;
|
||||||
set @ts=(select partition_description from information_schema.partitions
|
set @ts=(select partition_description from information_schema.partitions
|
||||||
where table_schema='test' and table_name='t1' and partition_name='p0');
|
where table_schema='test' and table_name='t1' and partition_name='p0');
|
||||||
alter table t1 add column b int;
|
alter table t1 add column b int;
|
||||||
@ -316,16 +351,16 @@ alter table t1 add partition (partition p1 history, partition p2 history);
|
|||||||
select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
|
select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
|
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
|
||||||
p0 1 SYSTEM_TIME 00:00:00.000000
|
p0 1 SYSTEM_TIME 00:00:00.000000
|
||||||
p1 2 SYSTEM_TIME 01:00:00.000000
|
p1 2 SYSTEM_TIME 00:59:00.000000
|
||||||
p2 3 SYSTEM_TIME 02:00:00.000000
|
p2 3 SYSTEM_TIME 01:58:00.000000
|
||||||
pn 4 SYSTEM_TIME NULL
|
pn 4 SYSTEM_TIME NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect time value: 'CURRENT'
|
Warning 1292 Incorrect time value: 'CURRENT'
|
||||||
alter table t1 drop partition p0;
|
alter table t1 drop partition p0;
|
||||||
select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
|
select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
|
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
|
||||||
p1 1 SYSTEM_TIME 01:00:00.000000
|
p1 1 SYSTEM_TIME 00:59:00.000000
|
||||||
p2 2 SYSTEM_TIME 02:00:00.000000
|
p2 2 SYSTEM_TIME 01:58:00.000000
|
||||||
pn 3 SYSTEM_TIME NULL
|
pn 3 SYSTEM_TIME NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect time value: 'CURRENT'
|
Warning 1292 Incorrect time value: 'CURRENT'
|
||||||
@ -333,8 +368,8 @@ alter table t1 drop partition p2;
|
|||||||
ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL
|
ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL
|
||||||
select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
|
select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
|
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
|
||||||
p1 1 SYSTEM_TIME 01:00:00.000000
|
p1 1 SYSTEM_TIME 00:59:00.000000
|
||||||
p2 2 SYSTEM_TIME 02:00:00.000000
|
p2 2 SYSTEM_TIME 01:58:00.000000
|
||||||
pn 3 SYSTEM_TIME NULL
|
pn 3 SYSTEM_TIME NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1292 Incorrect time value: 'CURRENT'
|
Warning 1292 Incorrect time value: 'CURRENT'
|
||||||
@ -343,6 +378,7 @@ create or replace table t1 (i int) with system versioning
|
|||||||
partition by system_time interval 1 day
|
partition by system_time interval 1 day
|
||||||
subpartition by key (i) subpartitions 2
|
subpartition by key (i) subpartitions 2
|
||||||
(partition p1 history, partition pn current);
|
(partition p1 history, partition pn current);
|
||||||
|
lock tables t1 write;
|
||||||
set timestamp=unix_timestamp('2001-02-03 10:20:40');
|
set timestamp=unix_timestamp('2001-02-03 10:20:40');
|
||||||
insert t1 values (1);
|
insert t1 values (1);
|
||||||
delete from t1;
|
delete from t1;
|
||||||
@ -353,28 +389,51 @@ Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out o
|
|||||||
delete from t1;
|
delete from t1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
|
Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need 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 from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
subpartition_name partition_description table_rows
|
subpartition_name partition_description
|
||||||
p1sp0 2001-02-04 00:00:00 1
|
p1sp0 2001-02-04 00:00:00
|
||||||
p1sp1 2001-02-04 00:00:00 1
|
p1sp1 2001-02-04 00:00:00
|
||||||
pnsp0 CURRENT 0
|
pnsp0 CURRENT
|
||||||
pnsp1 CURRENT 0
|
pnsp1 CURRENT
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
i
|
||||||
|
1
|
||||||
|
2
|
||||||
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;
|
||||||
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
|
select subpartition_name, partition_description from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
subpartition_name partition_description table_rows
|
subpartition_name partition_description
|
||||||
p1sp0 2001-02-04 00:00:00 1
|
p1sp0 2001-02-04 00:00:00
|
||||||
p1sp1 2001-02-04 00:00:00 0
|
p1sp1 2001-02-04 00:00:00
|
||||||
p0sp0 2001-02-05 00:00:00 1
|
p0sp0 2001-02-05 00:00:00
|
||||||
p0sp1 2001-02-05 00:00:00 1
|
p0sp1 2001-02-05 00:00:00
|
||||||
p2sp0 2001-02-06 00:00:00 0
|
p2sp0 2001-02-06 00:00:00
|
||||||
p2sp1 2001-02-06 00:00:00 0
|
p2sp1 2001-02-06 00:00:00
|
||||||
pnsp0 CURRENT 0
|
pnsp0 CURRENT
|
||||||
pnsp1 CURRENT 2
|
pnsp1 CURRENT
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
i
|
||||||
|
1
|
||||||
|
2
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
i
|
||||||
|
5
|
||||||
|
select * from t1 partition (p2);
|
||||||
|
i
|
||||||
|
alter table t1 rebuild partition p0, p1, p2;
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
i
|
||||||
|
1
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
i
|
||||||
|
5
|
||||||
|
2
|
||||||
|
select * from t1 partition (p2);
|
||||||
|
i
|
||||||
## pruning check
|
## pruning check
|
||||||
set @ts=(select partition_description from information_schema.partitions
|
set @ts=(select partition_description from information_schema.partitions
|
||||||
where table_schema='test' and table_name='t1' and partition_name='p0' limit 1);
|
where table_schema='test' and table_name='t1' and partition_name='p0' limit 1);
|
||||||
@ -395,6 +454,7 @@ 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 # #
|
||||||
|
unlock tables;
|
||||||
## INTERVAL ... STARTS
|
## INTERVAL ... STARTS
|
||||||
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 starts 'a';
|
partition by system_time interval 1 day starts 'a';
|
||||||
@ -542,6 +602,9 @@ set timestamp= unix_timestamp('2001-01-01 00:00:00');
|
|||||||
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 starts '2000-01-01 00:00:00'
|
partition by system_time interval 1 day starts '2000-01-01 00:00:00'
|
||||||
partitions 3;
|
partitions 3;
|
||||||
|
lock tables t1 write;
|
||||||
|
Warnings:
|
||||||
|
Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of INTERVAL, need more HISTORY partitions
|
||||||
# we are warned when we push to present:
|
# we are warned when we push to present:
|
||||||
insert into t1 values (0);
|
insert into t1 values (0);
|
||||||
Warnings:
|
Warnings:
|
||||||
@ -584,11 +647,13 @@ i row_end
|
|||||||
select *, row_end from t1 partition (p1);
|
select *, row_end from t1 partition (p1);
|
||||||
i row_end
|
i row_end
|
||||||
3 2000-01-04 00:00:01.000000
|
3 2000-01-04 00:00:01.000000
|
||||||
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
unlock tables;
|
||||||
# and this is how it usually goes:
|
# and this is how it usually goes:
|
||||||
|
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
||||||
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
|
||||||
partitions 3;
|
partitions 3;
|
||||||
|
lock tables t1 write;
|
||||||
insert into t1 values (0);
|
insert into t1 values (0);
|
||||||
set timestamp= unix_timestamp('2000-01-01 00:00:01');
|
set timestamp= unix_timestamp('2000-01-01 00:00:01');
|
||||||
update t1 set i= i + 1;
|
update t1 set i= i + 1;
|
||||||
@ -609,12 +674,26 @@ i row_end
|
|||||||
select *, row_end from t1 partition (p1);
|
select *, row_end from t1 partition (p1);
|
||||||
i row_end
|
i row_end
|
||||||
1 2000-01-02 00:00:01.000000
|
1 2000-01-02 00:00:01.000000
|
||||||
|
2 2000-01-03 00:00:01.000000
|
||||||
|
3 2000-01-04 00:00:01.000000
|
||||||
|
select *, row_end from t1 partition (p2);
|
||||||
|
i row_end
|
||||||
|
select *, row_end from t1 partition (p3);
|
||||||
|
i row_end
|
||||||
|
alter table t1 rebuild partition p0, p1, p2, p3;
|
||||||
|
select *, row_end from t1 partition (p0);
|
||||||
|
i row_end
|
||||||
|
0 2000-01-01 00:00:01.000000
|
||||||
|
select *, row_end from t1 partition (p1);
|
||||||
|
i row_end
|
||||||
|
1 2000-01-02 00:00:01.000000
|
||||||
select *, row_end from t1 partition (p2);
|
select *, row_end from t1 partition (p2);
|
||||||
i row_end
|
i row_end
|
||||||
2 2000-01-03 00:00:01.000000
|
2 2000-01-03 00:00:01.000000
|
||||||
select *, row_end from t1 partition (p3);
|
select *, row_end from t1 partition (p3);
|
||||||
i row_end
|
i row_end
|
||||||
3 2000-01-04 00:00:01.000000
|
3 2000-01-04 00:00:01.000000
|
||||||
|
unlock tables;
|
||||||
drop tables t1, t2;
|
drop tables t1, t2;
|
||||||
## Subpartitions
|
## Subpartitions
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
@ -632,9 +711,9 @@ select * from t1 partition (pnsp1);
|
|||||||
x
|
x
|
||||||
2
|
2
|
||||||
4
|
4
|
||||||
### warn about full partition
|
|
||||||
delete from t1 where x < 3;
|
delete from t1 where x < 3;
|
||||||
delete from t1;
|
delete from t1;
|
||||||
|
### warn about full partition
|
||||||
delete from t1;
|
delete from t1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
|
Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out of LIMIT, need more HISTORY partitions
|
||||||
@ -845,7 +924,7 @@ ERROR HY000: Can not DROP SYSTEM VERSIONING for table `t` partitioned BY SYSTEM_
|
|||||||
create or replace table t1 (i int) with system versioning;
|
create or replace table t1 (i int) with system versioning;
|
||||||
insert into t1 values (1), (2);
|
insert into t1 values (1), (2);
|
||||||
update t1 set i= 3;
|
update t1 set i= 3;
|
||||||
alter table t1 partition by system_time interval 1 month (partition p1 history, partition pn current);
|
alter table t1 partition by system_time interval 59 minute (partition p1 history, partition pn current);
|
||||||
lock table t1 write;
|
lock table t1 write;
|
||||||
alter table t1 add partition (partition p2 history);
|
alter table t1 add partition (partition p2 history);
|
||||||
insert into t1 values (4);
|
insert into t1 values (4);
|
||||||
|
@ -164,4 +164,23 @@ update t1 set i = 0;
|
|||||||
connection slave;
|
connection slave;
|
||||||
connection master;
|
connection master;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
#
|
||||||
|
# MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
|
||||||
|
#
|
||||||
|
create or replace table t1 (x int) with system versioning
|
||||||
|
partition by system_time limit 1000 auto_increment;
|
||||||
|
lock tables t1 write;
|
||||||
|
insert t1 values ();
|
||||||
|
delete from t1;
|
||||||
|
unlock tables;
|
||||||
|
select count(*) - 1 as hist_partitions from information_schema.partitions where table_name = 't1' and table_schema = 'test';
|
||||||
|
hist_partitions
|
||||||
|
2
|
||||||
|
connection slave;
|
||||||
|
select count(*) - 1 as hist_partitions from information_schema.partitions where table_name = 't1' and table_schema = 'test';
|
||||||
|
hist_partitions
|
||||||
|
2
|
||||||
|
connection master;
|
||||||
|
drop database test;
|
||||||
|
create database test;
|
||||||
include/rpl_end.inc
|
include/rpl_end.inc
|
||||||
|
@ -169,4 +169,15 @@ insert into t1 values (1);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
|
||||||
|
--echo #
|
||||||
|
--echo # Don't auto-create new partition on DELETE HISTORY:
|
||||||
|
create or replace table t (a int)
|
||||||
|
with system versioning
|
||||||
|
partition by system_time limit 1000;
|
||||||
|
delete history from t;
|
||||||
|
select count(*) - 1 as hist_partitions from information_schema.partitions where table_name = 't' and table_schema = 'test';
|
||||||
|
drop table t;
|
||||||
|
|
||||||
--source suite/versioning/common_finish.inc
|
--source suite/versioning/common_finish.inc
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
-- source suite/versioning/engines.inc
|
-- source suite/versioning/engines.inc
|
||||||
|
|
||||||
call mtr.add_suppression("need more HISTORY partitions");
|
call mtr.add_suppression("need more HISTORY partitions");
|
||||||
|
call mtr.add_suppression("Duplicate partition name");
|
||||||
|
call mtr.add_suppression("Wrong partitioning type");
|
||||||
|
call mtr.add_suppression("Table 'test.t1' doesn't exist");
|
||||||
|
let $wait_no_alter= select count(*) = 0 from information_schema.processlist where info like 'ALTER TABLE %';
|
||||||
|
let $wait_alter= select count(*) > 0 from information_schema.processlist where info like 'ALTER TABLE %';
|
||||||
|
|
||||||
set system_versioning_alter_history=keep;
|
set system_versioning_alter_history=keep;
|
||||||
--echo # Check conventional partitioning on temporal tables
|
--echo # Check conventional partitioning on temporal tables
|
||||||
@ -213,7 +218,9 @@ prepare stmt from @str; execute stmt; drop prepare stmt;
|
|||||||
select @ts0 = @ts1;
|
select @ts0 = @ts1;
|
||||||
select @ts2 = @ts3;
|
select @ts2 = @ts3;
|
||||||
|
|
||||||
--echo ## rotation by LIMIT
|
--echo #
|
||||||
|
--echo # Rotation by LIMIT
|
||||||
|
--echo #
|
||||||
--error ER_PART_WRONG_VALUE
|
--error ER_PART_WRONG_VALUE
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
@ -241,8 +248,37 @@ insert into t1 values (7), (8);
|
|||||||
delete from t1;
|
delete from t1;
|
||||||
select * from t1 partition (p1) order by x;
|
select * from t1 partition (p1) order by x;
|
||||||
|
|
||||||
|
--echo # Auto-create history partitions
|
||||||
|
create or replace table t1 (x int) with system versioning
|
||||||
|
partition by system_time limit 1000 auto_increment;
|
||||||
|
lock tables t1 write;
|
||||||
|
insert into t1 values (1);
|
||||||
|
update t1 set x= x + 1;
|
||||||
|
--let $wait_condition= $wait_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
select state, info from information_schema.processlist where info like 'ALTER TABLE %';
|
||||||
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
--replace_result $default_engine DEFAULT_ENGINE
|
||||||
|
show create table t1;
|
||||||
|
|
||||||
--echo ## rotation by INTERVAL
|
--echo ### Test ALTER failure
|
||||||
|
set @lock_wait_timeout0= @@global.lock_wait_timeout;
|
||||||
|
set global lock_wait_timeout= 1;
|
||||||
|
create or replace table t1 (x int) with system versioning partition by system_time limit 1000;
|
||||||
|
lock tables t1 write;
|
||||||
|
insert t1 values (1);
|
||||||
|
--real_sleep 1
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
insert t1 values (1);
|
||||||
|
unlock tables;
|
||||||
|
set global lock_wait_timeout= @lock_wait_timeout0;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Rotation by INTERVAL
|
||||||
|
--echo #
|
||||||
--error ER_PART_WRONG_VALUE
|
--error ER_PART_WRONG_VALUE
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
@ -258,7 +294,7 @@ partition by system_time interval 10 year partitions 3;
|
|||||||
|
|
||||||
--echo # INTERVAL and ALTER TABLE
|
--echo # INTERVAL and ALTER TABLE
|
||||||
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 hour;
|
partition by system_time interval 59 minute;
|
||||||
|
|
||||||
set @ts=(select partition_description from information_schema.partitions
|
set @ts=(select partition_description from information_schema.partitions
|
||||||
where table_schema='test' and table_name='t1' and partition_name='p0');
|
where table_schema='test' and table_name='t1' and partition_name='p0');
|
||||||
@ -281,12 +317,15 @@ create or replace table t1 (i int) with system versioning
|
|||||||
partition by system_time interval 1 day
|
partition by system_time interval 1 day
|
||||||
subpartition by key (i) subpartitions 2
|
subpartition by key (i) subpartitions 2
|
||||||
(partition p1 history, partition pn current);
|
(partition p1 history, partition pn current);
|
||||||
|
lock tables t1 write; # prevent partition auto-creation
|
||||||
|
|
||||||
set timestamp=unix_timestamp('2001-02-03 10:20:40');
|
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;
|
||||||
|
|
||||||
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
|
select subpartition_name, partition_description from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
|
||||||
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);
|
||||||
@ -295,7 +334,15 @@ 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;
|
||||||
|
|
||||||
select subpartition_name,partition_description,table_rows from information_schema.partitions where table_schema='test' and table_name='t1';
|
select subpartition_name, partition_description from information_schema.partitions where table_schema='test' and table_name='t1';
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
select * from t1 partition (p2);
|
||||||
|
|
||||||
|
alter table t1 rebuild partition p0, p1, p2;
|
||||||
|
select * from t1 partition (p1);
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
select * from t1 partition (p2);
|
||||||
|
|
||||||
--echo ## pruning check
|
--echo ## pruning check
|
||||||
set @ts=(select partition_description from information_schema.partitions
|
set @ts=(select partition_description from information_schema.partitions
|
||||||
@ -310,6 +357,9 @@ set @ts=(select row_end from t1 for system_time all where i=1);
|
|||||||
select * from t1 for system_time all where row_end = @ts;
|
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;
|
||||||
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
--echo ## INTERVAL ... STARTS
|
--echo ## INTERVAL ... STARTS
|
||||||
--error ER_PART_WRONG_VALUE
|
--error ER_PART_WRONG_VALUE
|
||||||
@ -406,6 +456,7 @@ set timestamp= unix_timestamp('2001-01-01 00:00:00');
|
|||||||
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 starts '2000-01-01 00:00:00'
|
partition by system_time interval 1 day starts '2000-01-01 00:00:00'
|
||||||
partitions 3;
|
partitions 3;
|
||||||
|
lock tables t1 write; # prevent partition auto-creation
|
||||||
|
|
||||||
--echo # we are warned when we push to present:
|
--echo # we are warned when we push to present:
|
||||||
insert into t1 values (0);
|
insert into t1 values (0);
|
||||||
@ -436,11 +487,16 @@ update t1 set i= i + 1;
|
|||||||
select *, row_end from t1 partition (p0);
|
select *, row_end from t1 partition (p0);
|
||||||
select *, row_end from t1 partition (p1);
|
select *, row_end from t1 partition (p1);
|
||||||
|
|
||||||
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
--echo # and this is how it usually goes:
|
--echo # and this is how it usually goes:
|
||||||
|
set timestamp= unix_timestamp('2000-01-01 00:00:00');
|
||||||
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
|
||||||
partitions 3;
|
partitions 3;
|
||||||
|
lock tables t1 write; # prevent partition auto-creation
|
||||||
|
|
||||||
insert into t1 values (0);
|
insert into t1 values (0);
|
||||||
set timestamp= unix_timestamp('2000-01-01 00:00:01');
|
set timestamp= unix_timestamp('2000-01-01 00:00:01');
|
||||||
@ -453,12 +509,20 @@ set timestamp= unix_timestamp('2000-01-04 00:00:01');
|
|||||||
update t1 set i= i + 1;
|
update t1 set i= i + 1;
|
||||||
|
|
||||||
alter table t1 add partition (partition p2 history, partition p3 history);
|
alter table t1 add partition (partition p2 history, partition p3 history);
|
||||||
|
|
||||||
select *, row_end from t1 partition (p0);
|
select *, row_end from t1 partition (p0);
|
||||||
select *, row_end from t1 partition (p1);
|
select *, row_end from t1 partition (p1);
|
||||||
select *, row_end from t1 partition (p2);
|
select *, row_end from t1 partition (p2);
|
||||||
select *, row_end from t1 partition (p3);
|
select *, row_end from t1 partition (p3);
|
||||||
|
|
||||||
|
alter table t1 rebuild partition p0, p1, p2, p3;
|
||||||
|
select *, row_end from t1 partition (p0);
|
||||||
|
select *, row_end from t1 partition (p1);
|
||||||
|
select *, row_end from t1 partition (p2);
|
||||||
|
select *, row_end from t1 partition (p3);
|
||||||
|
|
||||||
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
drop tables t1, t2;
|
drop tables t1, t2;
|
||||||
|
|
||||||
--echo ## Subpartitions
|
--echo ## Subpartitions
|
||||||
@ -472,9 +536,9 @@ insert into t1 (x) values (1), (2), (3), (4), (5);
|
|||||||
select * from t1 partition (pnsp0);
|
select * from t1 partition (pnsp0);
|
||||||
select * from t1 partition (pnsp1);
|
select * from t1 partition (pnsp1);
|
||||||
|
|
||||||
--echo ### warn about full partition
|
|
||||||
delete from t1 where x < 3;
|
delete from t1 where x < 3;
|
||||||
delete from t1;
|
delete from t1;
|
||||||
|
--echo ### warn about full partition
|
||||||
delete from t1;
|
delete from t1;
|
||||||
select * from t1 partition (p0sp0);
|
select * from t1 partition (p0sp0);
|
||||||
select * from t1 partition (p0sp1);
|
select * from t1 partition (p0sp1);
|
||||||
@ -627,6 +691,8 @@ alter table t1 partition by system_time interval 1 week (
|
|||||||
partition p1 history,
|
partition p1 history,
|
||||||
partition pn current);
|
partition pn current);
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-14748 Assertion in ha_myisammrg::attach_children()
|
--echo # MDEV-14748 Assertion in ha_myisammrg::attach_children()
|
||||||
@ -663,6 +729,8 @@ lock table t1 write;
|
|||||||
alter table t1 add partition (partition p0 history);
|
alter table t1 add partition (partition p0 history);
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW
|
--echo # MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW
|
||||||
@ -687,11 +755,13 @@ alter table t drop system versioning;
|
|||||||
create or replace table t1 (i int) with system versioning;
|
create or replace table t1 (i int) with system versioning;
|
||||||
insert into t1 values (1), (2);
|
insert into t1 values (1), (2);
|
||||||
update t1 set i= 3;
|
update t1 set i= 3;
|
||||||
alter table t1 partition by system_time interval 1 month (partition p1 history, partition pn current);
|
alter table t1 partition by system_time interval 59 minute (partition p1 history, partition pn current);
|
||||||
lock table t1 write;
|
lock table t1 write;
|
||||||
alter table t1 add partition (partition p2 history);
|
alter table t1 add partition (partition p2 history);
|
||||||
insert into t1 values (4);
|
insert into t1 values (4);
|
||||||
unlock tables;
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-15036 Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' in Diagnostics_area::set_ok_status or unexpected ER_RANGE_NOT_INCREASING_ERROR
|
--echo # MDEV-15036 Assertion `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' in Diagnostics_area::set_ok_status or unexpected ER_RANGE_NOT_INCREASING_ERROR
|
||||||
|
@ -133,4 +133,28 @@ sync_slave_with_master;
|
|||||||
connection master;
|
connection master;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-17554 Auto-create new partition for system versioned tables with history partitioned by INTERVAL/LIMIT
|
||||||
|
--echo #
|
||||||
|
let $wait_no_alter= select count(*) = 0 from information_schema.processlist where info like 'ALTER TABLE %';
|
||||||
|
let $wait_alter= select count(*) > 0 from information_schema.processlist where info like 'ALTER TABLE %';
|
||||||
|
|
||||||
|
create or replace table t1 (x int) with system versioning
|
||||||
|
partition by system_time limit 1000 auto_increment;
|
||||||
|
lock tables t1 write;
|
||||||
|
insert t1 values ();
|
||||||
|
delete from t1;
|
||||||
|
--let $wait_condition= $wait_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
unlock tables;
|
||||||
|
--let $wait_condition= $wait_no_alter
|
||||||
|
--source include/wait_condition.inc
|
||||||
|
select count(*) - 1 as hist_partitions from information_schema.partitions where table_name = 't1' and table_schema = 'test';
|
||||||
|
--sync_slave_with_master
|
||||||
|
select count(*) - 1 as hist_partitions from information_schema.partitions where table_name = 't1' and table_schema = 'test';
|
||||||
|
--connection master
|
||||||
|
|
||||||
|
drop database test;
|
||||||
|
create database test;
|
||||||
|
|
||||||
--source include/rpl_end.inc
|
--source include/rpl_end.inc
|
||||||
|
@ -1090,7 +1090,7 @@ static PSI_cond_info all_server_conds[]=
|
|||||||
PSI_thread_key key_thread_delayed_insert,
|
PSI_thread_key key_thread_delayed_insert,
|
||||||
key_thread_handle_manager, key_thread_main,
|
key_thread_handle_manager, key_thread_main,
|
||||||
key_thread_one_connection, key_thread_signal_hand,
|
key_thread_one_connection, key_thread_signal_hand,
|
||||||
key_thread_slave_background, key_rpl_parallel_thread;
|
key_thread_slave_background, key_rpl_parallel_thread, key_thread_query;
|
||||||
PSI_thread_key key_thread_ack_receiver;
|
PSI_thread_key key_thread_ack_receiver;
|
||||||
|
|
||||||
static PSI_thread_info all_server_threads[]=
|
static PSI_thread_info all_server_threads[]=
|
||||||
@ -1102,7 +1102,8 @@ static PSI_thread_info all_server_threads[]=
|
|||||||
{ &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
|
{ &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
|
||||||
{ &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL},
|
{ &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL},
|
||||||
{ &key_thread_ack_receiver, "Ack_receiver", PSI_FLAG_GLOBAL},
|
{ &key_thread_ack_receiver, "Ack_receiver", PSI_FLAG_GLOBAL},
|
||||||
{ &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
|
{ &key_rpl_parallel_thread, "rpl_parallel_thread", 0},
|
||||||
|
{ &key_thread_query, "vers_add_hist_part_thread", 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
|
@ -388,7 +388,7 @@ extern PSI_cond_key key_TABLE_SHARE_COND_rotation;
|
|||||||
extern PSI_thread_key key_thread_delayed_insert,
|
extern PSI_thread_key key_thread_delayed_insert,
|
||||||
key_thread_handle_manager, key_thread_kill_server, key_thread_main,
|
key_thread_handle_manager, key_thread_kill_server, key_thread_main,
|
||||||
key_thread_one_connection, key_thread_signal_hand,
|
key_thread_one_connection, key_thread_signal_hand,
|
||||||
key_thread_slave_background, key_rpl_parallel_thread;
|
key_thread_slave_background, key_rpl_parallel_thread, key_thread_query;
|
||||||
|
|
||||||
extern PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest,
|
extern PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest,
|
||||||
key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
|
key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
|
||||||
|
@ -322,13 +322,11 @@ bool partition_info::set_partition_bitmaps_from_table(TABLE_LIST *table_list)
|
|||||||
The external routine needing this code is check_partition_info
|
The external routine needing this code is check_partition_info
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MAX_PART_NAME_SIZE 8
|
|
||||||
|
|
||||||
char *partition_info::create_default_partition_names(THD *thd, uint part_no,
|
char *partition_info::create_default_partition_names(THD *thd, uint part_no,
|
||||||
uint num_parts_arg,
|
uint num_parts_arg,
|
||||||
uint start_no)
|
uint start_no)
|
||||||
{
|
{
|
||||||
char *ptr= (char*) thd->calloc(num_parts_arg * MAX_PART_NAME_SIZE);
|
char *ptr= (char*) thd->calloc(num_parts_arg * MAX_PART_NAME_SIZE + 1);
|
||||||
char *move_ptr= ptr;
|
char *move_ptr= ptr;
|
||||||
uint i= 0;
|
uint i= 0;
|
||||||
DBUG_ENTER("create_default_partition_names");
|
DBUG_ENTER("create_default_partition_names");
|
||||||
@ -337,7 +335,8 @@ char *partition_info::create_default_partition_names(THD *thd, uint part_no,
|
|||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
sprintf(move_ptr, "p%u", (start_no + i));
|
if (make_partition_name(move_ptr, (start_no + i)))
|
||||||
|
DBUG_RETURN(NULL);
|
||||||
move_ptr+= MAX_PART_NAME_SIZE;
|
move_ptr+= MAX_PART_NAME_SIZE;
|
||||||
} while (++i < num_parts_arg);
|
} while (++i < num_parts_arg);
|
||||||
}
|
}
|
||||||
@ -808,6 +807,13 @@ bool partition_info::has_unique_name(partition_element *element)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Auto-create history partition configuration */
|
||||||
|
static const uint VERS_MIN_EMPTY= 1;
|
||||||
|
static const uint VERS_MIN_INTERVAL= 3600; // seconds
|
||||||
|
static const uint VERS_MIN_LIMIT= 1000;
|
||||||
|
static const uint VERS_ERROR_TIMEOUT= 300; // seconds
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Switch history partition according limit or interval
|
@brief Switch history partition according limit or interval
|
||||||
|
|
||||||
@ -845,29 +851,265 @@ void partition_info::vers_set_hist_part(THD *thd)
|
|||||||
else
|
else
|
||||||
vers_info->hist_part= next;
|
vers_info->hist_part= next;
|
||||||
}
|
}
|
||||||
|
if (vers_info->limit >= VERS_MIN_LIMIT)
|
||||||
|
goto add_hist_part;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vers_info->interval.is_set())
|
if (vers_info->interval.is_set())
|
||||||
{
|
{
|
||||||
if (vers_info->hist_part->range_value > thd->query_start())
|
if (vers_info->hist_part->range_value <= thd->query_start())
|
||||||
return;
|
|
||||||
|
|
||||||
partition_element *next= NULL;
|
|
||||||
List_iterator<partition_element> it(partitions);
|
|
||||||
while (next != vers_info->hist_part)
|
|
||||||
next= it++;
|
|
||||||
|
|
||||||
while ((next= it++) != vers_info->now_part)
|
|
||||||
{
|
{
|
||||||
vers_info->hist_part= next;
|
partition_element *next= NULL;
|
||||||
if (next->range_value > thd->query_start())
|
bool error= true;
|
||||||
return;
|
List_iterator<partition_element> it(partitions);
|
||||||
|
while (next != vers_info->hist_part)
|
||||||
|
next= it++;
|
||||||
|
|
||||||
|
while ((next= it++) != vers_info->now_part)
|
||||||
|
{
|
||||||
|
vers_info->hist_part= next;
|
||||||
|
if (next->range_value > thd->query_start())
|
||||||
|
{
|
||||||
|
error= false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (error)
|
||||||
|
my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
|
||||||
|
table->s->db.str, table->s->table_name.str,
|
||||||
|
vers_info->hist_part->partition_name, "INTERVAL");
|
||||||
}
|
}
|
||||||
my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
|
if (vers_info->interval.ge(VERS_MIN_INTERVAL))
|
||||||
table->s->db.str, table->s->table_name.str,
|
goto add_hist_part;
|
||||||
vers_info->hist_part->partition_name, "INTERVAL");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
add_hist_part:
|
||||||
|
if (!vers_info->auto_inc)
|
||||||
|
return;
|
||||||
|
switch (thd->lex->sql_command)
|
||||||
|
{
|
||||||
|
case SQLCOM_DELETE:
|
||||||
|
if (thd->lex->last_table()->vers_conditions.type == SYSTEM_TIME_HISTORY)
|
||||||
|
break;
|
||||||
|
case SQLCOM_UPDATE:
|
||||||
|
case SQLCOM_INSERT:
|
||||||
|
case SQLCOM_INSERT_SELECT:
|
||||||
|
case SQLCOM_LOAD:
|
||||||
|
case SQLCOM_REPLACE:
|
||||||
|
case SQLCOM_REPLACE_SELECT:
|
||||||
|
case SQLCOM_DELETE_MULTI:
|
||||||
|
case SQLCOM_UPDATE_MULTI:
|
||||||
|
{
|
||||||
|
time_t &timeout= table->s->vers_hist_part_timeout;
|
||||||
|
if (!thd->slave_thread &&
|
||||||
|
vers_info->hist_part->id + VERS_MIN_EMPTY == vers_info->now_part->id)
|
||||||
|
{
|
||||||
|
if (!timeout || timeout < thd->query_start())
|
||||||
|
vers_add_hist_part(thd);
|
||||||
|
else if (table->s->vers_hist_part_error)
|
||||||
|
{
|
||||||
|
my_error(WARN_VERS_HIST_PART_ERROR, MYF(ME_WARNING),
|
||||||
|
table->s->db.str, table->s->table_name.str,
|
||||||
|
table->s->vers_hist_part_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct vers_add_hist_part_data
|
||||||
|
{
|
||||||
|
LEX_STRING query;
|
||||||
|
LEX_CSTRING db;
|
||||||
|
LEX_CSTRING table_name;
|
||||||
|
LEX_STRING part_name;
|
||||||
|
my_time_t start_time;
|
||||||
|
ulong start_time_sec_part;
|
||||||
|
|
||||||
|
TABLE_SHARE *s;
|
||||||
|
|
||||||
|
void assign(THD *thd, String &q, TABLE *table, LEX_CSTRING p)
|
||||||
|
{
|
||||||
|
start_time= thd->start_time;
|
||||||
|
start_time_sec_part= thd->start_time_sec_part;
|
||||||
|
s= table->s;
|
||||||
|
|
||||||
|
memcpy(query.str, q.c_ptr_quick(), q.length());
|
||||||
|
query.str[q.length()]= 0;
|
||||||
|
query.length= q.length();
|
||||||
|
|
||||||
|
db.length= table->s->db.length;
|
||||||
|
memcpy((char *)db.str, table->s->db.str, db.length);
|
||||||
|
((char *)db.str)[db.length]= 0;
|
||||||
|
|
||||||
|
table_name.length= table->s->table_name.length;
|
||||||
|
memcpy((char *)table_name.str, table->s->table_name.str, table_name.length);
|
||||||
|
((char *)table_name.str)[table_name.length]= 0;
|
||||||
|
|
||||||
|
memcpy(part_name.str, p.str, p.length + 1);
|
||||||
|
part_name.length= p.length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pthread_handler_t vers_add_hist_part_thread(void *arg)
|
||||||
|
{
|
||||||
|
Parser_state parser_state;
|
||||||
|
uint error;
|
||||||
|
DBUG_ASSERT(arg);
|
||||||
|
vers_add_hist_part_data &d= *(vers_add_hist_part_data *) arg;
|
||||||
|
sql_print_information("Adding history partition `%s` for table `%s`.`%s`",
|
||||||
|
d.part_name.str,
|
||||||
|
d.db.str,
|
||||||
|
d.table_name.str);
|
||||||
|
my_thread_init();
|
||||||
|
/* Initialize THD */
|
||||||
|
THD *thd= new THD(next_thread_id());
|
||||||
|
if (unlikely(!thd))
|
||||||
|
{
|
||||||
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_ERROR_LOG));
|
||||||
|
goto err1;
|
||||||
|
}
|
||||||
|
thd->thread_stack= (char*) &thd;
|
||||||
|
thd->store_globals();
|
||||||
|
thd->set_command(COM_DAEMON);
|
||||||
|
thd->system_thread= SYSTEM_THREAD_GENERIC;
|
||||||
|
thd->security_ctx->host_or_ip= "";
|
||||||
|
thd->security_ctx->master_access= ALTER_ACL;
|
||||||
|
thd->log_all_errors= true;
|
||||||
|
thd->start_time= d.start_time;
|
||||||
|
thd->start_time_sec_part= d.start_time_sec_part;
|
||||||
|
server_threads.insert(thd);
|
||||||
|
thd_proc_info(thd, "Add history partition");
|
||||||
|
/* Initialize parser */
|
||||||
|
lex_start(thd);
|
||||||
|
if (unlikely(parser_state.init(thd, d.query.str, d.query.length)))
|
||||||
|
{
|
||||||
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_ERROR_LOG));
|
||||||
|
lex_end(thd->lex);
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
if (unlikely(parse_sql(thd, &parser_state, NULL)))
|
||||||
|
{
|
||||||
|
lex_end(thd->lex);
|
||||||
|
goto err2;
|
||||||
|
}
|
||||||
|
thd->set_query_and_id(d.query.str, (uint32)d.query.length, thd->charset(), next_query_id());
|
||||||
|
MYSQL_QUERY_EXEC_START(thd->query(), thd->thread_id, "", "", "", 0);
|
||||||
|
error= (uint) mysql_execute_command(thd);
|
||||||
|
MYSQL_QUERY_EXEC_DONE(error);
|
||||||
|
if (unlikely(error) && thd->is_error())
|
||||||
|
{
|
||||||
|
error= thd->get_stmt_da()->get_sql_errno();
|
||||||
|
thd->clear_error();
|
||||||
|
TABLE_LIST table_list;
|
||||||
|
table_list.init_one_table(&d.db, &d.table_name, &d.table_name, TL_UNLOCK);
|
||||||
|
TABLE_SHARE *s= tdc_acquire_share(thd, &table_list, GTS_TABLE);
|
||||||
|
if (s == d.s)
|
||||||
|
{
|
||||||
|
/* Timeout new ALTER for 5 minutes in case of error */
|
||||||
|
s->vers_hist_part_timeout= thd->query_start() + VERS_ERROR_TIMEOUT;
|
||||||
|
s->vers_hist_part_error= error;
|
||||||
|
s->vers_altering= false;
|
||||||
|
}
|
||||||
|
if (s)
|
||||||
|
tdc_release_share(s);
|
||||||
|
}
|
||||||
|
/* In case of success ALTER invalidates TABLE_SHARE */
|
||||||
|
thd->end_statement();
|
||||||
|
thd->cleanup_after_query();
|
||||||
|
err2:
|
||||||
|
server_threads.erase(thd);
|
||||||
|
delete thd;
|
||||||
|
err1:
|
||||||
|
my_free(arg);
|
||||||
|
my_thread_end();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void partition_info::vers_add_hist_part(THD *thd)
|
||||||
|
{
|
||||||
|
pthread_t hThread;
|
||||||
|
int error;
|
||||||
|
char part_name[MAX_PART_NAME_SIZE + 1];
|
||||||
|
|
||||||
|
/* Prevent spawning multiple instances of same task */
|
||||||
|
bool altering;
|
||||||
|
mysql_mutex_lock(&table->s->LOCK_share);
|
||||||
|
altering= table->s->vers_altering;
|
||||||
|
if (!altering)
|
||||||
|
table->s->vers_altering= true;
|
||||||
|
mysql_mutex_unlock(&table->s->LOCK_share);
|
||||||
|
if (altering)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Choose first non-occupied name suffix starting from id + 1 */
|
||||||
|
uint32 suffix= vers_info->hist_part->id + 1;
|
||||||
|
if (make_partition_name(part_name, suffix))
|
||||||
|
{
|
||||||
|
sql_print_warning("vers_add_hist_part name generation failed for suffix %d",
|
||||||
|
suffix);
|
||||||
|
my_error(WARN_VERS_HIST_PART_ERROR, MYF(ME_WARNING),
|
||||||
|
table->s->db.str, table->s->table_name.str, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List_iterator_fast<partition_element> it(partitions);
|
||||||
|
partition_element *el;
|
||||||
|
|
||||||
|
while ((el= it++))
|
||||||
|
{
|
||||||
|
if (0 == my_strcasecmp(&my_charset_latin1, el->partition_name, part_name))
|
||||||
|
{
|
||||||
|
if (make_partition_name(part_name, ++suffix))
|
||||||
|
{
|
||||||
|
sql_print_warning("vers_add_hist_part name generation failed for suffix %d",
|
||||||
|
suffix);
|
||||||
|
my_error(WARN_VERS_HIST_PART_ERROR, MYF(ME_WARNING),
|
||||||
|
table->s->db.str, table->s->table_name.str, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
it.rewind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String q(STRING_WITH_LEN("ALTER TABLE `"), &my_charset_latin1);
|
||||||
|
if (q.append(table->s->db) ||
|
||||||
|
q.append(STRING_WITH_LEN("`.`")) ||
|
||||||
|
q.append(table->s->table_name) ||
|
||||||
|
q.append("` ADD PARTITION (PARTITION `") ||
|
||||||
|
q.append(part_name) ||
|
||||||
|
q.append("` HISTORY)"))
|
||||||
|
{
|
||||||
|
my_error(ER_OUT_OF_RESOURCES, MYF(ME_ERROR_LOG));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vers_add_hist_part_data *data;
|
||||||
|
vers_add_hist_part_data bufs;
|
||||||
|
LEX_CSTRING part_name2;
|
||||||
|
part_name2.str= part_name;
|
||||||
|
part_name2.length= strlen(part_name);
|
||||||
|
if (!my_multi_malloc(MYF(MY_WME|ME_ERROR_LOG), &data, sizeof(*data),
|
||||||
|
&bufs.query.str, q.length() + 1,
|
||||||
|
&bufs.db.str, table->s->db.length + 1,
|
||||||
|
&bufs.table_name.str, table->s->table_name.length + 1,
|
||||||
|
&bufs.part_name.str, part_name2.length + 1,
|
||||||
|
NULL))
|
||||||
|
return;
|
||||||
|
bufs.assign(thd, q, table, part_name2);
|
||||||
|
*data= bufs;
|
||||||
|
|
||||||
|
if ((error= mysql_thread_create(key_thread_query, &hThread,
|
||||||
|
&connection_attrib, vers_add_hist_part_thread, data)))
|
||||||
|
{
|
||||||
|
sql_print_warning("Can't create vers_add_hist_part thread (errno= %d)",
|
||||||
|
error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2646,13 +2888,14 @@ bool partition_info::vers_init_info(THD * thd)
|
|||||||
|
|
||||||
bool partition_info::vers_set_interval(THD* thd, Item* interval,
|
bool partition_info::vers_set_interval(THD* thd, Item* interval,
|
||||||
interval_type int_type, Item* starts,
|
interval_type int_type, Item* starts,
|
||||||
const char *table_name)
|
bool auto_inc, const char *table_name)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
||||||
|
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
uint err;
|
uint err;
|
||||||
vers_info->interval.type= int_type;
|
vers_info->interval.type= int_type;
|
||||||
|
vers_info->auto_inc= auto_inc;
|
||||||
|
|
||||||
/* 1. assign INTERVAL to interval.step */
|
/* 1. assign INTERVAL to interval.step */
|
||||||
if (interval->fix_fields_if_needed_for_scalar(thd, &interval))
|
if (interval->fix_fields_if_needed_for_scalar(thd, &interval))
|
||||||
|
@ -38,6 +38,7 @@ struct Vers_part_info : public Sql_alloc
|
|||||||
{
|
{
|
||||||
Vers_part_info() :
|
Vers_part_info() :
|
||||||
limit(0),
|
limit(0),
|
||||||
|
auto_inc(false),
|
||||||
now_part(NULL),
|
now_part(NULL),
|
||||||
hist_part(NULL)
|
hist_part(NULL)
|
||||||
{
|
{
|
||||||
@ -46,6 +47,7 @@ struct Vers_part_info : public Sql_alloc
|
|||||||
Vers_part_info(Vers_part_info &src) :
|
Vers_part_info(Vers_part_info &src) :
|
||||||
interval(src.interval),
|
interval(src.interval),
|
||||||
limit(src.limit),
|
limit(src.limit),
|
||||||
|
auto_inc(src.auto_inc),
|
||||||
now_part(NULL),
|
now_part(NULL),
|
||||||
hist_part(NULL)
|
hist_part(NULL)
|
||||||
{
|
{
|
||||||
@ -69,9 +71,30 @@ struct Vers_part_info : public Sql_alloc
|
|||||||
my_time_t start;
|
my_time_t start;
|
||||||
INTERVAL step;
|
INTERVAL step;
|
||||||
enum interval_type type;
|
enum interval_type type;
|
||||||
bool is_set() { return type < INTERVAL_LAST; }
|
bool is_set() const { return type < INTERVAL_LAST; }
|
||||||
|
bool lt(size_t seconds) const
|
||||||
|
{
|
||||||
|
if (step.second)
|
||||||
|
return step.second < seconds;
|
||||||
|
if (step.minute)
|
||||||
|
return step.minute * 60 < seconds;
|
||||||
|
if (step.hour)
|
||||||
|
return step.hour * 3600 < seconds;
|
||||||
|
if (step.day)
|
||||||
|
return step.day * 3600 * 24 < seconds;
|
||||||
|
// comparison is used in rough estimates, it doesn't need to be calendar-correct
|
||||||
|
if (step.month)
|
||||||
|
return step.month * 3600 * 24 * 30 < seconds;
|
||||||
|
DBUG_ASSERT(step.year);
|
||||||
|
return step.year * 86400 * 30 * 365 < seconds;
|
||||||
|
}
|
||||||
|
bool ge(size_t seconds) const
|
||||||
|
{
|
||||||
|
return !(this->lt(seconds));
|
||||||
|
}
|
||||||
} interval;
|
} interval;
|
||||||
ulonglong limit;
|
ulonglong limit;
|
||||||
|
bool auto_inc;
|
||||||
partition_element *now_part;
|
partition_element *now_part;
|
||||||
partition_element *hist_part;
|
partition_element *hist_part;
|
||||||
};
|
};
|
||||||
@ -394,14 +417,16 @@ public:
|
|||||||
bool vers_init_info(THD *thd);
|
bool vers_init_info(THD *thd);
|
||||||
bool vers_set_interval(THD *thd, Item *interval,
|
bool vers_set_interval(THD *thd, Item *interval,
|
||||||
interval_type int_type, Item *starts,
|
interval_type int_type, Item *starts,
|
||||||
const char *table_name);
|
bool auto_inc, const char *table_name);
|
||||||
bool vers_set_limit(ulonglong limit)
|
bool vers_set_limit(ulonglong limit, bool auto_inc)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
||||||
vers_info->limit= limit;
|
vers_info->limit= limit;
|
||||||
|
vers_info->auto_inc= auto_inc;
|
||||||
return !limit;
|
return !limit;
|
||||||
}
|
}
|
||||||
void vers_set_hist_part(THD *thd);
|
void vers_set_hist_part(THD *thd);
|
||||||
|
void vers_add_hist_part(THD *thd);
|
||||||
bool vers_fix_field_list(THD *thd);
|
bool vers_fix_field_list(THD *thd);
|
||||||
void vers_update_el_ids();
|
void vers_update_el_ids();
|
||||||
partition_element *get_partition(uint part_id)
|
partition_element *get_partition(uint part_id)
|
||||||
@ -500,4 +525,14 @@ void partition_info::vers_update_el_ids()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_PART_NAME_SIZE 8
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool make_partition_name(char *move_ptr, uint i)
|
||||||
|
{
|
||||||
|
int res= snprintf(move_ptr, MAX_PART_NAME_SIZE + 1, "p%u", i);
|
||||||
|
return res < 0 || res > MAX_PART_NAME_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* PARTITION_INFO_INCLUDED */
|
#endif /* PARTITION_INFO_INCLUDED */
|
||||||
|
@ -7944,4 +7944,8 @@ ER_WARN_HISTORY_ROW_START_TIME
|
|||||||
ER_PART_STARTS_BEYOND_INTERVAL
|
ER_PART_STARTS_BEYOND_INTERVAL
|
||||||
eng "%`s: STARTS is later than query time, first history partition may exceed INTERVAL value"
|
eng "%`s: STARTS is later than query time, first history partition may exceed INTERVAL value"
|
||||||
ER_GALERA_REPLICATION_NOT_SUPPORTED
|
ER_GALERA_REPLICATION_NOT_SUPPORTED
|
||||||
eng "DDL-statement is forbidden as table storage engine does not support Galera replication"
|
eng "DDL-statement is forbidden as table storage engine does not support Galera replication"
|
||||||
|
ER_VERS_MODIFY_HISTORY
|
||||||
|
eng "Modifying history is prohibited, set `secure_timestamp` to NO or SUPER"
|
||||||
|
WARN_VERS_HIST_PART_ERROR
|
||||||
|
eng "Versioned table %`s.%`s: adding HISTORY partition failed with error %u, see error log for details"
|
||||||
|
@ -2584,11 +2584,15 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info,
|
|||||||
err+= str.append(ctime, ctime_len);
|
err+= str.append(ctime, ctime_len);
|
||||||
err+= str.append('\'');
|
err+= str.append('\'');
|
||||||
}
|
}
|
||||||
|
if (vers_info->auto_inc)
|
||||||
|
err+= str.append(STRING_WITH_LEN(" AUTO_INCREMENT"));
|
||||||
}
|
}
|
||||||
if (vers_info->limit)
|
else if (vers_info->limit)
|
||||||
{
|
{
|
||||||
err+= str.append(STRING_WITH_LEN("LIMIT "));
|
err+= str.append(STRING_WITH_LEN("LIMIT "));
|
||||||
err+= str.append_ulonglong(vers_info->limit);
|
err+= str.append_ulonglong(vers_info->limit);
|
||||||
|
if (vers_info->auto_inc)
|
||||||
|
err+= str.append(STRING_WITH_LEN(" AUTO_INCREMENT"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (part_info->part_expr)
|
else if (part_info->part_expr)
|
||||||
@ -5313,12 +5317,6 @@ that are reorganised.
|
|||||||
now_part= el;
|
now_part= el;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*fast_alter_table && tab_part_info->vers_info->interval.is_set())
|
|
||||||
{
|
|
||||||
partition_element *hist_part= tab_part_info->vers_info->hist_part;
|
|
||||||
if (hist_part->range_value <= thd->query_start())
|
|
||||||
hist_part->part_state= PART_CHANGED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
List_iterator<partition_element> alt_it(alt_part_info->partitions);
|
List_iterator<partition_element> alt_it(alt_part_info->partitions);
|
||||||
uint part_count= 0;
|
uint part_count= 0;
|
||||||
@ -7218,7 +7216,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
|||||||
}
|
}
|
||||||
else if ((alter_info->partition_flags & ALTER_PARTITION_ADD) &&
|
else if ((alter_info->partition_flags & ALTER_PARTITION_ADD) &&
|
||||||
(part_info->part_type == RANGE_PARTITION ||
|
(part_info->part_type == RANGE_PARTITION ||
|
||||||
part_info->part_type == LIST_PARTITION))
|
part_info->part_type == LIST_PARTITION ||
|
||||||
|
part_info->part_type == VERSIONING_PARTITION))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
ADD RANGE/LIST PARTITIONS
|
ADD RANGE/LIST PARTITIONS
|
||||||
|
@ -1464,6 +1464,8 @@ End SQL_MODE_ORACLE_SPECIFIC */
|
|||||||
condition_number
|
condition_number
|
||||||
opt_versioning_interval_start
|
opt_versioning_interval_start
|
||||||
|
|
||||||
|
%type <num> opt_vers_auto_inc
|
||||||
|
|
||||||
%type <item_param> param_marker
|
%type <item_param> param_marker
|
||||||
|
|
||||||
%type <item_num>
|
%type <item_num>
|
||||||
@ -5306,24 +5308,24 @@ opt_part_option:
|
|||||||
|
|
||||||
opt_versioning_rotation:
|
opt_versioning_rotation:
|
||||||
/* empty */ {}
|
/* empty */ {}
|
||||||
| INTERVAL_SYM expr interval opt_versioning_interval_start
|
| INTERVAL_SYM expr interval opt_versioning_interval_start opt_vers_auto_inc
|
||||||
{
|
{
|
||||||
partition_info *part_info= Lex->part_info;
|
partition_info *part_info= Lex->part_info;
|
||||||
const char *table_name= Lex->create_last_non_select_table->table_name.str;
|
const char *table_name= Lex->create_last_non_select_table->table_name.str;
|
||||||
if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4, table_name)))
|
if (unlikely(part_info->vers_set_interval(thd, $2, $3, $4, $5, table_name)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| LIMIT ulonglong_num
|
| LIMIT ulonglong_num opt_vers_auto_inc
|
||||||
{
|
|
||||||
partition_info *part_info= Lex->part_info;
|
|
||||||
if (unlikely(part_info->vers_set_limit($2)))
|
|
||||||
{
|
{
|
||||||
my_error(ER_PART_WRONG_VALUE, MYF(0),
|
partition_info *part_info= Lex->part_info;
|
||||||
Lex->create_last_non_select_table->table_name.str,
|
if (unlikely(part_info->vers_set_limit($2, $3)))
|
||||||
"LIMIT");
|
{
|
||||||
MYSQL_YYABORT;
|
my_error(ER_PART_WRONG_VALUE, MYF(0),
|
||||||
|
Lex->create_last_non_select_table->table_name.str,
|
||||||
|
"LIMIT");
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
@ -5338,6 +5340,20 @@ opt_versioning_interval_start:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_vers_auto_inc:
|
||||||
|
/* empty */
|
||||||
|
{
|
||||||
|
$$= 0;
|
||||||
|
}
|
||||||
|
| AUTO_INC
|
||||||
|
{
|
||||||
|
$$= 1;
|
||||||
|
}
|
||||||
|
| AUTO_SYM
|
||||||
|
{
|
||||||
|
$$= 1;
|
||||||
|
}
|
||||||
|
;
|
||||||
/*
|
/*
|
||||||
End of partition parser part
|
End of partition parser part
|
||||||
*/
|
*/
|
||||||
|
@ -800,6 +800,9 @@ struct TABLE_SHARE
|
|||||||
uint partition_info_str_len;
|
uint partition_info_str_len;
|
||||||
uint partition_info_buffer_size;
|
uint partition_info_buffer_size;
|
||||||
plugin_ref default_part_plugin;
|
plugin_ref default_part_plugin;
|
||||||
|
bool vers_altering;
|
||||||
|
time_t vers_hist_part_timeout;
|
||||||
|
uint vers_hist_part_error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user