Commit 4c17825a authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Update of query cache code

parent 40da5046
...@@ -17477,6 +17477,7 @@ information and a description of what it means. ...@@ -17477,6 +17477,7 @@ information and a description of what it means.
* OPTIMIZE TABLE:: @code{OPTIMIZE TABLE} Syntax * OPTIMIZE TABLE:: @code{OPTIMIZE TABLE} Syntax
* ANALYZE TABLE:: @code{ANALYZE TABLE} Syntax * ANALYZE TABLE:: @code{ANALYZE TABLE} Syntax
* FLUSH:: @code{FLUSH} Syntax * FLUSH:: @code{FLUSH} Syntax
* RESET:: @code{RESET} Syntax
* KILL:: @code{KILL} Syntax * KILL:: @code{KILL} Syntax
* SHOW:: @code{SHOW} Syntax * SHOW:: @code{SHOW} Syntax
@end menu @end menu
...@@ -17564,7 +17565,7 @@ If the table hasn't changed since the last @code{ANALYZE TABLE} command, ...@@ -17564,7 +17565,7 @@ If the table hasn't changed since the last @code{ANALYZE TABLE} command,
the table will not be analysed again. 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 @subsection @code{FLUSH} Syntax
@findex FLUSH @findex FLUSH
...@@ -17605,7 +17606,9 @@ signal to the @code{mysqld} server. ...@@ -17605,7 +17606,9 @@ signal to the @code{mysqld} server.
@item @code{PRIVILEGES} @tab Reloads the privileges from the grant tables in @item @code{PRIVILEGES} @tab Reloads the privileges from the grant tables in
the @code{mysql} database. 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. @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} ...@@ -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}, utility, using the @code{flush-hosts}, @code{flush-logs}, @code{reload},
or @code{flush-tables} commands. or @code{flush-tables} commands.
Take also a look at the @code{RESET} command used with Take also a look at the @code{RESET} command used with replication.
replication. @xref{Replication SQL}. @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 @subsection @code{KILL} Syntax
@findex KILL @findex KILL
...@@ -78,8 +78,9 @@ enum enum_server_command {COM_SLEEP,COM_QUIT,COM_INIT_DB,COM_QUERY, ...@@ -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_READ_LOCK 16384 /* Lock tables for read */
#define REFRESH_FAST 32768 /* Intern flag */ #define REFRESH_FAST 32768 /* Intern flag */
#define REFRESH_QUERY_CACHE 65536 /* flush query cache */ /* RESET (remove all queries) from query cache */
#define REFRESH_QUERY_CACHE_FREE 0x10000L /* pack 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_LONG_PASSWORD 1 /* new more secure passwords */
#define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */ #define CLIENT_FOUND_ROWS 2 /* Found instead of affected rows */
......
...@@ -28,3 +28,8 @@ select * from t1; ...@@ -28,3 +28,8 @@ select * from t1;
n n
345 345
drop table t1; drop table t1;
flush query cache;
reset query cache;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
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
...@@ -66,3 +66,12 @@ connection con2; ...@@ -66,3 +66,12 @@ connection con2;
insert into t1 values (345); insert into t1 values (345);
select * from t1; select * from t1;
drop table 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";
--set-variable=query_cache_size=2M
#
# 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";
...@@ -46,7 +46,7 @@ $opt_loop_count=min(1000, $opt_loop_count) if ($opt_tcpip); ...@@ -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 $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 "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 ################################### ################################# PART:1 ###################################
#### ####
...@@ -139,7 +139,7 @@ if ($limits->{'select_without_from'}) ...@@ -139,7 +139,7 @@ if ($limits->{'select_without_from'})
$sth = $dbh->do("select 10000") or die $DBI::errstr; $sth = $dbh->do("select 10000") or die $DBI::errstr;
} }
$end_time=new Benchmark; $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"; timestr(timediff($end_time, $loop_time),"all") . "\n\n";
} }
...@@ -208,8 +208,24 @@ print "Time to select_1_row ($opt_loop_count): " . ...@@ -208,8 +208,24 @@ print "Time to select_1_row ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n"; 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"; print "Testing select 2 rows from table\n";
$sth = $dbh->do("insert into bench1 values(2,200,'BBB')") $sth = $dbh->do("insert into bench1 values(2,200,'BBB')")
...@@ -227,6 +243,10 @@ $end_time=new Benchmark; ...@@ -227,6 +243,10 @@ $end_time=new Benchmark;
print "Time to select_2_rows ($opt_loop_count): " . print "Time to select_2_rows ($opt_loop_count): " .
timestr(timediff($end_time, $loop_time),"all") . "\n\n"; timestr(timediff($end_time, $loop_time),"all") . "\n\n";
#
# Simple test to test speed of functions.
#
if ($limits->{'functions'}) if ($limits->{'functions'})
{ {
print "Test select with aritmetic (+)\n"; print "Test select with aritmetic (+)\n";
......
...@@ -156,7 +156,7 @@ if ($limits->{'group_functions'}) ...@@ -156,7 +156,7 @@ if ($limits->{'group_functions'})
fetch_all_rows($dbh,"select sum(idn+100),sum(rev_idn-100) from bench1"); fetch_all_rows($dbh,"select sum(idn+100),sum(rev_idn-100) from bench1");
} }
$end_time=new Benchmark; $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"; timestr(timediff($end_time, $loop_time),"all") . "\n\n";
# If the database has a query cache, the following loop should be much # If the database has a query cache, the following loop should be much
...@@ -168,7 +168,7 @@ if ($limits->{'group_functions'}) ...@@ -168,7 +168,7 @@ if ($limits->{'group_functions'})
fetch_all_rows($dbh,"select sum(idn+$tests),sum(rev_idn-$tests) from bench1"); fetch_all_rows($dbh,"select sum(idn+$tests),sum(rev_idn-$tests) from bench1");
} }
$end_time=new Benchmark; $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"; timestr(timediff($end_time, $loop_time),"all") . "\n\n";
} }
......
...@@ -277,7 +277,7 @@ bool do_command(THD *thd); ...@@ -277,7 +277,7 @@ bool do_command(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd, bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length); char* packet, uint packet_length);
bool check_stack_overrun(THD *thd,char *dummy); bool check_stack_overrun(THD *thd,char *dummy);
bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables); bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables);
void table_cache_init(void); void table_cache_init(void);
void table_cache_free(void); void table_cache_free(void);
uint cached_tables(void); uint cached_tables(void);
...@@ -697,7 +697,6 @@ void hostname_cache_refresh(void); ...@@ -697,7 +697,6 @@ void hostname_cache_refresh(void);
bool get_interval_info(const char *str,uint length,uint count, bool get_interval_info(const char *str,uint length,uint count,
long *values); long *values);
/* sql_cache */ /* sql_cache */
extern bool sql_cache_init(); extern bool sql_cache_init();
extern void sql_cache_free(); extern void sql_cache_free();
extern int sql_cache_hit(THD *thd, char *inBuf, uint length); extern int sql_cache_hit(THD *thd, char *inBuf, uint length);
......
...@@ -2195,16 +2195,18 @@ int setup_ftfuncs(THD *thd) ...@@ -2195,16 +2195,18 @@ int setup_ftfuncs(THD *thd)
int init_ftfuncs(THD *thd, bool no_order) int init_ftfuncs(THD *thd, bool no_order)
{ {
List_iterator<Item_func_match> li(thd->lex.select_lex.ftfunc_list); if (thd->lex.select_lex.ftfunc_list.elements)
Item_func_match *ifm;
DBUG_PRINT("info",("Performing FULLTEXT search"));
thd->proc_info="FULLTEXT initialization";
while ((ifm=li++))
{ {
ifm->init_search(no_order); List_iterator<Item_func_match> li(thd->lex.select_lex.ftfunc_list);
} Item_func_match *ifm;
DBUG_PRINT("info",("Performing FULLTEXT search"));
thd->proc_info="FULLTEXT initialization";
while ((ifm=li++))
{
ifm->init_search(no_order);
}
}
return 0; return 0;
} }
This diff is collapsed.
...@@ -241,12 +241,12 @@ protected: ...@@ -241,12 +241,12 @@ protected:
Query_cache_memory_bin *bins; // free block lists Query_cache_memory_bin *bins; // free block lists
Query_cache_memory_bin_step *steps; // bins spacing info Query_cache_memory_bin_step *steps; // bins spacing info
HASH queries, tables; HASH queries, tables;
uint mem_bin_num, mem_bin_steps; // See at init_cache & find_bin
my_bool initialized;
/* options */ /* options */
ulong min_allocation_unit, min_result_data_size; ulong min_allocation_unit, min_result_data_size;
uint def_query_hash_size, def_table_hash_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 */ /* Exclude/include from cyclic double linked list */
static void double_linked_list_exclude(Query_cache_block *point, static void double_linked_list_exclude(Query_cache_block *point,
...@@ -368,10 +368,7 @@ protected: ...@@ -368,10 +368,7 @@ protected:
/* Remove all queries that uses any of the listed following table */ /* Remove all queries that uses any of the listed following table */
void invalidate_by_MyISAM_filename(const char *filename); void invalidate_by_MyISAM_filename(const char *filename);
/* Remove all queries from cache */
void flush(); void flush();
/* Join result in cache in 1 block (if result length > join_limit) */
void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT, void pack(ulong join_limit = QUERY_CACHE_PACK_LIMIT,
uint iteration_limit = QUERY_CACHE_PACK_ITERATION); uint iteration_limit = QUERY_CACHE_PACK_ITERATION);
......
...@@ -122,7 +122,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -122,7 +122,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
server_status=SERVER_STATUS_AUTOCOMMIT; server_status=SERVER_STATUS_AUTOCOMMIT;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE; update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
options=thd_startup_options; 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; sql_mode=(uint) opt_sql_mode;
inactive_timeout=net_wait_timeout; inactive_timeout=net_wait_timeout;
open_options=ha_open_options; open_options=ha_open_options;
......
...@@ -951,7 +951,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -951,7 +951,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
} }
case COM_REFRESH: case COM_REFRESH:
{ {
uint options=(uchar) packet[0]; ulong options= (ulong) (uchar) packet[0];
if (check_access(thd,RELOAD_ACL,any_db)) if (check_access(thd,RELOAD_ACL,any_db))
break; break;
mysql_log.write(thd,command,NullS); mysql_log.write(thd,command,NullS);
...@@ -1432,7 +1432,6 @@ mysql_execute_command(void) ...@@ -1432,7 +1432,6 @@ mysql_execute_command(void)
(ORDER *) select_lex->order_list.first, (ORDER *) select_lex->order_list.first,
lex->drop_primary, lex->duplicates, lex->drop_primary, lex->duplicates,
lex->alter_keys_onoff, lex->simple_alter); lex->alter_keys_onoff, lex->simple_alter);
query_cache.invalidate(tables);
} }
break; break;
} }
...@@ -2984,7 +2983,7 @@ static bool check_dup(const char *db, const char *name, TABLE_LIST *tables) ...@@ -2984,7 +2983,7 @@ static bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
return 0; return 0;
} }
bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables) bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
{ {
bool result=0; bool result=0;
...@@ -3006,12 +3005,12 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables) ...@@ -3006,12 +3005,12 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
} }
if (options & REFRESH_QUERY_CACHE_FREE) 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 options &= ~REFRESH_QUERY_CACHE; //don't flush all cache, just free memory
} }
if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE)) if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
{ {
query_cache.flush(); query_cache.flush(); // RESET QUERY CACHE
} }
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK)) if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
{ {
......
...@@ -951,6 +951,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -951,6 +951,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name); sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name);
net_store_data(packet, buff); net_store_data(packet, buff);
close_thread_tables(thd); close_thread_tables(thd);
table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) thd->packet.ptr(), if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
packet->length())) packet->length()))
goto err; goto err;
...@@ -1028,6 +1029,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1028,6 +1029,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
remove_table_from_cache(thd, table->table->table_cache_key, remove_table_from_cache(thd, table->table->table_cache_key,
table->table->real_name); table->table->real_name);
close_thread_tables(thd); close_thread_tables(thd);
table->table=0; // For query cache
if (my_net_write(&thd->net, (char*) packet->ptr(), if (my_net_write(&thd->net, (char*) packet->ptr(),
packet->length())) packet->length()))
goto err; goto err;
...@@ -1037,9 +1039,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1037,9 +1039,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_RETURN(0); DBUG_RETURN(0);
err: err:
close_thread_tables(thd); // Shouldn't be needed close_thread_tables(thd); // Shouldn't be needed
if (table)
table->table=0;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
int mysql_backup_table(THD* thd, TABLE_LIST* table_list) int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
{ {
DBUG_ENTER("mysql_backup_table"); DBUG_ENTER("mysql_backup_table");
...@@ -1658,24 +1663,30 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1658,24 +1663,30 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
} }
if (error) 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); close_cached_table(thd,table);
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
goto err; goto err;
} }
if (thd->lock || new_name != table_name) // True if WIN32 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); close_cached_table(thd,table);
VOID(quick_rm_table(old_db_type,db,old_name)); VOID(quick_rm_table(old_db_type,db,old_name));
} }
else else
{ {
// Using LOCK TABLES without rename. /*
// This code is never executed on WIN32! Using LOCK TABLES without rename.
// Remove old renamed table, reopen table and get new locks This code is never executed on WIN32!
Remove old renamed table, reopen table and get new locks
*/
if (table) if (table)
{ {
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file 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, ...@@ -1712,7 +1723,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
} }
VOID(pthread_cond_broadcast(&COND_refresh)); VOID(pthread_cond_broadcast(&COND_refresh));
VOID(pthread_mutex_unlock(&LOCK_open)); 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); query_cache.invalidate(table_list);
end_temporary: end_temporary:
......
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