summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-02-25 14:14:17 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-02-25 15:43:23 +0300
commitf707c83fff4fa3f5291684e6226542fdb75bbdeb (patch)
tree1a554d5f3f27e38a7a2d78819207ddd0c6ea8514
parentc12609dd9ed65b245cee2e8b379b1e1f15aadf6a (diff)
downloadmariadb-git-f707c83fff4fa3f5291684e6226542fdb75bbdeb.tar.gz
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.
-rw-r--r--mysql-test/suite/versioning/r/delete_history.result12
-rw-r--r--mysql-test/suite/versioning/r/partition.result135
-rw-r--r--mysql-test/suite/versioning/r/rpl.result19
-rw-r--r--mysql-test/suite/versioning/t/delete_history.test11
-rw-r--r--mysql-test/suite/versioning/t/partition.test86
-rw-r--r--mysql-test/suite/versioning/t/rpl.test24
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/mysqld.h2
-rw-r--r--sql/partition_info.cc277
-rw-r--r--sql/partition_info.h41
-rw-r--r--sql/share/errmsg-utf8.txt6
-rw-r--r--sql/sql_partition.cc15
-rw-r--r--sql/sql_yacc.yy38
-rw-r--r--sql/table.h3
14 files changed, 595 insertions, 79 deletions
diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result
index cb865a835b3..b3086c867d1 100644
--- a/mysql-test/suite/versioning/r/delete_history.result
+++ b/mysql-test/suite/versioning/r/delete_history.result
@@ -154,3 +154,15 @@ select * from t1;
a
1
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;
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
index 038051055e7..87d7c112f3e 100644
--- a/mysql-test/suite/versioning/r/partition.result
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -1,4 +1,7 @@
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;
# Check conventional partitioning on temporal tables
create or replace table t1 (
@@ -237,7 +240,9 @@ select @ts0 = @ts1;
select @ts2 = @ts3;
@ts2 = @ts3
1
-## rotation by LIMIT
+#
+# Rotation by LIMIT
+#
create or replace table t1 (x int)
with system versioning
partition by system_time limit 0 partitions 3;
@@ -289,7 +294,37 @@ x
6
7
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)
with system versioning
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'
# INTERVAL and ALTER TABLE
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
where table_schema='test' and table_name='t1' and partition_name='p0');
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';
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
p0 1 SYSTEM_TIME 00:00:00.000000
-p1 2 SYSTEM_TIME 01:00:00.000000
-p2 3 SYSTEM_TIME 02:00:00.000000
+p1 2 SYSTEM_TIME 00:59:00.000000
+p2 3 SYSTEM_TIME 01:58:00.000000
pn 4 SYSTEM_TIME NULL
Warnings:
Warning 1292 Incorrect time value: 'CURRENT'
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';
partition_name partition_ordinal_position partition_method timediff(partition_description, @ts)
-p1 1 SYSTEM_TIME 01:00:00.000000
-p2 2 SYSTEM_TIME 02:00:00.000000
+p1 1 SYSTEM_TIME 00:59:00.000000
+p2 2 SYSTEM_TIME 01:58:00.000000
pn 3 SYSTEM_TIME NULL
Warnings:
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
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)
-p1 1 SYSTEM_TIME 01:00:00.000000
-p2 2 SYSTEM_TIME 02:00:00.000000
+p1 1 SYSTEM_TIME 00:59:00.000000
+p2 2 SYSTEM_TIME 01:58:00.000000
pn 3 SYSTEM_TIME NULL
Warnings:
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
subpartition by key (i) subpartitions 2
(partition p1 history, partition pn current);
+lock tables t1 write;
set timestamp=unix_timestamp('2001-02-03 10:20:40');
insert t1 values (1);
delete from t1;
@@ -353,28 +389,51 @@ Warning 4114 Versioned table `test`.`t1`: last HISTORY partition (`p1`) is out o
delete from t1;
Warnings:
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';
-subpartition_name partition_description table_rows
-p1sp0 2001-02-04 00:00:00 1
-p1sp1 2001-02-04 00:00:00 1
-pnsp0 CURRENT 0
-pnsp1 CURRENT 0
+select subpartition_name, partition_description from information_schema.partitions where table_schema='test' and table_name='t1';
+subpartition_name partition_description
+p1sp0 2001-02-04 00:00:00
+p1sp1 2001-02-04 00:00:00
+pnsp0 CURRENT
+pnsp1 CURRENT
+select * from t1 partition (p1);
+i
+1
+2
set timestamp=unix_timestamp('2001-02-04 10:20:55');
alter table t1 add partition (partition p0 history, partition p2 history);
set timestamp=unix_timestamp('2001-02-04 10:30:00');
insert t1 values (4),(5);
set timestamp=unix_timestamp('2001-02-04 10:30:10');
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';
-subpartition_name partition_description table_rows
-p1sp0 2001-02-04 00:00:00 1
-p1sp1 2001-02-04 00:00:00 0
-p0sp0 2001-02-05 00:00:00 1
-p0sp1 2001-02-05 00:00:00 1
-p2sp0 2001-02-06 00:00:00 0
-p2sp1 2001-02-06 00:00:00 0
-pnsp0 CURRENT 0
-pnsp1 CURRENT 2
+select subpartition_name, partition_description from information_schema.partitions where table_schema='test' and table_name='t1';
+subpartition_name partition_description
+p1sp0 2001-02-04 00:00:00
+p1sp1 2001-02-04 00:00:00
+p0sp0 2001-02-05 00:00:00
+p0sp1 2001-02-05 00:00:00
+p2sp0 2001-02-06 00:00:00
+p2sp1 2001-02-06 00:00:00
+pnsp0 CURRENT
+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
set @ts=(select partition_description from information_schema.partitions
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;
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 # #
+unlock tables;
## INTERVAL ... STARTS
create or replace table t1 (i int) with system versioning
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
partition by system_time interval 1 day starts '2000-01-01 00:00:00'
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:
insert into t1 values (0);
Warnings:
@@ -584,11 +647,13 @@ i row_end
select *, row_end from t1 partition (p1);
i row_end
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:
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
create or replace table t1 (i int) with system versioning
partition by system_time interval 1 day
partitions 3;
+lock tables t1 write;
insert into t1 values (0);
set timestamp= unix_timestamp('2000-01-01 00:00:01');
update t1 set i= i + 1;
@@ -609,12 +674,26 @@ i row_end
select *, row_end from t1 partition (p1);
i row_end
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);
i row_end
2 2000-01-03 00:00:01.000000
select *, row_end from t1 partition (p3);
i row_end
3 2000-01-04 00:00:01.000000
+unlock tables;
drop tables t1, t2;
## Subpartitions
create or replace table t1 (x int)
@@ -632,9 +711,9 @@ select * from t1 partition (pnsp1);
x
2
4
-### warn about full partition
delete from t1 where x < 3;
delete from t1;
+### warn about full partition
delete from t1;
Warnings:
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;
insert into t1 values (1), (2);
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;
alter table t1 add partition (partition p2 history);
insert into t1 values (4);
diff --git a/mysql-test/suite/versioning/r/rpl.result b/mysql-test/suite/versioning/r/rpl.result
index 627f3991499..a303e8f8e61 100644
--- a/mysql-test/suite/versioning/r/rpl.result
+++ b/mysql-test/suite/versioning/r/rpl.result
@@ -164,4 +164,23 @@ update t1 set i = 0;
connection slave;
connection master;
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
diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test
index fb5c8520bcb..be9f6afaec8 100644
--- a/mysql-test/suite/versioning/t/delete_history.test
+++ b/mysql-test/suite/versioning/t/delete_history.test
@@ -169,4 +169,15 @@ insert into t1 values (1);
select * from 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
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
index f55b43f56da..38755b3daec 100644
--- a/mysql-test/suite/versioning/t/partition.test
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -3,6 +3,11 @@
-- source suite/versioning/engines.inc
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;
--echo # Check conventional partitioning on temporal tables
@@ -213,7 +218,9 @@ prepare stmt from @str; execute stmt; drop prepare stmt;
select @ts0 = @ts1;
select @ts2 = @ts3;
---echo ## rotation by LIMIT
+--echo #
+--echo # Rotation by LIMIT
+--echo #
--error ER_PART_WRONG_VALUE
create or replace table t1 (x int)
with system versioning
@@ -241,8 +248,37 @@ insert into t1 values (7), (8);
delete from t1;
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
create or replace table t1 (x int)
with system versioning
@@ -258,7 +294,7 @@ partition by system_time interval 10 year partitions 3;
--echo # INTERVAL and ALTER TABLE
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
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
subpartition by key (i) subpartitions 2
(partition p1 history, partition pn current);
+lock tables t1 write; # prevent partition auto-creation
+
set timestamp=unix_timestamp('2001-02-03 10:20:40');
insert t1 values (1); delete from t1;
set timestamp=unix_timestamp('2001-02-04 10:20:50');
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');
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');
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
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;
--replace_column 5 # 10 # 11 #
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
--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
partition by system_time interval 1 day starts '2000-01-01 00:00:00'
partitions 3;
+lock tables t1 write; # prevent partition auto-creation
--echo # we are warned when we push to present:
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 (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:
+set timestamp= unix_timestamp('2000-01-01 00:00:00');
create or replace table t1 (i int) with system versioning
partition by system_time interval 1 day
partitions 3;
+lock tables t1 write; # prevent partition auto-creation
insert into t1 values (0);
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;
alter table t1 add partition (partition p2 history, partition p3 history);
+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);
+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;
--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 (pnsp1);
---echo ### warn about full partition
delete from t1 where x < 3;
delete from t1;
+--echo ### warn about full partition
delete from t1;
select * from t1 partition (p0sp0);
select * from t1 partition (p0sp1);
@@ -627,6 +691,8 @@ alter table t1 partition by system_time interval 1 week (
partition p1 history,
partition pn current);
unlock tables;
+--let $wait_condition= $wait_no_alter
+--source include/wait_condition.inc
--echo #
--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);
insert into t1 values (1);
unlock tables;
+--let $wait_condition= $wait_no_alter
+--source include/wait_condition.inc
--echo #
--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;
insert into t1 values (1), (2);
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;
alter table t1 add partition (partition p2 history);
insert into t1 values (4);
unlock tables;
+--let $wait_condition= $wait_no_alter
+--source include/wait_condition.inc
--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
diff --git a/mysql-test/suite/versioning/t/rpl.test b/mysql-test/suite/versioning/t/rpl.test
index b5be68feece..ec612551578 100644
--- a/mysql-test/suite/versioning/t/rpl.test
+++ b/mysql-test/suite/versioning/t/rpl.test
@@ -133,4 +133,28 @@ sync_slave_with_master;
connection master;
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
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b2f8afca7a6..7fdbb300298 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1090,7 +1090,7 @@ static PSI_cond_info all_server_conds[]=
PSI_thread_key key_thread_delayed_insert,
key_thread_handle_manager, key_thread_main,
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;
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_slave_background, "slave_background", 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
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 4f4e608e811..d1e13c2fc77 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -388,7 +388,7 @@ extern PSI_cond_key key_TABLE_SHARE_COND_rotation;
extern PSI_thread_key key_thread_delayed_insert,
key_thread_handle_manager, key_thread_kill_server, key_thread_main,
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,
key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 252744a3a73..e0ffaaecd36 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -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
*/
-#define MAX_PART_NAME_SIZE 8
-
char *partition_info::create_default_partition_names(THD *thd, uint part_no,
uint num_parts_arg,
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;
uint i= 0;
DBUG_ENTER("create_default_partition_names");
@@ -337,7 +335,8 @@ char *partition_info::create_default_partition_names(THD *thd, uint part_no,
{
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;
} 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
@@ -845,29 +851,265 @@ void partition_info::vers_set_hist_part(THD *thd)
else
vers_info->hist_part= next;
}
+ if (vers_info->limit >= VERS_MIN_LIMIT)
+ goto add_hist_part;
return;
}
if (vers_info->interval.is_set())
{
- if (vers_info->hist_part->range_value > thd->query_start())
- return;
+ if (vers_info->hist_part->range_value <= thd->query_start())
+ {
+ partition_element *next= NULL;
+ bool error= true;
+ List_iterator<partition_element> it(partitions);
+ while (next != vers_info->hist_part)
+ next= it++;
- 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;
+ 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");
+ }
+ if (vers_info->interval.ge(VERS_MIN_INTERVAL))
+ goto add_hist_part;
+ }
- while ((next= it++) != vers_info->now_part)
+ 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)
{
- vers_info->hist_part= next;
- if (next->range_value > thd->query_start())
+ 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();
}
- 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");
}
+
+ 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,
interval_type int_type, Item* starts,
- const char *table_name)
+ bool auto_inc, const char *table_name)
{
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
MYSQL_TIME ltime;
uint err;
vers_info->interval.type= int_type;
+ vers_info->auto_inc= auto_inc;
/* 1. assign INTERVAL to interval.step */
if (interval->fix_fields_if_needed_for_scalar(thd, &interval))
diff --git a/sql/partition_info.h b/sql/partition_info.h
index eb8e53a381a..1534189af2a 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -38,6 +38,7 @@ struct Vers_part_info : public Sql_alloc
{
Vers_part_info() :
limit(0),
+ auto_inc(false),
now_part(NULL),
hist_part(NULL)
{
@@ -46,6 +47,7 @@ struct Vers_part_info : public Sql_alloc
Vers_part_info(Vers_part_info &src) :
interval(src.interval),
limit(src.limit),
+ auto_inc(src.auto_inc),
now_part(NULL),
hist_part(NULL)
{
@@ -69,9 +71,30 @@ struct Vers_part_info : public Sql_alloc
my_time_t start;
INTERVAL step;
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;
ulonglong limit;
+ bool auto_inc;
partition_element *now_part;
partition_element *hist_part;
};
@@ -394,14 +417,16 @@ public:
bool vers_init_info(THD *thd);
bool vers_set_interval(THD *thd, Item *interval,
interval_type int_type, Item *starts,
- const char *table_name);
- bool vers_set_limit(ulonglong limit)
+ bool auto_inc, const char *table_name);
+ bool vers_set_limit(ulonglong limit, bool auto_inc)
{
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
vers_info->limit= limit;
+ vers_info->auto_inc= auto_inc;
return !limit;
}
void vers_set_hist_part(THD *thd);
+ void vers_add_hist_part(THD *thd);
bool vers_fix_field_list(THD *thd);
void vers_update_el_ids();
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 */
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 78b6cfa63c8..01cf2745c41 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7944,4 +7944,8 @@ ER_WARN_HISTORY_ROW_START_TIME
ER_PART_STARTS_BEYOND_INTERVAL
eng "%`s: STARTS is later than query time, first history partition may exceed INTERVAL value"
ER_GALERA_REPLICATION_NOT_SUPPORTED
- eng "DDL-statement is forbidden as table storage engine does not support Galera replication" \ No newline at end of file
+ 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"
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 5885e3715bf..f8ae91114f0 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2584,11 +2584,15 @@ char *generate_partition_syntax(THD *thd, partition_info *part_info,
err+= str.append(ctime, ctime_len);
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_ulonglong(vers_info->limit);
+ if (vers_info->auto_inc)
+ err+= str.append(STRING_WITH_LEN(" AUTO_INCREMENT"));
}
}
else if (part_info->part_expr)
@@ -5313,12 +5317,6 @@ that are reorganised.
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);
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) &&
(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
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f24da3ed412..692ed48ab8c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1464,6 +1464,8 @@ End SQL_MODE_ORACLE_SPECIFIC */
condition_number
opt_versioning_interval_start
+%type <num> opt_vers_auto_inc
+
%type <item_param> param_marker
%type <item_num>
@@ -5306,24 +5308,24 @@ opt_part_option:
opt_versioning_rotation:
/* 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;
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;
}
- | LIMIT ulonglong_num
- {
- partition_info *part_info= Lex->part_info;
- if (unlikely(part_info->vers_set_limit($2)))
+ | LIMIT ulonglong_num opt_vers_auto_inc
{
- my_error(ER_PART_WRONG_VALUE, MYF(0),
- Lex->create_last_non_select_table->table_name.str,
- "LIMIT");
- MYSQL_YYABORT;
+ partition_info *part_info= Lex->part_info;
+ if (unlikely(part_info->vers_set_limit($2, $3)))
+ {
+ 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
*/
diff --git a/sql/table.h b/sql/table.h
index 6ce92ee048e..50ac46fbe39 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -800,6 +800,9 @@ struct TABLE_SHARE
uint partition_info_str_len;
uint partition_info_buffer_size;
plugin_ref default_part_plugin;
+ bool vers_altering;
+ time_t vers_hist_part_timeout;
+ uint vers_hist_part_error;
#endif
/**