mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01: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. Docs/manual.texi: Update of query cache info. Docs/section.Comparisons.texi: Added indexing. client/mysqlbinlog.cc: Removed compiler warnings. client/mysqltest.c: Added enable_result_log/disable_result_log include/config-win.h: Added support of semaphores on Windows. include/my_pthread.h: Added pthread_mutex_trylock for windows. include/my_sys.h: Cleanup libmysql/libmysql.c: Fixed bug in mysql_use_result() (When reusing connections). myisam/ft_boolean_search.c: Removed compiler warnings myisam/ft_nlq_search.c: Removed compiler warnings myisam/ft_update.c: Removed compiler warnings mysql-test/r/query_cache.result: New tests mysql-test/t/query_cache-master.opt: New tests mysql-test/t/query_cache.test: New tests mysys/Makefile.am: Added new operators to be used with gcc 3.0.x sql/filesort.cc: Removed compiler warnings sql/item_func.cc: Removed compiler warnings sql/mysql_priv.h: Removed compiler warnings sql/mysqld.cc: Update of query cache code. sql/slave.cc: Removed compiler warnings. Code cleanup (Indentation) sql/sql_cache.cc: Updated code sql/sql_cache.h: Updated code sql/sql_repl.cc: Removed compiler warnings sql/sql_yacc.yy: Updated query cache
This commit is contained in:
parent
b05520526e
commit
f939a6b635
27 changed files with 1362 additions and 390 deletions
|
@ -18506,9 +18506,12 @@ If this is 0, the query cache is disabled (default).
|
||||||
|
|
||||||
@item @code{query_cache_startup_type}
|
@item @code{query_cache_startup_type}
|
||||||
This may be set (only numeric) to
|
This may be set (only numeric) to
|
||||||
0 (OFF, don't cache or retrieve results),
|
@multitable @columnfractions .1 .2 .7
|
||||||
1 (ON, cache all results except @code{SELECT SQL_NO_CACHE ...} queries) or
|
@item @strong{Value} @tab @strong{Alias} @tab @strong{Comment}
|
||||||
2 (DEMAND, cache only @code{SELECT SQL_CACHE ...} queries).
|
@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}
|
@item @code{safe_show_databases}
|
||||||
Don't show databases for which the user doesn't have any database or
|
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
|
@node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons
|
||||||
@subsection How MySQL Compares to @code{mSQL}
|
@subsection How MySQL Compares to @code{mSQL}
|
||||||
|
|
||||||
|
@cindex mSQL, MySQL vs mSQL, overview
|
||||||
@table @strong
|
@table @strong
|
||||||
@item Performance
|
@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
|
@subsubsection How @code{mSQL} and MySQL Client/Server Communications Protocols Differ
|
||||||
|
|
||||||
@cindex communications protocols
|
@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)
|
There are enough differences that it is impossible (or at least not easy)
|
||||||
to support both.
|
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
|
best choice. If you need some of the extra features that only PostgreSQL
|
||||||
can offer, you should use @code{PostgreSQL}.
|
can offer, you should use @code{PostgreSQL}.
|
||||||
|
|
||||||
@cindex PostgreSQL/MySQL, strategies
|
|
||||||
@menu
|
@menu
|
||||||
* MySQL-PostgreSQL goals:: MySQL and PostgreSQL development strategies
|
* MySQL-PostgreSQL goals:: MySQL and PostgreSQL development strategies
|
||||||
* MySQL-PostgreSQL features:: Featurewise Comparison of MySQL and PostgreSQL
|
* 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
|
@node MySQL-PostgreSQL goals, MySQL-PostgreSQL features, Compare PostgreSQL, Compare PostgreSQL
|
||||||
@subsubsection MySQL and PostgreSQL development strategies
|
@subsubsection MySQL and PostgreSQL development strategies
|
||||||
|
|
||||||
|
@cindex PostgreSQL vs. MySQL, strategies
|
||||||
When adding things to MySQL we take pride to do an optimal, definite
|
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
|
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
|
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
|
@node MySQL-PostgreSQL features, MySQL-PostgreSQL benchmarks, MySQL-PostgreSQL goals, Compare PostgreSQL
|
||||||
@subsubsection Featurewise Comparison of MySQL and PostgreSQL
|
@subsubsection Featurewise Comparison of MySQL and PostgreSQL
|
||||||
|
|
||||||
@cindex PostgreSQL/MySQL, features
|
@cindex PostgreSQL vs. MySQL, features
|
||||||
|
|
||||||
On the crash-me page
|
On the crash-me page
|
||||||
(@uref{http://www.mysql.com/information/crash-me.php})
|
(@uref{http://www.mysql.com/information/crash-me.php})
|
||||||
|
|
|
@ -385,9 +385,9 @@ static void dump_remote_log_entries(const char* logname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_header (IO_CACHE* file)
|
static int check_header(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[PROBE_HEADER_LEN];
|
byte buf[PROBE_HEADER_LEN];
|
||||||
int old_format;
|
int old_format;
|
||||||
|
|
||||||
my_off_t pos = my_b_tell(file);
|
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 <my_global.h>
|
||||||
#include <mysql_embed.h>
|
#include <mysql_embed.h>
|
||||||
|
@ -138,16 +138,16 @@ MYSQL_RES *last_result=0;
|
||||||
|
|
||||||
PARSER parser;
|
PARSER parser;
|
||||||
MASTER_POS master_pos;
|
MASTER_POS master_pos;
|
||||||
int* block_ok; /* set to 0 if the current block should not be executed */
|
int *block_ok; /* set to 0 if the current block should not be executed */
|
||||||
int false_block_depth = 0;
|
int false_block_depth = 0;
|
||||||
const char* result_file = 0; /* if set, all results are concated and
|
/* if set, all results are concated and compared against this file */
|
||||||
compared against this file*/
|
const char *result_file = 0;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char* name;
|
char *name;
|
||||||
int name_len;
|
int name_len;
|
||||||
char* str_val;
|
char *str_val;
|
||||||
int str_val_len;
|
int str_val_len;
|
||||||
int int_val;
|
int int_val;
|
||||||
int alloced_len;
|
int alloced_len;
|
||||||
|
@ -158,7 +158,7 @@ typedef struct
|
||||||
VAR var_reg[10];
|
VAR var_reg[10];
|
||||||
/*Perl/shell-like variable registers */
|
/*Perl/shell-like variable registers */
|
||||||
HASH var_hash;
|
HASH var_hash;
|
||||||
int disable_query_log=0;
|
int disable_query_log=0, disable_result_log=0;
|
||||||
|
|
||||||
struct connection cons[MAX_CONS];
|
struct connection cons[MAX_CONS];
|
||||||
struct connection* cur_con, *next_con, *cons_end;
|
struct connection* cur_con, *next_con, *cons_end;
|
||||||
|
@ -181,6 +181,7 @@ Q_PING, Q_EVAL,
|
||||||
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
Q_RPL_PROBE, Q_ENABLE_RPL_PARSE,
|
||||||
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT,
|
||||||
Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG,
|
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_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER,
|
||||||
Q_UNKNOWN, /* Unknown command. */
|
Q_UNKNOWN, /* Unknown command. */
|
||||||
Q_COMMENT, /* Comments, ignored. */
|
Q_COMMENT, /* Comments, ignored. */
|
||||||
|
@ -215,6 +216,7 @@ const char *command_names[] = {
|
||||||
"rpl_probe", "enable_rpl_parse",
|
"rpl_probe", "enable_rpl_parse",
|
||||||
"disable_rpl_parse", "eval_result",
|
"disable_rpl_parse", "eval_result",
|
||||||
"enable_query_log", "disable_query_log",
|
"enable_query_log", "disable_query_log",
|
||||||
|
"enable_result_log", "disable_result_log",
|
||||||
"server_start", "server_stop",
|
"server_start", "server_stop",
|
||||||
"require_manager",
|
"require_manager",
|
||||||
0
|
0
|
||||||
|
@ -224,22 +226,22 @@ TYPELIB command_typelib= {array_elements(command_names),"",
|
||||||
command_names};
|
command_names};
|
||||||
|
|
||||||
DYNAMIC_STRING ds_res;
|
DYNAMIC_STRING ds_res;
|
||||||
static void die(const char* fmt, ...);
|
static void die(const char *fmt, ...);
|
||||||
static void init_var_hash();
|
static void init_var_hash();
|
||||||
static byte* get_var_key(const byte* rec, uint* len,
|
static byte* get_var_key(const byte* rec, uint* len,
|
||||||
my_bool __attribute__((unused)) t);
|
my_bool __attribute__((unused)) t);
|
||||||
static VAR* var_init(VAR* v, const char* name, int name_len, const char* val,
|
static VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
|
||||||
int val_len);
|
int val_len);
|
||||||
|
|
||||||
static void var_free(void* v);
|
static void var_free(void* v);
|
||||||
|
|
||||||
int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname);
|
int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname);
|
||||||
void reject_dump(const char* record_file, char* buf, int size);
|
void reject_dump(const char *record_file, char *buf, int size);
|
||||||
|
|
||||||
int close_connection(struct st_query* q);
|
int close_connection(struct st_query* q);
|
||||||
VAR* var_get(const char* var_name, const char** var_name_end, int raw);
|
VAR* var_get(const char *var_name, const char** var_name_end, int raw);
|
||||||
int eval_expr(VAR* v, const char* p, const char** p_end);
|
int eval_expr(VAR* v, const char *p, const char** p_end);
|
||||||
static int read_server_arguments(const char* name);
|
static int read_server_arguments(const char *name);
|
||||||
|
|
||||||
/* Definitions for replace */
|
/* Definitions for replace */
|
||||||
|
|
||||||
|
@ -259,9 +261,9 @@ static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
|
||||||
void free_pointer_array(POINTER_ARRAY *pa);
|
void free_pointer_array(POINTER_ARRAY *pa);
|
||||||
static int initialize_replace_buffer(void);
|
static int initialize_replace_buffer(void);
|
||||||
static void free_replace_buffer(void);
|
static void free_replace_buffer(void);
|
||||||
static void do_eval(DYNAMIC_STRING* query_eval, const char* query);
|
static void do_eval(DYNAMIC_STRING* query_eval, const char *query);
|
||||||
void str_to_file(const char* fname, char* str, int size);
|
void str_to_file(const char *fname, char *str, int size);
|
||||||
int do_server_op(struct st_query* q,const char* op);
|
int do_server_op(struct st_query* q,const char *op);
|
||||||
|
|
||||||
struct st_replace *glob_replace;
|
struct st_replace *glob_replace;
|
||||||
static char *out_buff;
|
static char *out_buff;
|
||||||
|
@ -1960,20 +1962,20 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||||
int query_len;
|
int query_len;
|
||||||
DBUG_ENTER("run_query");
|
DBUG_ENTER("run_query");
|
||||||
|
|
||||||
if(q->type != Q_EVAL)
|
if (q->type != Q_EVAL)
|
||||||
{
|
{
|
||||||
query = q->query;
|
query = q->query;
|
||||||
query_len = strlen(query);
|
query_len = strlen(query);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
init_dynamic_string(&eval_query, "", 16384, 65536);
|
init_dynamic_string(&eval_query, "", 16384, 65536);
|
||||||
do_eval(&eval_query, q->query);
|
do_eval(&eval_query, q->query);
|
||||||
query = eval_query.str;
|
query = eval_query.str;
|
||||||
query_len = eval_query.length;
|
query_len = eval_query.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( q->record_file[0])
|
if (q->record_file[0])
|
||||||
{
|
{
|
||||||
init_dynamic_string(&ds_tmp, "", 16384, 65536);
|
init_dynamic_string(&ds_tmp, "", 16384, 65536);
|
||||||
ds = &ds_tmp;
|
ds = &ds_tmp;
|
||||||
|
@ -2060,44 +2062,45 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!res) goto end;
|
if (!res)
|
||||||
|
goto end;
|
||||||
|
|
||||||
fields = mysql_fetch_fields(res);
|
if (!disable_result_log)
|
||||||
num_fields = mysql_num_fields(res);
|
|
||||||
for( i = 0; i < num_fields; i++)
|
|
||||||
{
|
{
|
||||||
if (i)
|
fields = mysql_fetch_fields(res);
|
||||||
dynstr_append_mem(ds, "\t", 1);
|
num_fields = mysql_num_fields(res);
|
||||||
dynstr_append(ds, fields[i].name);
|
for (i = 0; i < num_fields; i++)
|
||||||
}
|
|
||||||
|
|
||||||
dynstr_append_mem(ds, "\n", 1);
|
|
||||||
|
|
||||||
|
|
||||||
while((row = mysql_fetch_row(res)))
|
|
||||||
{
|
|
||||||
lengths = mysql_fetch_lengths(res);
|
|
||||||
for(i = 0; i < num_fields; i++)
|
|
||||||
{
|
{
|
||||||
val = (char*)row[i];
|
|
||||||
len = lengths[i];
|
|
||||||
|
|
||||||
if (!val)
|
|
||||||
{
|
|
||||||
val = (char*)"NULL";
|
|
||||||
len = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
dynstr_append_mem(ds, "\t", 1);
|
dynstr_append_mem(ds, "\t", 1);
|
||||||
replace_dynstr_append_mem(ds, val, len);
|
dynstr_append(ds, fields[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
dynstr_append_mem(ds, "\n", 1);
|
dynstr_append_mem(ds, "\n", 1);
|
||||||
}
|
|
||||||
if (glob_replace)
|
|
||||||
free_replace();
|
|
||||||
|
|
||||||
|
while ((row = mysql_fetch_row(res)))
|
||||||
|
{
|
||||||
|
lengths = mysql_fetch_lengths(res);
|
||||||
|
for(i = 0; i < num_fields; i++)
|
||||||
|
{
|
||||||
|
val = (char*)row[i];
|
||||||
|
len = lengths[i];
|
||||||
|
|
||||||
|
if (!val)
|
||||||
|
{
|
||||||
|
val = (char*)"NULL";
|
||||||
|
len = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i)
|
||||||
|
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 (record)
|
||||||
{
|
{
|
||||||
if (!q->record_file[0] && !result_file)
|
if (!q->record_file[0] && !result_file)
|
||||||
|
@ -2111,7 +2114,8 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (res) mysql_free_result(res);
|
if (res)
|
||||||
|
mysql_free_result(res);
|
||||||
last_result=0;
|
last_result=0;
|
||||||
if (ds == &ds_tmp)
|
if (ds == &ds_tmp)
|
||||||
dynstr_free(&ds_tmp);
|
dynstr_free(&ds_tmp);
|
||||||
|
@ -2288,10 +2292,12 @@ int main(int argc, char** argv)
|
||||||
case Q_DIRTY_CLOSE:
|
case Q_DIRTY_CLOSE:
|
||||||
close_connection(q); break;
|
close_connection(q); break;
|
||||||
case Q_RPL_PROBE: do_rpl_probe(q); break;
|
case Q_RPL_PROBE: do_rpl_probe(q); break;
|
||||||
case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
|
case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break;
|
||||||
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
|
case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
|
||||||
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
|
case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
|
||||||
case Q_DISABLE_QUERY_LOG: disable_query_log=1; 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_SOURCE: do_source(q); break;
|
||||||
case Q_SLEEP: do_sleep(q); break;
|
case Q_SLEEP: do_sleep(q); break;
|
||||||
case Q_REQUIRE_MANAGER: do_require_manager(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_STRPBRK
|
||||||
#define HAVE_STRSTR
|
#define HAVE_STRSTR
|
||||||
#define HAVE_COMPRESS
|
#define HAVE_COMPRESS
|
||||||
|
#define HAVE_CREATESEMAPHORE
|
||||||
|
|
||||||
#ifdef NOT_USED
|
#ifdef NOT_USED
|
||||||
#define HAVE_SNPRINTF /* Gave link error */
|
#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))
|
#define pthread_equal(A,B) ((A) == (B))
|
||||||
#ifdef OS2
|
#ifdef OS2
|
||||||
int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
extern int pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||||
int pthread_mutex_lock (pthread_mutex_t *);
|
extern int pthread_mutex_lock (pthread_mutex_t *);
|
||||||
int pthread_mutex_unlock (pthread_mutex_t *);
|
extern int pthread_mutex_unlock (pthread_mutex_t *);
|
||||||
int pthread_mutex_destroy (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 my_pthread_setprio(A,B) DosSetPriority(PRTYS_THREAD,PRTYC_NOCHANGE, B, A)
|
||||||
#define pthread_kill(A,B) raise(B)
|
#define pthread_kill(A,B) raise(B)
|
||||||
#define pthread_exit(A) pthread_dummy()
|
#define pthread_exit(A) pthread_dummy()
|
||||||
#else
|
#else
|
||||||
#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
|
#define pthread_mutex_init(A,B) InitializeCriticalSection(A)
|
||||||
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
|
#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_unlock(A) LeaveCriticalSection(A)
|
||||||
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
|
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
|
||||||
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
|
#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
|
#ifndef _my_sys_h
|
||||||
#define _my_sys_h
|
#define _my_sys_h
|
||||||
#ifdef __cplusplus
|
C_MODE_START
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_AIOWAIT
|
#ifdef HAVE_AIOWAIT
|
||||||
#include <sys/asynch.h> /* Used by record-cache */
|
#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 */
|
extern my_bool have_tcpip; /* Is set if tcpip is used */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
C_MODE_END
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#include "raid.h"
|
#include "raid.h"
|
||||||
#endif /* _my_sys_h */
|
#endif /* _my_sys_h */
|
||||||
|
|
|
@ -2397,6 +2397,8 @@ mysql_fetch_row(MYSQL_RES *res)
|
||||||
DBUG_PRINT("info",("end of data"));
|
DBUG_PRINT("info",("end of data"));
|
||||||
res->eof=1;
|
res->eof=1;
|
||||||
res->handle->status=MYSQL_STATUS_READY;
|
res->handle->status=MYSQL_STATUS_READY;
|
||||||
|
/* Don't clear handle in mysql_free_results */
|
||||||
|
res->handle=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_RETURN((MYSQL_ROW) NULL);
|
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)))
|
while ((res=ft_get_word(start,end,&w,¶m)))
|
||||||
{
|
{
|
||||||
byte r=param.plusminus;
|
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) {
|
switch (res) {
|
||||||
case 1: /* word found */
|
case 1: /* word found */
|
||||||
ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
|
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->len=w.len+1;
|
||||||
ftbw->yesno=param.yesno;
|
ftbw->yesno=param.yesno;
|
||||||
ftbw->trunc=param.trunc; /* 0 or 1 */
|
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*));
|
ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
|
||||||
reinit_queue(& ftb->queue, res, 0, 0, FTB_WORD_cmp, ftb);
|
reinit_queue(& ftb->queue, res, 0, 0, FTB_WORD_cmp, ftb);
|
||||||
ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR));
|
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->up=0;
|
||||||
ftbe->ythresh=0;
|
ftbe->ythresh=0;
|
||||||
ftbe->docid=HA_POS_ERROR;
|
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)
|
if (ftbe->docid != curdoc)
|
||||||
{
|
{
|
||||||
ftbe->cur_weight=ftbe->yesses=ftbe->nos=0;
|
ftbe->cur_weight=0;
|
||||||
|
ftbe->yesses=ftbe->nos=0;
|
||||||
ftbe->docid=curdoc;
|
ftbe->docid=curdoc;
|
||||||
}
|
}
|
||||||
if (ftbe->nos)
|
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)
|
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;
|
ftbe->docid=HA_POS_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -248,7 +248,8 @@ int ft_nlq_read_next(FT_INFO *handler, char *record)
|
||||||
}
|
}
|
||||||
|
|
||||||
float ft_nlq_find_relevance(FT_INFO *handler,
|
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;
|
int a,b,c;
|
||||||
FT_DOC *docs=handler->doc;
|
FT_DOC *docs=handler->doc;
|
||||||
|
@ -267,7 +268,7 @@ float ft_nlq_find_relevance(FT_INFO *handler,
|
||||||
a=c;
|
a=c;
|
||||||
}
|
}
|
||||||
if (docs[a].dpos == docid)
|
if (docs[a].dpos == docid)
|
||||||
return docs[a].weight;
|
return (float) docs[a].weight;
|
||||||
else
|
else
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
@ -279,7 +280,7 @@ void ft_nlq_close_search(FT_INFO *handler)
|
||||||
|
|
||||||
float ft_nlq_get_relevance(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)
|
void ft_nlq_reinit_search(FT_INFO *handler)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
/* functions to work with full-text indices */
|
/* functions to work with full-text indices */
|
||||||
|
|
||||||
#include "ftdefs.h"
|
#include "ftdefs.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
/**************************************************************
|
/**************************************************************
|
||||||
This is to make ft-code to ignore keyseg.length at all *
|
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,
|
cmp=_mi_compare_text(default_charset_info,
|
||||||
(uchar*) old_word->pos,old_word->len,
|
(uchar*) old_word->pos,old_word->len,
|
||||||
(uchar*) new_word->pos,new_word->len,0);
|
(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)
|
if (cmp < 0 || cmp2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
reset query cache;
|
reset query cache;
|
||||||
flush status;
|
flush status;
|
||||||
drop table if exists t1;
|
drop table if exists t1,t2,t3;
|
||||||
create table t1 (a int not null);
|
create table t1 (a int not null);
|
||||||
insert into t1 values (1),(2),(3);
|
insert into t1 values (1),(2),(3);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
@ -36,3 +36,265 @@ drop table t1;
|
||||||
show status like "Qcache_queries_in_cache";
|
show status like "Qcache_queries_in_cache";
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
Qcache_queries_in_cache 0
|
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
|
# Tests with query cache
|
||||||
#
|
#
|
||||||
|
@ -6,7 +8,12 @@
|
||||||
|
|
||||||
reset query cache;
|
reset query cache;
|
||||||
flush status;
|
flush status;
|
||||||
drop table if exists t1;
|
drop table if exists t1,t2,t3;
|
||||||
|
|
||||||
|
#
|
||||||
|
# First simple test
|
||||||
|
#
|
||||||
|
|
||||||
create table t1 (a int not null);
|
create table t1 (a int not null);
|
||||||
insert into t1 values (1),(2),(3);
|
insert into t1 values (1),(2),(3);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
@ -24,3 +31,153 @@ show status like "Qcache_hits";
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
show status like "Qcache_queries_in_cache";
|
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 \
|
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
|
||||||
my_lock.c mf_brkhant.c my_alarm.c \
|
my_lock.c mf_brkhant.c my_alarm.c \
|
||||||
my_malloc.c my_realloc.c my_once.c mulalloc.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 \
|
my_error.c errors.c my_div.c my_messnc.c \
|
||||||
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
||||||
my_symlink.c my_symlink2.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;
|
int error;
|
||||||
ulong memavl;
|
ulong memavl;
|
||||||
uint maxbuffer,skr;
|
uint maxbuffer;
|
||||||
BUFFPEK *buffpek;
|
BUFFPEK *buffpek;
|
||||||
ha_rows records;
|
ha_rows records;
|
||||||
uchar **sort_keys;
|
uchar **sort_keys;
|
||||||
|
@ -163,7 +163,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||||
&tempfile, selected_records_file)) ==
|
&tempfile, selected_records_file)) ==
|
||||||
HA_POS_ERROR)
|
HA_POS_ERROR)
|
||||||
goto err;
|
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
|
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 (tmp)
|
||||||
{
|
{
|
||||||
if (reinit_io_cache(buffpek_pointers,READ_CACHE,0L,0,0) ||
|
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));
|
my_free((char*) tmp, MYF(0));
|
||||||
tmp=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 */
|
/* Skriver en buffert med nycklar till filen */
|
||||||
|
|
||||||
static int write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
|
static int
|
||||||
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
|
write_keys(SORTPARAM *param, register uchar **sort_keys, uint count,
|
||||||
|
IO_CACHE *buffpek_pointers, IO_CACHE *tempfile)
|
||||||
{
|
{
|
||||||
uint sort_length;
|
uint sort_length;
|
||||||
|
uchar **end;
|
||||||
BUFFPEK buffpek;
|
BUFFPEK buffpek;
|
||||||
DBUG_ENTER("write_keys");
|
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)
|
if ((ha_rows) count > param->max_rows)
|
||||||
count=(uint) param->max_rows; /* purecov: inspected */
|
count=(uint) param->max_rows; /* purecov: inspected */
|
||||||
buffpek.count=(ha_rows) count;
|
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))
|
if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length))
|
||||||
goto err;
|
goto err;
|
||||||
if (my_b_write(buffpek_pointers, (char*) &buffpek, sizeof(buffpek)))
|
if (my_b_write(buffpek_pointers, (byte*) &buffpek, sizeof(buffpek)))
|
||||||
goto err;
|
goto err;
|
||||||
DBUG_RETURN(0);
|
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_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)
|
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_SMALL_RESULT 8
|
||||||
#define SELECT_BIG_RESULT 16
|
#define SELECT_BIG_RESULT 16
|
||||||
#define OPTION_FOUND_ROWS 32
|
#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 SELECT_NO_JOIN_CACHE 256 /* Intern */
|
||||||
|
|
||||||
#define OPTION_BIG_TABLES 512 /* for SQL OPTION */
|
#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 SELECT_NO_UNLOCK (QUERY_NO_GOOD_INDEX_USED*2)
|
||||||
#define TMP_TABLE_ALL_COLUMNS (SELECT_NO_UNLOCK*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
|
#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},
|
{"Open_streams", (char*) &my_stream_opened, SHOW_INT_CONST},
|
||||||
{"Opened_tables", (char*) &opened_tables, SHOW_LONG},
|
{"Opened_tables", (char*) &opened_tables, SHOW_LONG},
|
||||||
{"Questions", (char*) 0, SHOW_QUESTION},
|
{"Questions", (char*) 0, SHOW_QUESTION},
|
||||||
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache,
|
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
|
||||||
SHOW_LONG},
|
|
||||||
{"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
|
{"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
|
||||||
{"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
|
{"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
|
||||||
{"Qcache_not_cached", (char*) &query_cache.refused, 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},
|
{"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
|
||||||
{"Select_full_join", (char*) &select_full_join_count, SHOW_LONG},
|
{"Select_full_join", (char*) &select_full_join_count, SHOW_LONG},
|
||||||
{"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG},
|
{"Select_full_range_join", (char*) &select_full_range_join_count, SHOW_LONG},
|
||||||
|
|
415
sql/slave.cc
415
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 wild_do_table_inited = 0, wild_ignore_table_inited = 0;
|
||||||
bool table_rules_on = 0;
|
bool table_rules_on = 0;
|
||||||
uint32 slave_skip_counter = 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;
|
int last_slave_errno = 0;
|
||||||
char last_slave_error[MAX_SLAVE_ERRMSG] = "";
|
char last_slave_error[MAX_SLAVE_ERRMSG] = "";
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -98,14 +101,14 @@ static TABLE_RULE_ENT* find_wild(DYNAMIC_ARRAY *a, const char* key, int len)
|
||||||
uint i;
|
uint i;
|
||||||
const char* key_end = key + len;
|
const char* key_end = key + len;
|
||||||
|
|
||||||
for(i = 0; i < a->elements; i++)
|
for (i = 0; i < a->elements; i++)
|
||||||
{
|
{
|
||||||
TABLE_RULE_ENT* e ;
|
TABLE_RULE_ENT* e ;
|
||||||
get_dynamic(a, (gptr)&e, i);
|
get_dynamic(a, (gptr)&e, i);
|
||||||
if(!wild_case_compare(key, key_end, (const char*)e->db,
|
if (!wild_case_compare(key, key_end, (const char*)e->db,
|
||||||
(const char*)(e->db + e->key_len),'\\'))
|
(const char*)(e->db + e->key_len),'\\'))
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -114,10 +117,10 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
|
||||||
{
|
{
|
||||||
for (; tables; tables = tables->next)
|
for (; tables; tables = tables->next)
|
||||||
{
|
{
|
||||||
if (!tables->updating)
|
|
||||||
continue;
|
|
||||||
char hash_key[2*NAME_LEN+2];
|
char hash_key[2*NAME_LEN+2];
|
||||||
char* p;
|
char* p;
|
||||||
|
if (!tables->updating)
|
||||||
|
continue;
|
||||||
p = strmov(hash_key, tables->db ? tables->db : thd->db);
|
p = strmov(hash_key, tables->db ? tables->db : thd->db);
|
||||||
*p++ = '.';
|
*p++ = '.';
|
||||||
uint len = strmov(p, tables->real_name) - hash_key ;
|
uint len = strmov(p, tables->real_name) - hash_key ;
|
||||||
|
@ -139,9 +142,10 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no explicit rule found
|
/*
|
||||||
// and there was a do list, do not replicate. If there was
|
If no explicit rule found and there was a do list, do not replicate.
|
||||||
// no do list, go ahead
|
If there was no do list, go ahead
|
||||||
|
*/
|
||||||
return !do_table_inited && !wild_do_table_inited;
|
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)
|
int add_table_rule(HASH* h, const char* table_spec)
|
||||||
{
|
{
|
||||||
const char* dot = strchr(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 '.'
|
// len is always > 0 because we know the there exists a '.'
|
||||||
uint len = (uint)strlen(table_spec);
|
uint len = (uint)strlen(table_spec);
|
||||||
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
|
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
|
||||||
+ len, MYF(MY_WME));
|
+ len, MYF(MY_WME));
|
||||||
if(!e) return 1;
|
if (!e)
|
||||||
|
return 1;
|
||||||
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
|
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
|
||||||
e->tbl_name = e->db + (dot - table_spec) + 1;
|
e->tbl_name = e->db + (dot - table_spec) + 1;
|
||||||
e->key_len = len;
|
e->key_len = len;
|
||||||
|
@ -166,11 +172,12 @@ int add_table_rule(HASH* h, const char* table_spec)
|
||||||
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
|
int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
|
||||||
{
|
{
|
||||||
const char* dot = strchr(table_spec, '.');
|
const char* dot = strchr(table_spec, '.');
|
||||||
if(!dot) return 1;
|
if (!dot) return 1;
|
||||||
uint len = (uint)strlen(table_spec);
|
uint len = (uint)strlen(table_spec);
|
||||||
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
|
TABLE_RULE_ENT* e = (TABLE_RULE_ENT*)my_malloc(sizeof(TABLE_RULE_ENT)
|
||||||
+ len, MYF(MY_WME));
|
+ len, MYF(MY_WME));
|
||||||
if(!e) return 1;
|
if (!e)
|
||||||
|
return 1;
|
||||||
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
|
e->db = (char*)e + sizeof(TABLE_RULE_ENT);
|
||||||
e->tbl_name = e->db + (dot - table_spec) + 1;
|
e->tbl_name = e->db + (dot - table_spec) + 1;
|
||||||
e->key_len = len;
|
e->key_len = len;
|
||||||
|
@ -182,12 +189,12 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
|
||||||
static void free_string_array(DYNAMIC_ARRAY *a)
|
static void free_string_array(DYNAMIC_ARRAY *a)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
for(i = 0; i < a->elements; i++)
|
for (i = 0; i < a->elements; i++)
|
||||||
{
|
{
|
||||||
char* p;
|
char* p;
|
||||||
get_dynamic(a, (gptr) &p, i);
|
get_dynamic(a, (gptr) &p, i);
|
||||||
my_free(p, MYF(MY_WME));
|
my_free(p, MYF(MY_WME));
|
||||||
}
|
}
|
||||||
delete_dynamic(a);
|
delete_dynamic(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,13 +214,13 @@ void end_slave()
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
pthread_mutex_unlock(&LOCK_slave);
|
||||||
|
|
||||||
end_master_info(&glob_mi);
|
end_master_info(&glob_mi);
|
||||||
if(do_table_inited)
|
if (do_table_inited)
|
||||||
hash_free(&replicate_do_table);
|
hash_free(&replicate_do_table);
|
||||||
if(ignore_table_inited)
|
if (ignore_table_inited)
|
||||||
hash_free(&replicate_ignore_table);
|
hash_free(&replicate_ignore_table);
|
||||||
if(wild_do_table_inited)
|
if (wild_do_table_inited)
|
||||||
free_string_array(&replicate_wild_do_table);
|
free_string_array(&replicate_wild_do_table);
|
||||||
if(wild_ignore_table_inited)
|
if (wild_ignore_table_inited)
|
||||||
free_string_array(&replicate_wild_ignore_table);
|
free_string_array(&replicate_wild_ignore_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,13 +248,13 @@ void skip_load_data_infile(NET* net)
|
||||||
|
|
||||||
char* rewrite_db(char* db)
|
char* rewrite_db(char* db)
|
||||||
{
|
{
|
||||||
if(replicate_rewrite_db.is_empty() || !db) return db;
|
if (replicate_rewrite_db.is_empty() || !db) return db;
|
||||||
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
|
I_List_iterator<i_string_pair> it(replicate_rewrite_db);
|
||||||
i_string_pair* tmp;
|
i_string_pair* tmp;
|
||||||
|
|
||||||
while((tmp=it++))
|
while((tmp=it++))
|
||||||
{
|
{
|
||||||
if(!strcmp(tmp->key, db))
|
if (!strcmp(tmp->key, db))
|
||||||
return tmp->val;
|
return tmp->val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,39 +264,39 @@ char* rewrite_db(char* db)
|
||||||
int db_ok(const char* db, I_List<i_string> &do_list,
|
int db_ok(const char* db, I_List<i_string> &do_list,
|
||||||
I_List<i_string> &ignore_list )
|
I_List<i_string> &ignore_list )
|
||||||
{
|
{
|
||||||
if(do_list.is_empty() && ignore_list.is_empty())
|
if (do_list.is_empty() && ignore_list.is_empty())
|
||||||
return 1; // ok to replicate if the user puts no constraints
|
return 1; // ok to replicate if the user puts no constraints
|
||||||
|
|
||||||
// if the user has specified restrictions on which databases to replicate
|
// if the user has specified restrictions on which databases to replicate
|
||||||
// and db was not selected, do not replicate
|
// and db was not selected, do not replicate
|
||||||
if(!db)
|
if (!db)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(!do_list.is_empty()) // if the do's are not empty
|
if (!do_list.is_empty()) // if the do's are not empty
|
||||||
{
|
{
|
||||||
I_List_iterator<i_string> it(do_list);
|
I_List_iterator<i_string> it(do_list);
|
||||||
i_string* tmp;
|
i_string* tmp;
|
||||||
|
|
||||||
while((tmp=it++))
|
while((tmp=it++))
|
||||||
{
|
{
|
||||||
if(!strcmp(tmp->ptr, db))
|
if (!strcmp(tmp->ptr, db))
|
||||||
return 1; // match
|
return 1; // match
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else // there are some elements in the don't, otherwise we cannot get here
|
else // there are some elements in the don't, otherwise we cannot get here
|
||||||
|
{
|
||||||
|
I_List_iterator<i_string> it(ignore_list);
|
||||||
|
i_string* tmp;
|
||||||
|
|
||||||
|
while((tmp=it++))
|
||||||
{
|
{
|
||||||
I_List_iterator<i_string> it(ignore_list);
|
if (!strcmp(tmp->ptr, db))
|
||||||
i_string* tmp;
|
return 0; // match
|
||||||
|
|
||||||
while((tmp=it++))
|
|
||||||
{
|
|
||||||
if(!strcmp(tmp->ptr, db))
|
|
||||||
return 0; // match
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
|
static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f,
|
||||||
|
@ -327,7 +334,7 @@ static int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
|
||||||
*var = atoi(buf);
|
*var = atoi(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(default_val)
|
else if (default_val)
|
||||||
{
|
{
|
||||||
*var = default_val;
|
*var = default_val;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -530,7 +537,7 @@ int fetch_nx_table(THD* thd, const char* db_name, const char* table_name,
|
||||||
|
|
||||||
void end_master_info(MASTER_INFO* mi)
|
void end_master_info(MASTER_INFO* mi)
|
||||||
{
|
{
|
||||||
if(mi->fd >= 0)
|
if (mi->fd >= 0)
|
||||||
{
|
{
|
||||||
end_io_cache(&mi->file);
|
end_io_cache(&mi->file);
|
||||||
(void)my_close(mi->fd, MYF(MY_WME));
|
(void)my_close(mi->fd, MYF(MY_WME));
|
||||||
|
@ -567,7 +574,7 @@ int init_master_info(MASTER_INFO* mi)
|
||||||
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
|
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
|
||||||
MYF(MY_WME)))
|
MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
if(fd >= 0)
|
if (fd >= 0)
|
||||||
my_close(fd, MYF(0));
|
my_close(fd, MYF(0));
|
||||||
pthread_mutex_unlock(&mi->lock);
|
pthread_mutex_unlock(&mi->lock);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -587,13 +594,13 @@ int init_master_info(MASTER_INFO* mi)
|
||||||
}
|
}
|
||||||
else // file exists
|
else // file exists
|
||||||
{
|
{
|
||||||
if(fd >= 0)
|
if (fd >= 0)
|
||||||
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
|
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
|
||||||
else if((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0
|
else if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0
|
||||||
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
|
|| init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
|
||||||
0, MYF(MY_WME)))
|
0, MYF(MY_WME)))
|
||||||
{
|
{
|
||||||
if(fd >= 0)
|
if (fd >= 0)
|
||||||
my_close(fd, MYF(0));
|
my_close(fd, MYF(0));
|
||||||
pthread_mutex_unlock(&mi->lock);
|
pthread_mutex_unlock(&mi->lock);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -608,7 +615,7 @@ int init_master_info(MASTER_INFO* mi)
|
||||||
|
|
||||||
mi->log_file_name[length-1]= 0; // kill \n
|
mi->log_file_name[length-1]= 0; // kill \n
|
||||||
/* Reuse fname buffer */
|
/* Reuse fname buffer */
|
||||||
if(!my_b_gets(&mi->file, fname, sizeof(fname)))
|
if (!my_b_gets(&mi->file, fname, sizeof(fname)))
|
||||||
{
|
{
|
||||||
msg="Error reading log file position from master info file";
|
msg="Error reading log file position from master info file";
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -616,7 +623,7 @@ int init_master_info(MASTER_INFO* mi)
|
||||||
mi->pos = strtoull(fname,(char**) 0, 10);
|
mi->pos = strtoull(fname,(char**) 0, 10);
|
||||||
|
|
||||||
mi->fd = fd;
|
mi->fd = fd;
|
||||||
if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
|
if (init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file,
|
||||||
master_host) ||
|
master_host) ||
|
||||||
init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
|
init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file,
|
||||||
master_user) ||
|
master_user) ||
|
||||||
|
@ -654,19 +661,19 @@ int register_slave_on_master(MYSQL* mysql)
|
||||||
String packet;
|
String packet;
|
||||||
char buf[4];
|
char buf[4];
|
||||||
|
|
||||||
if(!report_host)
|
if (!report_host)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int4store(buf, server_id);
|
int4store(buf, server_id);
|
||||||
packet.append(buf, 4);
|
packet.append(buf, 4);
|
||||||
|
|
||||||
net_store_data(&packet, report_host);
|
net_store_data(&packet, report_host);
|
||||||
if(report_user)
|
if (report_user)
|
||||||
net_store_data(&packet, report_user);
|
net_store_data(&packet, report_user);
|
||||||
else
|
else
|
||||||
packet.append((char)0);
|
packet.append((char)0);
|
||||||
|
|
||||||
if(report_password)
|
if (report_password)
|
||||||
net_store_data(&packet, report_user);
|
net_store_data(&packet, report_user);
|
||||||
else
|
else
|
||||||
packet.append((char)0);
|
packet.append((char)0);
|
||||||
|
@ -678,7 +685,7 @@ int register_slave_on_master(MYSQL* mysql)
|
||||||
int4store(buf, 0); /* tell the master will fill in master_id */
|
int4store(buf, 0); /* tell the master will fill in master_id */
|
||||||
packet.append(buf, 4);
|
packet.append(buf, 4);
|
||||||
|
|
||||||
if(mc_simple_command(mysql, COM_REGISTER_SLAVE, (char*)packet.ptr(),
|
if (mc_simple_command(mysql, COM_REGISTER_SLAVE, (char*)packet.ptr(),
|
||||||
packet.length(), 0))
|
packet.length(), 0))
|
||||||
{
|
{
|
||||||
sql_print_error("Error on COM_REGISTER_SLAVE: '%s'",
|
sql_print_error("Error on COM_REGISTER_SLAVE: '%s'",
|
||||||
|
@ -710,7 +717,7 @@ int show_master_info(THD* thd)
|
||||||
field_list.push_back(new Item_empty_string("Last_error", 20));
|
field_list.push_back(new Item_empty_string("Last_error", 20));
|
||||||
field_list.push_back(new Item_empty_string("Skip_counter", 12));
|
field_list.push_back(new Item_empty_string("Skip_counter", 12));
|
||||||
field_list.push_back(new Item_empty_string("Last_log_seq", 12));
|
field_list.push_back(new Item_empty_string("Last_log_seq", 12));
|
||||||
if(send_fields(thd, field_list, 1))
|
if (send_fields(thd, field_list, 1))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
||||||
String* packet = &thd->packet;
|
String* packet = &thd->packet;
|
||||||
|
@ -758,6 +765,7 @@ int flush_master_info(MASTER_INFO* mi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos)
|
int st_master_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos)
|
||||||
{
|
{
|
||||||
if (!inited) return -1;
|
if (!inited) return -1;
|
||||||
|
@ -901,17 +909,18 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
|
static int request_table_dump(MYSQL* mysql, const char* db, const char* table)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char * p = buf;
|
char * p = buf;
|
||||||
uint table_len = (uint) strlen(table);
|
uint table_len = (uint) strlen(table);
|
||||||
uint db_len = (uint) strlen(db);
|
uint db_len = (uint) strlen(db);
|
||||||
if(table_len + db_len > sizeof(buf) - 2)
|
if (table_len + db_len > sizeof(buf) - 2)
|
||||||
{
|
{
|
||||||
sql_print_error("request_table_dump: Buffer overrun");
|
sql_print_error("request_table_dump: Buffer overrun");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p++ = db_len;
|
*p++ = db_len;
|
||||||
memcpy(p, db, db_len);
|
memcpy(p, db, db_len);
|
||||||
|
@ -1008,12 +1017,12 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
||||||
if (ev->server_id == ::server_id ||
|
if (ev->server_id == ::server_id ||
|
||||||
(slave_skip_counter && type_code != ROTATE_EVENT))
|
(slave_skip_counter && type_code != ROTATE_EVENT))
|
||||||
{
|
{
|
||||||
if(type_code == LOAD_EVENT)
|
if (type_code == LOAD_EVENT)
|
||||||
skip_load_data_infile(net);
|
skip_load_data_infile(net);
|
||||||
|
|
||||||
mi->inc_pos(event_len, ev->log_seq);
|
mi->inc_pos(event_len, ev->log_seq);
|
||||||
flush_master_info(mi);
|
flush_master_info(mi);
|
||||||
if(slave_skip_counter && /* protect against common user error of
|
if (slave_skip_counter && /* protect against common user error of
|
||||||
setting the counter to 1 instead of 2
|
setting the counter to 1 instead of 2
|
||||||
while recovering from an failed
|
while recovering from an failed
|
||||||
auto-increment insert */
|
auto-increment insert */
|
||||||
|
@ -1026,7 +1035,7 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len)
|
||||||
|
|
||||||
thd->server_id = ev->server_id; // use the original server id for logging
|
thd->server_id = ev->server_id; // use the original server id for logging
|
||||||
thd->set_time(); // time the query
|
thd->set_time(); // time the query
|
||||||
if(!thd->log_seq)
|
if (!thd->log_seq)
|
||||||
thd->log_seq = ev->log_seq;
|
thd->log_seq = ev->log_seq;
|
||||||
if (!ev->when)
|
if (!ev->when)
|
||||||
ev->when = time(NULL);
|
ev->when = time(NULL);
|
||||||
|
@ -1050,7 +1059,7 @@ This may also be a network problem, or just a bug in the master or slave code.\
|
||||||
pthread_handler_decl(handle_slave,arg __attribute__((unused)))
|
pthread_handler_decl(handle_slave,arg __attribute__((unused)))
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
slave_begin:
|
slave_begin:
|
||||||
#endif
|
#endif
|
||||||
THD *thd; // needs to be first for thread_stack
|
THD *thd; // needs to be first for thread_stack
|
||||||
MYSQL *mysql = NULL ;
|
MYSQL *mysql = NULL ;
|
||||||
|
@ -1065,12 +1074,12 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
|
||||||
pthread_exit((void*)1);
|
pthread_exit((void*)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(slave_running)
|
if (slave_running)
|
||||||
{
|
{
|
||||||
pthread_cond_broadcast(&COND_slave_start);
|
pthread_cond_broadcast(&COND_slave_start);
|
||||||
pthread_mutex_unlock(&LOCK_slave);
|
pthread_mutex_unlock(&LOCK_slave);
|
||||||
pthread_exit((void*)1); // safety just in case
|
pthread_exit((void*)1); // safety just in case
|
||||||
}
|
}
|
||||||
slave_running = 1;
|
slave_running = 1;
|
||||||
abort_slave = 0;
|
abort_slave = 0;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
@ -1090,10 +1099,10 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
|
||||||
|
|
||||||
pthread_detach_this_thread();
|
pthread_detach_this_thread();
|
||||||
if (init_slave_thread(thd) || init_master_info(&glob_mi))
|
if (init_slave_thread(thd) || init_master_info(&glob_mi))
|
||||||
{
|
{
|
||||||
sql_print_error("Failed during slave thread initialization");
|
sql_print_error("Failed during slave thread initialization");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
thd->thread_stack = (char*)&thd; // remember where our stack is
|
thd->thread_stack = (char*)&thd; // remember where our stack is
|
||||||
thd->temporary_tables = save_temporary_tables; // restore temp tables
|
thd->temporary_tables = save_temporary_tables; // restore temp tables
|
||||||
threads.append(thd);
|
threads.append(thd);
|
||||||
|
@ -1116,11 +1125,11 @@ pthread_handler_decl(handle_slave,arg __attribute__((unused)))
|
||||||
#endif
|
#endif
|
||||||
// we can get killed during safe_connect
|
// we can get killed during safe_connect
|
||||||
if (!safe_connect(thd, mysql, &glob_mi))
|
if (!safe_connect(thd, mysql, &glob_mi))
|
||||||
sql_print_error("Slave: connected to master '%s@%s:%d',\
|
sql_print_error("Slave: connected to master '%s@%s:%d',\
|
||||||
replication started in log '%s' at position %s", glob_mi.user,
|
replication started in log '%s' at position %s", glob_mi.user,
|
||||||
glob_mi.host, glob_mi.port,
|
glob_mi.host, glob_mi.port,
|
||||||
RPL_LOG_NAME,
|
RPL_LOG_NAME,
|
||||||
llstr(glob_mi.pos,llbuff));
|
llstr(glob_mi.pos,llbuff));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sql_print_error("Slave thread killed while connecting to master");
|
sql_print_error("Slave thread killed while connecting to master");
|
||||||
|
@ -1147,154 +1156,154 @@ connected:
|
||||||
|
|
||||||
while (!slave_killed(thd))
|
while (!slave_killed(thd))
|
||||||
{
|
{
|
||||||
thd->proc_info = "Requesting binlog dump";
|
thd->proc_info = "Requesting binlog dump";
|
||||||
if(request_dump(mysql, &glob_mi))
|
if (request_dump(mysql, &glob_mi))
|
||||||
{
|
{
|
||||||
sql_print_error("Failed on request_dump()");
|
sql_print_error("Failed on request_dump()");
|
||||||
if(slave_killed(thd))
|
if (slave_killed(thd))
|
||||||
{
|
{
|
||||||
sql_print_error("Slave thread killed while requesting master \
|
sql_print_error("Slave thread killed while requesting master \
|
||||||
dump");
|
dump");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->proc_info = "Waiiting to reconnect after a failed dump request";
|
thd->proc_info = "Waiiting to reconnect after a failed dump request";
|
||||||
if(mysql->net.vio)
|
if (mysql->net.vio)
|
||||||
vio_close(mysql->net.vio);
|
vio_close(mysql->net.vio);
|
||||||
// first time retry immediately, assuming that we can recover
|
// first time retry immediately, assuming that we can recover
|
||||||
// right away - if first time fails, sleep between re-tries
|
// right away - if first time fails, sleep between re-tries
|
||||||
// hopefuly the admin can fix the problem sometime
|
// hopefuly the admin can fix the problem sometime
|
||||||
if(retried_once)
|
if (retried_once)
|
||||||
safe_sleep(thd, glob_mi.connect_retry);
|
safe_sleep(thd, glob_mi.connect_retry);
|
||||||
else
|
else
|
||||||
retried_once = 1;
|
retried_once = 1;
|
||||||
|
|
||||||
if(slave_killed(thd))
|
if (slave_killed(thd))
|
||||||
{
|
{
|
||||||
sql_print_error("Slave thread killed while retrying master \
|
sql_print_error("Slave thread killed while retrying master \
|
||||||
dump");
|
dump");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->proc_info = "Reconnecting after a failed dump request";
|
thd->proc_info = "Reconnecting after a failed dump request";
|
||||||
last_failed_pos=glob_mi.pos;
|
last_failed_pos=glob_mi.pos;
|
||||||
sql_print_error("Slave: failed dump request, reconnecting to \
|
sql_print_error("Slave: failed dump request, reconnecting to \
|
||||||
try again, log '%s' at postion %s", RPL_LOG_NAME,
|
try again, log '%s' at postion %s", RPL_LOG_NAME,
|
||||||
llstr(last_failed_pos,llbuff));
|
llstr(last_failed_pos,llbuff));
|
||||||
if(safe_reconnect(thd, mysql, &glob_mi) || slave_killed(thd))
|
if (safe_reconnect(thd, mysql, &glob_mi) || slave_killed(thd))
|
||||||
{
|
{
|
||||||
sql_print_error("Slave thread killed during or after reconnect");
|
sql_print_error("Slave thread killed during or after reconnect");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto connected;
|
goto connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while(!slave_killed(thd))
|
while(!slave_killed(thd))
|
||||||
|
{
|
||||||
|
thd->proc_info = "Reading master update";
|
||||||
|
ulong event_len = read_event(mysql, &glob_mi);
|
||||||
|
if (slave_killed(thd))
|
||||||
|
{
|
||||||
|
sql_print_error("Slave thread killed while reading event");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (event_len == packet_error)
|
||||||
|
{
|
||||||
|
if (mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE)
|
||||||
{
|
{
|
||||||
thd->proc_info = "Reading master update";
|
sql_print_error("Log entry on master is longer than \
|
||||||
ulong event_len = read_event(mysql, &glob_mi);
|
|
||||||
if(slave_killed(thd))
|
|
||||||
{
|
|
||||||
sql_print_error("Slave thread killed while reading event");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (event_len == packet_error)
|
|
||||||
{
|
|
||||||
if(mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE)
|
|
||||||
{
|
|
||||||
sql_print_error("Log entry on master is longer than \
|
|
||||||
max_allowed_packet on slave. Slave thread will be aborted. If the entry is \
|
max_allowed_packet on slave. Slave thread will be aborted. If the entry is \
|
||||||
really supposed to be that long, restart the server with a higher value of \
|
really supposed to be that long, restart the server with a higher value of \
|
||||||
max_allowed_packet. The current value is %ld", max_allowed_packet);
|
max_allowed_packet. The current value is %ld", max_allowed_packet);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->proc_info = "Waiting to reconnect after a failed read";
|
thd->proc_info = "Waiting to reconnect after a failed read";
|
||||||
if(mysql->net.vio)
|
if (mysql->net.vio)
|
||||||
vio_close(mysql->net.vio);
|
vio_close(mysql->net.vio);
|
||||||
if(retried_once) // punish repeat offender with sleep
|
if (retried_once) // punish repeat offender with sleep
|
||||||
safe_sleep(thd, glob_mi.connect_retry);
|
safe_sleep(thd, glob_mi.connect_retry);
|
||||||
else
|
else
|
||||||
retried_once = 1;
|
retried_once = 1;
|
||||||
|
|
||||||
if(slave_killed(thd))
|
if (slave_killed(thd))
|
||||||
{
|
{
|
||||||
sql_print_error("Slave thread killed while waiting to \
|
sql_print_error("Slave thread killed while waiting to \
|
||||||
reconnect after a failed read");
|
reconnect after a failed read");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
thd->proc_info = "Reconnecting after a failed read";
|
thd->proc_info = "Reconnecting after a failed read";
|
||||||
last_failed_pos= glob_mi.pos;
|
last_failed_pos= glob_mi.pos;
|
||||||
sql_print_error("Slave: Failed reading log event, \
|
sql_print_error("Slave: Failed reading log event, \
|
||||||
reconnecting to retry, log '%s' position %s", RPL_LOG_NAME,
|
reconnecting to retry, log '%s' position %s", RPL_LOG_NAME,
|
||||||
llstr(last_failed_pos, llbuff));
|
llstr(last_failed_pos, llbuff));
|
||||||
if(safe_reconnect(thd, mysql, &glob_mi) || slave_killed(thd))
|
if (safe_reconnect(thd, mysql, &glob_mi) || slave_killed(thd))
|
||||||
{
|
{
|
||||||
sql_print_error("Slave thread killed during or after a \
|
sql_print_error("Slave thread killed during or after a \
|
||||||
reconnect done to recover from failed read");
|
reconnect done to recover from failed read");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
goto connected;
|
goto connected;
|
||||||
} // if(event_len == packet_error)
|
} // if (event_len == packet_error)
|
||||||
|
|
||||||
thd->proc_info = "Processing master log event";
|
thd->proc_info = "Processing master log event";
|
||||||
if(exec_event(thd, &mysql->net, &glob_mi, event_len))
|
if (exec_event(thd, &mysql->net, &glob_mi, event_len))
|
||||||
{
|
{
|
||||||
sql_print_error("\
|
sql_print_error("\
|
||||||
Error running query, slave aborted. Fix the problem, and re-start \
|
Error running query, slave aborted. Fix the problem, and re-start \
|
||||||
the slave thread with \"mysqladmin start-slave\". We stopped at log \
|
the slave thread with \"mysqladmin start-slave\". We stopped at log \
|
||||||
'%s' position %s",
|
'%s' position %s",
|
||||||
RPL_LOG_NAME, llstr(glob_mi.pos, llbuff));
|
RPL_LOG_NAME, llstr(glob_mi.pos, llbuff));
|
||||||
goto err;
|
goto err;
|
||||||
// there was an error running the query
|
// there was an error running the query
|
||||||
// abort the slave thread, when the problem is fixed, the user
|
// abort the slave thread, when the problem is fixed, the user
|
||||||
// should restart the slave with mysqladmin start-slave
|
// should restart the slave with mysqladmin start-slave
|
||||||
}
|
}
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if(abort_slave_event_count && !--events_till_abort)
|
if (abort_slave_event_count && !--events_till_abort)
|
||||||
{
|
{
|
||||||
sql_print_error("Slave: debugging abort");
|
sql_print_error("Slave: debugging abort");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// successful exec with offset advance,
|
// successful exec with offset advance,
|
||||||
// the slave repents and his sins are forgiven!
|
// the slave repents and his sins are forgiven!
|
||||||
if(glob_mi.pos > last_failed_pos)
|
if (glob_mi.pos > last_failed_pos)
|
||||||
{
|
{
|
||||||
retried_once = 0;
|
retried_once = 0;
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
stuck_count = 0;
|
stuck_count = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// show a little mercy, allow slave to read one more event
|
// show a little mercy, allow slave to read one more event
|
||||||
// before cutting him off - otherwise he gets stuck
|
// before cutting him off - otherwise he gets stuck
|
||||||
// on Intvar events, since they do not advance the offset
|
// on Intvar events, since they do not advance the offset
|
||||||
// immediately
|
// immediately
|
||||||
if (++stuck_count > 2)
|
if (++stuck_count > 2)
|
||||||
events_till_disconnect++;
|
events_till_disconnect++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // while(!slave_killed(thd)) - read/exec loop
|
} // while(!slave_killed(thd)) - read/exec loop
|
||||||
} // while(!slave_killed(thd)) - slave loop
|
} // while(!slave_killed(thd)) - slave loop
|
||||||
|
|
||||||
// error = 0;
|
// error = 0;
|
||||||
err:
|
err:
|
||||||
// print the current replication position
|
// print the current replication position
|
||||||
sql_print_error("Slave thread exiting, replication stopped in log '%s' at \
|
sql_print_error("Slave thread exiting, replication stopped in log '%s' at \
|
||||||
position %s",
|
position %s",
|
||||||
RPL_LOG_NAME, llstr(glob_mi.pos,llbuff));
|
RPL_LOG_NAME, llstr(glob_mi.pos,llbuff));
|
||||||
thd->query = thd->db = 0; // extra safety
|
thd->query = thd->db = 0; // extra safety
|
||||||
if(mysql)
|
if (mysql)
|
||||||
mc_mysql_close(mysql);
|
mc_mysql_close(mysql);
|
||||||
thd->proc_info = "Waiting for slave mutex on exit";
|
thd->proc_info = "Waiting for slave mutex on exit";
|
||||||
pthread_mutex_lock(&LOCK_slave);
|
pthread_mutex_lock(&LOCK_slave);
|
||||||
slave_running = 0;
|
slave_running = 0;
|
||||||
|
@ -1309,7 +1318,7 @@ position %s",
|
||||||
delete thd;
|
delete thd;
|
||||||
my_thread_end();
|
my_thread_end();
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if(abort_slave_event_count && !events_till_abort)
|
if (abort_slave_event_count && !events_till_abort)
|
||||||
goto slave_begin;
|
goto slave_begin;
|
||||||
#endif
|
#endif
|
||||||
pthread_exit(0);
|
pthread_exit(0);
|
||||||
|
@ -1346,7 +1355,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
|
||||||
events_till_disconnect = disconnect_slave_event_count;
|
events_till_disconnect = disconnect_slave_event_count;
|
||||||
#endif
|
#endif
|
||||||
while (!(slave_was_killed = slave_killed(thd)) &&
|
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,
|
!mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0,
|
||||||
mi->port, 0, 0)))
|
mi->port, 0, 0)))
|
||||||
{
|
{
|
||||||
|
|
126
sql/sql_cache.cc
126
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)
|
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
|
||||||
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
|
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
|
||||||
pthread_mutex_lock(M);}
|
pthread_mutex_lock(M);}
|
||||||
#define 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",\
|
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
|
||||||
(ulong)(M))); pthread_mutex_unlock(M);}
|
(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__)); \
|
#define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \
|
||||||
pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
|
pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));}
|
||||||
#define STRUCT_UNLOCK(M) { \
|
#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();})
|
#define DUMP(C) DBUG_EXECUTE("qcache", {(C)->queries_dump();(C)->tables_dump();})
|
||||||
#else
|
#else
|
||||||
#define MUTEX_LOCK(M) pthread_mutex_lock(M)
|
#define MUTEX_LOCK(M) pthread_mutex_lock(M)
|
||||||
#define SEM_LOCK(M) sem_wait(M)
|
|
||||||
#define MUTEX_UNLOCK(M) pthread_mutex_unlock(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_LOCK(M) pthread_mutex_lock(M)
|
||||||
#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
|
#define STRUCT_UNLOCK(M) pthread_mutex_unlock(M)
|
||||||
#define BLOCK_LOCK_WR(B) B->query()->lock_writing()
|
#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()
|
inline Query_cache_block * Query_cache_block_table::block()
|
||||||
{
|
{
|
||||||
return (Query_cache_block *)(((byte*)this) -
|
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)));
|
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");
|
DBUG_ENTER("Query_cache_query::init_n_lock");
|
||||||
res=0; wri = 0; len = 0;
|
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);
|
pthread_mutex_init(&clients_guard,MY_MUTEX_INIT_FAST);
|
||||||
clients = 0;
|
clients = 0;
|
||||||
lock_writing();
|
lock_writing();
|
||||||
|
@ -445,14 +438,14 @@ void Query_cache_query::init_n_lock()
|
||||||
void Query_cache_query::unlock_n_destroy()
|
void Query_cache_query::unlock_n_destroy()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("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
|
The following call is not needed on system where one can destroy an
|
||||||
active semaphore
|
active semaphore
|
||||||
*/
|
*/
|
||||||
this->unlock_writing();
|
this->unlock_writing();
|
||||||
DBUG_PRINT("qcache", ("destroyed & unlocked query for block 0x%lx",
|
pthread_cond_destroy(&lock);
|
||||||
((byte*)this)-ALIGN_SIZE(sizeof(Query_cache_block))));
|
|
||||||
sem_destroy(&lock);
|
|
||||||
pthread_mutex_destroy(&clients_guard);
|
pthread_mutex_destroy(&clients_guard);
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -468,7 +461,9 @@ void Query_cache_query::unlock_n_destroy()
|
||||||
|
|
||||||
void Query_cache_query::lock_writing()
|
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()
|
my_bool Query_cache_query::try_lock_writing()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Query_cache_block::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_PRINT("qcache", ("can't lock mutex"));
|
||||||
DBUG_RETURN(0);
|
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_PRINT("qcache", ("mutex 'lock' 0x%lx locked", (ulong) &lock));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
@ -495,15 +496,14 @@ my_bool Query_cache_query::try_lock_writing()
|
||||||
void Query_cache_query::lock_reading()
|
void Query_cache_query::lock_reading()
|
||||||
{
|
{
|
||||||
MUTEX_LOCK(&clients_guard);
|
MUTEX_LOCK(&clients_guard);
|
||||||
if (!clients++)
|
clients++;
|
||||||
SEM_LOCK(&lock);
|
|
||||||
MUTEX_UNLOCK(&clients_guard);
|
MUTEX_UNLOCK(&clients_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Query_cache_query::unlock_writing()
|
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);
|
MUTEX_LOCK(&clients_guard);
|
||||||
if (--clients == 0)
|
if (--clients == 0)
|
||||||
SEM_UNLOCK(&lock);
|
pthread_cond_broadcast(&lock);
|
||||||
MUTEX_UNLOCK(&clients_guard);
|
MUTEX_UNLOCK(&clients_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,6 +677,7 @@ Query_cache::Query_cache(ulong query_cache_limit,
|
||||||
:query_cache_size(0),
|
:query_cache_size(0),
|
||||||
query_cache_limit(query_cache_limit),
|
query_cache_limit(query_cache_limit),
|
||||||
queries_in_cache(0), hits(0), inserts(0), refused(0),
|
queries_in_cache(0), hits(0), inserts(0), refused(0),
|
||||||
|
total_blocks(0),
|
||||||
min_allocation_unit(min_allocation_unit),
|
min_allocation_unit(min_allocation_unit),
|
||||||
min_result_data_size(min_result_data_size),
|
min_result_data_size(min_result_data_size),
|
||||||
def_query_hash_size(def_query_hash_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? */
|
/* Check if another thread is processing the same query? */
|
||||||
thd->query[thd->query_length] = (char) flags;
|
thd->query[thd->query_length] = (char) flags;
|
||||||
Query_cache_block *competitor = (Query_cache_block *)
|
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,
|
DBUG_PRINT("qcache", ("competitor 0x%lx, flags %x", (ulong) competitor,
|
||||||
flags));
|
flags));
|
||||||
if (competitor == 0)
|
if (competitor == 0)
|
||||||
|
@ -779,7 +780,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
|
||||||
{
|
{
|
||||||
refused++;
|
refused++;
|
||||||
DBUG_PRINT("warning", ("tables list including failed"));
|
DBUG_PRINT("warning", ("tables list including failed"));
|
||||||
hash_delete(&queries, (char *) query_block);
|
hash_delete(&queries, (byte *) query_block);
|
||||||
header->unlock_n_destroy();
|
header->unlock_n_destroy();
|
||||||
free_memory_block(query_block);
|
free_memory_block(query_block);
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||||
|
@ -790,7 +791,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
|
||||||
queries_in_cache++;
|
queries_in_cache++;
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||||
|
|
||||||
net->query_cache_query = (gptr) query_block;
|
net->query_cache_query= (gptr) query_block;
|
||||||
header->writer(net);
|
header->writer(net);
|
||||||
// init_n_lock make query block locked
|
// init_n_lock make query block locked
|
||||||
BLOCK_UNLOCK_WR(query_block);
|
BLOCK_UNLOCK_WR(query_block);
|
||||||
|
@ -890,7 +891,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
sql[query_length] = (char) flags;
|
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);
|
query_length+1);
|
||||||
sql[query_length] = '\0';
|
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);
|
STRUCT_LOCK(&structure_guard_mutex);
|
||||||
DUMP(this);
|
DUMP(this);
|
||||||
if (query_cache_size > 0 && tables_blocks[type] != 0)
|
if (query_cache_size > 0)
|
||||||
{
|
{
|
||||||
Query_cache_block *table_block = tables_blocks[type];
|
/* invalidate_table reduce list while only root of list remain */
|
||||||
do
|
while (tables_blocks[type] != 0)
|
||||||
{
|
invalidate_table(tables_blocks[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]);
|
|
||||||
}
|
}
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||||
}
|
}
|
||||||
|
@ -1060,27 +1052,11 @@ void Query_cache::invalidate(char *db)
|
||||||
if (query_cache_size > 0)
|
if (query_cache_size > 0)
|
||||||
{
|
{
|
||||||
DUMP(this);
|
DUMP(this);
|
||||||
int i = 0;
|
for (int i=0 ; i < (int) Query_cache_table::TYPES_NUMBER; i++)
|
||||||
for(; i < (int) Query_cache_table::TYPES_NUMBER; i++)
|
|
||||||
{
|
{
|
||||||
if (tables_blocks[i] != 0) // Cache not empty
|
/* invalidate_table reduce list while only root of list remain */
|
||||||
{
|
while (tables_blocks[i] !=0 )
|
||||||
Query_cache_block *table_block = tables_blocks[i];
|
invalidate_table(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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
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
|
if (query_cache_size > 0) // Safety if cache removed
|
||||||
{
|
{
|
||||||
Query_cache_block *table_block;
|
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)))
|
key_length)))
|
||||||
invalidate_table(table_block);
|
invalidate_table(table_block);
|
||||||
}
|
}
|
||||||
|
@ -1243,6 +1220,7 @@ ulong Query_cache::init_cache()
|
||||||
|
|
||||||
first_block = (Query_cache_block *) (cache + additional_data_size);
|
first_block = (Query_cache_block *) (cache + additional_data_size);
|
||||||
first_block->init(query_cache_size);
|
first_block->init(query_cache_size);
|
||||||
|
total_blocks++;
|
||||||
first_block->pnext=first_block->pprev=first_block;
|
first_block->pnext=first_block->pprev=first_block;
|
||||||
first_block->next=first_block->prev=first_block;
|
first_block->next=first_block->prev=first_block;
|
||||||
|
|
||||||
|
@ -1290,8 +1268,8 @@ ulong Query_cache::init_cache()
|
||||||
size += inc;
|
size += inc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bins[mem_bin_num].number= 1; // For easy end test
|
bins[mem_bin_num].number = 1; // For easy end test in get_free_block
|
||||||
free_memory= 0;
|
free_memory = free_memory_blocks = 0;
|
||||||
insert_into_free_memory_list(first_block);
|
insert_into_free_memory_list(first_block);
|
||||||
|
|
||||||
DUMP(this);
|
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 */
|
/* Becasue we did a flush, all cache memory must be in one this block */
|
||||||
bins[0].free_blocks->destroy();
|
bins[0].free_blocks->destroy();
|
||||||
|
total_blocks--;
|
||||||
DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
|
DBUG_PRINT("qcache", ("free memory %lu (should be %lu)",
|
||||||
free_memory , query_cache_size));
|
free_memory , query_cache_size));
|
||||||
my_free((gptr) cache, MYF(MY_ALLOW_ZERO_PTR));
|
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 ...
|
// We don't store temporary tables => no key_length+=4 ...
|
||||||
if ((table_block = (Query_cache_block*)
|
if ((table_block = (Query_cache_block*)
|
||||||
hash_search(&tables,key,key_length)))
|
hash_search(&tables,(byte*) key,key_length)))
|
||||||
invalidate_table(table_block);
|
invalidate_table(table_block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1747,7 +1726,7 @@ void Query_cache::invalidate_table(TABLE *table)
|
||||||
{
|
{
|
||||||
Query_cache_block *table_block;
|
Query_cache_block *table_block;
|
||||||
if ((table_block = ((Query_cache_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))))
|
table->key_length))))
|
||||||
invalidate_table(table_block);
|
invalidate_table(table_block);
|
||||||
}
|
}
|
||||||
|
@ -1856,7 +1835,8 @@ Query_cache::insert_table(uint key_len, char *key,
|
||||||
(ulong)node, key_len));
|
(ulong)node, key_len));
|
||||||
|
|
||||||
Query_cache_block *table_block = ((Query_cache_block *)
|
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)
|
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)
|
void Query_cache::unlink_table(Query_cache_block_table *node)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Query_cache::unlink_table");
|
||||||
node->prev->next = node->next;
|
node->prev->next = node->next;
|
||||||
node->next->prev = node->prev;
|
node->next->prev = node->prev;
|
||||||
Query_cache_block_table *neighbour = node->next;
|
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);
|
hash_delete(&tables,(byte *) table_block);
|
||||||
free_memory_block(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);
|
Query_cache_block *new_block = (Query_cache_block*)(((byte*) block)+len);
|
||||||
|
|
||||||
new_block->init(block->length - len);
|
new_block->init(block->length - len);
|
||||||
|
total_blocks++;
|
||||||
block->length=len;
|
block->length=len;
|
||||||
new_block->pnext = block->pnext;
|
new_block->pnext = block->pnext;
|
||||||
block->pnext = new_block;
|
block->pnext = new_block;
|
||||||
|
@ -2068,6 +2051,7 @@ Query_cache::join_free_blocks(Query_cache_block *first_block,
|
||||||
// May be was not free block
|
// May be was not free block
|
||||||
second_block->used=0;
|
second_block->used=0;
|
||||||
second_block->destroy();
|
second_block->destroy();
|
||||||
|
total_blocks--;
|
||||||
|
|
||||||
first_block->length += second_block->length;
|
first_block->length += second_block->length;
|
||||||
first_block->pnext = second_block->pnext;
|
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;
|
ulong old_len = block->length;
|
||||||
exclude_from_free_memory_list(next_block);
|
exclude_from_free_memory_list(next_block);
|
||||||
next_block->destroy();
|
next_block->destroy();
|
||||||
|
total_blocks--;
|
||||||
|
|
||||||
block->length += next_block->length;
|
block->length += next_block->length;
|
||||||
block->pnext = next_block->pnext;
|
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);
|
double_linked_list_exclude(free_block, &bin->free_blocks);
|
||||||
bin->number--;
|
bin->number--;
|
||||||
free_memory-=free_block->length;
|
free_memory-=free_block->length;
|
||||||
|
free_memory_blocks--;
|
||||||
DBUG_PRINT("qcache",("exclude block 0x%lx, bin 0x%lx", (ulong) free_block,
|
DBUG_PRINT("qcache",("exclude block 0x%lx, bin 0x%lx", (ulong) free_block,
|
||||||
(ulong) bin));
|
(ulong) bin));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
@ -2207,6 +2193,7 @@ void Query_cache::insert_into_free_memory_sorted_list(Query_cache_block *
|
||||||
point->next = new_block;
|
point->next = new_block;
|
||||||
}
|
}
|
||||||
free_memory+=new_block->length;
|
free_memory+=new_block->length;
|
||||||
|
free_memory_blocks++;
|
||||||
DBUG_VOID_RETURN;
|
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;
|
*list_pointer=point->next=point->prev=point;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// insert to and of list
|
||||||
point->next = (*list_pointer);
|
point->next = (*list_pointer);
|
||||||
point->prev = (*list_pointer)->prev;
|
point->prev = (*list_pointer)->prev;
|
||||||
point->prev->next = point;
|
point->prev->next = point;
|
||||||
(*list_pointer)->prev = point;
|
(*list_pointer)->prev = point;
|
||||||
(*list_pointer) = point;
|
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -2360,6 +2347,7 @@ void Query_cache::pack_cache()
|
||||||
{
|
{
|
||||||
Query_cache_block *new_block = (Query_cache_block *) border;
|
Query_cache_block *new_block = (Query_cache_block *) border;
|
||||||
new_block->init(gap);
|
new_block->init(gap);
|
||||||
|
total_blocks++;
|
||||||
new_block->pnext = before->pnext;
|
new_block->pnext = before->pnext;
|
||||||
before->pnext = new_block;
|
before->pnext = new_block;
|
||||||
new_block->pprev = before;
|
new_block->pprev = before;
|
||||||
|
@ -2395,6 +2383,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||||
block->pprev->pnext=block->pnext;
|
block->pprev->pnext=block->pnext;
|
||||||
block->pnext->pprev=block->pprev;
|
block->pnext->pprev=block->pprev;
|
||||||
block->destroy();
|
block->destroy();
|
||||||
|
total_blocks--;
|
||||||
DBUG_PRINT("qcache", ("added to gap (%lu)", *gap));
|
DBUG_PRINT("qcache", ("added to gap (%lu)", *gap));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2416,7 +2405,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||||
byte *key;
|
byte *key;
|
||||||
uint key_length;
|
uint key_length;
|
||||||
key=query_cache_table_get_key((byte*) block, &key_length,0);
|
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();
|
block->destroy();
|
||||||
new_block->init(len);
|
new_block->init(len);
|
||||||
|
@ -2432,8 +2421,10 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||||
nlist_root->n = 0;
|
nlist_root->n = 0;
|
||||||
nlist_root->next = (tnext == list_root ? nlist_root : tnext);
|
nlist_root->next = (tnext == list_root ? nlist_root : tnext);
|
||||||
nlist_root->prev = (tprev == list_root ? nlist_root: tnext);
|
nlist_root->prev = (tprev == list_root ? nlist_root: tnext);
|
||||||
tnext->prev = list_root;
|
tnext->prev = nlist_root;
|
||||||
tprev->next = list_root;
|
tprev->next = nlist_root;
|
||||||
|
for (;tnext != nlist_root; tnext=tnext->next)
|
||||||
|
tnext->parent = new_block->table();
|
||||||
*border += len;
|
*border += len;
|
||||||
*before = new_block;
|
*before = new_block;
|
||||||
/* Fix hash to point at moved block */
|
/* Fix hash to point at moved block */
|
||||||
|
@ -2462,7 +2453,7 @@ my_bool Query_cache::move_by_type(byte **border,
|
||||||
byte *key;
|
byte *key;
|
||||||
uint key_length;
|
uint key_length;
|
||||||
key=query_cache_query_get_key((byte*) block, &key_length,0);
|
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),
|
memcpy((char*) new_block->table(0), (char*) block->table(0),
|
||||||
ALIGN_SIZE(n_tables*sizeof(Query_cache_block_table)));
|
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)
|
uint Query_cache::filename_2_table_key (char *key, const char *path)
|
||||||
{
|
{
|
||||||
char tablename[FN_REFLEN+2], *filename, *dbname;
|
char tablename[FN_REFLEN+2], *filename, *dbname;
|
||||||
Query_cache_block *table_block;
|
|
||||||
uint db_length;
|
uint db_length;
|
||||||
DBUG_ENTER("Query_cache::filename_2_table_key");
|
DBUG_ENTER("Query_cache::filename_2_table_key");
|
||||||
|
|
||||||
|
@ -2666,7 +2656,7 @@ uint Query_cache::filename_2_table_key (char *key, const char *path)
|
||||||
filename= tablename + dirname_length(tablename + 2) + 2;
|
filename= tablename + dirname_length(tablename + 2) + 2;
|
||||||
/* Find start of databasename */
|
/* Find start of databasename */
|
||||||
for (dbname= filename - 2 ; dbname[-1] != FN_LIBCHAR ; dbname--) ;
|
for (dbname= filename - 2 ; dbname[-1] != FN_LIBCHAR ; dbname--) ;
|
||||||
db_length= (filename - dbname) - 1;
|
db_length= (filename - dbname) - 1;
|
||||||
DBUG_PRINT("qcache", ("table '%-.*s.%s'", db_length, dbname, filename));
|
DBUG_PRINT("qcache", ("table '%-.*s.%s'", db_length, dbname, filename));
|
||||||
|
|
||||||
DBUG_RETURN((uint) (strmov(strmake(key, dbname, db_length) + 1,
|
DBUG_RETURN((uint) (strmov(strmake(key, dbname, db_length) + 1,
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
#ifndef _SQL_CACHE_H
|
#ifndef _SQL_CACHE_H
|
||||||
#define _SQL_CACHE_H
|
#define _SQL_CACHE_H
|
||||||
|
|
||||||
#include <semaphore.h>
|
|
||||||
|
|
||||||
/* Query cache */
|
/* Query cache */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -105,7 +103,7 @@ struct Query_cache_query
|
||||||
Query_cache_block *res;
|
Query_cache_block *res;
|
||||||
NET *wri;
|
NET *wri;
|
||||||
ulong len;
|
ulong len;
|
||||||
sem_t lock; // R/W lock of block
|
pthread_cond_t lock; // R/W lock of block
|
||||||
pthread_mutex_t clients_guard;
|
pthread_mutex_t clients_guard;
|
||||||
uint clients;
|
uint clients;
|
||||||
|
|
||||||
|
@ -220,7 +218,8 @@ public:
|
||||||
/* Info */
|
/* Info */
|
||||||
ulong query_cache_size, query_cache_limit;
|
ulong query_cache_size, query_cache_limit;
|
||||||
/* statistics */
|
/* 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:
|
protected:
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1023,11 +1023,11 @@ err:
|
||||||
int log_loaded_block(IO_CACHE* file)
|
int log_loaded_block(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
LOAD_FILE_INFO* lf_info;
|
LOAD_FILE_INFO* lf_info;
|
||||||
uint block_len ;
|
ulong block_len ;
|
||||||
|
|
||||||
/* file->request_pos contains position where we started last read */
|
/* file->request_pos contains position where we started last read */
|
||||||
char* buffer = (char*) file->request_pos;
|
byte *buffer = file->request_pos;
|
||||||
if (!(block_len = file->read_end - buffer))
|
if (!(block_len = (ulong) (file->read_end - buffer)))
|
||||||
return 0;
|
return 0;
|
||||||
lf_info = (LOAD_FILE_INFO*)file->arg;
|
lf_info = (LOAD_FILE_INFO*)file->arg;
|
||||||
if (lf_info->last_pos_in_file != HA_POS_ERROR &&
|
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;
|
lf_info->last_pos_in_file = file->pos_in_file;
|
||||||
if (lf_info->wrote_create_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);
|
mysql_bin_log.write(&a);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
|
Create_file_log_event c(lf_info->thd,lf_info->ex,lf_info->db,
|
||||||
lf_info->table_name, *lf_info->fields,
|
lf_info->table_name, *lf_info->fields,
|
||||||
lf_info->handle_dup, buffer,
|
lf_info->handle_dup, (char*) buffer,
|
||||||
block_len);
|
block_len);
|
||||||
mysql_bin_log.write(&c);
|
mysql_bin_log.write(&c);
|
||||||
lf_info->wrote_create_file = 1;
|
lf_info->wrote_create_file = 1;
|
||||||
|
|
|
@ -3172,11 +3172,9 @@ option_value:
|
||||||
}
|
}
|
||||||
|
|
||||||
query_cache_type:
|
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; }
|
| OFF { current_thd->query_cache_type = 0; }
|
||||||
| '1' { current_thd->query_cache_type = 1; }
|
|
||||||
| ON { 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; }
|
| DEMAND_SYM { current_thd->query_cache_type = 2; }
|
||||||
|
|
||||||
text_or_password:
|
text_or_password:
|
||||||
|
|
Loading…
Reference in a new issue