Commit 82811f79 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-12485 foreign key on delete cascade stale entries with query cache enabled

During merge of innodb code QC invalidation was removed from innodb part but not added to server part.
We decided to keep it in innodb to keep server/engine interface the same.
parent e946297d
#
# MDEV-12485: foreign key on delete cascade stale entries with
# query cache enabled
#
SET NAMES utf8;
set global query_cache_type=1;
set global query_cache_size=1024*1024;
set query_cache_type=1;
create table t1 ( id int unsigned auto_increment, primary key(id) ) engine=innodb;
create table t2 ( t2id int unsigned, id int unsigned, primary key(t2id, id), foreign key (`id`) references t1(`id`) on delete cascade ) engine=innodb;
insert into t1 values (1);
insert into t2 values (1,1);
select * from t2;
t2id id
1 1
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
delete from t1;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from t2;
t2id id
optimize table t2;
Table Op Msg_type Msg_text
test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
test.t2 optimize status OK
select * from t2;
t2id id
drop table t2;
drop table t1;
create database `testdatabase$Ї`;
use `testdatabase$Ї`;
create table `t1$Ї` ( id int unsigned auto_increment, primary key(id) ) engine=innodb;
create table `t2$Ї` ( t2id int unsigned, id int unsigned, primary key(t2id, id), foreign key (`id`) references `t1$Ї`(`id`) on delete cascade ) engine=innodb;
insert into `t1$Ї` values (1);
insert into `t2$Ї`values (1,1);
select * from `t2$Ї`;
t2id id
1 1
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
delete from `t1$Ї`;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from `t2$Ї`;
t2id id
optimize table `t2$Ї`;
Table Op Msg_type Msg_text
testdatabase$Ї.t2$Ї optimize note Table does not support optimize, doing recreate + analyze instead
testdatabase$Ї.t2$Ї optimize status OK
select * from `t2$Ї`;
t2id id
use test;
drop database `testdatabase$Ї`;
SET NAMES default;
create database `#mysql50#-`;
use `#mysql50#-`;
create table `#mysql50#t-1` ( id int unsigned auto_increment, primary key(id) ) engine=innodb;
create table `#mysql50#t-2` ( t2id int unsigned, id int unsigned, primary key(t2id, id), foreign key (`id`) references `#mysql50#t-1`(`id`) on delete cascade ) engine=innodb;
insert into `#mysql50#t-1` values (1);
insert into `#mysql50#t-2`values (1,1);
select * from `#mysql50#t-2`;
t2id id
1 1
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
delete from `#mysql50#t-1`;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from `#mysql50#t-2`;
t2id id
optimize table `#mysql50#t-2`;
Table Op Msg_type Msg_text
#mysql50#-.#mysql50#t-2 optimize note Table does not support optimize, doing recreate + analyze instead
#mysql50#-.#mysql50#t-2 optimize status OK
select * from `#mysql50#t-2`;
t2id id
use test;
drop database `#mysql50#-`;
SET NAMES default;
FOUND 12 /\[ERROR\] Invalid \(old\?\) table or database name/ in mysqld.1.err
set global query_cache_type=DEFAULT;
set global query_cache_size=DEFAULT;
End of 10.2 tests
--source include/have_innodb.inc
--source include/have_query_cache.inc
--echo #
--echo # MDEV-12485: foreign key on delete cascade stale entries with
--echo # query cache enabled
--echo #
SET NAMES utf8;
set global query_cache_type=1;
set global query_cache_size=1024*1024;
set query_cache_type=1;
create table t1 ( id int unsigned auto_increment, primary key(id) ) engine=innodb;
create table t2 ( t2id int unsigned, id int unsigned, primary key(t2id, id), foreign key (`id`) references t1(`id`) on delete cascade ) engine=innodb;
insert into t1 values (1);
insert into t2 values (1,1);
select * from t2;
show status like "Qcache_queries_in_cache";
delete from t1;
show status like "Qcache_queries_in_cache";
select * from t2;
optimize table t2;
select * from t2;
drop table t2;
drop table t1;
create database `testdatabase$Ї`;
use `testdatabase$Ї`;
create table `t1$Ї` ( id int unsigned auto_increment, primary key(id) ) engine=innodb;
create table `t2$Ї` ( t2id int unsigned, id int unsigned, primary key(t2id, id), foreign key (`id`) references `t1$Ї`(`id`) on delete cascade ) engine=innodb;
insert into `t1$Ї` values (1);
insert into `t2$Ї`values (1,1);
select * from `t2$Ї`;
show status like "Qcache_queries_in_cache";
delete from `t1$Ї`;
show status like "Qcache_queries_in_cache";
select * from `t2$Ї`;
optimize table `t2$Ї`;
select * from `t2$Ї`;
use test;
drop database `testdatabase$Ї`;
SET NAMES default;
create database `#mysql50#-`;
use `#mysql50#-`;
create table `#mysql50#t-1` ( id int unsigned auto_increment, primary key(id) ) engine=innodb;
create table `#mysql50#t-2` ( t2id int unsigned, id int unsigned, primary key(t2id, id), foreign key (`id`) references `#mysql50#t-1`(`id`) on delete cascade ) engine=innodb;
insert into `#mysql50#t-1` values (1);
insert into `#mysql50#t-2`values (1,1);
select * from `#mysql50#t-2`;
show status like "Qcache_queries_in_cache";
delete from `#mysql50#t-1`;
show status like "Qcache_queries_in_cache";
select * from `#mysql50#t-2`;
optimize table `#mysql50#t-2`;
select * from `#mysql50#t-2`;
use test;
drop database `#mysql50#-`;
SET NAMES default;
--disable_query_log
call mtr.add_suppression("\\[ERROR\\] Invalid \\(old\\?\\) table or database name 't?-[12]?\\'");
--enable_query_log
--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err
--let SEARCH_PATTERN=\\[ERROR\\] Invalid \\(old\\?\\) table or database name
--source include/search_pattern_in_file.inc
set global query_cache_type=DEFAULT;
set global query_cache_size=DEFAULT;
--echo End of 10.2 tests
......@@ -3441,11 +3441,35 @@ innobase_invalidate_query_cache(
above the InnoDB trx_sys_t->lock. The caller of this function must
not have latches of a lower rank. */
/* Argument TRUE below means we are using transactions */
mysql_query_cache_invalidate4(trx->mysql_thd,
full_name,
(uint32) full_name_len,
TRUE);
#ifdef HAVE_QUERY_CACHE
char qcache_key_name[2 * (NAME_LEN + 1)];
char db_name[NAME_CHAR_LEN * MY_CS_MBMAXLEN + 1];
const char *key_ptr;
size_t tabname_len;
size_t dbname_len;
// Extract the database name.
key_ptr= strchr(full_name, '/');
DBUG_ASSERT(key_ptr != NULL); // Database name should be present
memcpy(db_name, full_name, (dbname_len= (key_ptr - full_name)));
db_name[dbname_len]= '\0';
/* Construct the key("db-name\0table$name\0") for the query cache using
the path name("db@002dname\0table@0024name\0") of the table in its
canonical form. */
dbname_len = filename_to_tablename(db_name, qcache_key_name,
sizeof(qcache_key_name));
tabname_len = filename_to_tablename(++key_ptr,
(qcache_key_name + dbname_len + 1),
sizeof(qcache_key_name) -
dbname_len - 1);
/* Argument TRUE below means we are using transactions */
mysql_query_cache_invalidate4(trx->mysql_thd,
qcache_key_name,
(dbname_len + tabname_len + 2),
TRUE);
#endif
}
/** Quote a standard SQL identifier like index or column name.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment