summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2022-04-25 13:58:41 +0300
committerAleksey Midenkov <midenok@gmail.com>2022-04-29 13:31:42 +0300
commitddc416c60698e1f8939faff0cb09c5b5af8e03a7 (patch)
treeff1fc268b37abe33a4bc0955ec9ec02b763584e5
parentea2f09979fc74a8fa7fb1e74c874e00df757c6db (diff)
downloadmariadb-git-ddc416c60698e1f8939faff0cb09c5b5af8e03a7.tar.gz
MDEV-20077 Warning on full history partition is delayed until next DML statement
Moved LIMIT warning from vers_set_hist_part() to new call vers_check_limit() at table unlock phase. At that point read_partitions bitmap is already pruned by DML code (see prune_partitions(), find_used_partitions()) so we have to set corresponding bits for working history partition. Also we don't do my_error(ME_WARNING|ME_ERROR_LOG), because at that point it doesn't update warnings number, so command reports 0 warnings (but warning list is still updated). Instead we do push_warning_printf() and sql_print_warning() separately. Under LOCK TABLES external_lock(F_UNLCK) is not executed. There is start_stmt(), but no corresponding "stop_stmt()". So for that mode we call vers_check_limit() directly from close_thread_tables(). Test result has been changed according to new LIMIT and warning printing algorithm. For convenience all LIMIT warnings are marked with "You see warning above ^". TODO MDEV-20345 fixed. Now vers_history_generating() contains fine-grained list of DML-commands that can generate history (and TODO mechanism worked well).
-rw-r--r--mysql-test/suite/versioning/r/delete_history.result3
-rw-r--r--mysql-test/suite/versioning/r/partition.result258
-rw-r--r--mysql-test/suite/versioning/t/delete_history.test1
-rw-r--r--mysql-test/suite/versioning/t/partition.test214
-rw-r--r--sql/ha_partition.cc17
-rw-r--r--sql/partition_info.cc53
-rw-r--r--sql/partition_info.h6
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_lex.h22
9 files changed, 530 insertions, 49 deletions
diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result
index 95d7304c3dd..065b1f00876 100644
--- a/mysql-test/suite/versioning/r/delete_history.result
+++ b/mysql-test/suite/versioning/r/delete_history.result
@@ -65,6 +65,9 @@ partition pn current);
insert into t values (1);
update t set a= 2;
update t set a= 3;
+Warnings:
+Warning 4114 Versioned table `test`.`t`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
delete history from t;
select * from t for system_time all;
a
diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result
index cada225db7e..a5bc8284f8c 100644
--- a/mysql-test/suite/versioning/r/partition.result
+++ b/mysql-test/suite/versioning/r/partition.result
@@ -244,6 +244,9 @@ x
6
delete from t1 where x < 4;
delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
select * from t1 partition (p0);
x
1
@@ -255,12 +258,11 @@ x
5
6
insert into t1 values (7), (8);
-Warnings:
-Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
### warn about full partition
delete from t1;
Warnings:
Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
select * from t1 partition (p1) order by x;
x
4
@@ -320,20 +322,26 @@ x
### warn about full partition
delete from t1 where x < 3;
delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^ (no matter if nothing was deleted)
select * from t1 partition (p0sp0);
x
1
-3
-5
select * from t1 partition (p0sp1);
x
2
-4
select * from t1 partition (p1sp0);
x
+3
+5
select * from t1 partition (p1sp1);
x
+4
create or replace table t1 (
a bigint,
row_start SYS_DATATYPE as row start invisible,
@@ -415,7 +423,13 @@ partition p1 history,
partition p2 history,
partition pn current);
delete from t1 where x = 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p2` is full, add more HISTORY partitions
+# You see warning above ^
delete from t1 where x = 2;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p2` is full, add more HISTORY partitions
+# You see warning above ^
# MDEV-14923 Assertion upon INSERT into locked versioned partitioned table
create or replace table t1 (x int) with system versioning
partition by system_time (partition p1 history, partition pn current);
@@ -577,9 +591,13 @@ create or replace table t1 (x int) with system versioning partition by system_ti
lock tables t1 write;
insert into t1 values (0), (1), (2), (3);
delete from t1 where x < 3;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
delete from t1;
Warnings:
Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
unlock tables;
#
# MDEV-20336 Assertion bitmap_is_set(read_partitions) upon SELECT FOR UPDATE from versioned table
@@ -680,6 +698,9 @@ partition by system_time limit 1
insert into t1 values (null);
update t1 set f= 'foo';
update t1 set f= 'bar';
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p2` is full, add more HISTORY partitions
+# You see warning above ^
create or replace view v1 as select * from t1 for system_time all;
update v1 set f= '';
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
@@ -846,23 +867,20 @@ create table t1 (x int) with system versioning
partition by system_time limit 1 (
partition p0 history,
partition p1 history,
+partition p2 history, # p2 just disables warning about p1 partition full
partition pn current);
insert into t1 values (0);
update t1 set x= x + 1;
update t1 set x= x + 1;
-update t1 set x= x + 1;
-update t1 set x= x + 1;
select * from t1 partition (p0);
x
0
-1
select * from t1 partition (p1);
x
-2
-3
+1
select * from t1 partition (pn);
x
-4
+2
# TRUNCATE TABLE deletes history and current data
truncate table t1;
select * from t1 partition (p0);
@@ -874,8 +892,6 @@ x
insert into t1 values (0);
update t1 set x= x + 1;
update t1 set x= x + 1;
-update t1 set x= x + 1;
-update t1 set x= x + 1;
# TRUNCATE PARTITION ALL does the same
alter table t1 truncate partition all;
select * from t1 partition (p0);
@@ -887,29 +903,235 @@ x
insert into t1 values (0);
update t1 set x= x + 1;
update t1 set x= x + 1;
-update t1 set x= x + 1;
-update t1 set x= x + 1;
# TRUNCATE PARTITION deletes data from HISTORY partition
alter table t1 truncate partition p1;
select * from t1 partition (p0);
x
0
-1
select * from t1 partition (p1);
x
select * from t1 partition (pn);
x
-4
+2
# or from CURRENT partition
alter table t1 truncate partition pn;
select * from t1 partition (p0);
x
0
-1
select * from t1 partition (p1);
x
select * from t1 partition (pn);
x
drop table t1;
+#
+# MDEV-20077 Warning on full history partition is delayed until next DML statement
+#
+# DELETE
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_200;
+# p0 is filled with 100 records (no warnings):
+delete from t1 where x <= 99;
+# p1 is filled with 1 + 100 records (warning is printed):
+delete from t1 where x <= 100;
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+101
+drop table t1;
+# DELETE under LOCK TABLES
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_200;
+lock tables t1 write;
+# (LOCK TABLES) p0 is filled with 100 records (no warnings):
+delete from t1 where x <= 99;
+# (LOCK TABLES) p1 is filled with 1 + 100 records (warning is printed):
+delete from t1 where x <= 100;
+delete from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+unlock tables;
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+101
+drop table t1;
+# DELETE multitable
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+create table t2 (y int);
+insert into t1 select seq from seq_0_to_200;
+insert into t2 select seq from seq_0_to_3;
+delete t1, t2 from t1 join t2 where x < 50 and y = 0;
+delete t1, t2 from t1 join t2 where x < 100 and y = 1;
+delete t1, t2 from t1 join t2 where x < 150 and y = 2;
+delete t1, t2 from t1 join t2;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+101
+drop table t1;
+# UDPATE
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_49;
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop tables t1, t2;
+# UPDATE multitable
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+create table t2 (y int);
+insert into t1 select seq from seq_0_to_49;
+insert into t2 values (5);
+update t1, t2 set x= x + 1;
+update t1, t2 set x= x + 1;
+update t1, t2 set x= x + 1;
+update t1, t2 set x= x + 1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop tables t1, t2;
+# INSERT .. ON DUPLICATE KEY UPDATE (ODKU)
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_100;
+delete from t1 where x <= 99;
+insert into t1 values (100) on duplicate key update x= 400;
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+1
+drop table t1;
+# INSERT .. SELECT .. ON DUPLICATE KEY UPDATE (ODKU)
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+create table t2 (y int);
+insert into t2 values (100);
+insert into t1 select seq from seq_0_to_100;
+delete from t1 where x <= 99;
+insert into t1 select * from t2 on duplicate key update x= 500;
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+1
+drop tables t1, t2;
+# REPLACE
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_100;
+delete from t1 where x < 99;
+replace t1 values (100);
+replace t1 values (100);
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+1
+drop table t1;
+# LOAD DATA .. REPLACE
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_49;
+select x into outfile 'MDEV-20077.data' from t1;
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop table t1;
+# REPLACE .. SELECT
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+partition p0 history,
+partition p1 history,
+partition pn current);
+insert into t1 select seq from seq_0_to_49;
+replace t1 select * from t1;
+replace t1 select * from t1;
+replace t1 select * from t1;
+replace t1 select * from t1;
+Warnings:
+Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions
+# You see warning above ^
+select count(*) from t1 partition (p0);
+count(*)
+100
+select count(*) from t1 partition (p1);
+count(*)
+100
+drop table t1;
# End of 10.3 tests
set global innodb_stats_persistent= @save_persistent;
diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test
index bd605c689ad..dae7ff2db9b 100644
--- a/mysql-test/suite/versioning/t/delete_history.test
+++ b/mysql-test/suite/versioning/t/delete_history.test
@@ -65,6 +65,7 @@ partition by system_time limit 1 (
insert into t values (1);
update t set a= 2;
update t set a= 3;
+--echo # You see warning above ^
delete history from t;
select * from t for system_time all;
diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test
index 7f75f905254..f65f544147f 100644
--- a/mysql-test/suite/versioning/t/partition.test
+++ b/mysql-test/suite/versioning/t/partition.test
@@ -228,12 +228,14 @@ insert into t1 values (1), (2), (3), (4), (5), (6);
select * from t1 partition (pn);
delete from t1 where x < 4;
delete from t1;
+--echo # You see warning above ^
select * from t1 partition (p0);
select * from t1 partition (p1);
insert into t1 values (7), (8);
--echo ### warn about full partition
delete from t1;
+--echo # You see warning above ^
select * from t1 partition (p1) order by x;
--echo ### Assertion in ALTER on warning from partitioning LIMIT [#446]
@@ -283,7 +285,9 @@ select * from t1 partition (pnsp1);
--echo ### warn about full partition
delete from t1 where x < 3;
delete from t1;
+--echo # You see warning above ^
delete from t1;
+--echo # You see warning above ^ (no matter if nothing was deleted)
select * from t1 partition (p0sp0);
select * from t1 partition (p0sp1);
select * from t1 partition (p1sp0);
@@ -381,7 +385,9 @@ alter table t1 partition by system_time limit 1 (
partition p2 history,
partition pn current);
delete from t1 where x = 1;
+--echo # You see warning above ^
delete from t1 where x = 2;
+--echo # You see warning above ^
--echo # MDEV-14923 Assertion upon INSERT into locked versioned partitioned table
create or replace table t1 (x int) with system versioning
@@ -529,7 +535,9 @@ create or replace table t1 (x int) with system versioning partition by system_ti
lock tables t1 write;
insert into t1 values (0), (1), (2), (3);
delete from t1 where x < 3;
+--echo # You see warning above ^
delete from t1;
+--echo # You see warning above ^
unlock tables;
--echo #
@@ -640,6 +648,7 @@ partition by system_time limit 1
insert into t1 values (null);
update t1 set f= 'foo';
update t1 set f= 'bar';
+--echo # You see warning above ^
create or replace view v1 as select * from t1 for system_time all;
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
@@ -830,22 +839,19 @@ create table t1 (x int) with system versioning
partition by system_time limit 1 (
partition p0 history,
partition p1 history,
+ partition p2 history, # p2 just disables warning about p1 partition full
partition pn current);
insert into t1 values (0);
update t1 set x= x + 1;
update t1 set x= x + 1;
-update t1 set x= x + 1;
-update t1 set x= x + 1;
select * from t1 partition (p0);
select * from t1 partition (p1);
select * from t1 partition (pn);
--echo # TRUNCATE TABLE deletes history and current data
---disable_warnings
truncate table t1;
---enable_warnings
select * from t1 partition (p0);
select * from t1 partition (p1);
select * from t1 partition (pn);
@@ -853,8 +859,6 @@ select * from t1 partition (pn);
insert into t1 values (0);
update t1 set x= x + 1;
update t1 set x= x + 1;
-update t1 set x= x + 1;
-update t1 set x= x + 1;
--echo # TRUNCATE PARTITION ALL does the same
alter table t1 truncate partition all;
@@ -865,8 +869,6 @@ select * from t1 partition (pn);
insert into t1 values (0);
update t1 set x= x + 1;
update t1 set x= x + 1;
-update t1 set x= x + 1;
-update t1 set x= x + 1;
--echo # TRUNCATE PARTITION deletes data from HISTORY partition
alter table t1 truncate partition p1;
@@ -882,6 +884,202 @@ select * from t1 partition (pn);
drop table t1;
+--echo #
+--echo # MDEV-20077 Warning on full history partition is delayed until next DML statement
+--echo #
+--echo # DELETE
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_200;
+
+--echo # p0 is filled with 100 records (no warnings):
+delete from t1 where x <= 99;
+--echo # p1 is filled with 1 + 100 records (warning is printed):
+delete from t1 where x <= 100;
+delete from t1;
+--echo # You see warning above ^
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
+
+--echo # DELETE under LOCK TABLES
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_200;
+
+lock tables t1 write;
+--echo # (LOCK TABLES) p0 is filled with 100 records (no warnings):
+delete from t1 where x <= 99;
+--echo # (LOCK TABLES) p1 is filled with 1 + 100 records (warning is printed):
+delete from t1 where x <= 100;
+delete from t1;
+--echo # You see warning above ^
+unlock tables;
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
+
+--echo # DELETE multitable
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+create table t2 (y int);
+
+insert into t1 select seq from seq_0_to_200;
+insert into t2 select seq from seq_0_to_3;
+delete t1, t2 from t1 join t2 where x < 50 and y = 0;
+delete t1, t2 from t1 join t2 where x < 100 and y = 1;
+delete t1, t2 from t1 join t2 where x < 150 and y = 2;
+delete t1, t2 from t1 join t2;
+--echo # You see warning above ^
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
+
+--echo # UDPATE
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_49;
+
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+update t1 set x= x + 1;
+--echo # You see warning above ^
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop tables t1, t2;
+
+--echo # UPDATE multitable
+create table t1 (x int) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+create table t2 (y int);
+
+insert into t1 select seq from seq_0_to_49;
+insert into t2 values (5);
+
+update t1, t2 set x= x + 1;
+update t1, t2 set x= x + 1;
+update t1, t2 set x= x + 1;
+update t1, t2 set x= x + 1;
+--echo # You see warning above ^
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop tables t1, t2;
+
+--echo # INSERT .. ON DUPLICATE KEY UPDATE (ODKU)
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_100;
+
+delete from t1 where x <= 99;
+insert into t1 values (100) on duplicate key update x= 400;
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
+
+--echo # INSERT .. SELECT .. ON DUPLICATE KEY UPDATE (ODKU)
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+create table t2 (y int);
+insert into t2 values (100);
+insert into t1 select seq from seq_0_to_100;
+
+delete from t1 where x <= 99;
+insert into t1 select * from t2 on duplicate key update x= 500;
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop tables t1, t2;
+
+--echo # REPLACE
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_100;
+
+delete from t1 where x < 99;
+replace t1 values (100);
+replace t1 values (100);
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
+
+--echo # LOAD DATA .. REPLACE
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_49;
+select x into outfile 'MDEV-20077.data' from t1;
+
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+load data infile 'MDEV-20077.data' replace into table t1 (x);
+--echo # You see warning above ^
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
+--remove_file $datadir/test/MDEV-20077.data
+
+--echo # REPLACE .. SELECT
+create table t1 (x int primary key) with system versioning
+partition by system_time limit 100 (
+ partition p0 history,
+ partition p1 history,
+ partition pn current);
+
+insert into t1 select seq from seq_0_to_49;
+replace t1 select * from t1;
+replace t1 select * from t1;
+replace t1 select * from t1;
+replace t1 select * from t1;
+--echo # You see warning above ^
+
+select count(*) from t1 partition (p0);
+select count(*) from t1 partition (p1);
+drop table t1;
--echo # End of 10.3 tests
set global innodb_stats_persistent= @save_persistent;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index b1645a9c4a7..48c479070a5 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -4008,6 +4008,8 @@ int ha_partition::external_lock(THD *thd, int lock_type)
if (lock_type == F_UNLCK)
{
bitmap_clear_all(used_partitions);
+ if (m_lock_type == F_WRLCK && m_part_info->vers_require_hist_part(thd))
+ m_part_info->vers_check_limit(thd);
}
else
{
@@ -4028,14 +4030,7 @@ int ha_partition::external_lock(THD *thd, int lock_type)
{
if (m_part_info->part_expr)
m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0);
- if (m_part_info->part_type == VERSIONING_PARTITION &&
- /* TODO: MDEV-20345 exclude more inapproriate commands like INSERT
- These commands may be excluded because working history partition is needed
- only for versioned DML. */
- thd->lex->sql_command != SQLCOM_SELECT &&
- thd->lex->sql_command != SQLCOM_INSERT_SELECT &&
- thd->lex->sql_command != SQLCOM_ALTER_TABLE &&
- (error= m_part_info->vers_set_hist_part(thd)))
+ if ((error= m_part_info->vers_set_hist_part(thd)))
goto err_handler;
}
DBUG_RETURN(0);
@@ -4188,11 +4183,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
case TL_WRITE_ONLY:
if (m_part_info->part_expr)
m_part_info->part_expr->walk(&Item::register_field_in_read_map, 1, 0);
- if (m_part_info->part_type == VERSIONING_PARTITION &&
- // TODO: MDEV-20345 (see above)
- thd->lex->sql_command != SQLCOM_SELECT &&
- thd->lex->sql_command != SQLCOM_INSERT_SELECT)
- error= m_part_info->vers_set_hist_part(thd);
+ error= m_part_info->vers_set_hist_part(thd);
default:;
}
DBUG_RETURN(error);
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index f523415f6cc..90ef388f3b9 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -835,6 +835,9 @@ bool partition_info::has_unique_name(partition_element *element)
int partition_info::vers_set_hist_part(THD *thd)
{
+ if (!vers_require_hist_part(thd))
+ return 0;
+
if (table->pos_in_table_list &&
table->pos_in_table_list->partition_names)
{
@@ -856,12 +859,8 @@ int partition_info::vers_set_hist_part(THD *thd)
vers_info->hist_part= next;
records= next_records;
}
- if (records > vers_info->limit)
- {
- if (next == vers_info->now_part)
- goto warn;
+ if (records >= vers_info->limit && next != vers_info->now_part)
vers_info->hist_part= next;
- }
return 0;
}
@@ -883,11 +882,45 @@ int partition_info::vers_set_hist_part(THD *thd)
}
}
return 0;
-warn:
- 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);
- return 0;
+}
+
+
+/**
+ Warn at the end of DML command if the last history partition is out of LIMIT.
+*/
+void partition_info::vers_check_limit(THD *thd)
+{
+ if (!vers_info->limit ||
+ vers_info->hist_part->id + 1 < vers_info->now_part->id)
+ return;
+
+ /*
+ NOTE: at this point read_partitions bitmap is already pruned by DML code,
+ we have to set read bits for working history partition. We could use
+ bitmap_set_all(), but this is not optimal since there can be quite a number
+ of partitions.
+ */
+ const uint32 sub_factor= num_subparts ? num_subparts : 1;
+ uint32 part_id= vers_info->hist_part->id * sub_factor;
+ const uint32 part_id_end= part_id + sub_factor;
+ DBUG_ASSERT(part_id_end <= num_parts * sub_factor);
+ for (; part_id < part_id_end; ++part_id)
+ bitmap_set_bit(&read_partitions, part_id);
+
+ ha_partition *hp= (ha_partition*)(table->file);
+ ha_rows hist_rows= hp->part_records(vers_info->hist_part);
+ if (hist_rows >= vers_info->limit)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ WARN_VERS_PART_FULL,
+ ER_THD(thd, WARN_VERS_PART_FULL),
+ table->s->db.str, table->s->table_name.str,
+ vers_info->hist_part->partition_name);
+
+ sql_print_warning(ER_THD(thd, WARN_VERS_PART_FULL),
+ table->s->db.str, table->s->table_name.str,
+ vers_info->hist_part->partition_name);
+ }
}
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 341ae363c7f..ddbb89fa605 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -421,7 +421,13 @@ public:
vers_info->limit= limit;
return !limit;
}
+ bool vers_require_hist_part(THD *thd) const
+ {
+ return part_type == VERSIONING_PARTITION &&
+ thd->lex->vers_history_generating();
+ }
int vers_set_hist_part(THD *thd);
+ void vers_check_limit(THD *thd);
bool vers_setup_expression(THD *thd, uint32 alter_add= 0); /* Stage 1. */
partition_element *get_partition(uint part_id)
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index f12ba831c7d..88eaf1bc0a5 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -750,7 +750,12 @@ void close_thread_tables(THD *thd)
DBUG_PRINT("tcache", ("table: '%s' query_id: %lu",
table->s->table_name.str, (ulong) table->query_id));
if (thd->locked_tables_mode)
+ {
+ if (table->part_info && table->part_info->vers_require_hist_part(thd) &&
+ !thd->stmt_arena->is_stmt_prepare())
+ table->part_info->vers_check_limit(thd);
table->vcol_cleanup_expr(thd);
+ }
if (thd->locked_tables_mode <= LTM_LOCK_TABLES ||
table->query_id == thd->query_id)
{
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index b5cc9604a8f..bd7bd2f248c 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -4084,6 +4084,28 @@ public:
{
return create_info.vers_info;
}
+ /* The list of history-generating DML commands */
+ bool vers_history_generating() const
+ {
+ switch (sql_command)
+ {
+ case SQLCOM_DELETE:
+ return !vers_conditions.delete_history;
+ case SQLCOM_UPDATE:
+ case SQLCOM_UPDATE_MULTI:
+ case SQLCOM_DELETE_MULTI:
+ case SQLCOM_REPLACE:
+ case SQLCOM_REPLACE_SELECT:
+ return true;
+ case SQLCOM_INSERT:
+ case SQLCOM_INSERT_SELECT:
+ return duplicates == DUP_UPDATE;
+ case SQLCOM_LOAD:
+ return duplicates == DUP_REPLACE;
+ default:
+ return false;
+ }
+ }
sp_package *get_sp_package() const;
/**