mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
Removed compiler warnings.
Added new operators to be used with gcc 3.0.x Update of query cache code. Added semaphores for Windows (not yet in use) Added pthread_mutex_trylock for windows.
This commit is contained in:
@ -18506,9 +18506,12 @@ If this is 0, the query cache is disabled (default).
|
||||
|
||||
@item @code{query_cache_startup_type}
|
||||
This may be set (only numeric) to
|
||||
0 (OFF, don't cache or retrieve results),
|
||||
1 (ON, cache all results except @code{SELECT SQL_NO_CACHE ...} queries) or
|
||||
2 (DEMAND, cache only @code{SELECT SQL_CACHE ...} queries).
|
||||
@multitable @columnfractions .1 .2 .7
|
||||
@item @strong{Value} @tab @strong{Alias} @tab @strong{Comment}
|
||||
@item 0 @tab OFF @tab Don't cache or retrieve results.
|
||||
@item 1 @tab ON @tab Cache all results except @code{SELECT SQL_NO_CACHE ...} queries.
|
||||
@item 2 @tab DEMAND @tab Cache only @code{SELECT SQL_CACHE ...} queries.
|
||||
@end multitable
|
||||
|
||||
@item @code{safe_show_databases}
|
||||
Don't show databases for which the user doesn't have any database or
|
||||
|
@ -34,6 +34,7 @@ see the @code{crash-me} web page at
|
||||
@node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons
|
||||
@subsection How MySQL Compares to @code{mSQL}
|
||||
|
||||
@cindex mSQL, MySQL vs mSQL, overview
|
||||
@table @strong
|
||||
@item Performance
|
||||
|
||||
@ -301,7 +302,7 @@ multiple connections to the server from the same process.
|
||||
@subsubsection How @code{mSQL} and MySQL Client/Server Communications Protocols Differ
|
||||
|
||||
@cindex communications protocols
|
||||
@cindex mSQL vs. MySQL
|
||||
@cindex mSQL vs. MySQL, protocol
|
||||
|
||||
There are enough differences that it is impossible (or at least not easy)
|
||||
to support both.
|
||||
@ -557,7 +558,6 @@ satisfies your application. If you need raw speed, MySQL is probably your
|
||||
best choice. If you need some of the extra features that only PostgreSQL
|
||||
can offer, you should use @code{PostgreSQL}.
|
||||
|
||||
@cindex PostgreSQL/MySQL, strategies
|
||||
@menu
|
||||
* MySQL-PostgreSQL goals:: MySQL and PostgreSQL development strategies
|
||||
* MySQL-PostgreSQL features:: Featurewise Comparison of MySQL and PostgreSQL
|
||||
@ -568,6 +568,7 @@ can offer, you should use @code{PostgreSQL}.
|
||||
@node MySQL-PostgreSQL goals, MySQL-PostgreSQL features, Compare PostgreSQL, Compare PostgreSQL
|
||||
@subsubsection MySQL and PostgreSQL development strategies
|
||||
|
||||
@cindex PostgreSQL vs. MySQL, strategies
|
||||
When adding things to MySQL we take pride to do an optimal, definite
|
||||
solution. The code should be so good that we shouldn't have any need to
|
||||
change it in the foreseeable future. We also do not like to sacrifice
|
||||
@ -609,7 +610,7 @@ code, we are better able to coordinate new features and releases.
|
||||
@node MySQL-PostgreSQL features, MySQL-PostgreSQL benchmarks, MySQL-PostgreSQL goals, Compare PostgreSQL
|
||||
@subsubsection Featurewise Comparison of MySQL and PostgreSQL
|
||||
|
||||
@cindex PostgreSQL/MySQL, features
|
||||
@cindex PostgreSQL vs. MySQL, features
|
||||
|
||||
On the crash-me page
|
||||
(@uref{http://www.mysql.com/information/crash-me.php})
|
||||
|
@ -387,7 +387,7 @@ static void dump_remote_log_entries(const char* logname)
|
||||
|
||||
static int check_header(IO_CACHE* file)
|
||||
{
|
||||
char buf[PROBE_HEADER_LEN];
|
||||
byte buf[PROBE_HEADER_LEN];
|
||||
int old_format;
|
||||
|
||||
my_off_t pos = my_b_tell(file);
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#define MTEST_VERSION "1.11"
|
||||
#define MTEST_VERSION "1.12"
|
||||
|
||||
#include <my_global.h>
|
||||
#include <mysql_embed.h>
|
||||
@ -140,8 +140,8 @@ PARSER parser;
|
||||
MASTER_POS master_pos;
|
||||
int *block_ok; /* set to 0 if the current block should not be executed */
|
||||
int false_block_depth = 0;
|
||||
const char* result_file = 0; /* if set, all results are concated and
|
||||
compared against this file*/
|
||||
/* if set, all results are concated and compared against this file */
|
||||
const char *result_file = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -158,7 +158,7 @@ typedef struct
|
||||
VAR var_reg[10];
|
||||
/*Perl/shell-like variable registers */
|
||||
HASH var_hash;
|
||||
int disable_query_log=0;
|
||||
int disable_query_log=0, disable_result_log=0;
|
||||
|
||||
struct connection cons[MAX_CONS];
|
||||
struct connection* cur_con, *next_con, *cons_end;
|
||||
@ -181,6 +181,7 @@ Q_PING, Q_EVAL,
|
||||
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
||||
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
||||
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
||||
Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG,
|
||||
Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
|
||||
Q_UNKNOWN, /* Unknown command. */
|
||||
Q_COMMENT, /* Comments, ignored. */
|
||||
@ -215,6 +216,7 @@ const char *command_names[] = {
|
||||
"rpl_probe", "enable_rpl_parse",
|
||||
"disable_rpl_parse", "eval_result",
|
||||
"enable_query_log", "disable_query_log",
|
||||
"enable_result_log", "disable_result_log",
|
||||
"server_start", "server_stop",
|
||||
"require_manager",
|
||||
0
|
||||
@ -2060,8 +2062,11 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!res) goto end;
|
||||
if (!res)
|
||||
goto end;
|
||||
|
||||
if (!disable_result_log)
|
||||
{
|
||||
fields = mysql_fetch_fields(res);
|
||||
num_fields = mysql_num_fields(res);
|
||||
for (i = 0; i < num_fields; i++)
|
||||
@ -2073,7 +2078,6 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||
|
||||
dynstr_append_mem(ds, "\n", 1);
|
||||
|
||||
|
||||
while ((row = mysql_fetch_row(res)))
|
||||
{
|
||||
lengths = mysql_fetch_lengths(res);
|
||||
@ -2092,12 +2096,11 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||
dynstr_append_mem(ds, "\t", 1);
|
||||
replace_dynstr_append_mem(ds, val, len);
|
||||
}
|
||||
|
||||
dynstr_append_mem(ds, "\n", 1);
|
||||
}
|
||||
if (glob_replace)
|
||||
free_replace();
|
||||
|
||||
}
|
||||
if (record)
|
||||
{
|
||||
if (!q->record_file[0] && !result_file)
|
||||
@ -2111,7 +2114,8 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||
}
|
||||
|
||||
end:
|
||||
if (res) mysql_free_result(res);
|
||||
if (res)
|
||||
mysql_free_result(res);
|
||||
last_result=0;
|
||||
if (ds == &ds_tmp)
|
||||
dynstr_free(&ds_tmp);
|
||||
@ -2292,6 +2296,8 @@ int main(int argc, char** argv)
|
||||
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
|
||||
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
|
||||
case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
|
||||
case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
|
||||
case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
|
||||
case Q_SOURCE: do_source(q); break;
|
||||
case Q_SLEEP: do_sleep(q); break;
|
||||
case Q_REQUIRE_MANAGER: do_require_manager(q); break;
|
||||
|
@ -253,6 +253,7 @@ inline double ulonglong2double(ulonglong value)
|
||||
#define HAVE_STRPBRK
|
||||
#define HAVE_STRSTR
|
||||
#define HAVE_COMPRESS
|
||||
#define HAVE_CREATESEMAPHORE
|
||||
|
||||
#ifdef NOT_USED
|
||||
#define HAVE_SNPRINTF /* Gave link error */
|
||||
|
@ -132,16 +132,17 @@ void pthread_exit(void *a); /* was #define pthread_exit(A) ExitThread(A)*/
|
||||
|
||||
#define pthread_equal(A,B) ((A) == (B))
|
||||
#ifdef OS2
|
||||
int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||
int pthread_mutex_lock (pthread_mutex_t *);
|
||||
int pthread_mutex_unlock (pthread_mutex_t *);
|
||||
int pthread_mutex_destroy (pthread_mutex_t *);
|
||||
extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||
extern int pthread_mutex_lock (pthread_mutex_t *);
|
||||
extern int pthread_mutex_unlock (pthread_mutex_t *);
|
||||
extern int pthread_mutex_destroy (pthread_mutex_t *);
|
||||
#define my_pthread_setprio(A,B) DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A)
|
||||
#define pthread_kill(A,B) raise(B)
|
||||
#define pthread_exit(A) pthread_dummy()
|
||||
#else
|
||||
#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
|
||||
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
|
||||
#define pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
|
||||
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
|
||||
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
|
||||
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
|
||||
|
51
include/my_semaphore.h
Normal file
51
include/my_semaphore.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Module: semaphore.h
|
||||
*
|
||||
* Purpose:
|
||||
* Semaphores aren't actually part of the PThreads standard.
|
||||
* They are defined by the POSIX Standard:
|
||||
*
|
||||
* POSIX 1003.1b-1993 (POSIX.1b)
|
||||
*
|
||||
* Pthreads-win32 - POSIX Threads Library for Win32
|
||||
* Copyright (C) 1998
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/* This is hacked by Monty to be included in mysys library */
|
||||
|
||||
#ifndef _my_semaphore_h_
|
||||
#define _my_semaphore_h_
|
||||
|
||||
#ifndef __WIN__
|
||||
#include <semaphore.h>
|
||||
#else
|
||||
|
||||
C_MODE_START
|
||||
|
||||
typedef HANDLE sem_t;
|
||||
int sem_init (sem_t * sem, int pshared, unsigned int value);
|
||||
int sem_destroy (sem_t * sem);
|
||||
int sem_trywait (sem_t * sem);
|
||||
int sem_wait (sem_t * sem);
|
||||
int sem_post (sem_t * sem);
|
||||
int sem_post_multiple (sem_t * sem,int count);
|
||||
int sem_getvalue (sem_t * sem, int * sval);
|
||||
|
||||
C_MODE_END
|
||||
#endif /* __WIN__ */
|
||||
#endif /* !_my_semaphore_h_ */
|
@ -16,9 +16,7 @@
|
||||
|
||||
#ifndef _my_sys_h
|
||||
#define _my_sys_h
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
C_MODE_START
|
||||
|
||||
#ifdef HAVE_AIOWAIT
|
||||
#include <sys/asynch.h> /* Used by record-cache */
|
||||
@ -649,8 +647,6 @@ extern void sleep(int sec);
|
||||
extern my_bool have_tcpip; /* Is set if tcpip is used */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
C_MODE_END
|
||||
#include "raid.h"
|
||||
#endif /* _my_sys_h */
|
||||
|
@ -2397,6 +2397,8 @@ mysql_fetch_row(MYSQL_RES *res)
|
||||
DBUG_PRINT("info",("end of data"));
|
||||
res->eof=1;
|
||||
res->handle->status=MYSQL_STATUS_READY;
|
||||
/* Don't clear handle in mysql_free_results */
|
||||
res->handle=0;
|
||||
}
|
||||
}
|
||||
DBUG_RETURN((MYSQL_ROW) NULL);
|
||||
|
@ -112,11 +112,13 @@ void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
|
||||
while ((res=ft_get_word(start,end,&w,¶m)))
|
||||
{
|
||||
byte r=param.plusminus;
|
||||
float weight=(param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
|
||||
float weight= (float) (param.pmsign ? nwghts : wghts)[(r>5)?5:((r<-5)?-5:r)];
|
||||
switch (res) {
|
||||
case 1: /* word found */
|
||||
ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
|
||||
sizeof(FTB_WORD) + (param.trunc ? MI_MAX_KEY_BUFF : w.len+extra));
|
||||
sizeof(FTB_WORD) +
|
||||
(param.trunc ? MI_MAX_KEY_BUFF :
|
||||
w.len+extra));
|
||||
ftbw->len=w.len+1;
|
||||
ftbw->yesno=param.yesno;
|
||||
ftbw->trunc=param.trunc; /* 0 or 1 */
|
||||
@ -216,7 +218,8 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
|
||||
ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
|
||||
reinit_queue(& ftb->queue, res, 0, 0, FTB_WORD_cmp, ftb);
|
||||
ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR));
|
||||
ftbe->weight=ftbe->yesno=ftbe->nos=1;
|
||||
ftbe->weight=1;
|
||||
ftbe->yesno=ftbe->nos=1;
|
||||
ftbe->up=0;
|
||||
ftbe->ythresh=0;
|
||||
ftbe->docid=HA_POS_ERROR;
|
||||
@ -236,7 +239,8 @@ void _ftb_climb_the_tree(FTB_WORD *ftbw, my_off_t curdoc)
|
||||
{
|
||||
if (ftbe->docid != curdoc)
|
||||
{
|
||||
ftbe->cur_weight=ftbe->yesses=ftbe->nos=0;
|
||||
ftbe->cur_weight=0;
|
||||
ftbe->yesses=ftbe->nos=0;
|
||||
ftbe->docid=curdoc;
|
||||
}
|
||||
if (ftbe->nos)
|
||||
@ -373,7 +377,8 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length)
|
||||
{
|
||||
if (ftbe->docid != HA_POS_ERROR)
|
||||
{
|
||||
ftbe->cur_weight=ftbe->yesses=ftbe->nos=0;
|
||||
ftbe->cur_weight=0;
|
||||
ftbe->yesses=ftbe->nos=0;
|
||||
ftbe->docid=HA_POS_ERROR;
|
||||
}
|
||||
else
|
||||
|
@ -248,7 +248,8 @@ int ft_nlq_read_next(FT_INFO *handler, char *record)
|
||||
}
|
||||
|
||||
float ft_nlq_find_relevance(FT_INFO *handler,
|
||||
byte *record __attribute__((unused)), uint length __attribute__((unused)))
|
||||
byte *record __attribute__((unused)),
|
||||
uint length __attribute__((unused)))
|
||||
{
|
||||
int a,b,c;
|
||||
FT_DOC *docs=handler->doc;
|
||||
@ -267,7 +268,7 @@ float ft_nlq_find_relevance(FT_INFO *handler,
|
||||
a=c;
|
||||
}
|
||||
if (docs[a].dpos == docid)
|
||||
return docs[a].weight;
|
||||
return (float) docs[a].weight;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
@ -279,7 +280,7 @@ void ft_nlq_close_search(FT_INFO *handler)
|
||||
|
||||
float ft_nlq_get_relevance(FT_INFO *handler)
|
||||
{
|
||||
return handler->doc[handler->curdoc].weight;
|
||||
return (float) handler->doc[handler->curdoc].weight;
|
||||
}
|
||||
|
||||
void ft_nlq_reinit_search(FT_INFO *handler)
|
||||
|
@ -19,6 +19,7 @@
|
||||
/* functions to work with full-text indices */
|
||||
|
||||
#include "ftdefs.h"
|
||||
#include <math.h>
|
||||
|
||||
/**************************************************************
|
||||
This is to make ft-code to ignore keyseg.length at all *
|
||||
@ -186,7 +187,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
|
||||
cmp=_mi_compare_text(default_charset_info,
|
||||
(uchar*) old_word->pos,old_word->len,
|
||||
(uchar*) new_word->pos,new_word->len,0);
|
||||
cmp2= cmp ? 0 : (abs(old_word->weight - new_word->weight) > 1.e-5);
|
||||
cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5);
|
||||
|
||||
if (cmp < 0 || cmp2)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
reset query cache;
|
||||
flush status;
|
||||
drop table if exists t1;
|
||||
drop table if exists t1,t2,t3;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
@ -36,3 +36,265 @@ drop table t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
create table t2 (a int not null);
|
||||
insert into t2 values (4),(5),(6);
|
||||
create table t3 (a int not null) type=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
|
||||
select * from t3;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
select * from t3;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
insert into t2 values (7);
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
insert into t3 values (8);
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select * from t3;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
8
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
update t2 set a=9 where a=7;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
8
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
update t3 set a=10 where a=1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select * from t3;
|
||||
a
|
||||
10
|
||||
2
|
||||
3
|
||||
8
|
||||
4
|
||||
5
|
||||
6
|
||||
9
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
delete from t2 where a=9;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select * from t1;
|
||||
a
|
||||
10
|
||||
2
|
||||
3
|
||||
8
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
delete from t3 where a=10;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
drop table t1, t2, t3;
|
||||
set autocommit=0;
|
||||
create table t1 (a int not null) type=innodb;
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
drop table t1;
|
||||
commit;
|
||||
set autocommit=1;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
create table t2 (a int not null);
|
||||
insert into t2 values (1),(2),(3);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
select * from t2;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
insert into t1 values (4);
|
||||
show status like "Qcache_free_blocks";
|
||||
Variable_name Value
|
||||
Qcache_free_blocks 2
|
||||
flush query cache;
|
||||
show status like "Qcache_free_blocks";
|
||||
Variable_name Value
|
||||
Qcache_free_blocks 1
|
||||
drop table t1, t2;
|
||||
set sql_query_cache_type=demand;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select sql_cache * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
set sql_query_cache_type=2;
|
||||
select sql_cache * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 1
|
||||
set sql_query_cache_type=on;
|
||||
reset query cache;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
select sql_no_cache * from t1;
|
||||
a
|
||||
1
|
||||
2
|
||||
3
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
drop table t1;
|
||||
create table t1 (a text not null);
|
||||
select CONNECTION_ID() from t1;
|
||||
CONNECTION_ID()
|
||||
select FOUND_ROWS();
|
||||
FOUND_ROWS()
|
||||
0
|
||||
select NOW() from t1;
|
||||
NOW()
|
||||
select CURDATE() from t1;
|
||||
CURDATE()
|
||||
select CURTIME() from t1;
|
||||
CURTIME()
|
||||
select DATABASE() from t1;
|
||||
DATABASE()
|
||||
select ENCRYPT("test") from t1;
|
||||
ENCRYPT("test")
|
||||
select LAST_INSERT_ID() from t1;
|
||||
last_insert_id()
|
||||
select RAND() from t1;
|
||||
RAND()
|
||||
select UNIX_TIMESTAMP() from t1;
|
||||
UNIX_TIMESTAMP()
|
||||
select USER() from t1;
|
||||
USER()
|
||||
select benchmark(1,1) from t1;
|
||||
benchmark(1,1)
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
create table t2 (a text not null);
|
||||
insert into t1 values("1111111111111111111111111111111111111111111111111111");
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2;
|
||||
drop table t2;
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
select a as a1, a as a2 from t1;
|
||||
select a as a2, a as a3 from t1;
|
||||
select a as a3, a as a4 from t1;
|
||||
select a as a1, a as a2 from t1;
|
||||
show status like "Qcache_hits";
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 2
|
||||
reset query cache;
|
||||
show variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 1039700
|
||||
show status like "Qcache_free_memory";
|
||||
Variable_name Value
|
||||
Qcache_free_memory 1039700
|
||||
drop table t1;
|
||||
|
@ -1 +1 @@
|
||||
--set-variable=query_cache_size=2M
|
||||
--set-variable=query_cache_size=1M
|
||||
|
@ -1,3 +1,5 @@
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
#
|
||||
# Tests with query cache
|
||||
#
|
||||
@ -6,7 +8,12 @@
|
||||
|
||||
reset query cache;
|
||||
flush status;
|
||||
drop table if exists t1;
|
||||
drop table if exists t1,t2,t3;
|
||||
|
||||
#
|
||||
# First simple test
|
||||
#
|
||||
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
@ -24,3 +31,153 @@ show status like "Qcache_hits";
|
||||
drop table t1;
|
||||
|
||||
show status like "Qcache_queries_in_cache";
|
||||
|
||||
#
|
||||
# MERGE TABLES with INSERT/UPDATE and DELETE
|
||||
#
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
create table t2 (a int not null);
|
||||
insert into t2 values (4),(5),(6);
|
||||
create table t3 (a int not null) type=MERGE UNION=(t1,t2) INSERT_METHOD=FIRST;
|
||||
# insert
|
||||
select * from t3;
|
||||
select * from t3;
|
||||
show status like "Qcache_hits";
|
||||
show status like "Qcache_queries_in_cache";
|
||||
insert into t2 values (7);
|
||||
show status like "Qcache_queries_in_cache";
|
||||
select * from t1;
|
||||
select * from t1;
|
||||
show status like "Qcache_hits";
|
||||
show status like "Qcache_queries_in_cache";
|
||||
insert into t3 values (8);
|
||||
show status like "Qcache_queries_in_cache";
|
||||
# update
|
||||
select * from t3;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
update t2 set a=9 where a=7;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
update t3 set a=10 where a=1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
#delete
|
||||
select * from t3;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
delete from t2 where a=9;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
delete from t3 where a=10;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
drop table t1, t2, t3;
|
||||
#
|
||||
# Without auto_commit.
|
||||
#
|
||||
set autocommit=0;
|
||||
create table t1 (a int not null) type=innodb;
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
drop table t1;
|
||||
commit;
|
||||
set autocommit=1;
|
||||
#
|
||||
# FLUSH QUERY CACHE
|
||||
#
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
create table t2 (a int not null);
|
||||
insert into t2 values (1),(2),(3);
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
insert into t1 values (4);
|
||||
show status like "Qcache_free_blocks";
|
||||
flush query cache;
|
||||
show status like "Qcache_free_blocks";
|
||||
drop table t1, t2;
|
||||
#
|
||||
# SELECT SQL_CACHE ...
|
||||
#
|
||||
set sql_query_cache_type=demand;
|
||||
create table t1 (a int not null);
|
||||
insert into t1 values (1),(2),(3);
|
||||
select * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
select sql_cache * from t1;
|
||||
set sql_query_cache_type=2;
|
||||
select sql_cache * from t1;
|
||||
show status like "Qcache_hits";
|
||||
show status like "Qcache_queries_in_cache";
|
||||
set sql_query_cache_type=on;
|
||||
#
|
||||
# RESET QUERY CACHE
|
||||
#
|
||||
reset query cache;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
#
|
||||
# SELECT SQL_NO_CACHE
|
||||
#
|
||||
select sql_no_cache * from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
drop table t1;
|
||||
#
|
||||
# Check that queries that uses NOW(), LAST_INSERT_ID()... are not cached.
|
||||
#
|
||||
create table t1 (a text not null);
|
||||
select CONNECTION_ID() from t1;
|
||||
#GET_LOCK
|
||||
#RELEASE_LOCK
|
||||
#LOAD_FILE
|
||||
select FOUND_ROWS();
|
||||
select NOW() from t1;
|
||||
select CURDATE() from t1;
|
||||
select CURTIME() from t1;
|
||||
select DATABASE() from t1;
|
||||
select ENCRYPT("test") from t1;
|
||||
select LAST_INSERT_ID() from t1;
|
||||
select RAND() from t1;
|
||||
select UNIX_TIMESTAMP() from t1;
|
||||
select USER() from t1;
|
||||
select benchmark(1,1) from t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
#
|
||||
# Tests when the cache is filled
|
||||
#
|
||||
create table t2 (a text not null);
|
||||
insert into t1 values("1111111111111111111111111111111111111111111111111111");
|
||||
insert into t2 select * from t1;
|
||||
insert into t1 select * from t2; # 2
|
||||
insert into t2 select * from t1; # 3
|
||||
insert into t1 select * from t2; # 5
|
||||
insert into t2 select * from t1; # 8
|
||||
insert into t1 select * from t2; # 13
|
||||
insert into t2 select * from t1; # 21
|
||||
insert into t1 select * from t2; # 34
|
||||
insert into t2 select * from t1; # 55
|
||||
insert into t1 select * from t2; # 89
|
||||
insert into t2 select * from t1; # 144
|
||||
insert into t1 select * from t2; # 233
|
||||
insert into t2 select * from t1; # 357
|
||||
insert into t1 select * from t2; # 610
|
||||
insert into t2 select * from t1; # 987
|
||||
insert into t1 select * from t2; # 1597
|
||||
insert into t2 select * from t1; # 2584
|
||||
insert into t1 select * from t2; # 4181
|
||||
drop table t2;
|
||||
|
||||
show status like "Qcache_hits";
|
||||
disable_result_log;
|
||||
select a as a1, a as a2 from t1;
|
||||
select a as a2, a as a3 from t1;
|
||||
select a as a3, a as a4 from t1;
|
||||
# next query must be out of 1Mb cache
|
||||
select a as a1, a as a2 from t1;
|
||||
enable_result_log;
|
||||
show status like "Qcache_hits";
|
||||
show status like "Qcache_queries_in_cache";
|
||||
reset query cache;
|
||||
show variables like "query_cache_size";
|
||||
show status like "Qcache_free_memory";
|
||||
drop table t1;
|
||||
|
@ -30,7 +30,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
|
||||
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
|
||||
my_lock.c mf_brkhant.c my_alarm.c \
|
||||
my_malloc.c my_realloc.c my_once.c mulalloc.c \
|
||||
my_alloc.c safemalloc.c my_fopen.c my_fstream.c \
|
||||
my_alloc.c safemalloc.c my_new.cc \
|
||||
my_fopen.c my_fstream.c \
|
||||
my_error.c errors.c my_div.c my_messnc.c \
|
||||
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
||||
my_symlink.c my_symlink2.c \
|
||||
|
49
mysys/my_new.cc
Normal file
49
mysys/my_new.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/* Copyright (C) 2000 MySQL AB
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
This is a replacement of new/delete operators to be used when compiling
|
||||
with gcc 3.0.x to avoid including libstdc++
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
|
||||
#ifdef USE_MYSYS_NEW
|
||||
|
||||
void *operator new (size_t sz)
|
||||
{
|
||||
return (void *) malloc (sz ? sz+1 : sz);
|
||||
}
|
||||
|
||||
void *operator new[] (size_t sz)
|
||||
{
|
||||
return (void *) malloc (sz ? sz+1 : sz);
|
||||
}
|
||||
|
||||
void operator delete (void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void operator delete[] (void *ptr) throw ()
|
||||
{
|
||||
if (ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#endif /* USE_MYSYS_NEW */
|
||||
|
432
mysys/my_winsem.c
Normal file
432
mysys/my_winsem.c
Normal file
@ -0,0 +1,432 @@
|
||||
/*
|
||||
* -------------------------------------------------------------
|
||||
*
|
||||
* Module: my_semaphore.c (Original: semaphore.c from pthreads library)
|
||||
*
|
||||
* Purpose:
|
||||
* Semaphores aren't actually part of the PThreads standard.
|
||||
* They are defined by the POSIX Standard:
|
||||
*
|
||||
* POSIX 1003.1b-1993 (POSIX.1b)
|
||||
*
|
||||
* -------------------------------------------------------------
|
||||
*
|
||||
* Pthreads-win32 - POSIX Threads Library for Win32
|
||||
* Copyright (C) 1998
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
NEED_SEM is not used in MySQL and should only be needed under
|
||||
Windows CE.
|
||||
|
||||
The big changes compared to the original version was to not allocate
|
||||
any additional memory in sem_init() but to instead store everthing
|
||||
we need in sem_t.
|
||||
|
||||
TODO:
|
||||
To get HAVE_CREATESEMAPHORE we have to define the struct
|
||||
in my_semaphore.h
|
||||
*/
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#ifdef __WIN__
|
||||
#include "my_semaphore.h"
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
DOCPUBLIC
|
||||
This function initializes an unnamed semaphore. the
|
||||
initial value of the semaphore is 'value'
|
||||
|
||||
PARAMETERS
|
||||
sem
|
||||
pointer to an instance of sem_t
|
||||
|
||||
pshared
|
||||
if zero, this semaphore may only be shared between
|
||||
threads in the same process.
|
||||
if nonzero, the semaphore can be shared between
|
||||
processes
|
||||
|
||||
value
|
||||
initial value of the semaphore counter
|
||||
|
||||
DESCRIPTION
|
||||
This function initializes an unnamed semaphore. The
|
||||
initial value of the semaphore is set to 'value'.
|
||||
|
||||
RESULTS
|
||||
0 successfully created semaphore,
|
||||
-1 failed, error in errno
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSPC a required resource has been exhausted,
|
||||
ENOSYS semaphores are not supported,
|
||||
EPERM the process lacks appropriate privilege
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
sem_init (sem_t *sem, int pshared, unsigned int value)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (pshared != 0)
|
||||
{
|
||||
/*
|
||||
We don't support creating a semaphore that can be shared between
|
||||
processes
|
||||
*/
|
||||
result = EPERM;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
sem->value = value;
|
||||
sem->event = CreateEvent(NULL,
|
||||
FALSE, /* manual reset */
|
||||
FALSE, /* initial state */
|
||||
NULL);
|
||||
if (!sem->event)
|
||||
result = ENOSPC;
|
||||
else
|
||||
{
|
||||
if (value)
|
||||
SetEvent(sem->event);
|
||||
InitializeCriticalSection(&sem->sem_lock_cs);
|
||||
}
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
*sem = CreateSemaphore (NULL, /* Always NULL */
|
||||
value, /* Initial value */
|
||||
0x7FFFFFFFL, /* Maximum value */
|
||||
NULL); /* Name */
|
||||
if (!*sem)
|
||||
result = ENOSPC;
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
}
|
||||
if (result != 0)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} /* sem_init */
|
||||
|
||||
|
||||
/*
|
||||
DOCPUBLIC
|
||||
This function destroys an unnamed semaphore.
|
||||
|
||||
PARAMETERS
|
||||
sem
|
||||
pointer to an instance of sem_t
|
||||
|
||||
DESCRIPTION
|
||||
This function destroys an unnamed semaphore.
|
||||
|
||||
RESULTS
|
||||
0 successfully destroyed semaphore,
|
||||
-1 failed, error in errno
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS semaphores are not supported,
|
||||
EBUSY threads (or processes) are currently
|
||||
blocked on 'sem'
|
||||
*/
|
||||
|
||||
int
|
||||
sem_destroy (sem_t * sem)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
if (! CloseHandle(sem->event))
|
||||
result = EINVAL;
|
||||
else
|
||||
DeleteCriticalSection(&sem->sem_lock_cs);
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
if (!CloseHandle(*sem))
|
||||
result = EINVAL;
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
if (result)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
}
|
||||
*sem=0; /* Safety */
|
||||
return 0;
|
||||
} /* sem_destroy */
|
||||
|
||||
|
||||
/*
|
||||
DOCPUBLIC
|
||||
This function tries to wait on a semaphore.
|
||||
|
||||
PARAMETERS
|
||||
sem
|
||||
pointer to an instance of sem_t
|
||||
|
||||
DESCRIPTION
|
||||
This function tries to wait on a semaphore. If the
|
||||
semaphore value is greater than zero, it decreases
|
||||
its value by one. If the semaphore value is zero, then
|
||||
this function returns immediately with the error EAGAIN
|
||||
|
||||
RESULTS
|
||||
0 successfully decreased semaphore,
|
||||
-1 failed, error in errno
|
||||
ERRNO
|
||||
EAGAIN the semaphore was already locked,
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS semaphores are not supported,
|
||||
EINTR the function was interrupted by a signal,
|
||||
EDEADLK a deadlock condition was detected.
|
||||
*/
|
||||
|
||||
int
|
||||
sem_trywait(sem_t * sem)
|
||||
{
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
/* not yet implemented! */
|
||||
int errno = EINVAL;
|
||||
return -1;
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
if (WaitForSingleObject (*sem, 0) == WAIT_TIMEOUT)
|
||||
{
|
||||
errno= EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
|
||||
} /* sem_trywait */
|
||||
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
|
||||
static void
|
||||
ptw32_decrease_semaphore(sem_t * sem)
|
||||
{
|
||||
EnterCriticalSection(&sem->sem_lock_cs);
|
||||
DBUG_ASSERT(sem->value != 0);
|
||||
sem->value--;
|
||||
if (sem->value != 0)
|
||||
SetEvent(sem->event);
|
||||
LeaveCriticalSection(&sem->sem_lock_cs);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
ptw32_increase_semaphore(sem_t * sem, unsigned int n)
|
||||
{
|
||||
BOOL result=FALSE;
|
||||
|
||||
EnterCriticalSection(&sem->sem_lock_cs);
|
||||
if (sem->value + n > sem->value)
|
||||
{
|
||||
sem->value += n;
|
||||
SetEvent(sem->event);
|
||||
result = TRUE;
|
||||
}
|
||||
LeaveCriticalSection(&sem->sem_lock_cs);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
DOCPUBLIC
|
||||
This function waits on a semaphore.
|
||||
|
||||
PARAMETERS
|
||||
sem
|
||||
pointer to an instance of sem_t
|
||||
|
||||
DESCRIPTION
|
||||
This function waits on a semaphore. If the
|
||||
semaphore value is greater than zero, it decreases
|
||||
its value by one. If the semaphore value is zero, then
|
||||
the calling thread (or process) is blocked until it can
|
||||
successfully decrease the value or until interrupted by
|
||||
a signal.
|
||||
|
||||
RESULTS
|
||||
0 successfully decreased semaphore,
|
||||
-1 failed, error in errno
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS semaphores are not supported,
|
||||
EINTR the function was interrupted by a signal,
|
||||
EDEADLK a deadlock condition was detected.
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
sem_wait(sem_t *sem)
|
||||
{
|
||||
int result;
|
||||
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
result=WaitForSingleObject(sem->event, INFINITE);
|
||||
#else
|
||||
result=WaitForSingleObject(*sem, INFINITE);
|
||||
#endif
|
||||
if (result == WAIT_FAILED || result == WAIT_ABANDONED_0)
|
||||
result = EINVAL;
|
||||
else if (result == WAIT_TIMEOUT)
|
||||
result = ETIMEDOUT;
|
||||
else
|
||||
result=0;
|
||||
if (result)
|
||||
{
|
||||
errno = result;
|
||||
return -1;
|
||||
}
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
ptw32_decrease_semaphore(sem);
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
DOCPUBLIC
|
||||
This function posts a wakeup to a semaphore.
|
||||
|
||||
PARAMETERS
|
||||
sem
|
||||
pointer to an instance of sem_t
|
||||
|
||||
DESCRIPTION
|
||||
This function posts a wakeup to a semaphore. If there
|
||||
are waiting threads (or processes), one is awakened;
|
||||
otherwise, the semaphore value is incremented by one.
|
||||
|
||||
RESULTS
|
||||
0 successfully posted semaphore,
|
||||
-1 failed, error in errno
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore,
|
||||
ENOSYS semaphores are not supported,
|
||||
|
||||
*/
|
||||
|
||||
int
|
||||
sem_post (sem_t * sem)
|
||||
{
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
if (! ptw32_increase_semaphore(sem, 1))
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
if (! ReleaseSemaphore(*sem, 1, 0))
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
DOCPUBLIC
|
||||
This function posts multiple wakeups to a semaphore.
|
||||
|
||||
PARAMETERS
|
||||
sem
|
||||
pointer to an instance of sem_t
|
||||
|
||||
count
|
||||
counter, must be greater than zero.
|
||||
|
||||
DESCRIPTION
|
||||
This function posts multiple wakeups to a semaphore. If there
|
||||
are waiting threads (or processes), n <= count are awakened;
|
||||
the semaphore value is incremented by count - n.
|
||||
|
||||
RESULTS
|
||||
0 successfully posted semaphore,
|
||||
-1 failed, error in errno
|
||||
ERRNO
|
||||
EINVAL 'sem' is not a valid semaphore
|
||||
or count is less than or equal to zero.
|
||||
*/
|
||||
|
||||
int
|
||||
sem_post_multiple (sem_t * sem, int count )
|
||||
{
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (sem == NULL || *sem == NULL || count <= 0)
|
||||
{
|
||||
errno=EINVAL;
|
||||
return -1;
|
||||
}
|
||||
#endif /* EXTRA_DEBUG */
|
||||
#ifndef HAVE_CREATESEMAPHORE
|
||||
if (! ptw32_increase_semaphore (sem, count))
|
||||
#else /* HAVE_CREATESEMAPHORE */
|
||||
if (! ReleaseSemaphore(*sem, count, 0))
|
||||
#endif /* HAVE_CREATESEMAPHORE */
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sem_getvalue (sem_t *sem, int *sval)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
} /* sem_getvalue */
|
||||
|
||||
#endif /* __WIN__ */
|
@ -69,7 +69,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
{
|
||||
int error;
|
||||
ulong memavl;
|
||||
uint maxbuffer,skr;
|
||||
uint maxbuffer;
|
||||
BUFFPEK *buffpek;
|
||||
ha_rows records;
|
||||
uchar **sort_keys;
|
||||
@ -163,7 +163,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
&tempfile, selected_records_file)) ==
|
||||
HA_POS_ERROR)
|
||||
goto err;
|
||||
maxbuffer= my_b_tell(&buffpek_pointers)/sizeof(*buffpek);
|
||||
maxbuffer= (uint) (my_b_tell(&buffpek_pointers)/sizeof(*buffpek));
|
||||
|
||||
if (maxbuffer == 0) // The whole set is in memory
|
||||
{
|
||||
@ -267,7 +267,7 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
||||
if (tmp)
|
||||
{
|
||||
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
|
||||
my_b_read(buffpek_pointers, (char*) tmp, length))
|
||||
my_b_read(buffpek_pointers, (byte*) tmp, length))
|
||||
{
|
||||
my_free((char*) tmp, MYF(0));
|
||||
tmp=0;
|
||||
@ -398,10 +398,12 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||
|
||||
/* Skriver en buffert med nycklar till filen */
|
||||
|
||||
static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
|
||||
static int
|
||||
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
|
||||
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
|
||||
{
|
||||
uint sort_length;
|
||||
uchar **end;
|
||||
BUFFPEK buffpek;
|
||||
DBUG_ENTER("write_keys");
|
||||
|
||||
@ -419,10 +421,10 @@ static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
|
||||
if ((ha_rows) count > param->max_rows)
|
||||
count=(uint) param->max_rows; /* purecov: inspected */
|
||||
buffpek.count=(ha_rows) count;
|
||||
for (uchar **end=sort_keys+count ; sort_keys != end ; sort_keys++)
|
||||
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
|
||||
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
|
||||
goto err;
|
||||
if (my_b_write(buffpek_pointers, (char*) &buffpek, sizeof(buffpek)))
|
||||
if (my_b_write(buffpek_pointers, (byte*) &buffpek, sizeof(buffpek)))
|
||||
goto err;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
@ -2019,7 +2019,9 @@ void Item_func_match::init_search(bool no_order)
|
||||
}
|
||||
|
||||
ft_handler=table->file->ft_init_ext(mode, key,
|
||||
ft_tmp->ptr(), ft_tmp->length(), join_key && !no_order);
|
||||
(byte*) ft_tmp->ptr(),
|
||||
ft_tmp->length(),
|
||||
join_key && !no_order);
|
||||
|
||||
if (join_key)
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
|
||||
#define SELECT_SMALL_RESULT 8
|
||||
#define SELECT_BIG_RESULT 16
|
||||
#define OPTION_FOUND_ROWS 32
|
||||
#define SELECT_HIGH_PRIORITY 64 /* Intern */
|
||||
#define OPTION_TO_QUERY_CACHE 64
|
||||
#define SELECT_NO_JOIN_CACHE 256 /* Intern */
|
||||
|
||||
#define OPTION_BIG_TABLES 512 /* for SQL OPTION */
|
||||
@ -179,7 +179,6 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
|
||||
|
||||
#define SELECT_NO_UNLOCK (QUERY_NO_GOOD_INDEX_USED*2)
|
||||
#define TMP_TABLE_ALL_COLUMNS (SELECT_NO_UNLOCK*2)
|
||||
#define OPTION_TO_QUERY_CACHE (TMP_TABLE_ALL_COLUMNS*2)
|
||||
|
||||
|
||||
#define MODE_REAL_AS_FLOAT 1
|
||||
|
@ -3157,12 +3157,16 @@ struct show_var_st status_vars[]= {
|
||||
{"Open_streams", (char*) &my_stream_opened, SHOW_INT_CONST},
|
||||
{"Opened_tables", (char*) &opened_tables, SHOW_LONG},
|
||||
{"Questions", (char*) 0, SHOW_QUESTION},
|
||||
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache,
|
||||
SHOW_LONG},
|
||||
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
|
||||
{"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
|
||||
{"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
|
||||
{"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
|
||||
{"Qcache_free_memory", (char*) &query_cache.free_memory,SHOW_LONG},
|
||||
{"Qcache_free_memory", (char*) &query_cache.free_memory,
|
||||
SHOW_LONG_CONST},
|
||||
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks,
|
||||
SHOW_LONG_CONST},
|
||||
{"Qcache_total_blocks", (char*) &query_cache.total_blocks,
|
||||
SHOW_LONG_CONST},
|
||||
{"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
|
||||
{"Select_full_join", (char*) &select_full_join_count, SHOW_LONG},
|
||||
{"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG},
|
||||
|
35
sql/slave.cc
35
sql/slave.cc
@ -35,11 +35,14 @@ bool do_table_inited = 0, ignore_table_inited = 0;
|
||||
bool wild_do_table_inited = 0, wild_ignore_table_inited = 0;
|
||||
bool table_rules_on = 0;
|
||||
uint32 slave_skip_counter = 0;
|
||||
static TABLE* save_temporary_tables = 0;
|
||||
THD* slave_thd = 0;
|
||||
// when slave thread exits, we need to remember the temporary tables so we
|
||||
// can re-use them on slave start
|
||||
|
||||
/*
|
||||
When slave thread exits, we need to remember the temporary tables so we
|
||||
can re-use them on slave start
|
||||
*/
|
||||
static TABLE* save_temporary_tables = 0;
|
||||
|
||||
THD* slave_thd = 0;
|
||||
int last_slave_errno = 0;
|
||||
char last_slave_error[MAX_SLAVE_ERRMSG] = "";
|
||||
#ifndef DBUG_OFF
|
||||
@ -114,10 +117,10 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
|
||||
{
|
||||
for (; tables; tables = tables->next)
|
||||
{
|
||||
if (!tables->updating)
|
||||
continue;
|
||||
char hash_key[2*NAME_LEN+2];
|
||||
char* p;
|
||||
if (!tables->updating)
|
||||
continue;
|
||||
p = strmov(hash_key, tables->db ? tables->db : thd->db);
|
||||
*p++ = '.';
|
||||
uint len = strmov(p, tables->real_name) - hash_key ;
|
||||
@ -139,9 +142,10 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if no explicit rule found
|
||||
// and there was a do list, do not replicate. If there was
|
||||
// no do list, go ahead
|
||||
/*
|
||||
If no explicit rule found and there was a do list, do not replicate.
|
||||
If there was no do list, go ahead
|
||||
*/
|
||||
return !do_table_inited && !wild_do_table_inited;
|
||||
}
|
||||
|
||||
@ -149,12 +153,14 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
|
||||
int add_table_rule(HASH* h, const char* table_spec)
|
||||
{
|
||||
const char* dot = strchr(table_spec, '.');
|
||||
if(!dot) return 1;
|
||||
if (!dot)
|
||||
return 1;
|
||||
// len is always > 0 because we know the there exists a '.'
|
||||
uint len = (uint)strlen(table_spec);
|
||||
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
|
||||
+ len, MYF(MY_WME));
|
||||
if(!e) return 1;
|
||||
if (!e)
|
||||
return 1;
|
||||
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
|
||||
e->tbl_name = e->db + (dot - table_spec) + 1;
|
||||
e->key_len = len;
|
||||
@ -170,7 +176,8 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
|
||||
uint len = (uint)strlen(table_spec);
|
||||
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
|
||||
+ len, MYF(MY_WME));
|
||||
if(!e) return 1;
|
||||
if (!e)
|
||||
return 1;
|
||||
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
|
||||
e->tbl_name = e->db + (dot - table_spec) + 1;
|
||||
e->key_len = len;
|
||||
@ -758,6 +765,7 @@ int flush_master_info(MASTER_INFO* mi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos)
|
||||
{
|
||||
if (!inited) return -1;
|
||||
@ -901,6 +909,7 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
|
||||
{
|
||||
char buf[1024];
|
||||
@ -1346,7 +1355,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
|
||||
events_till_disconnect = disconnect_slave_event_count;
|
||||
#endif
|
||||
while (!(slave_was_killed = slave_killed(thd)) &&
|
||||
(reconnect ? mc_mysql_reconnect(mysql) :
|
||||
(reconnect ? mc_mysql_reconnect(mysql) != 0 :
|
||||
!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
|
||||
mi->port, 0, 0)))
|
||||
{
|
||||
|
122
sql/sql_cache.cc
122
sql/sql_cache.cc
@ -286,13 +286,8 @@ If join_results allocated new block(s) then we need call pack_cache again.
|
||||
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
|
||||
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
|
||||
pthread_mutex_lock(M);}
|
||||
#define SEM_LOCK(M) { int val = 0; sem_getvalue (M, &val); \
|
||||
DBUG_PRINT("lock", ("sem lock 0x%lx (%d)", (ulong)(M), val)); \
|
||||
sem_wait(M); DBUG_PRINT("lock", ("sem lock ok")); }
|
||||
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
|
||||
(ulong)(M))); pthread_mutex_unlock(M);}
|
||||
#define SEM_UNLOCK(M) {DBUG_PRINT("lock", ("sem unlock 0x%lx", (ulong)(M))); \
|
||||
sem_post(M); DBUG_PRINT("lock", ("sem unlock ok")); }
|
||||
#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \
|
||||
pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
|
||||
#define STRUCT_UNLOCK(M) { \
|
||||
@ -313,9 +308,7 @@ If join_results allocated new block(s) then we need call pack_cache again.
|
||||
#define DUMP(C) DBUG_EXECUTE("qcache", {(C)->queries_dump();(C)->tables_dump();})
|
||||
#else
|
||||
#define MUTEX_LOCK(M) pthread_mutex_lock(M)
|
||||
#define SEM_LOCK(M) sem_wait(M)
|
||||
#define MUTEX_UNLOCK(M) pthread_mutex_unlock(M)
|
||||
#define SEM_UNLOCK(M) sem_post(M)
|
||||
#define STRUCT_LOCK(M) pthread_mutex_lock(M)
|
||||
#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
|
||||
#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
|
||||
@ -332,7 +325,7 @@ If join_results allocated new block(s) then we need call pack_cache again.
|
||||
inline Query_cache_block * Query_cache_block_table::block()
|
||||
{
|
||||
return (Query_cache_block *)(((byte*)this) -
|
||||
sizeof(Query_cache_block_table)*n -
|
||||
ALIGN_SIZE(sizeof(Query_cache_block_table)*n) -
|
||||
ALIGN_SIZE(sizeof(Query_cache_block)));
|
||||
};
|
||||
|
||||
@ -432,7 +425,7 @@ void Query_cache_query::init_n_lock()
|
||||
{
|
||||
DBUG_ENTER("Query_cache_query::init_n_lock");
|
||||
res=0; wri = 0; len = 0;
|
||||
sem_init(&lock, 0, 1);
|
||||
pthread_cond_init(&lock, NULL);
|
||||
pthread_mutex_init(&clients_guard,MY_MUTEX_INIT_FAST);
|
||||
clients = 0;
|
||||
lock_writing();
|
||||
@ -445,14 +438,14 @@ void Query_cache_query::init_n_lock()
|
||||
void Query_cache_query::unlock_n_destroy()
|
||||
{
|
||||
DBUG_ENTER("Query_cache_query::unlock_n_destroy");
|
||||
DBUG_PRINT("qcache", ("destroyed & unlocked query for block 0x%lx",
|
||||
((byte*)this)-ALIGN_SIZE(sizeof(Query_cache_block))));
|
||||
/*
|
||||
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))));
|
||||
sem_destroy(&lock);
|
||||
pthread_cond_destroy(&lock);
|
||||
pthread_mutex_destroy(&clients_guard);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -468,7 +461,9 @@ void Query_cache_query::unlock_n_destroy()
|
||||
|
||||
void Query_cache_query::lock_writing()
|
||||
{
|
||||
SEM_LOCK(&lock);
|
||||
MUTEX_LOCK(&clients_guard);
|
||||
while (clients != 0)
|
||||
pthread_cond_wait(&lock,&clients_guard);
|
||||
}
|
||||
|
||||
|
||||
@ -482,11 +477,17 @@ void Query_cache_query::lock_writing()
|
||||
my_bool Query_cache_query::try_lock_writing()
|
||||
{
|
||||
DBUG_ENTER("Query_cache_block::try_lock_writing");
|
||||
if (sem_trywait(&lock)!=0 || clients != 0)
|
||||
if (pthread_mutex_trylock(&clients_guard))
|
||||
{
|
||||
DBUG_PRINT("qcache", ("can't lock mutex"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (clients != 0)
|
||||
{
|
||||
DBUG_PRINT("info", ("already locked (r)"));
|
||||
MUTEX_UNLOCK(&clients_guard);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
DBUG_PRINT("qcache", ("mutex 'lock' 0x%lx locked", (ulong) &lock));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -495,15 +496,14 @@ my_bool Query_cache_query::try_lock_writing()
|
||||
void Query_cache_query::lock_reading()
|
||||
{
|
||||
MUTEX_LOCK(&clients_guard);
|
||||
if (!clients++)
|
||||
SEM_LOCK(&lock);
|
||||
clients++;
|
||||
MUTEX_UNLOCK(&clients_guard);
|
||||
}
|
||||
|
||||
|
||||
void Query_cache_query::unlock_writing()
|
||||
{
|
||||
SEM_UNLOCK(&lock);
|
||||
MUTEX_UNLOCK(&clients_guard);
|
||||
}
|
||||
|
||||
|
||||
@ -511,7 +511,7 @@ void Query_cache_query::unlock_reading()
|
||||
{
|
||||
MUTEX_LOCK(&clients_guard);
|
||||
if (--clients == 0)
|
||||
SEM_UNLOCK(&lock);
|
||||
pthread_cond_broadcast(&lock);
|
||||
MUTEX_UNLOCK(&clients_guard);
|
||||
}
|
||||
|
||||
@ -677,6 +677,7 @@ Query_cache::Query_cache(ulong query_cache_limit,
|
||||
:query_cache_size(0),
|
||||
query_cache_limit(query_cache_limit),
|
||||
queries_in_cache(0), hits(0), inserts(0), refused(0),
|
||||
total_blocks(0),
|
||||
min_allocation_unit(min_allocation_unit),
|
||||
min_result_data_size(min_result_data_size),
|
||||
def_query_hash_size(def_query_hash_size),
|
||||
@ -747,7 +748,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
|
||||
/* Check if another thread is processing the same query? */
|
||||
thd->query[thd->query_length] = (char) flags;
|
||||
Query_cache_block *competitor = (Query_cache_block *)
|
||||
hash_search(&queries, thd->query, thd->query_length+1);
|
||||
hash_search(&queries, (byte*) thd->query, thd->query_length+1);
|
||||
DBUG_PRINT("qcache", ("competitor 0x%lx, flags %x", (ulong) competitor,
|
||||
flags));
|
||||
if (competitor == 0)
|
||||
@ -779,7 +780,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
|
||||
{
|
||||
refused++;
|
||||
DBUG_PRINT("warning", ("tables list including failed"));
|
||||
hash_delete(&queries, (char *) query_block);
|
||||
hash_delete(&queries, (byte *) query_block);
|
||||
header->unlock_n_destroy();
|
||||
free_memory_block(query_block);
|
||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||
@ -890,7 +891,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
||||
}
|
||||
|
||||
sql[query_length] = (char) flags;
|
||||
query_block = (Query_cache_block *) hash_search(&queries, sql,
|
||||
query_block = (Query_cache_block *) hash_search(&queries, (byte*) sql,
|
||||
query_length+1);
|
||||
sql[query_length] = '\0';
|
||||
|
||||
@ -1026,20 +1027,11 @@ void Query_cache::invalidate(Query_cache_table::query_cache_table_type type)
|
||||
{
|
||||
STRUCT_LOCK(&structure_guard_mutex);
|
||||
DUMP(this);
|
||||
if (query_cache_size > 0 && tables_blocks[type] != 0)
|
||||
if (query_cache_size > 0)
|
||||
{
|
||||
Query_cache_block *table_block = tables_blocks[type];
|
||||
do
|
||||
{
|
||||
/* 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]);
|
||||
/* invalidate_table reduce list while only root of list remain */
|
||||
while (tables_blocks[type] != 0)
|
||||
invalidate_table(tables_blocks[type]);
|
||||
}
|
||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||
}
|
||||
@ -1060,27 +1052,11 @@ void Query_cache::invalidate(char *db)
|
||||
if (query_cache_size > 0)
|
||||
{
|
||||
DUMP(this);
|
||||
int i = 0;
|
||||
for(; i < (int) Query_cache_table::TYPES_NUMBER; i++)
|
||||
for (int i=0 ; i < (int) Query_cache_table::TYPES_NUMBER; i++)
|
||||
{
|
||||
if (tables_blocks[i] != 0) // Cache not empty
|
||||
{
|
||||
Query_cache_block *table_block = tables_blocks[i];
|
||||
do
|
||||
{
|
||||
/*
|
||||
Store next block address defore deletetion of current block
|
||||
*/
|
||||
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]);
|
||||
}
|
||||
/* invalidate_table reduce list while only root of list remain */
|
||||
while (tables_blocks[i] !=0 )
|
||||
invalidate_table(tables_blocks[i]);
|
||||
}
|
||||
}
|
||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||
@ -1101,7 +1077,8 @@ void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
|
||||
if (query_cache_size > 0) // Safety if cache removed
|
||||
{
|
||||
Query_cache_block *table_block;
|
||||
if ((table_block = (Query_cache_block*) hash_search(&tables, key,
|
||||
if ((table_block = (Query_cache_block*) hash_search(&tables,
|
||||
(byte*) key,
|
||||
key_length)))
|
||||
invalidate_table(table_block);
|
||||
}
|
||||
@ -1243,6 +1220,7 @@ ulong Query_cache::init_cache()
|
||||
|
||||
first_block = (Query_cache_block *) (cache + additional_data_size);
|
||||
first_block->init(query_cache_size);
|
||||
total_blocks++;
|
||||
first_block->pnext=first_block->pprev=first_block;
|
||||
first_block->next=first_block->prev=first_block;
|
||||
|
||||
@ -1290,8 +1268,8 @@ ulong Query_cache::init_cache()
|
||||
size += inc;
|
||||
}
|
||||
}
|
||||
bins[mem_bin_num].number= 1; // For easy end test
|
||||
free_memory= 0;
|
||||
bins[mem_bin_num].number = 1; // For easy end test in get_free_block
|
||||
free_memory = free_memory_blocks = 0;
|
||||
insert_into_free_memory_list(first_block);
|
||||
|
||||
DUMP(this);
|
||||
@ -1348,6 +1326,7 @@ void Query_cache::free_cache(my_bool destruction)
|
||||
|
||||
/* Becasue we did a flush, all cache memory must be in one this block */
|
||||
bins[0].free_blocks->destroy();
|
||||
total_blocks--;
|
||||
DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
|
||||
free_memory , query_cache_size));
|
||||
my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
|
||||
@ -1738,7 +1717,7 @@ void Query_cache::invalidate_table(TABLE_LIST *table_list)
|
||||
|
||||
// We don't store temporary tables => no key_length+=4 ...
|
||||
if ((table_block = (Query_cache_block*)
|
||||
hash_search(&tables,key,key_length)))
|
||||
hash_search(&tables,(byte*) key,key_length)))
|
||||
invalidate_table(table_block);
|
||||
}
|
||||
}
|
||||
@ -1747,7 +1726,7 @@ void Query_cache::invalidate_table(TABLE *table)
|
||||
{
|
||||
Query_cache_block *table_block;
|
||||
if ((table_block = ((Query_cache_block*)
|
||||
hash_search(&tables, table->table_cache_key,
|
||||
hash_search(&tables, (byte*) table->table_cache_key,
|
||||
table->key_length))))
|
||||
invalidate_table(table_block);
|
||||
}
|
||||
@ -1856,7 +1835,8 @@ Query_cache::insert_table(uint key_len, char *key,
|
||||
(ulong)node, key_len));
|
||||
|
||||
Query_cache_block *table_block = ((Query_cache_block *)
|
||||
hash_search(&tables, key, key_len));
|
||||
hash_search(&tables, (byte*) key,
|
||||
key_len));
|
||||
|
||||
if (table_block == 0)
|
||||
{
|
||||
@ -1905,6 +1885,7 @@ Query_cache::insert_table(uint key_len, char *key,
|
||||
|
||||
void Query_cache::unlink_table(Query_cache_block_table *node)
|
||||
{
|
||||
DBUG_ENTER("Query_cache::unlink_table");
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
Query_cache_block_table *neighbour = node->next;
|
||||
@ -1917,6 +1898,7 @@ void Query_cache::unlink_table(Query_cache_block_table *node)
|
||||
hash_delete(&tables,(byte *) table_block);
|
||||
free_memory_block(table_block);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
@ -2038,6 +2020,7 @@ void Query_cache::split_block(Query_cache_block *block,ulong len)
|
||||
Query_cache_block *new_block = (Query_cache_block*)(((byte*) block)+len);
|
||||
|
||||
new_block->init(block->length - len);
|
||||
total_blocks++;
|
||||
block->length=len;
|
||||
new_block->pnext = block->pnext;
|
||||
block->pnext = new_block;
|
||||
@ -2068,6 +2051,7 @@ Query_cache::join_free_blocks(Query_cache_block *first_block,
|
||||
// May be was not free block
|
||||
second_block->used=0;
|
||||
second_block->destroy();
|
||||
total_blocks--;
|
||||
|
||||
first_block->length += second_block->length;
|
||||
first_block->pnext = second_block->pnext;
|
||||
@ -2090,6 +2074,7 @@ my_bool Query_cache::append_next_free_block(Query_cache_block *block,
|
||||
ulong old_len = block->length;
|
||||
exclude_from_free_memory_list(next_block);
|
||||
next_block->destroy();
|
||||
total_blocks--;
|
||||
|
||||
block->length += next_block->length;
|
||||
block->pnext = next_block->pnext;
|
||||
@ -2112,6 +2097,7 @@ void Query_cache::exclude_from_free_memory_list(Query_cache_block *free_block)
|
||||
double_linked_list_exclude(free_block, &bin->free_blocks);
|
||||
bin->number--;
|
||||
free_memory-=free_block->length;
|
||||
free_memory_blocks--;
|
||||
DBUG_PRINT("qcache",("exclude block 0x%lx, bin 0x%lx", (ulong) free_block,
|
||||
(ulong) bin));
|
||||
DBUG_VOID_RETURN;
|
||||
@ -2207,6 +2193,7 @@ void Query_cache::insert_into_free_memory_sorted_list(Query_cache_block *
|
||||
point->next = new_block;
|
||||
}
|
||||
free_memory+=new_block->length;
|
||||
free_memory_blocks++;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -2222,11 +2209,11 @@ Query_cache::double_linked_list_simple_include(Query_cache_block *point,
|
||||
*list_pointer=point->next=point->prev=point;
|
||||
else
|
||||
{
|
||||
// insert to and of list
|
||||
point->next = (*list_pointer);
|
||||
point->prev = (*list_pointer)->prev;
|
||||
point->prev->next = point;
|
||||
(*list_pointer)->prev = point;
|
||||
(*list_pointer) = point;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -2360,6 +2347,7 @@ void Query_cache::pack_cache()
|
||||
{
|
||||
Query_cache_block *new_block = (Query_cache_block *) border;
|
||||
new_block->init(gap);
|
||||
total_blocks++;
|
||||
new_block->pnext = before->pnext;
|
||||
before->pnext = new_block;
|
||||
new_block->pprev = before;
|
||||
@ -2395,6 +2383,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||
block->pprev->pnext=block->pnext;
|
||||
block->pnext->pprev=block->pprev;
|
||||
block->destroy();
|
||||
total_blocks--;
|
||||
DBUG_PRINT("qcache", ("added to gap (%lu)", *gap));
|
||||
break;
|
||||
}
|
||||
@ -2416,7 +2405,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||
byte *key;
|
||||
uint key_length;
|
||||
key=query_cache_table_get_key((byte*) block, &key_length,0);
|
||||
hash_search(&tables, key, key_length);
|
||||
hash_search(&tables, (byte*) key, key_length);
|
||||
|
||||
block->destroy();
|
||||
new_block->init(len);
|
||||
@ -2432,8 +2421,10 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||
nlist_root->n = 0;
|
||||
nlist_root->next = (tnext == list_root ? nlist_root : tnext);
|
||||
nlist_root->prev = (tprev == list_root ? nlist_root: tnext);
|
||||
tnext->prev = list_root;
|
||||
tprev->next = list_root;
|
||||
tnext->prev = nlist_root;
|
||||
tprev->next = nlist_root;
|
||||
for (;tnext != nlist_root; tnext=tnext->next)
|
||||
tnext->parent = new_block->table();
|
||||
*border += len;
|
||||
*before = new_block;
|
||||
/* Fix hash to point at moved block */
|
||||
@ -2462,7 +2453,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||
byte *key;
|
||||
uint key_length;
|
||||
key=query_cache_query_get_key((byte*) block, &key_length,0);
|
||||
hash_search(&queries, key, key_length);
|
||||
hash_search(&queries, (byte*) key, key_length);
|
||||
|
||||
memcpy((char*) new_block->table(0), (char*) block->table(0),
|
||||
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
|
||||
@ -2654,7 +2645,6 @@ my_bool Query_cache::join_results(ulong join_limit)
|
||||
uint Query_cache::filename_2_table_key (char *key, const char *path)
|
||||
{
|
||||
char tablename[FN_REFLEN+2], *filename, *dbname;
|
||||
Query_cache_block *table_block;
|
||||
uint db_length;
|
||||
DBUG_ENTER("Query_cache::filename_2_table_key");
|
||||
|
||||
|
@ -17,8 +17,6 @@
|
||||
#ifndef _SQL_CACHE_H
|
||||
#define _SQL_CACHE_H
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
/* Query cache */
|
||||
|
||||
/*
|
||||
@ -105,7 +103,7 @@ struct Query_cache_query
|
||||
Query_cache_block *res;
|
||||
NET *wri;
|
||||
ulong len;
|
||||
sem_t lock; // R/W lock of block
|
||||
pthread_cond_t lock; // R/W lock of block
|
||||
pthread_mutex_t clients_guard;
|
||||
uint clients;
|
||||
|
||||
@ -220,7 +218,8 @@ public:
|
||||
/* Info */
|
||||
ulong query_cache_size, query_cache_limit;
|
||||
/* statistics */
|
||||
ulong free_memory, queries_in_cache, hits, inserts, refused;
|
||||
ulong free_memory, queries_in_cache, hits, inserts, refused,
|
||||
free_memory_blocks, total_blocks;
|
||||
|
||||
protected:
|
||||
/*
|
||||
|
@ -1023,11 +1023,11 @@ err:
|
||||
int log_loaded_block(IO_CACHE* file)
|
||||
{
|
||||
LOAD_FILE_INFO* lf_info;
|
||||
uint block_len ;
|
||||
ulong block_len ;
|
||||
|
||||
/* file->request_pos contains position where we started last read */
|
||||
char* buffer = (char*) file->request_pos;
|
||||
if (!(block_len = file->read_end - buffer))
|
||||
byte *buffer = file->request_pos;
|
||||
if (!(block_len = (ulong) (file->read_end - buffer)))
|
||||
return 0;
|
||||
lf_info = (LOAD_FILE_INFO*)file->arg;
|
||||
if (lf_info->last_pos_in_file != HA_POS_ERROR &&
|
||||
@ -1036,14 +1036,14 @@ int log_loaded_block(IO_CACHE* file)
|
||||
lf_info->last_pos_in_file = file->pos_in_file;
|
||||
if (lf_info->wrote_create_file)
|
||||
{
|
||||
Append_block_log_event a(lf_info->thd, buffer, block_len);
|
||||
Append_block_log_event a(lf_info->thd, (char*) buffer, block_len);
|
||||
mysql_bin_log.write(&a);
|
||||
}
|
||||
else
|
||||
{
|
||||
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
|
||||
lf_info->table_name, *lf_info->fields,
|
||||
lf_info->handle_dup, buffer,
|
||||
lf_info->handle_dup, (char*) buffer,
|
||||
block_len);
|
||||
mysql_bin_log.write(&c);
|
||||
lf_info->wrote_create_file = 1;
|
||||
|
@ -3172,11 +3172,9 @@ option_value:
|
||||
}
|
||||
|
||||
query_cache_type:
|
||||
'0' { current_thd->query_cache_type = 0; }
|
||||
NUM { current_thd->query_cache_type = set_zone(atoi($1.str),0,3); }
|
||||
| OFF { current_thd->query_cache_type = 0; }
|
||||
| '1' { current_thd->query_cache_type = 1; }
|
||||
| ON { current_thd->query_cache_type = 1; }
|
||||
| '2' { current_thd->query_cache_type = 2; }
|
||||
| DEMAND_SYM { current_thd->query_cache_type = 2; }
|
||||
|
||||
text_or_password:
|
||||
|
Reference in New Issue
Block a user