Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
34b85449
Commit
34b85449
authored
Jan 27, 2005
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed QC invaluidation and processing with view (BUG#8050) (BUG#8054)
parent
8881bead
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
219 additions
and
73 deletions
+219
-73
mysql-test/r/view_query_cache.result
mysql-test/r/view_query_cache.result
+25
-0
mysql-test/t/view_query_cache.test
mysql-test/t/view_query_cache.test
+30
-1
sql/sql_cache.cc
sql/sql_cache.cc
+157
-72
sql/sql_cache.h
sql/sql_cache.h
+4
-0
sql/sql_view.cc
sql/sql_view.cc
+3
-0
No files found.
mysql-test/r/view_query_cache.result
View file @
34b85449
drop table if exists t1,t2,v1,v2,v3;
drop view if exists t1,t2,v1,v2,v3;
set GLOBAL query_cache_size=1355776;
set GLOBAL query_cache_size=1355776;
flush status;
flush status;
create table t1 (a int, b int);
create table t1 (a int, b int);
...
@@ -98,4 +100,27 @@ Qcache_hits 1
...
@@ -98,4 +100,27 @@ Qcache_hits 1
drop view v1;
drop view v1;
set query_cache_type=default;
set query_cache_type=default;
drop table t1;
drop table t1;
create table t1 (a int);
insert into t1 values (1), (2), (3);
create view v1 as select a from t1 where a > 1;
select * from v1;
a
2
3
alter view v1 as select a from t1 where a > 2;
select * from v1;
a
3
drop view v1;
select * from v1;
ERROR 42S02: Table 'test.v1' doesn't exist
drop table t1;
create table t1 (a int, primary key (a), b int);
create table t2 (a int, primary key (a), b int);
insert into t2 values (1000, 2000);
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
select * from v3;
a b
drop view v3;
drop table t1, t2;
set GLOBAL query_cache_size=default;
set GLOBAL query_cache_size=default;
mysql-test/t/view_query_cache.test
View file @
34b85449
...
@@ -2,6 +2,11 @@
...
@@ -2,6 +2,11 @@
#
#
# QUERY CACHE options for VIEWs
# QUERY CACHE options for VIEWs
#
#
--
disable_warnings
drop
table
if
exists
t1
,
t2
,
v1
,
v2
,
v3
;
drop
view
if
exists
t1
,
t2
,
v1
,
v2
,
v3
;
--
enable_warnings
set
GLOBAL
query_cache_size
=
1355776
;
set
GLOBAL
query_cache_size
=
1355776
;
flush
status
;
flush
status
;
create
table
t1
(
a
int
,
b
int
);
create
table
t1
(
a
int
,
b
int
);
...
@@ -53,6 +58,30 @@ drop view v1;
...
@@ -53,6 +58,30 @@ drop view v1;
set
query_cache_type
=
default
;
set
query_cache_type
=
default
;
drop
table
t1
;
drop
table
t1
;
set
GLOBAL
query_cache_size
=
default
;
#
# invalidation of view
#
create
table
t1
(
a
int
);
insert
into
t1
values
(
1
),
(
2
),
(
3
);
create
view
v1
as
select
a
from
t1
where
a
>
1
;
select
*
from
v1
;
alter
view
v1
as
select
a
from
t1
where
a
>
2
;
select
*
from
v1
;
drop
view
v1
;
--
error
1146
select
*
from
v1
;
drop
table
t1
;
#
# join view with QC
#
create
table
t1
(
a
int
,
primary
key
(
a
),
b
int
);
create
table
t2
(
a
int
,
primary
key
(
a
),
b
int
);
insert
into
t2
values
(
1000
,
2000
);
create
view
v3
(
a
,
b
)
as
select
t1
.
a
as
a
,
t2
.
a
as
b
from
t1
,
t2
;
select
*
from
v3
;
drop
view
v3
;
drop
table
t1
,
t2
;
set
GLOBAL
query_cache_size
=
default
;
sql/sql_cache.cc
View file @
34b85449
...
@@ -311,7 +311,7 @@ TODO list:
...
@@ -311,7 +311,7 @@ TODO list:
#include "emb_qcache.h"
#include "emb_qcache.h"
#endif
#endif
#if
defined(EXTRA_DEBUG
) && !defined(DBUG_OFF)
#if
!defined(DBUG_OFF
) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
pthread_mutex_lock(M);}
pthread_mutex_lock(M);}
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
...
@@ -2089,43 +2089,55 @@ void Query_cache::invalidate_table(Query_cache_block *table_block)
...
@@ -2089,43 +2089,55 @@ void Query_cache::invalidate_table(Query_cache_block *table_block)
}
}
}
}
/*
Store all used tables
SYNOPSIS
TABLE_COUNTER_TYPE
register_all_tables()
Query_cache
::
register_tables_from_list
(
TABLE_LIST
*
tables_used
,
block Store tables in this block
TABLE_COUNTER_TYPE
counter
,
tables_used List if used tables
Query_cache_block_table
*
block_table
)
tables_arg Not used ?
*/
my_bool
Query_cache
::
register_all_tables
(
Query_cache_block
*
block
,
TABLE_LIST
*
tables_used
,
TABLE_COUNTER_TYPE
tables_arg
)
{
{
TABLE_COUNTER_TYPE
n
;
TABLE_COUNTER_TYPE
n
;
DBUG_PRINT
(
"qcache"
,
(
"register tables block 0x%lx, n %d, header %x"
,
DBUG_ENTER
(
"Query_cache::register_tables_from_list"
);
(
ulong
)
block
,
(
int
)
tables_arg
,
for
(
n
=
counter
;
(
int
)
ALIGN_SIZE
(
sizeof
(
Query_cache_block
))));
Query_cache_block_table
*
block_table
=
block
->
table
(
0
);
for
(
n
=
0
;
tables_used
;
tables_used
;
tables_used
=
tables_used
->
next_global
,
n
++
,
block_table
++
)
tables_used
=
tables_used
->
next_global
,
n
++
,
block_table
++
)
{
block_table
->
n
=
n
;
if
(
tables_used
->
view
)
{
char
key
[
MAX_DBKEY_LENGTH
];
uint
key_length
;
DBUG_PRINT
(
"qcache"
,
(
"view %s, db %s"
,
tables_used
->
view_name
.
str
,
tables_used
->
view_db
.
str
));
key_length
=
(
uint
)
(
strmov
(
strmov
(
key
,
tables_used
->
view_db
.
str
)
+
1
,
tables_used
->
view_name
.
str
)
-
key
)
+
1
;
insert_table
(
key_length
,
key
,
block_table
,
tables_used
->
view_db
.
length
+
1
,
HA_CACHE_TBL_NONTRANSACT
);
{
TABLE_COUNTER_TYPE
inc
=
register_tables_from_list
(
tables_used
->
ancestor
,
n
+
1
,
block_table
+
1
);
if
(
!
inc
)
DBUG_RETURN
(
0
);
n
+=
inc
;
block_table
+=
inc
;
}
}
else
{
{
DBUG_PRINT
(
"qcache"
,
DBUG_PRINT
(
"qcache"
,
(
"table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx"
,
(
"table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx"
,
tables_used
->
table_name
,
tables_used
->
db
,
tables_used
->
table
->
s
->
table_name
,
tables_used
->
table
->
s
->
table_cache_key
,
(
ulong
)
tables_used
->
table
,
(
ulong
)
tables_used
->
table
,
tables_used
->
table
->
s
->
key_length
,
tables_used
->
table
->
s
->
key_length
,
(
ulong
)
tables_used
->
table
->
s
->
table_cache_key
));
(
ulong
)
tables_used
->
table
->
s
->
table_cache_key
));
block_table
->
n
=
n
;
if
(
!
insert_table
(
tables_used
->
table
->
s
->
key_length
,
if
(
!
insert_table
(
tables_used
->
table
->
s
->
key_length
,
tables_used
->
table
->
s
->
table_cache_key
,
block_table
,
tables_used
->
table
->
s
->
table_cache_key
,
block_table
,
tables_used
->
db_length
,
tables_used
->
db_length
,
tables_used
->
table
->
file
->
table_cache_type
()))
tables_used
->
table
->
file
->
table_cache_type
()))
break
;
DBUG_RETURN
(
0
)
;
if
(
tables_used
->
table
->
s
->
db_type
==
DB_TYPE_MRG_MYISAM
)
if
(
tables_used
->
table
->
s
->
db_type
==
DB_TYPE_MRG_MYISAM
)
{
{
...
@@ -2143,13 +2155,39 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
...
@@ -2143,13 +2155,39 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
if
(
!
insert_table
(
key_length
,
key
,
block_table
,
if
(
!
insert_table
(
key_length
,
key
,
block_table
,
db_length
,
db_length
,
tables_used
->
table
->
file
->
table_cache_type
()))
tables_used
->
table
->
file
->
table_cache_type
()))
goto
err
;
DBUG_RETURN
(
0
);
}
}
}
}
}
}
}
DBUG_RETURN
(
n
-
counter
);
}
/*
Store all used tables
SYNOPSIS
register_all_tables()
block Store tables in this block
tables_used List if used tables
tables_arg Not used ?
*/
my_bool
Query_cache
::
register_all_tables
(
Query_cache_block
*
block
,
TABLE_LIST
*
tables_used
,
TABLE_COUNTER_TYPE
tables_arg
)
{
TABLE_COUNTER_TYPE
n
;
DBUG_PRINT
(
"qcache"
,
(
"register tables block 0x%lx, n %d, header %x"
,
(
ulong
)
block
,
(
int
)
tables_arg
,
(
int
)
ALIGN_SIZE
(
sizeof
(
Query_cache_block
))));
Query_cache_block_table
*
block_table
=
block
->
table
(
0
);
n
=
register_tables_from_list
(
tables_used
,
0
,
block_table
);
err:
err:
if
(
tables_used
)
if
(
n
)
{
{
DBUG_PRINT
(
"qcache"
,
(
"failed at table %d"
,
(
int
)
n
));
DBUG_PRINT
(
"qcache"
,
(
"failed at table %d"
,
(
int
)
n
));
/* Unlink the tables we allocated above */
/* Unlink the tables we allocated above */
...
@@ -2158,7 +2196,7 @@ err:
...
@@ -2158,7 +2196,7 @@ err:
tmp
++
)
tmp
++
)
unlink_table
(
tmp
);
unlink_table
(
tmp
);
}
}
return
(
tables_used
==
0
);
return
(
n
);
}
}
/*
/*
...
@@ -2635,36 +2673,49 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
...
@@ -2635,36 +2673,49 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
*****************************************************************************/
*****************************************************************************/
/*
/*
If query is cacheable return number tables in query
Collect information about table types, check that tables are cachable and
(query without tables are not cached)
count them
SYNOPSIS
process_and_count_tables()
tables_used table list for processing
tables_type pointer to variable for table types collection
RETURN
0 error
>0 number of tables
*/
*/
TABLE_COUNTER_TYPE
Query_cache
::
is_cacheable
(
THD
*
thd
,
uint32
query_len
,
static
TABLE_COUNTER_TYPE
process_and_count_tables
(
TABLE_LIST
*
tables_used
,
char
*
query
,
LEX
*
lex
,
TABLE_LIST
*
tables_used
,
uint8
*
tables_type
)
uint8
*
tables_type
)
{
{
DBUG_ENTER
(
"process_and_count_tables"
);
TABLE_COUNTER_TYPE
table_count
=
0
;
TABLE_COUNTER_TYPE
table_count
=
0
;
DBUG_ENTER
(
"Query_cache::is_cacheable"
);
for
(;
tables_used
;
tables_used
=
tables_used
->
next_global
)
if
(
lex
->
sql_command
==
SQLCOM_SELECT
&&
(
thd
->
variables
.
query_cache_type
==
1
||
(
thd
->
variables
.
query_cache_type
==
2
&&
(
lex
->
select_lex
.
options
&
OPTION_TO_QUERY_CACHE
)))
&&
lex
->
safe_to_cache_query
)
{
{
DBUG_PRINT
(
"qcache"
,
(
"options %lx %lx, type %u"
,
OPTION_TO_QUERY_CACHE
,
lex
->
select_lex
.
options
,
(
int
)
thd
->
variables
.
query_cache_type
));
for
(;
tables_used
;
tables_used
=
tables_used
->
next_global
)
if
(
tables_used
->
view
)
{
DBUG_PRINT
(
"qcache"
,
(
"view %s, db %s"
,
tables_used
->
view_name
.
str
,
tables_used
->
view_db
.
str
));
table_count
++
;
*
tables_type
|=
HA_CACHE_TBL_NONTRANSACT
;
{
TABLE_COUNTER_TYPE
subcount
;
if
(
!
(
subcount
=
process_and_count_tables
(
tables_used
->
ancestor
,
tables_type
)))
DBUG_RETURN
(
0
);
table_count
+=
subcount
;
}
}
else
{
{
table_count
++
;
table_count
++
;
DBUG_PRINT
(
"qcache"
,
(
"table %s, db %s, type %u"
,
DBUG_PRINT
(
"qcache"
,
(
"table %s, db %s, type %u"
,
tables_used
->
table_name
,
tables_used
->
table
->
s
->
table_name
,
tables_used
->
db
,
tables_used
->
table
->
s
->
db_type
));
tables_used
->
table
->
s
->
table_cache_key
,
tables_used
->
table
->
s
->
db_type
));
*
tables_type
|=
tables_used
->
table
->
file
->
table_cache_type
();
*
tables_type
|=
tables_used
->
table
->
file
->
table_cache_type
();
/*
/*
...
@@ -2674,12 +2725,13 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
...
@@ -2674,12 +2725,13 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
if
(
tables_used
->
table
->
s
->
tmp_table
!=
NO_TMP_TABLE
||
if
(
tables_used
->
table
->
s
->
tmp_table
!=
NO_TMP_TABLE
||
(
*
tables_type
&
HA_CACHE_TBL_NOCACHE
)
||
(
*
tables_type
&
HA_CACHE_TBL_NOCACHE
)
||
(
tables_used
->
db_length
==
5
&&
(
tables_used
->
db_length
==
5
&&
my_strnncoll
(
table_alias_charset
,
(
uchar
*
)
tables_used
->
db
,
6
,
my_strnncoll
(
table_alias_charset
,
(
uchar
*
)
tables_used
->
table
->
s
->
table_cache_key
,
6
,
(
uchar
*
)
"mysql"
,
6
)
==
0
))
(
uchar
*
)
"mysql"
,
6
)
==
0
))
{
{
DBUG_PRINT
(
"qcache"
,
DBUG_PRINT
(
"qcache"
,
(
"select not cacheable: temporary, system or \
(
"select not cacheable: temporary, system or \
other non-cacheable table(s)"
));
other non-cacheable table(s)"
));
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
if
(
tables_used
->
table
->
s
->
db_type
==
DB_TYPE_MRG_MYISAM
)
if
(
tables_used
->
table
->
s
->
db_type
==
DB_TYPE_MRG_MYISAM
)
...
@@ -2689,6 +2741,38 @@ other non-cacheable table(s)"));
...
@@ -2689,6 +2741,38 @@ other non-cacheable table(s)"));
table_count
+=
(
file
->
end_table
-
file
->
open_tables
);
table_count
+=
(
file
->
end_table
-
file
->
open_tables
);
}
}
}
}
}
DBUG_RETURN
(
table_count
);
}
/*
If query is cacheable return number tables in query
(query without tables are not cached)
*/
TABLE_COUNTER_TYPE
Query_cache
::
is_cacheable
(
THD
*
thd
,
uint32
query_len
,
char
*
query
,
LEX
*
lex
,
TABLE_LIST
*
tables_used
,
uint8
*
tables_type
)
{
TABLE_COUNTER_TYPE
table_count
;
DBUG_ENTER
(
"Query_cache::is_cacheable"
);
if
(
lex
->
sql_command
==
SQLCOM_SELECT
&&
(
thd
->
variables
.
query_cache_type
==
1
||
(
thd
->
variables
.
query_cache_type
==
2
&&
(
lex
->
select_lex
.
options
&
OPTION_TO_QUERY_CACHE
)))
&&
lex
->
safe_to_cache_query
)
{
DBUG_PRINT
(
"qcache"
,
(
"options %lx %lx, type %u"
,
OPTION_TO_QUERY_CACHE
,
lex
->
select_lex
.
options
,
(
int
)
thd
->
variables
.
query_cache_type
));
if
(
!
(
table_count
=
process_and_count_tables
(
tables_used
,
tables_type
)))
DBUG_RETURN
(
0
);
if
((
thd
->
options
&
(
OPTION_NOT_AUTOCOMMIT
|
OPTION_BEGIN
))
&&
if
((
thd
->
options
&
(
OPTION_NOT_AUTOCOMMIT
|
OPTION_BEGIN
))
&&
((
*
tables_type
)
&
HA_CACHE_TBL_TRANSACT
))
((
*
tables_type
)
&
HA_CACHE_TBL_TRANSACT
))
...
@@ -2729,7 +2813,8 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
...
@@ -2729,7 +2813,8 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
for
(;
tables_used
;
tables_used
=
tables_used
->
next_global
)
for
(;
tables_used
;
tables_used
=
tables_used
->
next_global
)
{
{
TABLE
*
table
=
tables_used
->
table
;
TABLE
*
table
=
tables_used
->
table
;
if
(
!
ha_caching_allowed
(
thd
,
table
->
s
->
table_cache_key
,
if
(
table
&&
!
ha_caching_allowed
(
thd
,
table
->
s
->
table_cache_key
,
table
->
s
->
key_length
,
table
->
s
->
key_length
,
table
->
file
->
table_cache_type
()))
table
->
file
->
table_cache_type
()))
{
{
...
...
sql/sql_cache.h
View file @
34b85449
...
@@ -277,6 +277,10 @@ protected:
...
@@ -277,6 +277,10 @@ protected:
void
invalidate_table
(
TABLE
*
table
);
void
invalidate_table
(
TABLE
*
table
);
void
invalidate_table
(
byte
*
key
,
uint32
key_length
);
void
invalidate_table
(
byte
*
key
,
uint32
key_length
);
void
invalidate_table
(
Query_cache_block
*
table_block
);
void
invalidate_table
(
Query_cache_block
*
table_block
);
TABLE_COUNTER_TYPE
register_tables_from_list
(
TABLE_LIST
*
tables_used
,
TABLE_COUNTER_TYPE
counter
,
Query_cache_block_table
*
block_table
);
my_bool
register_all_tables
(
Query_cache_block
*
block
,
my_bool
register_all_tables
(
Query_cache_block
*
block
,
TABLE_LIST
*
tables_used
,
TABLE_LIST
*
tables_used
,
TABLE_COUNTER_TYPE
tables
);
TABLE_COUNTER_TYPE
tables
);
...
...
sql/sql_view.cc
View file @
34b85449
...
@@ -305,6 +305,8 @@ bool mysql_create_view(THD *thd,
...
@@ -305,6 +305,8 @@ bool mysql_create_view(THD *thd,
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
res
=
mysql_register_view
(
thd
,
view
,
mode
);
res
=
mysql_register_view
(
thd
,
view
,
mode
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
if
(
view
->
revision
!=
1
)
query_cache_invalidate3
(
thd
,
view
,
0
);
start_waiting_global_read_lock
(
thd
);
start_waiting_global_read_lock
(
thd
);
if
(
res
)
if
(
res
)
goto
err
;
goto
err
;
...
@@ -912,6 +914,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
...
@@ -912,6 +914,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
}
}
if
(
my_delete
(
path
,
MYF
(
MY_WME
)))
if
(
my_delete
(
path
,
MYF
(
MY_WME
)))
goto
err
;
goto
err
;
query_cache_invalidate3
(
thd
,
view
,
0
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
}
}
send_ok
(
thd
);
send_ok
(
thd
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment