Generalize handle_flush thread to also handle various management

tasks for different handlers.  Add a callback from berkeley db to
delete log files that are no longer needed.
parent 9f62130f
...@@ -1821,7 +1821,12 @@ then ...@@ -1821,7 +1821,12 @@ then
sql_server_dirs="$have_berkeley_db/build_unix $sql_server_dirs" sql_server_dirs="$have_berkeley_db/build_unix $sql_server_dirs"
echo "CONFIGURING FOR BERKELEY DB" echo "CONFIGURING FOR BERKELEY DB"
(cd $bdb && cd build_unix && sh ../dist/configure) \ bdb_conf_flags=
if test $with_debug = "yes"
then
bdb_conf_flags="$bdb_conf_flags --enable-debug --enable-diagnostic"
fi
(cd $bdb && cd build_unix && sh ../dist/configure $bdb_conf_flags) \
|| AC_MSG_ERROR([could not configure Berkeley DB]) || AC_MSG_ERROR([could not configure Berkeley DB])
echo "Modifying Berkeley DB install target" echo "Modifying Berkeley DB install target"
......
...@@ -42,7 +42,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ...@@ -42,7 +42,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \ item_strfunc.h item_timefunc.h item_uniq.h \
item_create.h mysql_priv.h \ item_create.h mysql_priv.h \
procedure.h sql_class.h sql_lex.h sql_list.h \ procedure.h sql_class.h sql_lex.h sql_list.h \
sql_map.h sql_string.h unireg.h \ sql_manager.h sql_map.h sql_string.h unireg.h \
field.h handler.h ha_isammrg.h ha_isam.h ha_myisammrg.h\ field.h handler.h ha_isammrg.h ha_isam.h ha_myisammrg.h\
ha_heap.h ha_myisam.h ha_berkeley.h\ ha_heap.h ha_myisam.h ha_berkeley.h\
opt_range.h opt_ft.h \ opt_range.h opt_ft.h \
...@@ -55,7 +55,7 @@ mysqld_SOURCES = sql_lex.cc \ ...@@ -55,7 +55,7 @@ mysqld_SOURCES = sql_lex.cc \
thr_malloc.cc item_create.cc \ thr_malloc.cc item_create.cc \
field.cc key.cc sql_class.cc sql_list.cc \ field.cc key.cc sql_class.cc sql_list.cc \
net_serv.cc violite.c net_pkg.cc lock.cc my_lock.c \ net_serv.cc violite.c net_pkg.cc lock.cc my_lock.c \
sql_string.cc sql_map.cc \ sql_string.cc sql_manager.cc sql_map.cc \
mysqld.cc password.c hash_filo.cc hostname.cc \ mysqld.cc password.c hash_filo.cc hostname.cc \
convert.cc sql_parse.cc sql_yacc.yy \ convert.cc sql_parse.cc sql_yacc.yy \
sql_base.cc table.cc sql_select.cc sql_insert.cc \ sql_base.cc table.cc sql_select.cc sql_insert.cc \
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <assert.h> #include <assert.h>
#include <hash.h> #include <hash.h>
#include "ha_berkeley.h" #include "ha_berkeley.h"
#include "sql_manager.h"
#define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */ #define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_BERKELEY_RANGE_COUNT 100 #define HA_BERKELEY_RANGE_COUNT 100
...@@ -87,6 +88,7 @@ static byte* bdb_get_key(BDB_SHARE *share,uint *length, ...@@ -87,6 +88,7 @@ static byte* bdb_get_key(BDB_SHARE *share,uint *length,
my_bool not_used __attribute__((unused))); my_bool not_used __attribute__((unused)));
static BDB_SHARE *get_share(const char *table_name); static BDB_SHARE *get_share(const char *table_name);
static void free_share(BDB_SHARE *share); static void free_share(BDB_SHARE *share);
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
/* General functions */ /* General functions */
...@@ -106,6 +108,7 @@ bool berkeley_init(void) ...@@ -106,6 +108,7 @@ bool berkeley_init(void)
DBUG_RETURN(1); DBUG_RETURN(1);
db_env->set_errcall(db_env,berkeley_print_error); db_env->set_errcall(db_env,berkeley_print_error);
db_env->set_errpfx(db_env,"bdb"); db_env->set_errpfx(db_env,"bdb");
db_env->set_noticecall(db_env, berkeley_noticecall);
db_env->set_tmp_dir(db_env, berkeley_tmpdir); db_env->set_tmp_dir(db_env, berkeley_tmpdir);
db_env->set_data_dir(db_env, mysql_data_home); db_env->set_data_dir(db_env, mysql_data_home);
if (berkeley_logdir) if (berkeley_logdir)
...@@ -120,6 +123,7 @@ bool berkeley_init(void) ...@@ -120,6 +123,7 @@ bool berkeley_init(void)
db_env->set_lk_detect(db_env, berkeley_lock_type); db_env->set_lk_detect(db_env, berkeley_lock_type);
if (berkeley_lock_max) if (berkeley_lock_max)
db_env->set_lk_max(db_env, berkeley_lock_max); db_env->set_lk_max(db_env, berkeley_lock_max);
if (db_env->open(db_env, if (db_env->open(db_env,
berkeley_home, berkeley_home,
berkeley_init_flags | DB_INIT_LOCK | berkeley_init_flags | DB_INIT_LOCK |
...@@ -129,6 +133,7 @@ bool berkeley_init(void) ...@@ -129,6 +133,7 @@ bool berkeley_init(void)
db_env->close(db_env,0); db_env->close(db_env,0);
db_env=0; db_env=0;
} }
(void) hash_init(&bdb_open_tables,32,0,0, (void) hash_init(&bdb_open_tables,32,0,0,
(hash_get_key) bdb_get_key,0,0); (hash_get_key) bdb_get_key,0,0);
pthread_mutex_init(&bdb_mutex,NULL); pthread_mutex_init(&bdb_mutex,NULL);
...@@ -196,6 +201,48 @@ static void berkeley_print_error(const char *db_errpfx, char *buffer) ...@@ -196,6 +201,48 @@ static void berkeley_print_error(const char *db_errpfx, char *buffer)
sql_print_error("%s: %s",db_errpfx,buffer); sql_print_error("%s: %s",db_errpfx,buffer);
} }
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice)
{
switch (notice)
{
case DB_NOTICE_LOGFILE_CHANGED:
pthread_mutex_lock(&LOCK_manager);
manager_status |= MANAGER_BERKELEY_LOG_CLEANUP;
pthread_mutex_unlock(&LOCK_manager);
pthread_cond_signal(&COND_manager);
break;
}
}
void berkeley_cleanup_log_files(void)
{
DBUG_ENTER("berkeley_cleanup_log_files");
char **names;
int error;
/* XXX: Probably this should be done somewhere else, and
* should be tunable by the user. */
if ((error = txn_checkpoint(db_env, 0, 0, 0)))
my_error(ER_ERROR_DURING_CHECKPOINT, MYF(0), error);
if ((error = log_archive(db_env, &names, DB_ARCH_ABS, NULL)) != 0)
{
DBUG_PRINT("error", ("log_archive failed (error %d)", error));
db_env->err(db_env, error, "log_archive: DB_ARCH_ABS");
DBUG_VOID_RETURN;
}
if (names)
{
char **np;
for (np = names; *np; ++np)
my_delete(*np, MYF(MY_WME));
free(names);
}
DBUG_VOID_RETURN;
}
/***************************************************************************** /*****************************************************************************
......
...@@ -419,6 +419,17 @@ int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list, ...@@ -419,6 +419,17 @@ int mysql_load(THD *thd,sql_exchange *ex, TABLE_LIST *table_list,
List<Item> &fields, enum enum_duplicates handle_duplicates, List<Item> &fields, enum enum_duplicates handle_duplicates,
bool local_file,thr_lock_type lock_type); bool local_file,thr_lock_type lock_type);
int write_record(TABLE *table,COPY_INFO *info); int write_record(TABLE *table,COPY_INFO *info);
/* sql_manager.cc */
/* bits set in manager_status */
#define MANAGER_BERKELEY_LOG_CLEANUP (1L << 0)
extern ulong manager_status;
extern bool volatile manager_thread_in_use;
extern pthread_t manager_thread;
extern pthread_mutex_t LOCK_manager;
extern pthread_cond_t COND_manager;
pthread_handler_decl(handle_manager, arg);
/* sql_test.cc */ /* sql_test.cc */
#ifndef DBUG_OFF #ifndef DBUG_OFF
void print_where(COND *cond,const char *info); void print_where(COND *cond,const char *info);
......
...@@ -154,7 +154,6 @@ static my_string opt_logname=0,opt_update_logname=0, ...@@ -154,7 +154,6 @@ static my_string opt_logname=0,opt_update_logname=0,
opt_binlog_index_name = 0,opt_slow_logname=0; opt_binlog_index_name = 0,opt_slow_logname=0;
static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
static pthread_t select_thread; static pthread_t select_thread;
static pthread_t flush_thread; // Used when debugging
static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4;
...@@ -213,7 +212,7 @@ ulong max_tmp_tables,max_heap_table_size; ...@@ -213,7 +212,7 @@ ulong max_tmp_tables,max_heap_table_size;
ulong bytes_sent = 0L, bytes_received = 0L; ulong bytes_sent = 0L, bytes_received = 0L;
bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
bool volatile abort_loop,select_thread_in_use,flush_thread_in_use,grant_option; bool volatile abort_loop,select_thread_in_use,grant_option;
bool volatile ready_to_exit,shutdown_in_progress; bool volatile ready_to_exit,shutdown_in_progress;
ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */ ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */
ulong query_id=1L,long_query_count,long_query_time,aborted_threads, ulong query_id=1L,long_query_count,long_query_time,aborted_threads,
...@@ -256,10 +255,10 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, ...@@ -256,10 +255,10 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_mapped_file, LOCK_status, LOCK_grant, LOCK_mapped_file, LOCK_status, LOCK_grant,
LOCK_error_log, LOCK_error_log,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_flush, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
LOCK_binlog_update, LOCK_slave, LOCK_server_id; LOCK_binlog_update, LOCK_slave, LOCK_server_id;
pthread_cond_t COND_refresh,COND_thread_count,COND_flush, COND_binlog_update, pthread_cond_t COND_refresh,COND_thread_count,COND_binlog_update,
COND_slave_stopped; COND_slave_stopped;
pthread_cond_t COND_thread_cache,COND_flush_thread_cache; pthread_cond_t COND_thread_cache,COND_flush_thread_cache;
pthread_t signal_thread; pthread_t signal_thread;
...@@ -288,7 +287,6 @@ static pthread_handler_decl(handle_connections_namedpipes,arg); ...@@ -288,7 +287,6 @@ static pthread_handler_decl(handle_connections_namedpipes,arg);
#ifdef __WIN__ #ifdef __WIN__
static int get_service_parameters(); static int get_service_parameters();
#endif #endif
static pthread_handler_decl(handle_flush,arg);
extern pthread_handler_decl(handle_slave,arg); extern pthread_handler_decl(handle_slave,arg);
#ifdef SET_RLIMIT_NOFILE #ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit); static uint set_maximum_open_files(uint max_file_limit);
...@@ -312,13 +310,13 @@ static void close_connections(void) ...@@ -312,13 +310,13 @@ static void close_connections(void)
flush_thread_cache(); flush_thread_cache();
/* kill flush thread */ /* kill flush thread */
(void) pthread_mutex_lock(&LOCK_flush); (void) pthread_mutex_lock(&LOCK_manager);
if (flush_thread_in_use) if (manager_thread_in_use)
{ {
DBUG_PRINT("quit",("killing flush thread: %lx",flush_thread)); DBUG_PRINT("quit",("killing manager thread: %lx",manager_thread));
(void) pthread_cond_signal(&COND_flush); (void) pthread_cond_signal(&COND_manager);
} }
(void) pthread_mutex_unlock(&LOCK_flush); (void) pthread_mutex_unlock(&LOCK_manager);
/* kill connection thread */ /* kill connection thread */
#if !defined(__WIN__) && !defined(__EMX__) #if !defined(__WIN__) && !defined(__EMX__)
...@@ -1396,8 +1394,8 @@ int main(int argc, char **argv) ...@@ -1396,8 +1394,8 @@ int main(int argc, char **argv)
(void) pthread_cond_init(&COND_refresh,NULL); (void) pthread_cond_init(&COND_refresh,NULL);
(void) pthread_cond_init(&COND_thread_cache,NULL); (void) pthread_cond_init(&COND_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush_thread_cache,NULL); (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
(void) pthread_cond_init(&COND_flush,NULL); (void) pthread_cond_init(&COND_manager,NULL);
(void) pthread_mutex_init(&LOCK_flush,NULL); (void) pthread_mutex_init(&LOCK_manager,NULL);
(void) pthread_mutex_init(&LOCK_crypt,NULL); (void) pthread_mutex_init(&LOCK_crypt,NULL);
(void) pthread_mutex_init(&LOCK_bytes_sent,NULL); (void) pthread_mutex_init(&LOCK_bytes_sent,NULL);
(void) pthread_mutex_init(&LOCK_bytes_received,NULL); (void) pthread_mutex_init(&LOCK_bytes_received,NULL);
...@@ -1604,11 +1602,15 @@ int main(int argc, char **argv) ...@@ -1604,11 +1602,15 @@ int main(int argc, char **argv)
} }
#endif #endif
if (flush_time && flush_time != ~(ulong) 0L) if ((flush_time && flush_time != ~(ulong) 0L)
#ifdef HAVE_BERKELEY_DB
|| !berkeley_skip
#endif
)
{ {
pthread_t hThread; pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_flush,0)) if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
sql_print_error("Warning: Can't create thread to handle flush"); sql_print_error("Warning: Can't create thread to manage maintenance");
} }
// slave thread // slave thread
...@@ -2159,41 +2161,6 @@ pthread_handler_decl(handle_connections_namedpipes,arg) ...@@ -2159,41 +2161,6 @@ pthread_handler_decl(handle_connections_namedpipes,arg)
} }
#endif /* __NT__ */ #endif /* __NT__ */
/****************************************************************************
** Create thread that automaticly flush all tables after a given time
****************************************************************************/
pthread_handler_decl(handle_flush,arg __attribute__((unused)))
{
my_thread_init();
DBUG_ENTER("handle_flush");
pthread_detach_this_thread();
flush_thread=pthread_self();
flush_thread_in_use=1;
pthread_mutex_lock(&LOCK_flush);
while (flush_time)
{
struct timespec abstime;
#ifdef HAVE_TIMESPEC_TS_SEC
abstime.ts_sec=time(NULL)+flush_time; // Bsd 2.1
abstime.ts_nsec=0;
#else
abstime.tv_sec=time(NULL)+flush_time; // Linux or Solairs
abstime.tv_nsec=0;
#endif
(void) pthread_cond_timedwait(&COND_flush,&LOCK_flush, &abstime);
if (abort_loop)
break;
flush_tables();
}
flush_thread_in_use=0;
pthread_mutex_unlock(&LOCK_flush);
my_thread_end();
DBUG_RETURN(0);
}
/****************************************************************************** /******************************************************************************
** handle start options ** handle start options
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 */
/*
* sql_manager.cc
* This thread manages various maintenance tasks.
*
* o Flushing the tables every flush_time seconds.
* o Berkeley DB: removing unneeded log files.
*/
#include "mysql_priv.h"
#include "sql_manager.h"
ulong manager_status;
bool volatile manager_thread_in_use;
pthread_t manager_thread;
pthread_mutex_t LOCK_manager;
pthread_cond_t COND_manager;
pthread_handler_decl(handle_manager,arg __attribute__((unused)))
{
int error = 0;
ulong status;
struct timespec abstime;
bool reset_flush_time = TRUE;
my_thread_init();
DBUG_ENTER("handle_manager");
pthread_detach_this_thread();
manager_thread = pthread_self();
manager_status = 0;
manager_thread_in_use = 1;
for (;;)
{
pthread_mutex_lock(&LOCK_manager);
/* XXX: This will need to be made more general to handle different
* polling needs. */
if (flush_time)
{
if (reset_flush_time)
{
#ifdef HAVE_TIMESPEC_TS_SEC
abstime.ts_sec = time(NULL)+flush_time; // Bsd 2.1
abstime.ts_nsec = 0;
#else
abstime.tv_sec = time(NULL)+flush_time; // Linux or Solairs
abstime.tv_nsec = 0;
#endif
reset_flush_time = FALSE;
}
while (!manager_status && !error && !abort_loop)
error = pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime);
}
else
while (!manager_status && !error && !abort_loop)
error = pthread_cond_wait(&COND_manager, &LOCK_manager);
status = manager_status;
manager_status = 0;
pthread_mutex_unlock(&LOCK_manager);
if (abort_loop)
break;
if (error) /* == ETIMEDOUT */
{
flush_tables();
error = 0;
reset_flush_time = TRUE;
}
#ifdef HAVE_BERKELEY_DB
if (status & MANAGER_BERKELEY_LOG_CLEANUP)
{
berkeley_cleanup_log_files();
status &= ~MANAGER_BERKELEY_LOG_CLEANUP;
}
#endif
if (status)
DBUG_PRINT("error", ("manager did not handle something: %lx", status));
}
manager_thread_in_use = 0;
my_thread_end();
DBUG_RETURN(NULL);
}
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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 */
#ifdef HAVE_BERKELEY_DB
void berkeley_cleanup_log_files(void);
#endif /* HAVE_BERKELEY_DB */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment