mirror of
https://github.com/MariaDB/server.git
synced 2025-07-11 15:22:09 +03:00
SQL: (0.6) Pruning for VERSIONING partitions [closes #97]
* based on RANGE pruning by COLUMNS (sys_trx_end) condition * removed DEFAULT; AS OF NOW is always last; current VERSIONING as last non-empty (or first empty) * Min/Max stats in TABLE_SHARE * ALTER TABLE ADD PARTITION adds before AS OF NOW partition
This commit is contained in:
@ -28,7 +28,7 @@ wait/synch/rwlock/sql/LOGGER::LOCK_logger YES YES
|
|||||||
wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for YES YES
|
wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for YES YES
|
||||||
wait/synch/rwlock/sql/MDL_lock::rwlock YES YES
|
wait/synch/rwlock/sql/MDL_lock::rwlock YES YES
|
||||||
wait/synch/rwlock/sql/Query_cache_query::lock YES YES
|
wait/synch/rwlock/sql/Query_cache_query::lock YES YES
|
||||||
wait/synch/rwlock/sql/THR_LOCK_servers YES YES
|
wait/synch/rwlock/sql/TABLE_SHARE::LOCK_stat_serial YES YES
|
||||||
select * from performance_schema.setup_instruments
|
select * from performance_schema.setup_instruments
|
||||||
where name like 'Wait/Synch/Cond/sql/%'
|
where name like 'Wait/Synch/Cond/sql/%'
|
||||||
and name not in (
|
and name not in (
|
||||||
|
@ -30,14 +30,14 @@ x
|
|||||||
300
|
300
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning);
|
partition pn as of now);
|
||||||
ERROR HY000: System Versioning required: `BY SYSTEM_TIME` partitioning
|
ERROR HY000: System Versioning required: `BY SYSTEM_TIME` partitioning
|
||||||
create or replace table t1 (x int);
|
create or replace table t1 (x int);
|
||||||
alter table t1
|
alter table t1
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning);
|
partition pn as of now);
|
||||||
ERROR HY000: System Versioning required: `BY SYSTEM_TIME` partitioning
|
ERROR HY000: System Versioning required: `BY SYSTEM_TIME` partitioning
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
@ -59,127 +59,21 @@ ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: no `AS OF NOW` partition def
|
|||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 as of now,
|
partition pn as of now,
|
||||||
partition p1 versioning);
|
partition p0 versioning);
|
||||||
alter table t1 add partition (
|
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: AS OF NOW partition is not last
|
||||||
partition p2 as of now);
|
|
||||||
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: multiple `AS OF NOW` partitions
|
|
||||||
alter table t1 add partition (
|
|
||||||
partition p2 versioning default);
|
|
||||||
Warnings:
|
|
||||||
Warning 4078 Maybe missing parameters: no rotation condition for multiple `VERSIONING` partitions.
|
|
||||||
alter table t1 drop partition p0;
|
|
||||||
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: `AS OF NOW` partition can not be dropped
|
|
||||||
alter table t1 drop partition p2;
|
|
||||||
alter table t1 drop partition p1;
|
|
||||||
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: one `AS OF NOW` and at least one `VERSIONING` partition required
|
|
||||||
insert into t1 values (1);
|
|
||||||
select * from t1;
|
|
||||||
x
|
|
||||||
1
|
|
||||||
select * from t1 partition (p0);
|
|
||||||
x
|
|
||||||
1
|
|
||||||
select * from t1 partition (p1);
|
|
||||||
x
|
|
||||||
delete from t1;
|
|
||||||
select * from t1 partition (p0) for system_time all;
|
|
||||||
x
|
|
||||||
select * from t1 partition (p1) for system_time all;
|
|
||||||
x
|
|
||||||
1
|
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 versioning,
|
partition p0 versioning,
|
||||||
|
partition pn as of now);
|
||||||
|
alter table t1 add partition (
|
||||||
partition p1 as of now);
|
partition p1 as of now);
|
||||||
insert into t1 values (1);
|
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: AS OF NOW partition can not be added
|
||||||
select * from t1;
|
alter table t1 add partition (
|
||||||
x
|
partition p1 versioning);
|
||||||
1
|
|
||||||
select * from t1 partition (p0);
|
|
||||||
x
|
|
||||||
select * from t1 partition (p1);
|
|
||||||
x
|
|
||||||
1
|
|
||||||
delete from t1;
|
|
||||||
select * from t1 partition (p0) for system_time all;
|
|
||||||
x
|
|
||||||
1
|
|
||||||
select * from t1 partition (p1) for system_time all;
|
|
||||||
x
|
|
||||||
create or replace table t1 (x int)
|
|
||||||
with system versioning
|
|
||||||
engine myisam
|
|
||||||
partition by system_time limit 1 (
|
|
||||||
partition p0 as of now,
|
|
||||||
partition p1 versioning,
|
|
||||||
partition p2 versioning);
|
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4078 No `DEFAULT` for `VERSIONING` partitions. Setting `p1` as default.
|
Warning 4078 Maybe missing parameters: no rotation condition for multiple `VERSIONING` partitions.
|
||||||
insert into t1 values (1), (2);
|
|
||||||
select * from t1 partition (p0);
|
|
||||||
x
|
|
||||||
1
|
|
||||||
2
|
|
||||||
delete from t1;
|
|
||||||
Warnings:
|
|
||||||
Note 4079 Switching from partition `p1` to `p2`
|
|
||||||
select * from t1 partition (p1) for system_time all;
|
|
||||||
x
|
|
||||||
1
|
|
||||||
select * from t1 partition (p2) for system_time all;
|
|
||||||
x
|
|
||||||
2
|
|
||||||
insert into t1 values (3);
|
|
||||||
delete from t1;
|
|
||||||
Warnings:
|
|
||||||
Warning 4077 Using full partition `p2`, need more VERSIONING partitions!
|
|
||||||
select * from t1 partition (p2) for system_time all;
|
|
||||||
x
|
|
||||||
2
|
|
||||||
3
|
|
||||||
create or replace table t1 (x int)
|
|
||||||
with system versioning
|
|
||||||
engine myisam
|
|
||||||
partition by system_time interval 1 second (
|
|
||||||
partition p0 as of now,
|
|
||||||
partition p1 versioning default,
|
|
||||||
partition p2 versioning);
|
|
||||||
insert into t1 values (1), (2), (3);
|
|
||||||
select * from t1 partition (p0);
|
|
||||||
x
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
delete from t1;
|
|
||||||
select * from t1 partition (p1) for system_time all;
|
|
||||||
x
|
|
||||||
1
|
|
||||||
2
|
|
||||||
3
|
|
||||||
insert into t1 values (4);
|
|
||||||
delete from t1;
|
|
||||||
Warnings:
|
|
||||||
Note 4079 Switching from partition `p1` to `p2`
|
|
||||||
select * from t1 partition (p2) for system_time all;
|
|
||||||
x
|
|
||||||
4
|
|
||||||
create or replace table t1 (x int)
|
|
||||||
with system versioning
|
|
||||||
engine myisam
|
|
||||||
partition by system_time limit 1 (
|
|
||||||
partition p0 as of now,
|
|
||||||
partition p1 versioning default,
|
|
||||||
partition p2 versioning default);
|
|
||||||
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: multiple `DEFAULT` partitions
|
|
||||||
create or replace table t1 (x int)
|
|
||||||
with system versioning
|
|
||||||
engine myisam
|
|
||||||
partition by system_time limit 1 (
|
|
||||||
partition p0 as of now,
|
|
||||||
partition p1 versioning,
|
|
||||||
partition p2 versioning default);
|
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
@ -188,50 +82,115 @@ t1 CREATE TABLE `t1` (
|
|||||||
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
`sys_trx_end` timestamp(6) GENERATED ALWAYS AS ROW END,
|
||||||
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
PERIOD FOR SYSTEM_TIME (`sys_trx_start`, `sys_trx_end`)
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING
|
||||||
PARTITION BY SYSTEM_TIME LIMIT 1
|
PARTITION BY SYSTEM_TIME
|
||||||
(PARTITION p0 AS OF NOW ENGINE = MyISAM,
|
(PARTITION p0 VERSIONING ENGINE = MyISAM,
|
||||||
PARTITION p1 VERSIONING ENGINE = MyISAM,
|
PARTITION p1 VERSIONING ENGINE = MyISAM,
|
||||||
PARTITION p2 VERSIONING DEFAULT ENGINE = MyISAM)
|
PARTITION pn AS OF NOW ENGINE = MyISAM)
|
||||||
insert into t1 values (4), (5);
|
alter table t1 drop partition pn;
|
||||||
|
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: `AS OF NOW` partition can not be dropped
|
||||||
|
alter table t1 drop partition p1;
|
||||||
|
alter table t1 drop partition p0;
|
||||||
|
ERROR HY000: Wrong parameters for `BY SYSTEM_TIME`: one `AS OF NOW` and at least one `VERSIONING` partition required
|
||||||
|
insert into t1 values (1);
|
||||||
|
select * from t1;
|
||||||
|
x
|
||||||
|
1
|
||||||
|
select * from t1 partition (p0);
|
||||||
|
x
|
||||||
|
select * from t1 partition (pn);
|
||||||
|
x
|
||||||
|
1
|
||||||
|
delete from t1;
|
||||||
|
select * from t1 partition (p0) for system_time all;
|
||||||
|
x
|
||||||
|
1
|
||||||
|
select * from t1 partition (pn) for system_time all;
|
||||||
|
x
|
||||||
|
create or replace table t1 (x int)
|
||||||
|
with system versioning
|
||||||
|
engine myisam
|
||||||
|
partition by system_time limit 1 (
|
||||||
|
partition p0 versioning,
|
||||||
|
partition p1 versioning,
|
||||||
|
partition pn as of now);
|
||||||
|
insert into t1 values (1), (2);
|
||||||
|
select * from t1 partition (pn);
|
||||||
|
x
|
||||||
|
1
|
||||||
|
2
|
||||||
delete from t1;
|
delete from t1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 4079 Switching from partition `p2` to `p1`
|
Note 4079 Switching from partition `p0` to `p1`
|
||||||
select * from t1 partition (p2) for system_time all;
|
select * from t1 partition (p0) for system_time all;
|
||||||
x
|
x
|
||||||
4
|
1
|
||||||
select * from t1 partition (p1) for system_time all;
|
select * from t1 partition (p1) for system_time all;
|
||||||
x
|
x
|
||||||
5
|
2
|
||||||
|
insert into t1 values (3);
|
||||||
|
delete from t1;
|
||||||
|
Warnings:
|
||||||
|
Warning 4077 Using full partition `p1`, need more VERSIONING partitions!
|
||||||
|
select * from t1 partition (p1) for system_time all;
|
||||||
|
x
|
||||||
|
2
|
||||||
|
3
|
||||||
|
create or replace table t1 (x int)
|
||||||
|
with system versioning
|
||||||
|
engine myisam
|
||||||
|
partition by system_time interval 1 second (
|
||||||
|
partition p0 versioning,
|
||||||
|
partition p1 versioning,
|
||||||
|
partition pn as of now);
|
||||||
|
insert into t1 values (1), (2), (3);
|
||||||
|
select * from t1 partition (pn);
|
||||||
|
x
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
delete from t1;
|
||||||
|
select * from t1 partition (p0) for system_time all;
|
||||||
|
x
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
insert into t1 values (4);
|
||||||
|
delete from t1;
|
||||||
|
Warnings:
|
||||||
|
Note 4079 Switching from partition `p0` to `p1`
|
||||||
|
select * from t1 partition (p1) for system_time all;
|
||||||
|
x
|
||||||
|
4
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
engine myisam
|
engine myisam
|
||||||
partition by system_time limit 1
|
partition by system_time limit 1
|
||||||
subpartition by key (x)
|
subpartition by key (x)
|
||||||
subpartitions 2 (
|
subpartitions 2 (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning default,
|
partition p1 versioning,
|
||||||
partition p2 versioning);
|
partition pn as of now);
|
||||||
insert into t1 (x) values (1), (2), (3);
|
insert into t1 (x) values (1), (2), (3);
|
||||||
select * from t1 partition (p0sp0);
|
select * from t1 partition (pnsp0);
|
||||||
x
|
x
|
||||||
1
|
1
|
||||||
3
|
3
|
||||||
select * from t1 partition (p0sp1);
|
select * from t1 partition (pnsp1);
|
||||||
x
|
x
|
||||||
2
|
2
|
||||||
delete from t1;
|
delete from t1;
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 4079 Switching from partition `p1` to `p2`
|
Note 4079 Switching from partition `p0` to `p1`
|
||||||
Warning 4077 Using full partition `p2`, need more VERSIONING partitions!
|
Warning 4077 Using full partition `p1`, need more VERSIONING partitions!
|
||||||
select * from t1 partition (p1sp0) for system_time all;
|
select * from t1 partition (p0sp0) for system_time all;
|
||||||
x
|
x
|
||||||
1
|
1
|
||||||
select * from t1 partition (p1sp1) for system_time all;
|
select * from t1 partition (p0sp1) for system_time all;
|
||||||
x
|
x
|
||||||
select * from t1 partition (p2sp0) for system_time all;
|
select * from t1 partition (p1sp0) for system_time all;
|
||||||
x
|
x
|
||||||
3
|
3
|
||||||
select * from t1 partition (p2sp1) for system_time all;
|
select * from t1 partition (p1sp1) for system_time all;
|
||||||
x
|
x
|
||||||
2
|
2
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -27,15 +27,15 @@ select * from t1 partition (p1) for system_time all;
|
|||||||
--error ER_VERSIONING_REQUIRED
|
--error ER_VERSIONING_REQUIRED
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning);
|
partition pn as of now);
|
||||||
|
|
||||||
create or replace table t1 (x int);
|
create or replace table t1 (x int);
|
||||||
--error ER_VERSIONING_REQUIRED
|
--error ER_VERSIONING_REQUIRED
|
||||||
alter table t1
|
alter table t1
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning);
|
partition pn as of now);
|
||||||
|
|
||||||
--error ER_VERS_WRONG_PARAMS
|
--error ER_VERS_WRONG_PARAMS
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
@ -57,112 +57,81 @@ partition by system_time (
|
|||||||
partition p0 versioning,
|
partition p0 versioning,
|
||||||
partition p1 versioning);
|
partition p1 versioning);
|
||||||
|
|
||||||
|
--error ER_VERS_WRONG_PARAMS
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 as of now,
|
partition pn as of now,
|
||||||
partition p1 versioning);
|
partition p0 versioning);
|
||||||
|
|
||||||
# alter table
|
|
||||||
--error ER_VERS_WRONG_PARAMS
|
|
||||||
alter table t1 add partition (
|
|
||||||
partition p2 as of now);
|
|
||||||
|
|
||||||
alter table t1 add partition (
|
|
||||||
partition p2 versioning default);
|
|
||||||
|
|
||||||
--error ER_VERS_WRONG_PARAMS
|
|
||||||
alter table t1 drop partition p0;
|
|
||||||
alter table t1 drop partition p2;
|
|
||||||
--error ER_VERS_WRONG_PARAMS
|
|
||||||
alter table t1 drop partition p1;
|
|
||||||
|
|
||||||
# insertion, deletion
|
|
||||||
insert into t1 values (1);
|
|
||||||
select * from t1;
|
|
||||||
select * from t1 partition (p0);
|
|
||||||
select * from t1 partition (p1);
|
|
||||||
|
|
||||||
delete from t1;
|
|
||||||
select * from t1 partition (p0) for system_time all;
|
|
||||||
select * from t1 partition (p1) for system_time all;
|
|
||||||
|
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
partition by system_time (
|
partition by system_time (
|
||||||
partition p0 versioning,
|
partition p0 versioning,
|
||||||
|
partition pn as of now);
|
||||||
|
|
||||||
|
# alter table
|
||||||
|
--error ER_VERS_WRONG_PARAMS
|
||||||
|
alter table t1 add partition (
|
||||||
partition p1 as of now);
|
partition p1 as of now);
|
||||||
|
|
||||||
|
alter table t1 add partition (
|
||||||
|
partition p1 versioning);
|
||||||
|
|
||||||
|
show create table t1;
|
||||||
|
|
||||||
|
--error ER_VERS_WRONG_PARAMS
|
||||||
|
alter table t1 drop partition pn;
|
||||||
|
alter table t1 drop partition p1;
|
||||||
|
--error ER_VERS_WRONG_PARAMS
|
||||||
|
alter table t1 drop partition p0;
|
||||||
|
|
||||||
|
# insertion, deletion
|
||||||
insert into t1 values (1);
|
insert into t1 values (1);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
select * from t1 partition (p0);
|
select * from t1 partition (p0);
|
||||||
select * from t1 partition (p1);
|
select * from t1 partition (pn);
|
||||||
|
|
||||||
delete from t1;
|
delete from t1;
|
||||||
select * from t1 partition (p0) for system_time all;
|
select * from t1 partition (p0) for system_time all;
|
||||||
select * from t1 partition (p1) for system_time all;
|
select * from t1 partition (pn) for system_time all;
|
||||||
|
|
||||||
# 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
|
||||||
engine myisam
|
engine myisam
|
||||||
partition by system_time limit 1 (
|
partition by system_time limit 1 (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning,
|
partition p1 versioning,
|
||||||
partition p2 versioning);
|
partition pn as of now);
|
||||||
|
|
||||||
insert into t1 values (1), (2);
|
insert into t1 values (1), (2);
|
||||||
select * from t1 partition (p0);
|
select * from t1 partition (pn);
|
||||||
delete from t1;
|
delete from t1;
|
||||||
|
select * from t1 partition (p0) for system_time all;
|
||||||
select * from t1 partition (p1) for system_time all;
|
select * from t1 partition (p1) for system_time all;
|
||||||
select * from t1 partition (p2) for system_time all;
|
|
||||||
|
|
||||||
insert into t1 values (3);
|
insert into t1 values (3);
|
||||||
delete from t1;
|
delete from t1;
|
||||||
select * from t1 partition (p2) for system_time all;
|
select * from t1 partition (p1) for system_time all;
|
||||||
|
|
||||||
# rotation by INTERVAL
|
# rotation by INTERVAL
|
||||||
create or replace table t1 (x int)
|
create or replace table t1 (x int)
|
||||||
with system versioning
|
with system versioning
|
||||||
engine myisam
|
engine myisam
|
||||||
partition by system_time interval 1 second (
|
partition by system_time interval 1 second (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning default,
|
partition p1 versioning,
|
||||||
partition p2 versioning);
|
partition pn as of now);
|
||||||
|
|
||||||
insert into t1 values (1), (2), (3);
|
insert into t1 values (1), (2), (3);
|
||||||
select * from t1 partition (p0);
|
select * from t1 partition (pn);
|
||||||
delete from t1;
|
delete from t1;
|
||||||
select * from t1 partition (p1) for system_time all;
|
select * from t1 partition (p0) for system_time all;
|
||||||
|
|
||||||
--sleep 2
|
--sleep 2
|
||||||
insert into t1 values (4);
|
insert into t1 values (4);
|
||||||
delete from t1;
|
delete from t1;
|
||||||
select * from t1 partition (p2) for system_time all;
|
|
||||||
|
|
||||||
# DEFAULT partition
|
|
||||||
--error ER_VERS_WRONG_PARAMS
|
|
||||||
create or replace table t1 (x int)
|
|
||||||
with system versioning
|
|
||||||
engine myisam
|
|
||||||
partition by system_time limit 1 (
|
|
||||||
partition p0 as of now,
|
|
||||||
partition p1 versioning default,
|
|
||||||
partition p2 versioning default);
|
|
||||||
|
|
||||||
create or replace table t1 (x int)
|
|
||||||
with system versioning
|
|
||||||
engine myisam
|
|
||||||
partition by system_time limit 1 (
|
|
||||||
partition p0 as of now,
|
|
||||||
partition p1 versioning,
|
|
||||||
partition p2 versioning default);
|
|
||||||
|
|
||||||
show create table t1;
|
|
||||||
|
|
||||||
insert into t1 values (4), (5);
|
|
||||||
delete from t1;
|
|
||||||
select * from t1 partition (p2) for system_time all;
|
|
||||||
select * from t1 partition (p1) for system_time all;
|
select * from t1 partition (p1) for system_time all;
|
||||||
|
|
||||||
# Subpartitions
|
# Subpartitions
|
||||||
@ -172,19 +141,19 @@ engine myisam
|
|||||||
partition by system_time limit 1
|
partition by system_time limit 1
|
||||||
subpartition by key (x)
|
subpartition by key (x)
|
||||||
subpartitions 2 (
|
subpartitions 2 (
|
||||||
partition p0 as of now,
|
partition p0 versioning,
|
||||||
partition p1 versioning default,
|
partition p1 versioning,
|
||||||
partition p2 versioning);
|
partition pn as of now);
|
||||||
|
|
||||||
insert into t1 (x) values (1), (2), (3);
|
insert into t1 (x) values (1), (2), (3);
|
||||||
select * from t1 partition (p0sp0);
|
select * from t1 partition (pnsp0);
|
||||||
select * from t1 partition (p0sp1);
|
select * from t1 partition (pnsp1);
|
||||||
|
|
||||||
delete from t1;
|
delete from t1;
|
||||||
|
select * from t1 partition (p0sp0) for system_time all;
|
||||||
|
select * from t1 partition (p0sp1) for system_time all;
|
||||||
select * from t1 partition (p1sp0) for system_time all;
|
select * from t1 partition (p1sp0) for system_time all;
|
||||||
select * from t1 partition (p1sp1) for system_time all;
|
select * from t1 partition (p1sp1) for system_time all;
|
||||||
select * from t1 partition (p2sp0) for system_time all;
|
|
||||||
select * from t1 partition (p2sp1) for system_time all;
|
|
||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
@ -4289,6 +4289,15 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
|
|||||||
if (error)
|
if (error)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
if (m_part_info->part_type == VERSIONING_PARTITION)
|
||||||
|
{
|
||||||
|
uint sub_factor= m_part_info->num_subparts ? m_part_info->num_subparts : 1;
|
||||||
|
DBUG_ASSERT(m_tot_parts == m_part_info->num_parts * sub_factor);
|
||||||
|
uint lpart_id= new_part_id / sub_factor;
|
||||||
|
// lpart_id is VERSIONING partition because new_part_id != old_part_id
|
||||||
|
m_part_info->vers_update_stats(thd, lpart_id);
|
||||||
|
}
|
||||||
|
|
||||||
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
|
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
|
||||||
error= m_file[old_part_id]->ha_delete_row(old_data);
|
error= m_file[old_part_id]->ha_delete_row(old_data);
|
||||||
reenable_binlog(thd);
|
reenable_binlog(thd);
|
||||||
|
@ -1295,9 +1295,7 @@ public:
|
|||||||
{
|
{
|
||||||
handler *file= m_file[part_id];
|
handler *file= m_file[part_id];
|
||||||
DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
|
DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), part_id));
|
||||||
file->info(HA_STATUS_TIME | HA_STATUS_VARIABLE |
|
file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
|
||||||
HA_STATUS_VARIABLE_EXTRA | HA_STATUS_NO_LOCK);
|
|
||||||
|
|
||||||
part_recs+= file->stats.records;
|
part_recs+= file->stats.records;
|
||||||
}
|
}
|
||||||
return part_recs;
|
return part_recs;
|
||||||
|
20
sql/item.cc
20
sql/item.cc
@ -6989,6 +6989,26 @@ bool Item_temporal_literal::eq(const Item *item, bool binary_cmp) const
|
|||||||
&((Item_temporal_literal *) item)->cached_time);
|
&((Item_temporal_literal *) item)->cached_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item_temporal_literal::set_lower(MYSQL_TIME * ltime)
|
||||||
|
{
|
||||||
|
if (my_time_compare(ltime, &cached_time) < 0)
|
||||||
|
{
|
||||||
|
cached_time= *ltime;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Item_temporal_literal::set_higher(MYSQL_TIME * ltime)
|
||||||
|
{
|
||||||
|
if (my_time_compare(ltime, &cached_time) > 0)
|
||||||
|
{
|
||||||
|
cached_time= *ltime;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_date_literal::print(String *str, enum_query_type query_type)
|
void Item_date_literal::print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
|
@ -3865,6 +3865,12 @@ public:
|
|||||||
{ return val_decimal_from_date(decimal_value); }
|
{ return val_decimal_from_date(decimal_value); }
|
||||||
int save_in_field(Field *field, bool no_conversions)
|
int save_in_field(Field *field, bool no_conversions)
|
||||||
{ return save_date_in_field(field, no_conversions); }
|
{ return save_date_in_field(field, no_conversions); }
|
||||||
|
void set_time(MYSQL_TIME *ltime)
|
||||||
|
{
|
||||||
|
cached_time= *ltime;
|
||||||
|
}
|
||||||
|
bool set_lower(MYSQL_TIME *ltime);
|
||||||
|
bool set_higher(MYSQL_TIME *ltime);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1017,7 +1017,8 @@ static PSI_mutex_info all_server_mutexes[]=
|
|||||||
|
|
||||||
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
|
PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
|
||||||
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
|
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
|
||||||
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock;
|
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
|
||||||
|
key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial;
|
||||||
|
|
||||||
static PSI_rwlock_info all_server_rwlocks[]=
|
static PSI_rwlock_info all_server_rwlocks[]=
|
||||||
{
|
{
|
||||||
@ -1029,7 +1030,9 @@ static PSI_rwlock_info all_server_rwlocks[]=
|
|||||||
{ &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL},
|
{ &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_GLOBAL},
|
||||||
{ &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL},
|
{ &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_GLOBAL},
|
||||||
{ &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
|
{ &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
|
||||||
{ &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0}
|
{ &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0},
|
||||||
|
{ &key_rwlock_LOCK_vers_stats, "Vers_field_stats::lock", 0},
|
||||||
|
{ &key_rwlock_LOCK_stat_serial, "TABLE_SHARE::LOCK_stat_serial", 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
|
@ -314,7 +314,8 @@ extern PSI_mutex_key key_LOCK_gtid_waiting;
|
|||||||
|
|
||||||
extern PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
|
extern PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
|
||||||
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
|
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
|
||||||
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock;
|
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
|
||||||
|
key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial;
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_MMAP
|
||||||
extern PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
|
extern PSI_cond_key key_PAGE_cond, key_COND_active, key_COND_pool;
|
||||||
|
@ -3454,6 +3454,11 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
|||||||
free_root(&alloc,MYF(0)); // Return memory & allocator
|
free_root(&alloc,MYF(0)); // Return memory & allocator
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (part_info->part_type == VERSIONING_PARTITION)
|
||||||
|
{
|
||||||
|
part_info->vers_update_range_constants(thd);
|
||||||
|
}
|
||||||
|
|
||||||
dbug_tmp_use_all_columns(table, old_sets,
|
dbug_tmp_use_all_columns(table, old_sets,
|
||||||
table->read_set, table->write_set);
|
table->read_set, table->write_set);
|
||||||
@ -3980,7 +3985,7 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
|
|||||||
simply set res= -1 as if the mapper had returned that.
|
simply set res= -1 as if the mapper had returned that.
|
||||||
TODO: What to do here is defined in WL#4065.
|
TODO: What to do here is defined in WL#4065.
|
||||||
*/
|
*/
|
||||||
if (ppar->arg_stack[0]->part == 0)
|
if (ppar->arg_stack[0]->part == 0 || ppar->part_info->part_type == VERSIONING_PARTITION)
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
uint32 store_length_array[MAX_KEY];
|
uint32 store_length_array[MAX_KEY];
|
||||||
|
@ -90,38 +90,64 @@ typedef struct p_elem_val
|
|||||||
|
|
||||||
struct st_ddl_log_memory_entry;
|
struct st_ddl_log_memory_entry;
|
||||||
|
|
||||||
class Stat_timestampf : public Sql_alloc
|
class Vers_field_stats : public Sql_alloc
|
||||||
{
|
{
|
||||||
static const uint buf_size= 4 + (TIME_SECOND_PART_DIGITS + 1) / 2;
|
static const uint buf_size= 4 + (TIME_SECOND_PART_DIGITS + 1) / 2;
|
||||||
uchar min_buf[buf_size];
|
uchar min_buf[buf_size];
|
||||||
uchar max_buf[buf_size];
|
uchar max_buf[buf_size];
|
||||||
Field_timestampf min_value;
|
Field_timestampf min_value;
|
||||||
Field_timestampf max_value;
|
Field_timestampf max_value;
|
||||||
|
mysql_rwlock_t lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Stat_timestampf(const char *field_name, TABLE_SHARE *share) :
|
Vers_field_stats(const char *field_name, TABLE_SHARE *share) :
|
||||||
min_value(min_buf, NULL, 0, Field::NONE, field_name, share, 6),
|
min_value(min_buf, NULL, 0, Field::NONE, field_name, share, 6),
|
||||||
max_value(max_buf, NULL, 0, Field::NONE, field_name, share, 6)
|
max_value(max_buf, NULL, 0, Field::NONE, field_name, share, 6)
|
||||||
{
|
{
|
||||||
min_value.set_max();
|
min_value.set_max();
|
||||||
memset(max_buf, 0, buf_size);
|
memset(max_buf, 0, buf_size);
|
||||||
|
mysql_rwlock_init(key_rwlock_LOCK_vers_stats, &lock);
|
||||||
}
|
}
|
||||||
void update(Field *from)
|
~Vers_field_stats()
|
||||||
{
|
{
|
||||||
from->update_min(&min_value, false);
|
mysql_rwlock_destroy(&lock);
|
||||||
from->update_max(&max_value, false);
|
}
|
||||||
|
bool update_unguarded(Field *from)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
from->update_min(&min_value, false) +
|
||||||
|
from->update_max(&max_value, false);
|
||||||
|
}
|
||||||
|
bool update(Field *from)
|
||||||
|
{
|
||||||
|
mysql_rwlock_wrlock(&lock);
|
||||||
|
bool res= update_unguarded(from);
|
||||||
|
mysql_rwlock_unlock(&lock);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
my_time_t min_time()
|
my_time_t min_time()
|
||||||
{
|
{
|
||||||
return min_value.get_timestamp();
|
mysql_rwlock_rdlock(&lock);
|
||||||
|
my_time_t res= min_value.get_timestamp();
|
||||||
|
mysql_rwlock_unlock(&lock);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
my_time_t max_time()
|
my_time_t max_time()
|
||||||
{
|
{
|
||||||
return max_value.get_timestamp();
|
mysql_rwlock_rdlock(&lock);
|
||||||
|
my_time_t res= max_value.get_timestamp();
|
||||||
|
mysql_rwlock_unlock(&lock);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class partition_element :public Sql_alloc {
|
enum stat_trx_field
|
||||||
|
{
|
||||||
|
STAT_TRX_END= 0
|
||||||
|
};
|
||||||
|
|
||||||
|
class partition_element :public Sql_alloc
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
List<partition_element> subpartitions;
|
List<partition_element> subpartitions;
|
||||||
List<part_elem_value> list_val_list;
|
List<part_elem_value> list_val_list;
|
||||||
@ -142,6 +168,7 @@ public:
|
|||||||
bool signed_flag; // Range value signed
|
bool signed_flag; // Range value signed
|
||||||
bool max_value; // MAXVALUE range
|
bool max_value; // MAXVALUE range
|
||||||
uint32 id;
|
uint32 id;
|
||||||
|
bool empty;
|
||||||
|
|
||||||
enum elem_type
|
enum elem_type
|
||||||
{
|
{
|
||||||
@ -151,7 +178,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
elem_type type;
|
elem_type type;
|
||||||
Stat_timestampf *stat_trx_end;
|
|
||||||
|
|
||||||
partition_element()
|
partition_element()
|
||||||
: part_max_rows(0), part_min_rows(0), range_value(0),
|
: part_max_rows(0), part_min_rows(0), range_value(0),
|
||||||
@ -162,10 +188,9 @@ public:
|
|||||||
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
|
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
|
||||||
signed_flag(FALSE), max_value(FALSE),
|
signed_flag(FALSE), max_value(FALSE),
|
||||||
id(UINT32_MAX),
|
id(UINT32_MAX),
|
||||||
type(CONVENTIONAL),
|
empty(true),
|
||||||
stat_trx_end(NULL)
|
type(CONVENTIONAL)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
partition_element(partition_element *part_elem)
|
partition_element(partition_element *part_elem)
|
||||||
: part_max_rows(part_elem->part_max_rows),
|
: part_max_rows(part_elem->part_max_rows),
|
||||||
part_min_rows(part_elem->part_min_rows),
|
part_min_rows(part_elem->part_min_rows),
|
||||||
@ -180,11 +205,19 @@ public:
|
|||||||
nodegroup_id(part_elem->nodegroup_id),
|
nodegroup_id(part_elem->nodegroup_id),
|
||||||
has_null_value(FALSE),
|
has_null_value(FALSE),
|
||||||
id(part_elem->id),
|
id(part_elem->id),
|
||||||
type(part_elem->type),
|
empty(part_elem->empty),
|
||||||
stat_trx_end(NULL)
|
type(part_elem->type)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
~partition_element() {}
|
~partition_element() {}
|
||||||
|
|
||||||
|
part_column_list_val& get_col_val(uint idx)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(type != CONVENTIONAL);
|
||||||
|
DBUG_ASSERT(list_val_list.elements == 1);
|
||||||
|
part_elem_value *ev= static_cast<part_elem_value*>(list_val_list.first_node()->info);
|
||||||
|
DBUG_ASSERT(ev && ev->col_val_array);
|
||||||
|
return ev->col_val_array[idx];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PARTITION_ELEMENT_INCLUDED */
|
#endif /* PARTITION_ELEMENT_INCLUDED */
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <my_global.h>
|
#include <my_global.h>
|
||||||
|
#include <tztime.h>
|
||||||
#include "sql_priv.h"
|
#include "sql_priv.h"
|
||||||
// Required to get server definitions for mysql/plugin.h right
|
// Required to get server definitions for mysql/plugin.h right
|
||||||
#include "sql_plugin.h"
|
#include "sql_plugin.h"
|
||||||
@ -796,6 +797,7 @@ bool partition_info::vers_init_info(THD * thd)
|
|||||||
part_type= VERSIONING_PARTITION;
|
part_type= VERSIONING_PARTITION;
|
||||||
list_of_part_fields= TRUE;
|
list_of_part_fields= TRUE;
|
||||||
column_list= TRUE;
|
column_list= TRUE;
|
||||||
|
num_columns= 1;
|
||||||
vers_info= new (thd->mem_root) Vers_part_info;
|
vers_info= new (thd->mem_root) Vers_part_info;
|
||||||
if (!vers_info)
|
if (!vers_info)
|
||||||
{
|
{
|
||||||
@ -854,8 +856,11 @@ partition_element*
|
|||||||
partition_info::vers_part_rotate(THD * thd)
|
partition_info::vers_part_rotate(THD * thd)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(table && table->s);
|
DBUG_ASSERT(table && table->s);
|
||||||
if (table->s->free_parts.is_empty())
|
DBUG_ASSERT(vers_info && vers_info->initialized());
|
||||||
|
|
||||||
|
if (table->s->hist_part_id >= vers_info->now_part->id - 1)
|
||||||
{
|
{
|
||||||
|
DBUG_ASSERT(table->s->hist_part_id == vers_info->now_part->id - 1);
|
||||||
push_warning_printf(thd,
|
push_warning_printf(thd,
|
||||||
Sql_condition::WARN_LEVEL_WARN,
|
Sql_condition::WARN_LEVEL_WARN,
|
||||||
WARN_VERS_PART_FULL,
|
WARN_VERS_PART_FULL,
|
||||||
@ -864,8 +869,7 @@ partition_info::vers_part_rotate(THD * thd)
|
|||||||
return vers_info->hist_part;
|
return vers_info->hist_part;
|
||||||
}
|
}
|
||||||
|
|
||||||
table->s->vers_part_rotate();
|
table->s->hist_part_id++;
|
||||||
DBUG_ASSERT(table->s->hist_part_id < num_parts);
|
|
||||||
const char* old_part_name= vers_info->hist_part->partition_name;
|
const char* old_part_name= vers_info->hist_part->partition_name;
|
||||||
vers_hist_part();
|
vers_hist_part();
|
||||||
|
|
||||||
@ -879,18 +883,100 @@ partition_info::vers_part_rotate(THD * thd)
|
|||||||
return vers_info->hist_part;
|
return vers_info->hist_part;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool partition_info::vers_setup_1(THD * thd)
|
bool partition_info::vers_setup_1(THD * thd, uint32 added)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
||||||
|
|
||||||
if (!table->versioned())
|
if (!table->versioned())
|
||||||
{
|
{
|
||||||
my_error(ER_VERSIONING_REQUIRED, MYF(0), "`BY SYSTEM_TIME` partitioning");
|
my_error(ER_VERSIONING_REQUIRED, MYF(0), "`BY SYSTEM_TIME` partitioning");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Field *sys_trx_end= table->vers_end_field();
|
|
||||||
part_field_list.empty();
|
if (added)
|
||||||
part_field_list.push_back(const_cast<char *>(sys_trx_end->field_name), thd->mem_root);
|
{
|
||||||
sys_trx_end->flags|= GET_FIXED_FIELDS_FLAG; // needed in handle_list_of_fields()
|
DBUG_ASSERT(partitions.elements > added + 1);
|
||||||
|
Vers_field_stats** old_array= table->s->stat_trx;
|
||||||
|
table->s->stat_trx= static_cast<Vers_field_stats**>(
|
||||||
|
alloc_root(&table->s->mem_root, sizeof(void *) * partitions.elements * num_columns));
|
||||||
|
memcpy(table->s->stat_trx, old_array, sizeof(void *) * (partitions.elements - added) * num_columns);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Field *sys_trx_end= table->vers_end_field();
|
||||||
|
part_field_list.empty();
|
||||||
|
part_field_list.push_back(const_cast<char *>(sys_trx_end->field_name), thd->mem_root);
|
||||||
|
DBUG_ASSERT(part_field_list.elements == num_columns);
|
||||||
|
// needed in handle_list_of_fields()
|
||||||
|
sys_trx_end->flags|= GET_FIXED_FIELDS_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
List_iterator<partition_element> it(partitions);
|
||||||
|
partition_element *el;
|
||||||
|
MYSQL_TIME t;
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
my_time_t ts= TIMESTAMP_MAX_VALUE - partitions.elements;
|
||||||
|
uint32 id= 0;
|
||||||
|
while ((el= it++))
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(el->type != partition_element::CONVENTIONAL);
|
||||||
|
++ts;
|
||||||
|
if (added)
|
||||||
|
{
|
||||||
|
if (el->type == partition_element::VERSIONING && !el->empty)
|
||||||
|
{
|
||||||
|
++id;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (el->id == UINT32_MAX || el->type == partition_element::AS_OF_NOW)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(table && table->s);
|
||||||
|
Vers_field_stats *stat_trx_end= new (&table->s->mem_root)
|
||||||
|
Vers_field_stats(table->s->vers_end_field()->field_name, table->s);
|
||||||
|
table->s->stat_trx[id * num_columns + STAT_TRX_END]= stat_trx_end;
|
||||||
|
el->id= id++;
|
||||||
|
if (el->type == partition_element::AS_OF_NOW)
|
||||||
|
break;
|
||||||
|
goto create_col_val;
|
||||||
|
}
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(&t, ts);
|
||||||
|
for (uint i= 0; i < num_columns; ++i)
|
||||||
|
{
|
||||||
|
part_column_list_val &col_val= el->get_col_val(i);
|
||||||
|
static_cast<Item_datetime_literal *>(col_val.item_expression)->set_time(&t);
|
||||||
|
col_val.fixed= 0;
|
||||||
|
}
|
||||||
|
++id;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_col_val:
|
||||||
|
curr_part_elem= el;
|
||||||
|
init_column_part(thd);
|
||||||
|
el->list_val_list.empty();
|
||||||
|
el->list_val_list.push_back(curr_list_val, thd->mem_root);
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(&t, ts);
|
||||||
|
for (uint i= 0; i < num_columns; ++i)
|
||||||
|
{
|
||||||
|
part_column_list_val *col_val= add_column_value(thd);
|
||||||
|
if (el->type == partition_element::AS_OF_NOW)
|
||||||
|
{
|
||||||
|
col_val->max_value= true;
|
||||||
|
col_val->item_expression= NULL;
|
||||||
|
col_val->column_value= NULL;
|
||||||
|
col_val->part_info= this;
|
||||||
|
col_val->fixed= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Item *item_expression= new (thd->mem_root) Item_datetime_literal(thd, &t);
|
||||||
|
/* We initialize col_val with bogus max value to make fix_partition_func() and check_range_constants() happy.
|
||||||
|
Later in vers_setup_2() it is initialized with real stat value if there will be any. */
|
||||||
|
/* FIXME: TIME_RESULT in col_val is expensive. It should be INT_RESULT
|
||||||
|
(got to be fixed when InnoDB is supported). */
|
||||||
|
init_col_val(col_val, item_expression);
|
||||||
|
DBUG_ASSERT(item_expression == el->get_col_val(i).item_expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,6 +988,8 @@ bool partition_info::vers_scan_min_max(THD *thd, partition_element *part)
|
|||||||
uint32 sub_factor= num_subparts ? num_subparts : 1;
|
uint32 sub_factor= num_subparts ? num_subparts : 1;
|
||||||
uint32 part_id= part->id * sub_factor;
|
uint32 part_id= part->id * sub_factor;
|
||||||
uint32 part_id_end= part_id + sub_factor;
|
uint32 part_id_end= part_id + sub_factor;
|
||||||
|
DBUG_ASSERT(part->empty);
|
||||||
|
DBUG_ASSERT(table->s->stat_trx);
|
||||||
for (; part_id < part_id_end; ++part_id)
|
for (; part_id < part_id_end; ++part_id)
|
||||||
{
|
{
|
||||||
handler *file= table->file->part_handler(part_id);
|
handler *file= table->file->part_handler(part_id);
|
||||||
@ -913,6 +1001,8 @@ bool partition_info::vers_scan_min_max(THD *thd, partition_element *part)
|
|||||||
{
|
{
|
||||||
while ((rc= file->ha_rnd_next(table->record[0])) != HA_ERR_END_OF_FILE)
|
while ((rc= file->ha_rnd_next(table->record[0])) != HA_ERR_END_OF_FILE)
|
||||||
{
|
{
|
||||||
|
if (part->empty)
|
||||||
|
part->empty= false;
|
||||||
if (thd->killed)
|
if (thd->killed)
|
||||||
{
|
{
|
||||||
file->ha_rnd_end();
|
file->ha_rnd_end();
|
||||||
@ -924,7 +1014,7 @@ bool partition_info::vers_scan_min_max(THD *thd, partition_element *part)
|
|||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
part->stat_trx_end->update(table->vers_end_field());
|
vers_stat_trx(STAT_TRX_END, part).update_unguarded(table->vers_end_field());
|
||||||
}
|
}
|
||||||
file->ha_rnd_end();
|
file->ha_rnd_end();
|
||||||
}
|
}
|
||||||
@ -939,12 +1029,49 @@ bool partition_info::vers_scan_min_max(THD *thd, partition_element *part)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void partition_info::vers_update_col_vals(THD *thd, partition_element *el0, partition_element *el1)
|
||||||
|
{
|
||||||
|
MYSQL_TIME t;
|
||||||
|
memset(&t, 0, sizeof(t));
|
||||||
|
DBUG_ASSERT(table && table->s && table->s->stat_trx);
|
||||||
|
DBUG_ASSERT(!el0 || el1->id == el0->id + 1);
|
||||||
|
const uint idx= el1->id * num_columns;
|
||||||
|
my_time_t ts;
|
||||||
|
part_column_list_val *col_val;
|
||||||
|
Item_datetime_literal *val_item;
|
||||||
|
Vers_field_stats *stat_trx_x;
|
||||||
|
for (uint i= 0; i < num_columns; ++i)
|
||||||
|
{
|
||||||
|
stat_trx_x= table->s->stat_trx[idx + i];
|
||||||
|
if (el0)
|
||||||
|
{
|
||||||
|
ts= stat_trx_x->min_time();
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(&t, ts);
|
||||||
|
col_val= &el0->get_col_val(i);
|
||||||
|
val_item= static_cast<Item_datetime_literal*>(col_val->item_expression);
|
||||||
|
DBUG_ASSERT(val_item);
|
||||||
|
if (val_item->set_lower(&t))
|
||||||
|
col_val->fixed= 0;
|
||||||
|
}
|
||||||
|
col_val= &el1->get_col_val(i);
|
||||||
|
if (!col_val->max_value)
|
||||||
|
{
|
||||||
|
ts= stat_trx_x->max_time() + 1;
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(&t, ts);
|
||||||
|
val_item= static_cast<Item_datetime_literal*>(col_val->item_expression);
|
||||||
|
DBUG_ASSERT(val_item);
|
||||||
|
if (val_item->set_higher(&t))
|
||||||
|
col_val->fixed= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// setup at open stage (TABLE_SHARE is initialized)
|
// setup at open stage (TABLE_SHARE is initialized)
|
||||||
bool partition_info::vers_setup_2(THD * thd, bool is_create_table_ind)
|
bool partition_info::vers_setup_2(THD * thd, bool is_create_table_ind)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
DBUG_ASSERT(part_type == VERSIONING_PARTITION);
|
||||||
DBUG_ASSERT(vers_info && vers_info->initialized(is_create_table_ind) && vers_info->hist_default != UINT32_MAX);
|
DBUG_ASSERT(vers_info && vers_info->initialized(false));
|
||||||
DBUG_ASSERT(table && table->s);
|
DBUG_ASSERT(table && table->s);
|
||||||
if (!table->versioned_by_sql())
|
if (!table->versioned_by_sql())
|
||||||
{
|
{
|
||||||
@ -961,38 +1088,78 @@ bool partition_info::vers_setup_2(THD * thd, bool is_create_table_ind)
|
|||||||
{
|
{
|
||||||
table->s->busy_rotation= true;
|
table->s->busy_rotation= true;
|
||||||
mysql_mutex_unlock(&table->s->LOCK_rotation);
|
mysql_mutex_unlock(&table->s->LOCK_rotation);
|
||||||
|
|
||||||
|
DBUG_ASSERT(part_field_list.elements == num_columns);
|
||||||
|
|
||||||
|
bool dont_stat= true;
|
||||||
|
bool col_val_updated= false;
|
||||||
|
if (!table->s->stat_trx)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(partitions.elements > 1);
|
||||||
|
table->s->stat_trx= static_cast<Vers_field_stats**>(
|
||||||
|
alloc_root(&table->s->mem_root, sizeof(void *) * partitions.elements * num_columns));
|
||||||
|
dont_stat= false;
|
||||||
|
}
|
||||||
|
|
||||||
// build freelist, scan min/max, assign hist_part
|
// build freelist, scan min/max, assign hist_part
|
||||||
List_iterator<partition_element> it(partitions);
|
List_iterator<partition_element> it(partitions);
|
||||||
partition_element *el;
|
partition_element *el= NULL, *prev;
|
||||||
while ((el= it++))
|
while ((prev= el, el= it++))
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(el->type != partition_element::CONVENTIONAL);
|
if (el->type == partition_element::VERSIONING && dont_stat)
|
||||||
if (el->type == partition_element::VERSIONING)
|
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!el->stat_trx_end);
|
if (el->id == table->s->hist_part_id)
|
||||||
el->stat_trx_end= new (&table->mem_root)
|
{
|
||||||
Stat_timestampf(table->s->vers_end_field()->field_name, table->s);
|
vers_info->hist_part= el;
|
||||||
if (!is_create_table_ind && vers_scan_min_max(thd, el))
|
break;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
if (el == vers_info->now_part || el == vers_info->hist_part)
|
|
||||||
continue;
|
continue;
|
||||||
if (!vers_info->hist_part && el->id == vers_info->hist_default)
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
Vers_field_stats *stat_trx_end= new (&table->s->mem_root)
|
||||||
|
Vers_field_stats(table->s->vers_end_field()->field_name, table->s);
|
||||||
|
table->s->stat_trx[el->id * num_columns + STAT_TRX_END]= stat_trx_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_create_table_ind)
|
||||||
|
{
|
||||||
|
if (vers_scan_min_max(thd, el))
|
||||||
|
return true;
|
||||||
|
if (!el->empty)
|
||||||
|
{
|
||||||
|
vers_update_col_vals(thd, prev, el);
|
||||||
|
col_val_updated= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el->type == partition_element::AS_OF_NOW)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DBUG_ASSERT(el->type == partition_element::VERSIONING);
|
||||||
|
|
||||||
|
if (vers_info->hist_part)
|
||||||
|
{
|
||||||
|
if (!el->empty)
|
||||||
|
goto set_hist_part;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set_hist_part:
|
||||||
vers_info->hist_part= el;
|
vers_info->hist_part= el;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (is_create_table_ind || (
|
} // while
|
||||||
table->s->free_parts_init &&
|
|
||||||
!vers_limit_exceed(el) &&
|
if (!dont_stat)
|
||||||
!vers_interval_exceed(el)))
|
{
|
||||||
{
|
if (col_val_updated)
|
||||||
table->s->free_parts.push_back((void *) el->id, &table->s->mem_root);
|
table->s->stat_serial++;
|
||||||
}
|
|
||||||
|
table->s->hist_part_id= vers_info->hist_part->id;
|
||||||
|
if (!is_create_table_ind && (vers_limit_exceed() || vers_interval_exceed()))
|
||||||
|
vers_part_rotate(thd);
|
||||||
}
|
}
|
||||||
table->s->hist_part_id= vers_info->hist_part->id;
|
|
||||||
if (!is_create_table_ind && (vers_limit_exceed() || vers_interval_exceed()))
|
|
||||||
vers_part_rotate(thd);
|
|
||||||
table->s->free_parts_init= false;
|
|
||||||
mysql_mutex_lock(&table->s->LOCK_rotation);
|
mysql_mutex_lock(&table->s->LOCK_rotation);
|
||||||
mysql_cond_broadcast(&table->s->COND_rotation);
|
mysql_cond_broadcast(&table->s->COND_rotation);
|
||||||
table->s->busy_rotation= false;
|
table->s->busy_rotation= false;
|
||||||
@ -1184,7 +1351,7 @@ error:
|
|||||||
called for RANGE PARTITIONed tables.
|
called for RANGE PARTITIONed tables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool partition_info::check_range_constants(THD *thd)
|
bool partition_info::check_range_constants(THD *thd, bool init)
|
||||||
{
|
{
|
||||||
partition_element* part_def;
|
partition_element* part_def;
|
||||||
bool first= TRUE;
|
bool first= TRUE;
|
||||||
@ -1201,12 +1368,15 @@ bool partition_info::check_range_constants(THD *thd)
|
|||||||
part_column_list_val *UNINIT_VAR(current_largest_col_val);
|
part_column_list_val *UNINIT_VAR(current_largest_col_val);
|
||||||
uint num_column_values= part_field_list.elements;
|
uint num_column_values= part_field_list.elements;
|
||||||
uint size_entries= sizeof(part_column_list_val) * num_column_values;
|
uint size_entries= sizeof(part_column_list_val) * num_column_values;
|
||||||
range_col_array= (part_column_list_val*) thd->calloc(num_parts *
|
if (init)
|
||||||
size_entries);
|
|
||||||
if (unlikely(range_col_array == NULL))
|
|
||||||
{
|
{
|
||||||
mem_alloc_error(num_parts * size_entries);
|
range_col_array= (part_column_list_val*) thd->calloc(num_parts *
|
||||||
goto end;
|
size_entries);
|
||||||
|
if (unlikely(range_col_array == NULL))
|
||||||
|
{
|
||||||
|
mem_alloc_error(num_parts * size_entries);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loc_range_col_array= range_col_array;
|
loc_range_col_array= range_col_array;
|
||||||
i= 0;
|
i= 0;
|
||||||
@ -1239,11 +1409,14 @@ bool partition_info::check_range_constants(THD *thd)
|
|||||||
longlong part_range_value;
|
longlong part_range_value;
|
||||||
bool signed_flag= !part_expr->unsigned_flag;
|
bool signed_flag= !part_expr->unsigned_flag;
|
||||||
|
|
||||||
range_int_array= (longlong*) thd->alloc(num_parts * sizeof(longlong));
|
if (init)
|
||||||
if (unlikely(range_int_array == NULL))
|
|
||||||
{
|
{
|
||||||
mem_alloc_error(num_parts * sizeof(longlong));
|
range_int_array= (longlong*) thd->alloc(num_parts * sizeof(longlong));
|
||||||
goto end;
|
if (unlikely(range_int_array == NULL))
|
||||||
|
{
|
||||||
|
mem_alloc_error(num_parts * sizeof(longlong));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
i= 0;
|
i= 0;
|
||||||
do
|
do
|
||||||
@ -1609,7 +1782,6 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||||||
char *same_name;
|
char *same_name;
|
||||||
uint32 hist_parts= 0;
|
uint32 hist_parts= 0;
|
||||||
uint32 now_parts= 0;
|
uint32 now_parts= 0;
|
||||||
const char* hist_default= NULL;
|
|
||||||
DBUG_ENTER("partition_info::check_partition_info");
|
DBUG_ENTER("partition_info::check_partition_info");
|
||||||
DBUG_ASSERT(default_engine_type != partition_hton);
|
DBUG_ASSERT(default_engine_type != partition_hton);
|
||||||
|
|
||||||
@ -1816,13 +1988,6 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||||||
if (part_elem->type == partition_element::VERSIONING)
|
if (part_elem->type == partition_element::VERSIONING)
|
||||||
{
|
{
|
||||||
hist_parts++;
|
hist_parts++;
|
||||||
if (vers_info->hist_default == UINT32_MAX)
|
|
||||||
{
|
|
||||||
vers_info->hist_default= part_elem->id;
|
|
||||||
hist_default= part_elem->partition_name;
|
|
||||||
}
|
|
||||||
if (vers_info->hist_default == part_elem->id)
|
|
||||||
vers_info->hist_part= part_elem;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1861,7 +2026,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||||||
|
|
||||||
if (add_or_reorg_part)
|
if (add_or_reorg_part)
|
||||||
{
|
{
|
||||||
if (unlikely((part_type == RANGE_PARTITION &&
|
if (unlikely(((part_type == RANGE_PARTITION || part_type == VERSIONING_PARTITION) &&
|
||||||
check_range_constants(thd)) ||
|
check_range_constants(thd)) ||
|
||||||
(part_type == LIST_PARTITION &&
|
(part_type == LIST_PARTITION &&
|
||||||
check_list_constants(thd))))
|
check_list_constants(thd))))
|
||||||
@ -1878,14 +2043,6 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||||||
ER_THD(thd, WARN_VERS_PARAMETERS),
|
ER_THD(thd, WARN_VERS_PARAMETERS),
|
||||||
"no rotation condition for multiple `VERSIONING` partitions.");
|
"no rotation condition for multiple `VERSIONING` partitions.");
|
||||||
}
|
}
|
||||||
if (hist_default)
|
|
||||||
{
|
|
||||||
push_warning_printf(thd,
|
|
||||||
Sql_condition::WARN_LEVEL_WARN,
|
|
||||||
WARN_VERS_PARAMETERS,
|
|
||||||
"No `DEFAULT` for `VERSIONING` partitions. Setting `%s` as default.",
|
|
||||||
hist_default);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (now_parts > 1)
|
if (now_parts > 1)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ struct Vers_part_info : public Sql_alloc
|
|||||||
limit(0),
|
limit(0),
|
||||||
now_part(NULL),
|
now_part(NULL),
|
||||||
hist_part(NULL),
|
hist_part(NULL),
|
||||||
hist_default(UINT32_MAX)
|
stat_serial(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Vers_part_info(Vers_part_info &src) :
|
Vers_part_info(Vers_part_info &src) :
|
||||||
@ -49,7 +49,7 @@ struct Vers_part_info : public Sql_alloc
|
|||||||
limit(src.limit),
|
limit(src.limit),
|
||||||
now_part(NULL),
|
now_part(NULL),
|
||||||
hist_part(NULL),
|
hist_part(NULL),
|
||||||
hist_default(src.hist_default)
|
stat_serial(src.stat_serial)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
bool initialized(bool fully= true)
|
bool initialized(bool fully= true)
|
||||||
@ -71,7 +71,7 @@ struct Vers_part_info : public Sql_alloc
|
|||||||
ulonglong limit;
|
ulonglong limit;
|
||||||
partition_element *now_part;
|
partition_element *now_part;
|
||||||
partition_element *hist_part;
|
partition_element *hist_part;
|
||||||
uint32 hist_default;
|
ulonglong stat_serial;
|
||||||
};
|
};
|
||||||
|
|
||||||
class partition_info : public Sql_alloc
|
class partition_info : public Sql_alloc
|
||||||
@ -182,8 +182,9 @@ public:
|
|||||||
LIST_PART_ENTRY *list_array;
|
LIST_PART_ENTRY *list_array;
|
||||||
part_column_list_val *range_col_array;
|
part_column_list_val *range_col_array;
|
||||||
part_column_list_val *list_col_array;
|
part_column_list_val *list_col_array;
|
||||||
Vers_part_info *vers_info;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Vers_part_info *vers_info;
|
||||||
|
|
||||||
/********************************************
|
/********************************************
|
||||||
* INTERVAL ANALYSIS
|
* INTERVAL ANALYSIS
|
||||||
@ -350,7 +351,7 @@ public:
|
|||||||
char *find_duplicate_field();
|
char *find_duplicate_field();
|
||||||
char *find_duplicate_name();
|
char *find_duplicate_name();
|
||||||
bool check_engine_mix(handlerton *engine_type, bool default_engine);
|
bool check_engine_mix(handlerton *engine_type, bool default_engine);
|
||||||
bool check_range_constants(THD *thd);
|
bool check_range_constants(THD *thd, bool init= true);
|
||||||
bool check_list_constants(THD *thd);
|
bool check_list_constants(THD *thd);
|
||||||
bool check_partition_info(THD *thd, handlerton **eng_type,
|
bool check_partition_info(THD *thd, handlerton **eng_type,
|
||||||
handler *file, HA_CREATE_INFO *info,
|
handler *file, HA_CREATE_INFO *info,
|
||||||
@ -400,9 +401,10 @@ public:
|
|||||||
bool vers_set_interval(const INTERVAL &i);
|
bool vers_set_interval(const INTERVAL &i);
|
||||||
bool vers_set_limit(ulonglong limit);
|
bool vers_set_limit(ulonglong limit);
|
||||||
partition_element* vers_part_rotate(THD *thd);
|
partition_element* vers_part_rotate(THD *thd);
|
||||||
bool vers_setup_1(THD *thd);
|
bool vers_setup_1(THD *thd, uint32 added= 0);
|
||||||
bool vers_setup_2(THD *thd, bool is_create_table_ind);
|
bool vers_setup_2(THD *thd, bool is_create_table_ind);
|
||||||
bool vers_scan_min_max(THD *thd, partition_element *part);
|
bool vers_scan_min_max(THD *thd, partition_element *part);
|
||||||
|
void vers_update_col_vals(THD *thd, partition_element *el0, partition_element *el1);
|
||||||
|
|
||||||
partition_element *vers_hist_part()
|
partition_element *vers_hist_part()
|
||||||
{
|
{
|
||||||
@ -427,6 +429,17 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
partition_element *get_partition(uint part_id)
|
||||||
|
{
|
||||||
|
List_iterator<partition_element> it(partitions);
|
||||||
|
partition_element *el;
|
||||||
|
while ((el= it++))
|
||||||
|
{
|
||||||
|
if (el->id == part_id)
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
bool vers_limit_exceed(partition_element *part= NULL)
|
bool vers_limit_exceed(partition_element *part= NULL)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(vers_info);
|
DBUG_ASSERT(vers_info);
|
||||||
@ -440,6 +453,18 @@ public:
|
|||||||
// TODO: cache thread-shared part_recs and increment on INSERT
|
// TODO: cache thread-shared part_recs and increment on INSERT
|
||||||
return table->file->part_recs_slow(part) >= vers_info->limit;
|
return table->file->part_recs_slow(part) >= vers_info->limit;
|
||||||
}
|
}
|
||||||
|
Vers_field_stats& vers_stat_trx(stat_trx_field fld, uint32 part_element_id)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(table && table->s && table->s->stat_trx);
|
||||||
|
Vers_field_stats* res= table->s->stat_trx[part_element_id * num_columns + fld];
|
||||||
|
DBUG_ASSERT(res);
|
||||||
|
return *res;
|
||||||
|
}
|
||||||
|
Vers_field_stats& vers_stat_trx(stat_trx_field fld, partition_element *part)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(part);
|
||||||
|
return vers_stat_trx(fld, part->id);
|
||||||
|
}
|
||||||
bool vers_interval_exceed(my_time_t max_time, partition_element *part= NULL)
|
bool vers_interval_exceed(my_time_t max_time, partition_element *part= NULL)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(vers_info);
|
DBUG_ASSERT(vers_info);
|
||||||
@ -450,19 +475,63 @@ public:
|
|||||||
DBUG_ASSERT(vers_info->initialized());
|
DBUG_ASSERT(vers_info->initialized());
|
||||||
part= vers_hist_part();
|
part= vers_hist_part();
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(part->stat_trx_end);
|
max_time-= vers_stat_trx(STAT_TRX_END, part).min_time();
|
||||||
max_time-= part->stat_trx_end->min_time();
|
|
||||||
return max_time > vers_info->interval;
|
return max_time > vers_info->interval;
|
||||||
}
|
}
|
||||||
bool vers_interval_exceed(partition_element *part)
|
bool vers_interval_exceed(partition_element *part)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(part->stat_trx_end);
|
return vers_interval_exceed(vers_stat_trx(STAT_TRX_END, part).max_time(), part);
|
||||||
return vers_interval_exceed(part->stat_trx_end->max_time(), part);
|
|
||||||
}
|
}
|
||||||
bool vers_interval_exceed()
|
bool vers_interval_exceed()
|
||||||
{
|
{
|
||||||
return vers_interval_exceed(vers_hist_part());
|
return vers_interval_exceed(vers_hist_part());
|
||||||
}
|
}
|
||||||
|
void vers_update_stats(THD *thd, partition_element *el)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(vers_info && vers_info->initialized());
|
||||||
|
DBUG_ASSERT(table && table->s);
|
||||||
|
DBUG_ASSERT(el && el->type == partition_element::VERSIONING);
|
||||||
|
mysql_rwlock_wrlock(&table->s->LOCK_stat_serial);
|
||||||
|
el->empty= false;
|
||||||
|
bool updated=
|
||||||
|
vers_stat_trx(STAT_TRX_END, el->id).update(table->vers_end_field());
|
||||||
|
if (updated)
|
||||||
|
table->s->stat_serial++;
|
||||||
|
mysql_rwlock_unlock(&table->s->LOCK_stat_serial);
|
||||||
|
if (updated)
|
||||||
|
{
|
||||||
|
vers_update_col_vals(thd,
|
||||||
|
el->id > 0 ? get_partition(el->id - 1) : NULL,
|
||||||
|
el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void vers_update_stats(THD *thd, uint part_id)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(vers_info && vers_info->initialized());
|
||||||
|
if (part_id < vers_info->now_part->id)
|
||||||
|
vers_update_stats(thd, get_partition(part_id));
|
||||||
|
}
|
||||||
|
void vers_update_range_constants(THD *thd)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(vers_info && vers_info->initialized());
|
||||||
|
DBUG_ASSERT(table && table->s);
|
||||||
|
|
||||||
|
mysql_rwlock_rdlock(&table->s->LOCK_stat_serial);
|
||||||
|
if (vers_info->stat_serial == table->s->stat_serial)
|
||||||
|
{
|
||||||
|
mysql_rwlock_unlock(&table->s->LOCK_stat_serial);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint i= 0; i < num_columns; ++i)
|
||||||
|
{
|
||||||
|
Field *f= part_field_array[i];
|
||||||
|
bitmap_set_bit(f->table->write_set, f->field_index);
|
||||||
|
}
|
||||||
|
check_range_constants(thd, false);
|
||||||
|
vers_info->stat_serial= table->s->stat_serial;
|
||||||
|
mysql_rwlock_unlock(&table->s->LOCK_stat_serial);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
|
uint32 get_next_partition_id_range(struct st_partition_iter* part_iter);
|
||||||
|
@ -1716,6 +1716,8 @@ bool fix_partition_func(THD *thd, TABLE *table,
|
|||||||
else if (part_info->part_type == VERSIONING_PARTITION)
|
else if (part_info->part_type == VERSIONING_PARTITION)
|
||||||
{
|
{
|
||||||
error_str= partition_keywords[PKW_SYSTEM_TIME].str;
|
error_str= partition_keywords[PKW_SYSTEM_TIME].str;
|
||||||
|
if (unlikely(part_info->check_range_constants(thd)))
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2396,9 +2398,6 @@ static int add_partition_values(File fptr, partition_info *part_info,
|
|||||||
break;
|
break;
|
||||||
case partition_element::VERSIONING:
|
case partition_element::VERSIONING:
|
||||||
err+= add_string(fptr, " VERSIONING");
|
err+= add_string(fptr, " VERSIONING");
|
||||||
DBUG_ASSERT(part_info->vers_info);
|
|
||||||
if (part_info->vers_info->hist_default == p_elem->id)
|
|
||||||
err+= add_string(fptr, " DEFAULT");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0 && "wrong p_elem->type");
|
DBUG_ASSERT(0 && "wrong p_elem->type");
|
||||||
@ -3423,7 +3422,8 @@ int vers_get_partition_id(partition_info *part_info,
|
|||||||
longlong *func_value)
|
longlong *func_value)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("vers_get_partition_id");
|
DBUG_ENTER("vers_get_partition_id");
|
||||||
Field *sys_trx_end= part_info->part_field_array[0];
|
DBUG_ASSERT(part_info);
|
||||||
|
Field *sys_trx_end= part_info->part_field_array[STAT_TRX_END];
|
||||||
DBUG_ASSERT(sys_trx_end);
|
DBUG_ASSERT(sys_trx_end);
|
||||||
DBUG_ASSERT(part_info->table);
|
DBUG_ASSERT(part_info->table);
|
||||||
Vers_part_info *vers_info= part_info->vers_info;
|
Vers_part_info *vers_info= part_info->vers_info;
|
||||||
@ -3438,7 +3438,6 @@ int vers_get_partition_id(partition_info *part_info,
|
|||||||
}
|
}
|
||||||
else // row is historical
|
else // row is historical
|
||||||
{
|
{
|
||||||
partition_element *part= vers_info->hist_part;
|
|
||||||
THD *thd= current_thd;
|
THD *thd= current_thd;
|
||||||
TABLE *table= part_info->table;
|
TABLE *table= part_info->table;
|
||||||
|
|
||||||
@ -3461,18 +3460,13 @@ int vers_get_partition_id(partition_info *part_info,
|
|||||||
mysql_mutex_unlock(&table->s->LOCK_rotation);
|
mysql_mutex_unlock(&table->s->LOCK_rotation);
|
||||||
if (part_info->vers_limit_exceed() || part_info->vers_interval_exceed(sys_trx_end->get_timestamp()))
|
if (part_info->vers_limit_exceed() || part_info->vers_interval_exceed(sys_trx_end->get_timestamp()))
|
||||||
{
|
{
|
||||||
part= part_info->vers_part_rotate(thd);
|
part_info->vers_part_rotate(thd);
|
||||||
}
|
}
|
||||||
mysql_mutex_lock(&table->s->LOCK_rotation);
|
mysql_mutex_lock(&table->s->LOCK_rotation);
|
||||||
mysql_cond_broadcast(&table->s->COND_rotation);
|
mysql_cond_broadcast(&table->s->COND_rotation);
|
||||||
table->s->busy_rotation= false;
|
table->s->busy_rotation= false;
|
||||||
}
|
}
|
||||||
mysql_mutex_unlock(&table->s->LOCK_rotation);
|
mysql_mutex_unlock(&table->s->LOCK_rotation);
|
||||||
if (vers_info->interval)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(part->stat_trx_end);
|
|
||||||
part->stat_trx_end->update(sys_trx_end);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
@ -5295,6 +5289,21 @@ that are reorganised.
|
|||||||
partition configuration is made.
|
partition configuration is made.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
partition_element *now_part= NULL;
|
||||||
|
if (tab_part_info->part_type == VERSIONING_PARTITION)
|
||||||
|
{
|
||||||
|
List_iterator<partition_element> it(tab_part_info->partitions);
|
||||||
|
partition_element *el;
|
||||||
|
while ((el= it++))
|
||||||
|
{
|
||||||
|
if (el->type == partition_element::AS_OF_NOW)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(tab_part_info->vers_info && el == tab_part_info->vers_info->now_part);
|
||||||
|
it.remove();
|
||||||
|
now_part= el;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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;
|
||||||
do
|
do
|
||||||
@ -5309,6 +5318,15 @@ that are reorganised.
|
|||||||
}
|
}
|
||||||
} while (++part_count < num_new_partitions);
|
} while (++part_count < num_new_partitions);
|
||||||
tab_part_info->num_parts+= num_new_partitions;
|
tab_part_info->num_parts+= num_new_partitions;
|
||||||
|
if (tab_part_info->part_type == VERSIONING_PARTITION)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(now_part);
|
||||||
|
if (tab_part_info->partitions.push_back(now_part, thd->mem_root))
|
||||||
|
{
|
||||||
|
mem_alloc_error(1);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
If we specify partitions explicitly we don't use defaults anymore.
|
If we specify partitions explicitly we don't use defaults anymore.
|
||||||
@ -5697,6 +5715,12 @@ the generated partition syntax in a correct manner.
|
|||||||
tab_part_info->use_default_subpartitions= FALSE;
|
tab_part_info->use_default_subpartitions= FALSE;
|
||||||
tab_part_info->use_default_num_subpartitions= FALSE;
|
tab_part_info->use_default_num_subpartitions= FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alter_info->flags & Alter_info::ALTER_ADD_PARTITION &&
|
||||||
|
tab_part_info->part_type == VERSIONING_PARTITION &&
|
||||||
|
tab_part_info->vers_setup_1(thd, alt_part_info->partitions.elements))
|
||||||
|
goto err;
|
||||||
|
|
||||||
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
|
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
|
||||||
table->file, 0, TRUE))
|
table->file, 0, TRUE))
|
||||||
{
|
{
|
||||||
@ -7548,6 +7572,7 @@ static void set_up_range_analysis_info(partition_info *part_info)
|
|||||||
switch (part_info->part_type) {
|
switch (part_info->part_type) {
|
||||||
case RANGE_PARTITION:
|
case RANGE_PARTITION:
|
||||||
case LIST_PARTITION:
|
case LIST_PARTITION:
|
||||||
|
case VERSIONING_PARTITION:
|
||||||
if (!part_info->column_list)
|
if (!part_info->column_list)
|
||||||
{
|
{
|
||||||
if (part_info->part_expr->get_monotonicity_info() != NON_MONOTONIC)
|
if (part_info->part_expr->get_monotonicity_info() != NON_MONOTONIC)
|
||||||
@ -7848,7 +7873,7 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
|
|||||||
uint full_length= 0;
|
uint full_length= 0;
|
||||||
DBUG_ENTER("get_part_iter_for_interval_cols_via_map");
|
DBUG_ENTER("get_part_iter_for_interval_cols_via_map");
|
||||||
|
|
||||||
if (part_info->part_type == RANGE_PARTITION)
|
if (part_info->part_type == RANGE_PARTITION || part_info->part_type == VERSIONING_PARTITION)
|
||||||
{
|
{
|
||||||
get_col_endpoint= get_partition_id_cols_range_for_endpoint;
|
get_col_endpoint= get_partition_id_cols_range_for_endpoint;
|
||||||
part_iter->get_next= get_next_partition_id_range;
|
part_iter->get_next= get_next_partition_id_range;
|
||||||
@ -7894,7 +7919,7 @@ int get_part_iter_for_interval_cols_via_map(partition_info *part_info,
|
|||||||
}
|
}
|
||||||
if (flags & NO_MAX_RANGE)
|
if (flags & NO_MAX_RANGE)
|
||||||
{
|
{
|
||||||
if (part_info->part_type == RANGE_PARTITION)
|
if (part_info->part_type == RANGE_PARTITION || part_info->part_type == VERSIONING_PARTITION)
|
||||||
part_iter->part_nums.end= part_info->num_parts;
|
part_iter->part_nums.end= part_info->num_parts;
|
||||||
else /* LIST_PARTITION */
|
else /* LIST_PARTITION */
|
||||||
{
|
{
|
||||||
|
@ -5197,6 +5197,7 @@ opt_part_values:
|
|||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
partition_info *part_info= lex->part_info;
|
partition_info *part_info= lex->part_info;
|
||||||
|
partition_element *elem= part_info->curr_part_elem;
|
||||||
if (! lex->is_partition_management())
|
if (! lex->is_partition_management())
|
||||||
{
|
{
|
||||||
if (part_info->part_type != VERSIONING_PARTITION)
|
if (part_info->part_type != VERSIONING_PARTITION)
|
||||||
@ -5205,17 +5206,22 @@ opt_part_values:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
part_info->vers_init_info(thd);
|
// FIXME: other ALTER commands?
|
||||||
|
my_yyabort_error((ER_VERS_WRONG_PARAMS, MYF(0), "BY SYSTEM_TIME", "AS OF NOW partition can not be added"));
|
||||||
}
|
}
|
||||||
partition_element *elem= part_info->curr_part_elem;
|
|
||||||
elem->type= partition_element::AS_OF_NOW;
|
elem->type= partition_element::AS_OF_NOW;
|
||||||
DBUG_ASSERT(part_info->vers_info);
|
DBUG_ASSERT(part_info->vers_info);
|
||||||
part_info->vers_info->now_part= elem;
|
part_info->vers_info->now_part= elem;
|
||||||
|
if (part_info->init_column_part(thd))
|
||||||
|
{
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
| VERSIONING_SYM
|
| VERSIONING_SYM
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
partition_info *part_info= lex->part_info;
|
partition_info *part_info= lex->part_info;
|
||||||
|
partition_element *elem= part_info->curr_part_elem;
|
||||||
if (! lex->is_partition_management())
|
if (! lex->is_partition_management())
|
||||||
{
|
{
|
||||||
if (part_info->part_type != VERSIONING_PARTITION)
|
if (part_info->part_type != VERSIONING_PARTITION)
|
||||||
@ -5225,10 +5231,17 @@ opt_part_values:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
part_info->vers_init_info(thd);
|
part_info->vers_init_info(thd);
|
||||||
|
elem->id= UINT32_MAX;
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(part_info->vers_info);
|
||||||
|
if (part_info->vers_info->now_part)
|
||||||
|
my_yyabort_error((ER_VERS_WRONG_PARAMS, MYF(0), "BY SYSTEM_TIME", "AS OF NOW partition is not last"));
|
||||||
|
elem->type= partition_element::VERSIONING;
|
||||||
|
if (part_info->init_column_part(thd))
|
||||||
|
{
|
||||||
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
part_info->curr_part_elem->type= partition_element::VERSIONING;
|
|
||||||
}
|
}
|
||||||
opt_default_hist_part
|
|
||||||
| DEFAULT
|
| DEFAULT
|
||||||
{
|
{
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
@ -5556,20 +5569,6 @@ opt_versioning_limit:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_default_hist_part:
|
|
||||||
/* empty */ {}
|
|
||||||
| DEFAULT
|
|
||||||
{
|
|
||||||
partition_info *part_info= Lex->part_info;
|
|
||||||
DBUG_ASSERT(part_info && part_info->vers_info && part_info->curr_part_elem);
|
|
||||||
if (part_info->vers_info->hist_part)
|
|
||||||
my_yyabort_error((ER_VERS_WRONG_PARAMS, MYF(0),
|
|
||||||
"BY SYSTEM_TIME", "multiple `DEFAULT` partitions"));
|
|
||||||
part_info->vers_info->hist_part= part_info->curr_part_elem;
|
|
||||||
part_info->vers_info->hist_default= part_info->curr_part_elem->id;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
End of partition parser part
|
End of partition parser part
|
||||||
*/
|
*/
|
||||||
|
32
sql/table.cc
32
sql/table.cc
@ -3226,6 +3226,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
|
bool work_part_info_used;
|
||||||
if (share->partition_info_str_len && outparam->file)
|
if (share->partition_info_str_len && outparam->file)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -3246,7 +3247,6 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
|||||||
thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
|
thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
|
||||||
thd->stmt_arena= &part_func_arena;
|
thd->stmt_arena= &part_func_arena;
|
||||||
bool tmp;
|
bool tmp;
|
||||||
bool work_part_info_used;
|
|
||||||
|
|
||||||
tmp= mysql_unpack_partition(thd, share->partition_info_str,
|
tmp= mysql_unpack_partition(thd, share->partition_info_str,
|
||||||
share->partition_info_str_len,
|
share->partition_info_str_len,
|
||||||
@ -3412,12 +3412,32 @@ partititon_err:
|
|||||||
|
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
if (outparam->part_info &&
|
if (outparam->part_info &&
|
||||||
outparam->part_info->part_type == VERSIONING_PARTITION &&
|
outparam->part_info->part_type == VERSIONING_PARTITION)
|
||||||
outparam->part_info->vers_setup_2(thd, is_create_table))
|
|
||||||
{
|
{
|
||||||
error= OPEN_FRM_OPEN_ERROR;
|
Query_arena *backup_stmt_arena_ptr= thd->stmt_arena;
|
||||||
error_reported= true;
|
Query_arena backup_arena;
|
||||||
goto err;
|
Query_arena part_func_arena(&outparam->mem_root,
|
||||||
|
Query_arena::STMT_INITIALIZED);
|
||||||
|
if (!work_part_info_used)
|
||||||
|
{
|
||||||
|
thd->set_n_backup_active_arena(&part_func_arena, &backup_arena);
|
||||||
|
thd->stmt_arena= &part_func_arena;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool err= outparam->part_info->vers_setup_2(thd, is_create_table);
|
||||||
|
|
||||||
|
if (!work_part_info_used)
|
||||||
|
{
|
||||||
|
thd->stmt_arena= backup_stmt_arena_ptr;
|
||||||
|
thd->restore_active_arena(&part_func_arena, &backup_arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
error= OPEN_FRM_OPEN_ERROR;
|
||||||
|
error_reported= true;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
20
sql/table.h
20
sql/table.h
@ -561,6 +561,8 @@ struct TABLE_STATISTICS_CB
|
|||||||
bool histograms_are_read;
|
bool histograms_are_read;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Vers_field_stats;
|
||||||
|
|
||||||
#ifndef UINT32_MAX
|
#ifndef UINT32_MAX
|
||||||
#define UINT32_MAX (4294967295U)
|
#define UINT32_MAX (4294967295U)
|
||||||
#endif
|
#endif
|
||||||
@ -752,26 +754,30 @@ struct TABLE_SHARE
|
|||||||
uint16 row_start_field;
|
uint16 row_start_field;
|
||||||
uint16 row_end_field;
|
uint16 row_end_field;
|
||||||
uint32 hist_part_id;
|
uint32 hist_part_id;
|
||||||
List<void> free_parts;
|
Vers_field_stats** stat_trx;
|
||||||
bool free_parts_init;
|
ulonglong stat_serial; // guards check_range_constants() updates
|
||||||
|
|
||||||
bool busy_rotation;
|
bool busy_rotation;
|
||||||
mysql_mutex_t LOCK_rotation;
|
mysql_mutex_t LOCK_rotation;
|
||||||
mysql_cond_t COND_rotation;
|
mysql_cond_t COND_rotation;
|
||||||
|
mysql_rwlock_t LOCK_stat_serial;
|
||||||
|
|
||||||
void vers_init()
|
void vers_init()
|
||||||
{
|
{
|
||||||
hist_part_id= UINT32_MAX;
|
hist_part_id= UINT32_MAX;
|
||||||
busy_rotation= false;
|
busy_rotation= false;
|
||||||
free_parts.empty();
|
stat_trx= NULL;
|
||||||
free_parts_init= true;
|
stat_serial= 0;
|
||||||
mysql_mutex_init(key_TABLE_SHARE_LOCK_rotation, &LOCK_rotation, MY_MUTEX_INIT_FAST);
|
mysql_mutex_init(key_TABLE_SHARE_LOCK_rotation, &LOCK_rotation, MY_MUTEX_INIT_FAST);
|
||||||
mysql_cond_init(key_TABLE_SHARE_COND_rotation, &COND_rotation, NULL);
|
mysql_cond_init(key_TABLE_SHARE_COND_rotation, &COND_rotation, NULL);
|
||||||
|
mysql_rwlock_init(key_rwlock_LOCK_stat_serial, &LOCK_stat_serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vers_destroy()
|
void vers_destroy()
|
||||||
{
|
{
|
||||||
mysql_mutex_destroy(&LOCK_rotation);
|
mysql_mutex_destroy(&LOCK_rotation);
|
||||||
mysql_cond_destroy(&COND_rotation);
|
mysql_cond_destroy(&COND_rotation);
|
||||||
|
mysql_rwlock_destroy(&LOCK_stat_serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
Field *vers_start_field()
|
Field *vers_start_field()
|
||||||
@ -784,12 +790,6 @@ struct TABLE_SHARE
|
|||||||
return field[row_end_field];
|
return field[row_end_field];
|
||||||
}
|
}
|
||||||
|
|
||||||
void vers_part_rotate()
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(!free_parts.is_empty());
|
|
||||||
hist_part_id= (ulong)(void *)(free_parts.pop());
|
|
||||||
}
|
|
||||||
|
|
||||||
void vers_wait_rotation()
|
void vers_wait_rotation()
|
||||||
{
|
{
|
||||||
while (busy_rotation)
|
while (busy_rotation)
|
||||||
|
Reference in New Issue
Block a user