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
4c17825a
Commit
4c17825a
authored
Dec 06, 2001
by
monty@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update of query cache code
parent
40da5046
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
305 additions
and
80 deletions
+305
-80
Docs/manual.texi
Docs/manual.texi
+30
-5
include/mysql_com.h
include/mysql_com.h
+3
-2
mysql-test/r/flush.result
mysql-test/r/flush.result
+5
-0
mysql-test/r/query_cache.result
mysql-test/r/query_cache.result
+38
-0
mysql-test/t/flush.test
mysql-test/t/flush.test
+9
-0
mysql-test/t/query_cache-master.opt
mysql-test/t/query_cache-master.opt
+1
-0
mysql-test/t/query_cache.test
mysql-test/t/query_cache.test
+26
-0
sql-bench/test-connect.sh
sql-bench/test-connect.sh
+23
-3
sql-bench/test-select.sh
sql-bench/test-select.sh
+2
-2
sql/mysql_priv.h
sql/mysql_priv.h
+1
-2
sql/sql_base.cc
sql/sql_base.cc
+10
-8
sql/sql_cache.cc
sql/sql_cache.cc
+130
-38
sql/sql_cache.h
sql/sql_cache.h
+3
-6
sql/sql_class.cc
sql/sql_class.cc
+1
-1
sql/sql_parse.cc
sql/sql_parse.cc
+4
-5
sql/sql_table.cc
sql/sql_table.cc
+19
-8
No files found.
Docs/manual.texi
View file @
4c17825a
...
...
@@ -17477,6 +17477,7 @@ information and a description of what it means.
* OPTIMIZE TABLE:: @code{OPTIMIZE TABLE} Syntax
* ANALYZE TABLE:: @code{ANALYZE TABLE} Syntax
* FLUSH:: @code{FLUSH} Syntax
* RESET:: @code{RESET} Syntax
* KILL:: @code{KILL} Syntax
* SHOW:: @code{SHOW} Syntax
@end menu
...
...
@@ -17564,7 +17565,7 @@ If the table hasn't changed since the last @code{ANALYZE TABLE} command,
the table will not be analysed again.
@node FLUSH,
KILL
, ANALYZE TABLE, Database Administration
@node FLUSH,
RESET
, ANALYZE TABLE, Database Administration
@subsection @code{FLUSH} Syntax
@findex FLUSH
...
...
@@ -17605,7 +17606,9 @@ signal to the @code{mysqld} server.
@item @code{PRIVILEGES} @tab Reloads the privileges from the grant tables in
the @code{mysql} database.
@item @code{TABLES} @tab Closes all open tables and force all tables in use to be closed.
@item @code{QUERY CACHE} @tab Defragment the query cache to better utilize the memory. This command will not remove any queries from the cache.
@item @code{TABLES} @tab Closes all open tables and force all tables in use to be closed. This also flushes the query cache.
@item @code{[TABLE | TABLES] table_name [,table_name...]} @tab Flushes only the given tables.
...
...
@@ -17618,12 +17621,34 @@ You can also access each of the commands shown above with the @code{mysqladmin}
utility, using the @code{flush-hosts}, @code{flush-logs}, @code{reload},
or @code{flush-tables} commands.
Take also a look at the @code{RESET} command used with
replication. @xref{Replication SQL
}.
Take also a look at the @code{RESET} command used with
replication.
@xref{RESET
}.
@node RESET, KILL, FLUSH, Database Administration
@subsection @code{RESET} Syntax
@example
FLUSH flush_option [,flush_option]
@end example
The @code{RESET} command is used to clear things. It also acts as an stronger
version of the @code{FLUSH} command. @xref{FLUSH}.
@multitable @columnfractions .15 .85
@item @code{MASTER}
@tab Deletes all binary logs listed in the index file, resetting the binlog
index file to be empty. In pre-3.23.26 versions, @code{FLUSH MASTER} (Master)
@item @code{SLAVE}
@tab Makes the slave forget its replication position in the master
logs. In pre 3.23.26 versions the command was called
@code{FLUSH SLAVE}(Slave)
@item @code{QUERY CACHE}
@tab Removes all query results from the query cache.
@end multitable
@node KILL, SHOW,
FLUSH
, Database Administration
@node KILL, SHOW,
RESET
, Database Administration
@subsection @code{KILL} Syntax
@findex KILL
include/mysql_com.h
View file @
4c17825a
...
...
@@ -78,8 +78,9 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY,
#define REFRESH_READ_LOCK 16384
/* Lock tables for read */
#define REFRESH_FAST 32768
/* Intern flag */
#define REFRESH_QUERY_CACHE 65536
/* flush query cache */
#define REFRESH_QUERY_CACHE_FREE 0x10000L
/* pack query cache */
/* RESET (remove all queries) from query cache */
#define REFRESH_QUERY_CACHE 65536
#define REFRESH_QUERY_CACHE_FREE 0x20000L
/* pack query cache */
#define CLIENT_LONG_PASSWORD 1
/* new more secure passwords */
#define CLIENT_FOUND_ROWS 2
/* Found instead of affected rows */
...
...
mysql-test/r/flush.result
View file @
4c17825a
...
...
@@ -28,3 +28,8 @@ select * from t1;
n
345
drop table t1;
flush query cache;
reset query cache;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
mysql-test/r/query_cache.result
0 → 100644
View file @
4c17825a
reset query cache;
flush status;
drop table if exists t1;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
select * from t1;
a
1
2
3
select sql_no_cache * from t1;
a
1
2
3
select length(now()) from t1;
length(now())
19
19
19
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
drop table t1;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
mysql-test/t/flush.test
View file @
4c17825a
...
...
@@ -66,3 +66,12 @@ connection con2;
insert
into
t1
values
(
345
);
select
*
from
t1
;
drop
table
t1
;
#
# Test that QUERY CACHE commands doesn't core dump.
# (Normally we don't have a cache active at this point)
#
flush
query
cache
;
reset
query
cache
;
show
status
like
"Qcache_queries_in_cache"
;
mysql-test/t/query_cache-master.opt
0 → 100644
View file @
4c17825a
--set-variable=query_cache_size=2M
mysql-test/t/query_cache.test
0 → 100644
View file @
4c17825a
#
# Tests with query cache
#
# Reset query cache variables.
reset
query
cache
;
flush
status
;
drop
table
if
exists
t1
;
create
table
t1
(
a
int
not
null
);
insert
into
t1
values
(
1
),(
2
),(
3
);
select
*
from
t1
;
select
*
from
t1
;
select
sql_no_cache
*
from
t1
;
select
length
(
now
())
from
t1
;
# Only check the variables that are independent of the machine and startup
# options
show
status
like
"Qcache_queries_in_cache"
;
show
status
like
"Qcache_inserts"
;
show
status
like
"Qcache_hits"
;
drop
table
t1
;
show
status
like
"Qcache_queries_in_cache"
;
sql-bench/test-connect.sh
View file @
4c17825a
...
...
@@ -46,7 +46,7 @@ $opt_loop_count=min(1000, $opt_loop_count) if ($opt_tcpip);
$small_loop_count
=
$opt_loop_count
/10
;
# For connect tests
print
"Testing the speed of connecting to the server and sending of data
\n
"
;
print
"Connect tests are done
$
opt_small_loop_count
and other tests
$opt_loop_count
times
\n\n
"
;
print
"Connect tests are done
$
small_loop_count
times
and other tests
$opt_loop_count
times
\n\n
"
;
################################# PART:1 ###################################
####
...
...
@@ -139,7 +139,7 @@ if ($limits->{'select_without_from'})
$sth
=
$dbh
->do
(
"select 10000"
)
or die
$DBI
::errstr
;
}
$end_time
=
new Benchmark
;
print
"Time for select_simple_
query_
cache (
$opt_loop_count
): "
.
print
"Time for select_simple_cache (
$opt_loop_count
): "
.
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n\n
"
;
}
...
...
@@ -208,8 +208,24 @@ print "Time to select_1_row ($opt_loop_count): " .
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n\n
"
;
#
#
The same test, but with 2 rows.
#
Same test (as with one row) but now with a cacheable query
#
$loop_time
=
new Benchmark
;
for
(
$i
=
0
;
$i
<
$opt_loop_count
;
$i
++
)
{
$sth
=
$dbh
->do
(
"select a,i,s from bench1"
)
# Select * from table with 1 record
or die
$DBI
::errstr
;
}
$end_time
=
new Benchmark
;
print
"Time to select_1_row_cache (
$opt_loop_count
): "
.
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n\n
"
;
#
# The same test, but with 2 rows (not cacheable).
#
print
"Testing select 2 rows from table
\n
"
;
$sth
=
$dbh
->do
(
"insert into bench1 values(2,200,'BBB')"
)
...
...
@@ -227,6 +243,10 @@ $end_time=new Benchmark;
print
"Time to select_2_rows (
$opt_loop_count
): "
.
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n\n
"
;
#
# Simple test to test speed of functions.
#
if
(
$limits
->
{
'functions'
})
{
print
"Test select with aritmetic (+)
\n
"
;
...
...
sql-bench/test-select.sh
View file @
4c17825a
...
...
@@ -156,7 +156,7 @@ if ($limits->{'group_functions'})
fetch_all_rows
(
$dbh
,
"select sum(idn+100),sum(rev_idn-100) from bench1"
)
;
}
$end_time
=
new Benchmark
;
print
"Time for select_
query_
cache (
$opt_loop_count
): "
.
print
"Time for select_cache (
$opt_loop_count
): "
.
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n\n
"
;
# If the database has a query cache, the following loop should be much
...
...
@@ -168,7 +168,7 @@ if ($limits->{'group_functions'})
fetch_all_rows
(
$dbh
,
"select sum(idn+
$tests
),sum(rev_idn-
$tests
) from bench1"
)
;
}
$end_time
=
new Benchmark
;
print
"Time for select_
query_
cache2 (
$opt_loop_count
): "
.
print
"Time for select_cache2 (
$opt_loop_count
): "
.
timestr
(
timediff
(
$end_time
,
$loop_time
)
,
"all"
)
.
"
\n\n
"
;
}
...
...
sql/mysql_priv.h
View file @
4c17825a
...
...
@@ -277,7 +277,7 @@ bool do_command(THD *thd);
bool
dispatch_command
(
enum
enum_server_command
command
,
THD
*
thd
,
char
*
packet
,
uint
packet_length
);
bool
check_stack_overrun
(
THD
*
thd
,
char
*
dummy
);
bool
reload_acl_and_cache
(
THD
*
thd
,
u
int
options
,
TABLE_LIST
*
tables
);
bool
reload_acl_and_cache
(
THD
*
thd
,
u
long
options
,
TABLE_LIST
*
tables
);
void
table_cache_init
(
void
);
void
table_cache_free
(
void
);
uint
cached_tables
(
void
);
...
...
@@ -697,7 +697,6 @@ void hostname_cache_refresh(void);
bool
get_interval_info
(
const
char
*
str
,
uint
length
,
uint
count
,
long
*
values
);
/* sql_cache */
extern
bool
sql_cache_init
();
extern
void
sql_cache_free
();
extern
int
sql_cache_hit
(
THD
*
thd
,
char
*
inBuf
,
uint
length
);
...
...
sql/sql_base.cc
View file @
4c17825a
...
...
@@ -2195,6 +2195,8 @@ int setup_ftfuncs(THD *thd)
int
init_ftfuncs
(
THD
*
thd
,
bool
no_order
)
{
if
(
thd
->
lex
.
select_lex
.
ftfunc_list
.
elements
)
{
List_iterator
<
Item_func_match
>
li
(
thd
->
lex
.
select_lex
.
ftfunc_list
);
Item_func_match
*
ifm
;
DBUG_PRINT
(
"info"
,(
"Performing FULLTEXT search"
));
...
...
@@ -2204,7 +2206,7 @@ int init_ftfuncs(THD *thd, bool no_order)
{
ifm
->
init_search
(
no_order
);
}
}
return
0
;
}
sql/sql_cache.cc
View file @
4c17825a
...
...
@@ -200,6 +200,74 @@ stored in Query_cache_memory_bin_step structure.
Free memory blocks are sorted in bins in lists with size-ascending order
(more small blocks needed frequently then bigger one).
6. Packing cache.
Query cache packing is divided into two operation:
- pack_cache
- join_results
pack_cache moved all blocks to "top" of cache and create one block of free
space at the "bottom":
before pack_cache after pack_cache
+-------------+ +-------------+
| query 1 | | query 1 |
+-------------+ +-------------+
| table 1 | | table 1 |
+-------------+ +-------------+
| results 1.1 | | results 1.1 |
+-------------+ +-------------+
| free | | query 2 |
+-------------+ +-------------+
| query 2 | | table 2 |
+-------------+ ---> +-------------+
| table 2 | | results 1.2 |
+-------------+ +-------------+
| results 1.2 | | results 2 |
+-------------+ +-------------+
| free | | free |
+-------------+ | |
| results 2 | | |
+-------------+ | |
| free | | |
+-------------+ +-------------+
pack_cache scan blocks in physical address order and move every non-free
block "higher".
pack_cach remove every free block it finds. The length of the deleted block
is accumulated to the "gap". All non free blocks should be shifted with the
"gap" step.
join_results scans all complete queries. If the results of query are not
stored in the same block, join_results tries to move results so, that they
are stored in one block.
before join_results after join_results
+-------------+ +-------------+
| query 1 | | query 1 |
+-------------+ +-------------+
| table 1 | | table 1 |
+-------------+ +-------------+
| results 1.1 | | free |
+-------------+ +-------------+
| query 2 | | query 2 |
+-------------+ +-------------+
| table 2 | | table 2 |
+-------------+ ---> +-------------+
| results 1.2 | | free |
+-------------+ +-------------+
| results 2 | | results 2 |
+-------------+ +-------------+
| free | | results 1 |
| | | |
| | +-------------+
| | | free |
| | | |
+-------------+ +-------------+
If join_results allocated new block(s) then we need call pack_cache again.
*/
#include "mysql_priv.h"
...
...
@@ -377,6 +445,10 @@ void Query_cache_query::init_n_lock()
void
Query_cache_query
::
unlock_n_destroy
()
{
DBUG_ENTER
(
"Query_cache_query::unlock_n_destroy"
);
/*
The following call is not needed on system where one can destroy an
active semaphore
*/
this
->
unlock_writing
();
DBUG_PRINT
(
"qcache"
,
(
"destroyed & unlocked query for block 0x%lx"
,
((
byte
*
)
this
)
-
ALIGN_SIZE
(
sizeof
(
Query_cache_block
))));
...
...
@@ -465,7 +537,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
DBUG_ENTER
(
"query_cache_insert"
);
#ifndef DBUG_OFF
//
Debugging method wreck may cause this
//
Check if we have called query_cache.wreck() (which disables the cache)
if
(
query_cache
.
query_cache_size
==
0
)
DBUG_VOID_RETURN
;
#endif
...
...
@@ -493,6 +565,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
if
(
!
query_cache
.
append_result_data
(
&
result
,
length
,
(
gptr
)
packet
,
query_block
))
{
query_cache
.
refused
++
;
DBUG_PRINT
(
"warning"
,
(
"Can't append data"
));
header
->
result
(
result
);
DBUG_PRINT
(
"qcache"
,
(
"free query 0x%lx"
,
(
ulong
)
query_block
));
...
...
@@ -517,7 +590,7 @@ void query_cache_abort(NET *net)
DBUG_ENTER
(
"query_cache_abort"
);
#ifndef DBUG_OFF
//
Debugging method wreck may cause this
//
Check if we have called query_cache.wreck() (which disables the cache)
if
(
query_cache
.
query_cache_size
==
0
)
DBUG_VOID_RETURN
;
#endif
...
...
@@ -545,7 +618,7 @@ void query_cache_end_of_result(NET *net)
DBUG_ENTER
(
"query_cache_end_of_result"
);
#ifndef DBUG_OFF
//
Debugging method wreck may cause this
//
Check if we have called query_cache.wreck() (which disables the cache)
if
(
query_cache
.
query_cache_size
==
0
)
DBUG_VOID_RETURN
;
#endif
...
...
@@ -603,11 +676,11 @@ Query_cache::Query_cache(ulong query_cache_limit,
uint
def_table_hash_size
)
:
query_cache_size
(
0
),
query_cache_limit
(
query_cache_limit
),
queries_in_cache
(
0
),
hits
(
0
),
inserts
(
0
),
refused
(
0
),
min_allocation_unit
(
min_allocation_unit
),
min_result_data_size
(
min_result_data_size
),
def_query_hash_size
(
def_query_hash_size
),
def_table_hash_size
(
def_table_hash_size
),
queries_in_cache
(
0
),
hits
(
0
),
inserts
(
0
),
refused
(
0
),
initialized
(
0
)
{
ulong
min_needed
=
(
ALIGN_SIZE
(
sizeof
(
Query_cache_block
))
+
...
...
@@ -622,11 +695,11 @@ Query_cache::Query_cache(ulong query_cache_limit,
ulong
Query_cache
::
resize
(
ulong
query_cache_size
)
{
/*
TODO: when will be realized pack() optimize case when
TODO:
When will be realized pack() optimize case when
query_cache_size < this->query_cache_size
*/
/*
TODO: try to copy old cache in new memory
Try to copy old cache in new memory
*/
DBUG_ENTER
(
"Query_cache::resize"
);
DBUG_PRINT
(
"qcache"
,
(
"from %lu to %lu"
,
this
->
query_cache_size
,
...
...
@@ -739,7 +812,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
}
}
else
refused
++
;
statistic_increment
(
refused
,
&
structure_guard_mutex
)
;
end:
thd
->
query
[
thd
->
query_length
]
=
0
;
// Restore end null
...
...
@@ -834,7 +907,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
/* Now lock and test that nothing changed while blocks was unlocked */
BLOCK_LOCK_RD
(
query_block
);
STRUCT_UNLOCK
(
&
structure_guard_mutex
);
query
=
query_block
->
query
();
result_block
=
first_result_block
=
query
->
result
();
...
...
@@ -843,6 +915,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
{
/* The query is probably yet processed */
DBUG_PRINT
(
"qcache"
,
(
"query found, but no data or data incomplete"
));
BLOCK_UNLOCK_RD
(
query_block
);
goto
err
;
}
DBUG_PRINT
(
"qcache"
,
(
"Query have result 0x%lx"
,
(
ulong
)
query
));
...
...
@@ -863,12 +936,15 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
DBUG_PRINT
(
"qcache"
,
(
"probably no SELECT access to %s.%s => return to normal processing"
,
table_list
.
db
,
table_list
.
name
));
BLOCK_UNLOCK_RD
(
query_block
);
STRUCT_UNLOCK
(
&
structure_guard_mutex
);
goto
err
;
}
}
move_to_query_list_end
(
query_block
);
hits
++
;
STRUCT_UNLOCK
(
&
structure_guard_mutex
);
/*
Send cached result to client
*/
...
...
@@ -957,12 +1033,11 @@ void Query_cache::invalidate(Query_cache_table::query_cache_table_type type)
{
/* Store next block address defore deleting the current block */
Query_cache_block
*
next
=
table_block
->
next
;
invalidate_table
(
table_block
);
#ifdef TO_BE_DELETED
if
(
next
==
table_block
)
// End of list
break
;
#endif
table_block
=
next
;
}
while
(
table_block
!=
tables_blocks
[
type
]);
}
...
...
@@ -999,10 +1074,10 @@ void Query_cache::invalidate(char *db)
Query_cache_block
*
next
=
table_block
->
next
;
invalidate_table_in_db
(
table_block
,
db
);
#ifdef TO_BE_DELETED
if
(
table_block
==
next
)
break
;
#endif
table_block
=
next
;
}
while
(
table_block
!=
tables_blocks
[
i
]);
}
...
...
@@ -1035,21 +1110,24 @@ void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
DBUG_VOID_RETURN
;
}
/* Remove all queries from cache */
void
Query_cache
::
flush
()
{
DBUG_ENTER
(
"Query_cache::flush"
);
STRUCT_LOCK
(
&
structure_guard_mutex
);
if
(
query_cache_size
>
0
)
{
DUMP
(
this
);
STRUCT_LOCK
(
&
structure_guard_mutex
);
flush_cache
();
DUMP
(
this
);
STRUCT_UNLOCK
(
&
structure_guard_mutex
);
}
STRUCT_UNLOCK
(
&
structure_guard_mutex
);
DBUG_VOID_RETURN
;
}
/* Join result in cache in 1 block (if result length > join_limit) */
void
Query_cache
::
pack
(
ulong
join_limit
,
uint
iteration_limit
)
{
DBUG_ENTER
(
"Query_cache::pack"
);
...
...
@@ -1307,7 +1385,7 @@ void Query_cache::flush_cache()
my_bool
Query_cache
::
free_old_query
()
{
DBUG_ENTER
(
"Query_cache::free_old_query"
);
if
(
!
queries_blocks
)
if
(
queries_blocks
)
{
/*
try_lock_writing used to prevent client because here lock
...
...
@@ -1371,6 +1449,11 @@ void Query_cache::free_query(Query_cache_block *query_block)
for
(
TABLE_COUNTER_TYPE
i
=
0
;
i
<
query_block
->
n_tables
;
i
++
)
unlink_table
(
table
++
);
Query_cache_block
*
result_block
=
query
->
result
();
/*
The following is true when query destruction was called and no results
in query . (query just registered and then abort/pack/flush called)
*/
if
(
result_block
!=
0
)
{
Query_cache_block
*
block
=
result_block
;
...
...
@@ -1522,7 +1605,15 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
DBUG_ENTER
(
"Query_cache::write_result_data"
);
DBUG_PRINT
(
"qcache"
,
(
"data_len %lu"
,
data_len
));
// Reserve block(s) for filling
/*
Reserve block(s) for filling
During data allocation we must have structure_guard_mutex locked.
As data copy is not a fast operation, it's better if we don't have
structure_guard_mutex locked during data coping.
Thus we first allocate space and lock query, then unlock
structure_guard_mutex and copy data.
*/
my_bool
success
=
allocate_data_chain
(
result_block
,
data_len
,
query_block
);
if
(
success
)
{
...
...
@@ -1975,7 +2066,6 @@ Query_cache::join_free_blocks(Query_cache_block *first_block,
exclude_from_free_memory_list
(
block_in_list
);
second_block
=
first_block
->
pnext
;
// May be was not free block
second_block
->
type
=
Query_cache_block
::
FREE
;
second_block
->
used
=
0
;
second_block
->
destroy
();
...
...
@@ -2254,15 +2344,17 @@ void Query_cache::pack_cache()
Query_cache_block
*
before
=
0
;
ulong
gap
=
0
;
my_bool
ok
=
1
;
Query_cache_block
*
i
=
first_block
;
Query_cache_block
*
block
=
first_block
;
DBUG_ENTER
(
"Query_cache::pack_cache"
);
DUMP
(
this
);
if
(
first_block
)
{
do
{
ok
=
move_by_type
(
&
border
,
&
before
,
&
gap
,
i
);
i
=
i
->
pnext
;
}
while
(
ok
&&
i
!=
first_block
);
ok
=
move_by_type
(
&
border
,
&
before
,
&
gap
,
block
);
block
=
block
->
pnext
;
}
while
(
ok
&&
block
!=
first_block
);
if
(
border
!=
0
)
{
...
...
@@ -2275,6 +2367,7 @@ void Query_cache::pack_cache()
insert_into_free_memory_list
(
new_block
);
}
DUMP
(
this
);
}
STRUCT_UNLOCK
(
&
structure_guard_mutex
);
DBUG_VOID_RETURN
;
}
...
...
@@ -2487,7 +2580,6 @@ void Query_cache::relink(Query_cache_block *oblock,
my_bool
Query_cache
::
join_results
(
ulong
join_limit
)
{
//TODO
my_bool
has_moving
=
0
;
DBUG_ENTER
(
"Query_cache::join_results"
);
...
...
@@ -2577,7 +2669,7 @@ uint Query_cache::filename_2_table_key (char *key, const char *path)
db_length
=
(
filename
-
dbname
)
-
1
;
DBUG_PRINT
(
"qcache"
,
(
"table '%-.*s.%s'"
,
db_length
,
dbname
,
filename
));
DBUG_RETURN
((
uint
)
(
strmov
(
str
nmov
(
key
,
dbname
,
db_length
)
+
1
,
DBUG_RETURN
((
uint
)
(
strmov
(
str
make
(
key
,
dbname
,
db_length
)
+
1
,
filename
)
-
key
)
+
1
);
}
...
...
sql/sql_cache.h
View file @
4c17825a
...
...
@@ -241,12 +241,12 @@ protected:
Query_cache_memory_bin
*
bins
;
// free block lists
Query_cache_memory_bin_step
*
steps
;
// bins spacing info
HASH
queries
,
tables
;
uint
mem_bin_num
,
mem_bin_steps
;
// See at init_cache & find_bin
my_bool
initialized
;
/* options */
ulong
min_allocation_unit
,
min_result_data_size
;
uint
def_query_hash_size
,
def_table_hash_size
;
uint
mem_bin_num
,
mem_bin_steps
;
// See at init_cache & find_bin
my_bool
initialized
;
/* Exclude/include from cyclic double linked list */
static
void
double_linked_list_exclude
(
Query_cache_block
*
point
,
...
...
@@ -368,10 +368,7 @@ protected:
/* Remove all queries that uses any of the listed following table */
void
invalidate_by_MyISAM_filename
(
const
char
*
filename
);
/* Remove all queries from cache */
void
flush
();
/* Join result in cache in 1 block (if result length > join_limit) */
void
pack
(
ulong
join_limit
=
QUERY_CACHE_PACK_LIMIT
,
uint
iteration_limit
=
QUERY_CACHE_PACK_ITERATION
);
...
...
sql/sql_class.cc
View file @
4c17825a
...
...
@@ -122,7 +122,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
server_status
=
SERVER_STATUS_AUTOCOMMIT
;
update_lock_default
=
low_priority_updates
?
TL_WRITE_LOW_PRIORITY
:
TL_WRITE
;
options
=
thd_startup_options
;
query_cache_type
=
(
byte
)
query_cache_startup_type
;
query_cache_type
=
(
byte
)
query_cache_startup_type
;
sql_mode
=
(
uint
)
opt_sql_mode
;
inactive_timeout
=
net_wait_timeout
;
open_options
=
ha_open_options
;
...
...
sql/sql_parse.cc
View file @
4c17825a
...
...
@@ -951,7 +951,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
case
COM_REFRESH
:
{
u
int
options
=
(
uchar
)
packet
[
0
];
u
long
options
=
(
ulong
)
(
uchar
)
packet
[
0
];
if
(
check_access
(
thd
,
RELOAD_ACL
,
any_db
))
break
;
mysql_log
.
write
(
thd
,
command
,
NullS
);
...
...
@@ -1432,7 +1432,6 @@ mysql_execute_command(void)
(
ORDER
*
)
select_lex
->
order_list
.
first
,
lex
->
drop_primary
,
lex
->
duplicates
,
lex
->
alter_keys_onoff
,
lex
->
simple_alter
);
query_cache
.
invalidate
(
tables
);
}
break
;
}
...
...
@@ -2984,7 +2983,7 @@ static bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
return
0
;
}
bool
reload_acl_and_cache
(
THD
*
thd
,
u
int
options
,
TABLE_LIST
*
tables
)
bool
reload_acl_and_cache
(
THD
*
thd
,
u
long
options
,
TABLE_LIST
*
tables
)
{
bool
result
=
0
;
...
...
@@ -3006,12 +3005,12 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
}
if
(
options
&
REFRESH_QUERY_CACHE_FREE
)
{
query_cache
.
pack
();
query_cache
.
pack
();
// FLUSH QUERY CACHE
options
&=
~
REFRESH_QUERY_CACHE
;
//don't flush all cache, just free memory
}
if
(
options
&
(
REFRESH_TABLES
|
REFRESH_QUERY_CACHE
))
{
query_cache
.
flush
();
query_cache
.
flush
();
// RESET QUERY CACHE
}
if
(
options
&
(
REFRESH_TABLES
|
REFRESH_READ_LOCK
))
{
...
...
sql/sql_table.cc
View file @
4c17825a
...
...
@@ -951,6 +951,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
sprintf
(
buff
,
ER
(
ER_OPEN_AS_READONLY
),
table_name
);
net_store_data
(
packet
,
buff
);
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
if
(
my_net_write
(
&
thd
->
net
,
(
char
*
)
thd
->
packet
.
ptr
(),
packet
->
length
()))
goto
err
;
...
...
@@ -1028,6 +1029,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
remove_table_from_cache
(
thd
,
table
->
table
->
table_cache_key
,
table
->
table
->
real_name
);
close_thread_tables
(
thd
);
table
->
table
=
0
;
// For query cache
if
(
my_net_write
(
&
thd
->
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
()))
goto
err
;
...
...
@@ -1037,9 +1039,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_RETURN
(
0
);
err:
close_thread_tables
(
thd
);
// Shouldn't be needed
if
(
table
)
table
->
table
=
0
;
DBUG_RETURN
(
-
1
);
}
int
mysql_backup_table
(
THD
*
thd
,
TABLE_LIST
*
table_list
)
{
DBUG_ENTER
(
"mysql_backup_table"
);
...
...
@@ -1658,24 +1663,30 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
if
(
error
)
{
// This shouldn't happen. We solve this the safe way by
// closing the locked table.
/*
This shouldn't happen. We solve this the safe way by
closing the locked table.
*/
close_cached_table
(
thd
,
table
);
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
goto
err
;
}
if
(
thd
->
lock
||
new_name
!=
table_name
)
// True if WIN32
{
// Not table locking or alter table with rename
// free locks and remove old table
/*
Not table locking or alter table with rename
free locks and remove old table
*/
close_cached_table
(
thd
,
table
);
VOID
(
quick_rm_table
(
old_db_type
,
db
,
old_name
));
}
else
{
// Using LOCK TABLES without rename.
// This code is never executed on WIN32!
// Remove old renamed table, reopen table and get new locks
/*
Using LOCK TABLES without rename.
This code is never executed on WIN32!
Remove old renamed table, reopen table and get new locks
*/
if
(
table
)
{
VOID
(
table
->
file
->
extra
(
HA_EXTRA_FORCE_REOPEN
));
// Use new file
...
...
@@ -1712,7 +1723,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
VOID
(
pthread_cond_broadcast
(
&
COND_refresh
));
VOID
(
pthread_mutex_unlock
(
&
LOCK_open
));
table_list
->
table
=
0
;
//
Table is closed
table_list
->
table
=
0
;
//
For query cache
query_cache
.
invalidate
(
table_list
);
end_temporary:
...
...
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