Commit ff18cf42 authored by unknown's avatar unknown

Max open files handling moved to my_set_max_open_files()

This ensures that my_file_info takes this the max number of files into account and one can now use --open-files-limit on windows to increase number of used files up to 2048


client/client_priv.h:
  Added --open-files-limit to mysqlbinlog
client/mysqlbinlog.cc:
  Added --open-files-limit to mysqlbinlog
include/config-win.h:
  Define that you can have up to 2048 files open on windows
include/my_global.h:
  Allow override of OS_FILE_LIMIT
include/my_sys.h:
  Cleanup
  Added prototypes for my_set_max_open_files() and my_free_open_files()
libmysql/Makefile.shared:
  Added my_file.c
myisam/myisamlog.c:
  Use my_set_max_open_files()
mysys/Makefile.am:
  Use my_file.c (for mysqlbinlog)
mysys/my_alloc.c:
  Remove compiler warning
mysys/my_div.c:
  MY_NFILE -> my_file_limit
mysys/my_dup.c:
  MY_NFILE -> my_file_limit
mysys/my_fopen.c:
  MY_NFILE -> my_file_limit
mysys/my_open.c:
  MY_NFILE -> my_file_limit
mysys/my_static.c:
  Allow changing of open files limit
mysys/my_static.h:
  Allow changing of open files limit
sql/mysqld.cc:
  Max open files handling moved to my_set_max_open_files()
parent fcb47f5a
...@@ -43,4 +43,5 @@ enum options_client ...@@ -43,4 +43,5 @@ enum options_client
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION,
OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH, OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH,
OPT_OPEN_FILES_LIMIT
}; };
...@@ -33,6 +33,7 @@ ulong server_id = 0; ...@@ -33,6 +33,7 @@ ulong server_id = 0;
// needed by net_serv.c // needed by net_serv.c
ulong bytes_sent = 0L, bytes_received = 0L; ulong bytes_sent = 0L, bytes_received = 0L;
ulong mysqld_net_retry_count = 10L; ulong mysqld_net_retry_count = 10L;
ulong open_files_limit;
uint test_flags = 0; uint test_flags = 0;
static uint opt_protocol= 0; static uint opt_protocol= 0;
static FILE *result_file; static FILE *result_file;
...@@ -68,7 +69,7 @@ static MYSQL* safe_connect(); ...@@ -68,7 +69,7 @@ static MYSQL* safe_connect();
class Load_log_processor class Load_log_processor
{ {
char target_dir_name[MY_NFILE]; char target_dir_name[FN_REFLEN];
int target_dir_name_len; int target_dir_name_len;
DYNAMIC_ARRAY file_names; DYNAMIC_ARRAY file_names;
...@@ -429,6 +430,10 @@ static struct my_option my_long_options[] = ...@@ -429,6 +430,10 @@ static struct my_option my_long_options[] =
{"read-from-remote-server", 'R', "Read binary logs from a MySQL server", {"read-from-remote-server", 'R', "Read binary logs from a MySQL server",
(gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, (gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0}, 0, 0},
{"open_files_limit", OPT_OPEN_FILES_LIMIT,
"Used to reserve file descriptors for usage by this program",
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
{"short-form", 's', "Just show the queries, no extra info.", {"short-form", 's', "Just show the queries, no extra info.",
(gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0}, 0, 0},
...@@ -878,6 +883,7 @@ int main(int argc, char** argv) ...@@ -878,6 +883,7 @@ int main(int argc, char** argv)
exit(1); exit(1);
} }
my_set_max_open_files(open_files_limit);
if (remote_opt) if (remote_opt)
mysql = safe_connect(); mysql = safe_connect();
...@@ -915,6 +921,7 @@ int main(int argc, char** argv) ...@@ -915,6 +921,7 @@ int main(int argc, char** argv)
mysql_close(mysql); mysql_close(mysql);
cleanup(); cleanup();
free_defaults(defaults_argv); free_defaults(defaults_argv);
my_free_open_file_info();
my_end(0); my_end(0);
exit(exit_value); exit(exit_value);
DBUG_RETURN(exit_value); // Keep compilers happy DBUG_RETURN(exit_value); // Keep compilers happy
......
...@@ -323,7 +323,7 @@ inline double ulonglong2double(ulonglong value) ...@@ -323,7 +323,7 @@ inline double ulonglong2double(ulonglong value)
#define FN_ROOTDIR "\\" #define FN_ROOTDIR "\\"
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */ #define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
#define FN_NO_CASE_SENCE /* Files are not case-sensitive */ #define FN_NO_CASE_SENCE /* Files are not case-sensitive */
#define MY_NFILE 1024 #define OS_FILE_LIMIT 2048
#define DO_NOT_REMOVE_THREAD_WRAPPERS #define DO_NOT_REMOVE_THREAD_WRAPPERS
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V)) #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
......
...@@ -535,7 +535,10 @@ typedef SOCKET_SIZE_TYPE size_socket; ...@@ -535,7 +535,10 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_LIBCHAR '/' #define FN_LIBCHAR '/'
#define FN_ROOTDIR "/" #define FN_ROOTDIR "/"
#endif #endif
#define MY_NFILE 1024 /* This is only used to save filenames */ #endif
#define MY_NFILE 64 /* This is only used to save filenames */
#ifndef OS_FILE_LIMIT
#define OS_FILE_LIMIT 65535
#endif #endif
/* #define EXT_IN_LIBNAME */ /* #define EXT_IN_LIBNAME */
......
...@@ -202,26 +202,13 @@ extern char NEAR curr_dir[]; /* Current directory for user */ ...@@ -202,26 +202,13 @@ extern char NEAR curr_dir[]; /* Current directory for user */
extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags); extern int (*error_handler_hook)(uint my_err, const char *str,myf MyFlags);
extern int (*fatal_error_handler_hook)(uint my_err, const char *str, extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
myf MyFlags); myf MyFlags);
extern uint my_file_limit;
/* charsets */ /* charsets */
extern CHARSET_INFO *default_charset_info; extern CHARSET_INFO *default_charset_info;
extern CHARSET_INFO *all_charsets[256]; extern CHARSET_INFO *all_charsets[256];
extern CHARSET_INFO compiled_charsets[]; extern CHARSET_INFO compiled_charsets[];
extern uint get_charset_number(const char *cs_name, uint cs_flags);
extern uint get_collation_number(const char *name);
extern const char *get_charset_name(uint cs_number);
extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
uint cs_flags, myf my_flags);
extern void free_charsets(void);
extern char *get_charsets_dir(char *buf);
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
extern my_bool init_compiled_charsets(myf flags);
extern void add_compiled_collation(CHARSET_INFO *cs);
/* statistics */ /* statistics */
extern ulong my_cache_w_requests, my_cache_write, my_cache_r_requests, extern ulong my_cache_w_requests, my_cache_write, my_cache_r_requests,
my_cache_read; my_cache_read;
...@@ -288,14 +275,16 @@ enum file_type ...@@ -288,14 +275,16 @@ enum file_type
FILE_BY_MKSTEMP, FILE_BY_DUP FILE_BY_MKSTEMP, FILE_BY_DUP
}; };
extern struct my_file_info struct st_my_file_info
{ {
my_string name; my_string name;
enum file_type type; enum file_type type;
#if defined(THREAD) && !defined(HAVE_PREAD) #if defined(THREAD) && !defined(HAVE_PREAD)
pthread_mutex_t mutex; pthread_mutex_t mutex;
#endif #endif
} my_file_info[MY_NFILE]; };
extern struct st_my_file_info *my_file_info;
typedef struct st_my_tmpdir typedef struct st_my_tmpdir
{ {
...@@ -747,6 +736,23 @@ extern uint my_bit_log2(ulong value); ...@@ -747,6 +736,23 @@ extern uint my_bit_log2(ulong value);
extern uint my_count_bits(ulonglong v); extern uint my_count_bits(ulonglong v);
extern void my_sleep(ulong m_seconds); extern void my_sleep(ulong m_seconds);
extern ulong crc32(ulong crc, const uchar *buf, uint len); extern ulong crc32(ulong crc, const uchar *buf, uint len);
extern uint my_set_max_open_files(uint files);
void my_free_open_file_info(void);
/* character sets */
extern uint get_charset_number(const char *cs_name, uint cs_flags);
extern uint get_collation_number(const char *name);
extern const char *get_charset_name(uint cs_number);
extern CHARSET_INFO *get_charset(uint cs_number, myf flags);
extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags);
extern CHARSET_INFO *get_charset_by_csname(const char *cs_name,
uint cs_flags, myf my_flags);
extern void free_charsets(void);
extern char *get_charsets_dir(char *buf);
extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2);
extern my_bool init_compiled_charsets(myf flags);
extern void add_compiled_collation(CHARSET_INFO *cs);
#ifdef __WIN__ #ifdef __WIN__
extern my_bool have_tcpip; /* Is set if tcpip is used */ extern my_bool have_tcpip; /* Is set if tcpip is used */
......
...@@ -50,7 +50,7 @@ mysysheaders = mysys_priv.h my_static.h ...@@ -50,7 +50,7 @@ mysysheaders = mysys_priv.h my_static.h
vioheaders = vio_priv.h vioheaders = vio_priv.h
mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \ my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
my_read.lo my_write.lo errors.lo \ my_file.lo my_read.lo my_write.lo errors.lo \
my_error.lo my_getwd.lo my_div.lo \ my_error.lo my_getwd.lo my_div.lo \
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\ mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \ mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
......
...@@ -60,7 +60,6 @@ static int file_info_compare(void *cmp_arg, void *a,void *b); ...@@ -60,7 +60,6 @@ static int file_info_compare(void *cmp_arg, void *a,void *b);
static int test_if_open(struct file_info *key,element_count count, static int test_if_open(struct file_info *key,element_count count,
struct test_if_open_param *param); struct test_if_open_param *param);
static void fix_blob_pointers(MI_INFO *isam,byte *record); static void fix_blob_pointers(MI_INFO *isam,byte *record);
static uint set_maximum_open_files(uint);
static int test_when_accessed(struct file_info *key,element_count count, static int test_when_accessed(struct file_info *key,element_count count,
struct st_access_param *access_param); struct st_access_param *access_param);
static void file_info_free(struct file_info *info); static void file_info_free(struct file_info *info);
...@@ -89,9 +88,8 @@ int main(int argc, char **argv) ...@@ -89,9 +88,8 @@ int main(int argc, char **argv)
log_filename=myisam_log_filename; log_filename=myisam_log_filename;
get_options(&argc,&argv); get_options(&argc,&argv);
/* Nr of isam-files */ /* Number of MyISAM files we can have open at one time */
max_files=(set_maximum_open_files(min(max_files,8))-6)/2; max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
if (update) if (update)
printf("Trying to %s MyISAM files according to log '%s'\n", printf("Trying to %s MyISAM files according to log '%s'\n",
(recover ? "recover" : "update"),log_filename); (recover ? "recover" : "update"),log_filename);
...@@ -123,6 +121,7 @@ int main(int argc, char **argv) ...@@ -123,6 +121,7 @@ int main(int argc, char **argv)
printf("Had to do %d re-open because of too few possibly open files\n", printf("Had to do %d re-open because of too few possibly open files\n",
re_open_count); re_open_count);
VOID(mi_panic(HA_PANIC_CLOSE)); VOID(mi_panic(HA_PANIC_CLOSE));
my_free_open_file_info();
my_end(test_info ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); my_end(test_info ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(error); exit(error);
return 0; /* No compiler warning */ return 0; /* No compiler warning */
...@@ -732,38 +731,6 @@ static void fix_blob_pointers(MI_INFO *info, byte *record) ...@@ -732,38 +731,6 @@ static void fix_blob_pointers(MI_INFO *info, byte *record)
} }
} }
static uint set_maximum_open_files(uint maximum_files)
{
#if defined(HAVE_GETRUSAGE) && defined(RLIMIT_NOFILE)
struct rlimit rlimit;
int old_max;
if (maximum_files > MY_NFILE)
maximum_files=MY_NFILE; /* Don't crash my_open */
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
{
old_max=rlimit.rlim_max;
if (maximum_files && (int) maximum_files > old_max)
rlimit.rlim_max=maximum_files;
rlimit.rlim_cur=rlimit.rlim_max;
if (setrlimit(RLIMIT_NOFILE,&rlimit))
{
if (old_max != (int) maximum_files)
{ /* Set as much as we can */
rlimit.rlim_max=rlimit.rlim_cur=old_max;
setrlimit(RLIMIT_NOFILE,&rlimit);
}
}
getrlimit(RLIMIT_NOFILE,&rlimit); /* Read if broken setrlimit */
if (maximum_files && maximum_files < rlimit.rlim_cur)
VOID(fprintf(stderr,"Warning: Error from setrlimit: Max open files is %d\n",old_max));
return rlimit.rlim_cur;
}
#endif
return min(maximum_files,MY_NFILE);
}
/* close the file with hasn't been accessed for the longest time */ /* close the file with hasn't been accessed for the longest time */
/* ARGSUSED */ /* ARGSUSED */
......
...@@ -25,8 +25,8 @@ noinst_HEADERS = mysys_priv.h my_static.h \ ...@@ -25,8 +25,8 @@ noinst_HEADERS = mysys_priv.h my_static.h \
my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \ my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \
my_os2dlfcn.c my_os2file64.c my_os2mutex.c \ my_os2dlfcn.c my_os2file64.c my_os2mutex.c \
my_os2thread.c my_os2tls.c my_os2thread.c my_os2tls.c
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c \
mf_path.c mf_loadpath.c\ mf_path.c mf_loadpath.c my_file.c \
my_open.c my_create.c my_dup.c my_seek.c my_read.c \ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
my_pread.c my_write.c \ my_pread.c my_write.c \
mf_keycache.c mf_keycaches.c my_crc32.c \ mf_keycache.c mf_keycaches.c my_crc32.c \
......
...@@ -68,7 +68,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size, ...@@ -68,7 +68,7 @@ void init_alloc_root(MEM_ROOT *mem_root, uint block_size,
*/ */
void reset_root_defaults(MEM_ROOT *mem_root, uint block_size, void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
uint pre_alloc_size) uint pre_alloc_size __attribute__((unused)))
{ {
mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8; mem_root->block_size= block_size-MALLOC_OVERHEAD-sizeof(USED_MEM)-8;
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG)) #if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
my_string my_filename(File fd) my_string my_filename(File fd)
{ {
DBUG_ENTER("my_filename"); DBUG_ENTER("my_filename");
if (fd >= MY_NFILE) if ((uint) fd >= (uint) my_file_limit)
DBUG_RETURN((char*) "UNKNOWN"); DBUG_RETURN((char*) "UNKNOWN");
if (fd >= 0 && my_file_info[fd].type != UNOPEN) if (fd >= 0 && my_file_info[fd].type != UNOPEN)
{ {
......
...@@ -32,7 +32,7 @@ File my_dup(File file, myf MyFlags) ...@@ -32,7 +32,7 @@ File my_dup(File file, myf MyFlags)
DBUG_ENTER("my_dup"); DBUG_ENTER("my_dup");
DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags)); DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags));
fd = dup(file); fd = dup(file);
filename= (((int) file < MY_NFILE) ? filename= (((uint) file < my_file_limit) ?
my_file_info[(int) file].name : "Unknown"); my_file_info[(int) file].name : "Unknown");
DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP, DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
EE_FILENOTFOUND, MyFlags)); EE_FILENOTFOUND, MyFlags));
......
/* 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 */
#include "mysys_priv.h"
#include "my_static.h"
#include <m_string.h>
/*
set how many open files we want to be able to handle
SYNOPSIS
set_maximum_open_files()
max_file_limit Files to open
NOTES
The request may not fulfilled becasue of system limitations
RETURN
Files available to open.
May be more or less than max_file_limit!
*/
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
#ifndef RLIM_INFINITY
#define RLIM_INFINITY ((uint) 0xffffffff)
#endif
static uint set_max_open_files(uint max_file_limit)
{
struct rlimit rlimit;
uint old_cur;
DBUG_ENTER("set_max_open_files");
DBUG_PRINT("enter",("files: %u", max_file_limit));
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
{
old_cur= (uint) rlimit.rlim_cur;
DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
(uint) rlimit.rlim_cur,
(uint) rlimit.rlim_max));
if (rlimit.rlim_cur == RLIM_INFINITY)
rlimit.rlim_cur = max_file_limit;
if (rlimit.rlim_cur >= max_file_limit)
DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
if (setrlimit(RLIMIT_NOFILE, &rlimit))
max_file_limit= old_cur; /* Use original value */
else
{
rlimit.rlim_cur= 0; /* Safety if next call fails */
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
if (rlimit.rlim_cur) /* If call didn't fail */
max_file_limit= (uint) rlimit.rlim_cur;
}
}
DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
DBUG_RETURN(max_file_limit);
}
#elif defined (OS2)
static uint set_max_open_files(uint max_file_limit)
{
LONG cbReqCount;
ULONG cbCurMaxFH0;
APIRET ulrc;
DBUG_ENTER("set_max_open_files");
/* get current limit */
cbReqCount = 0;
DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH0);
/* set new limit */
if ((cbReqCount = max_file_limit - cbCurMaxFH0) > 0)
ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH);
DBUG_RETURN(cbCurMaxFH0);
}
#else
static int set_max_open_files(uint max_file_limit)
{
/* We don't know the limit. Return best guess */
return min(max_file_limit, OS_FILE_LIMIT);
}
#endif
/*
Change number of open files
SYNOPSIS:
my_set_max_open_files()
files Number of requested files
RETURN
number of files available for open
*/
uint my_set_max_open_files(uint files)
{
struct st_my_file_info *tmp;
DBUG_ENTER("my_set_max_open_files");
DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
files= set_max_open_files(min(files, OS_FILE_LIMIT));
if (files <= MY_NFILE)
DBUG_RETURN(files);
if (!(tmp= (struct st_my_file_info*) my_malloc(sizeof(*tmp) * files,
MYF(MY_WME))))
DBUG_RETURN(MY_NFILE);
/* Copy any initialized files */
memcpy((char*) tmp, (char*) my_file_info, sizeof(*tmp) * my_file_limit);
my_free_open_file_info(); /* Free if already allocated */
my_file_info= tmp;
my_file_limit= files;
DBUG_PRINT("exit",("files: %u", files));
DBUG_RETURN(files);
}
void my_free_open_file_info()
{
DBUG_ENTER("my_free_file_info");
if (my_file_info != my_file_info_default)
{
my_free((char*) my_file_info, MYF(0));
my_file_info= my_file_info_default;
}
DBUG_VOID_RETURN;
}
...@@ -42,7 +42,7 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags) ...@@ -42,7 +42,7 @@ FILE *my_fopen(const char *FileName, int Flags, myf MyFlags)
on some OS (SUNOS). Actually the filename save isn't that important on some OS (SUNOS). Actually the filename save isn't that important
so we can ignore if this doesn't work. so we can ignore if this doesn't work.
*/ */
if ((uint) fileno(fd) >= MY_NFILE) if ((uint) fileno(fd) >= my_file_limit)
{ {
thread_safe_increment(my_stream_opened,&THR_LOCK_open); thread_safe_increment(my_stream_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */ DBUG_RETURN(fd); /* safeguard */
...@@ -91,7 +91,7 @@ int my_fclose(FILE *fd, myf MyFlags) ...@@ -91,7 +91,7 @@ int my_fclose(FILE *fd, myf MyFlags)
} }
else else
my_stream_opened--; my_stream_opened--;
if ((uint) file < MY_NFILE && my_file_info[file].type != UNOPEN) if ((uint) file < my_file_limit && my_file_info[file].type != UNOPEN)
{ {
my_file_info[file].type = UNOPEN; my_file_info[file].type = UNOPEN;
my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR)); my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR));
...@@ -123,11 +123,11 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) ...@@ -123,11 +123,11 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
{ {
pthread_mutex_lock(&THR_LOCK_open); pthread_mutex_lock(&THR_LOCK_open);
my_stream_opened++; my_stream_opened++;
if (Filedes < MY_NFILE) if ((uint) Filedes < (uint) my_file_limit)
{ {
if (my_file_info[Filedes].type != UNOPEN) if (my_file_info[Filedes].type != UNOPEN)
{ {
my_file_opened--; /* File is opened with my_open ! */ my_file_opened--; /* File is opened with my_open ! */
} }
else else
{ {
......
...@@ -86,7 +86,7 @@ int my_close(File fd, myf MyFlags) ...@@ -86,7 +86,7 @@ int my_close(File fd, myf MyFlags)
if (MyFlags & (MY_FAE | MY_WME)) if (MyFlags & (MY_FAE | MY_WME))
my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno); my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);
} }
if ((uint) fd < MY_NFILE && my_file_info[fd].type != UNOPEN) if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
{ {
my_free(my_file_info[fd].name, MYF(0)); my_free(my_file_info[fd].name, MYF(0));
#if defined(THREAD) && !defined(HAVE_PREAD) #if defined(THREAD) && !defined(HAVE_PREAD)
...@@ -115,7 +115,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type ...@@ -115,7 +115,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type
{ {
if ((int) fd >= 0) if ((int) fd >= 0)
{ {
if ((int) fd >= MY_NFILE) if ((uint) fd >= my_file_limit)
{ {
#if defined(THREAD) && !defined(HAVE_PREAD) #if defined(THREAD) && !defined(HAVE_PREAD)
(void) my_close(fd,MyFlags); (void) my_close(fd,MyFlags);
......
...@@ -34,7 +34,9 @@ int NEAR my_umask=0664, NEAR my_umask_dir=0777; ...@@ -34,7 +34,9 @@ int NEAR my_umask=0664, NEAR my_umask_dir=0777;
#ifndef THREAD #ifndef THREAD
int NEAR my_errno=0; int NEAR my_errno=0;
#endif #endif
struct my_file_info my_file_info[MY_NFILE]= {{0,UNOPEN}}; struct st_my_file_info my_file_info_default[MY_NFILE]= {{0,UNOPEN}};
uint my_file_limit= MY_NFILE;
struct st_my_file_info *my_file_info= my_file_info_default;
/* From mf_brkhant */ /* From mf_brkhant */
int NEAR my_dont_interrupt=0; int NEAR my_dont_interrupt=0;
......
...@@ -68,6 +68,8 @@ extern byte *sf_min_adress,*sf_max_adress; ...@@ -68,6 +68,8 @@ extern byte *sf_min_adress,*sf_max_adress;
extern uint sf_malloc_count; extern uint sf_malloc_count;
extern struct st_irem *sf_malloc_root; extern struct st_irem *sf_malloc_root;
extern struct st_my_file_info my_file_info_default[MY_NFILE];
#if defined(THREAD) && !defined(__WIN__) #if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */ extern sigset_t my_signals; /* signals blocked by mf_brkhant */
#endif #endif
...@@ -183,9 +183,6 @@ inline void reset_floating_point_exceptions() ...@@ -183,9 +183,6 @@ inline void reset_floating_point_exceptions()
#else #else
#include <my_pthread.h> // For thr_setconcurency() #include <my_pthread.h> // For thr_setconcurency()
#endif #endif
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
#define SET_RLIMIT_NOFILE
#endif
#ifdef SOLARIS #ifdef SOLARIS
extern "C" int gethostname(char *name, int namelen); extern "C" int gethostname(char *name, int namelen);
...@@ -492,9 +489,6 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg); ...@@ -492,9 +489,6 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg);
static pthread_handler_decl(handle_connections_shared_memory,arg); static pthread_handler_decl(handle_connections_shared_memory,arg);
#endif #endif
extern "C" pthread_handler_decl(handle_slave,arg); extern "C" pthread_handler_decl(handle_slave,arg);
#ifdef SET_RLIMIT_NOFILE
static uint set_maximum_open_files(uint max_file_limit);
#endif
static ulong find_bit_type(const char *x, TYPELIB *bit_lib); static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
static void clean_up(bool print_message); static void clean_up(bool print_message);
static void clean_up_mutexes(void); static void clean_up_mutexes(void);
...@@ -919,6 +913,7 @@ void clean_up(bool print_message) ...@@ -919,6 +913,7 @@ void clean_up(bool print_message)
#ifdef USE_RAID #ifdef USE_RAID
end_raid(); end_raid();
#endif #endif
my_free_open_file_info();
my_free((char*) global_system_variables.date_format, my_free((char*) global_system_variables.date_format,
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) global_system_variables.time_format, my_free((char*) global_system_variables.time_format,
...@@ -2108,28 +2103,32 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -2108,28 +2103,32 @@ static int init_common_variables(const char *conf_file_name, int argc,
DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname, DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
server_version, SYSTEM_TYPE,MACHINE_TYPE)); server_version, SYSTEM_TYPE,MACHINE_TYPE));
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
/* connections and databases needs lots of files */ /* connections and databases needs lots of files */
{ {
uint wanted_files=10+(uint) max(max_connections*5, uint files, wanted_files;
max_connections+table_cache_size*2);
wanted_files= 10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
set_if_bigger(wanted_files, open_files_limit); set_if_bigger(wanted_files, open_files_limit);
// Note that some system returns 0 if we succeed here: files= my_set_max_open_files(wanted_files);
uint files=set_maximum_open_files(wanted_files);
if (files && files < wanted_files && ! open_files_limit) if (files < wanted_files)
{ {
max_connections= (ulong) min((files-10),max_connections); if (!open_files_limit)
table_cache_size= (ulong) max((files-10-max_connections)/2,64); {
DBUG_PRINT("warning", max_connections= (ulong) min((files-10),max_connections);
("Changed limits: max_connections: %ld table_cache: %ld", table_cache_size= (ulong) max((files-10-max_connections)/2,64);
max_connections,table_cache_size)); DBUG_PRINT("warning",
sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size); ("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
files, max_connections, table_cache_size));
sql_print_error("Warning: Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
files, max_connections, table_cache_size);
}
else
sql_print_error("Warning: Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
} }
open_files_limit= files; open_files_limit= files;
} }
#else
open_files_limit= 0; /* Can't set or detect limit */
#endif
unireg_init(opt_specialflag); /* Set up extern variabels */ unireg_init(opt_specialflag); /* Set up extern variabels */
if (init_errmessage()) /* Read error messages from file */ if (init_errmessage()) /* Read error messages from file */
return 1; return 1;
...@@ -4506,7 +4505,7 @@ The minimum value for this variable is 4096.", ...@@ -4506,7 +4505,7 @@ The minimum value for this variable is 4096.",
{"open_files_limit", OPT_OPEN_FILES_LIMIT, {"open_files_limit", OPT_OPEN_FILES_LIMIT,
"If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.", "If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of files.",
(gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG, (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, 65535, 0, 1, 0}, REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE, {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes", "The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size, (gptr*) &global_system_variables.preload_buff_size,
...@@ -5812,95 +5811,6 @@ static void fix_paths(void) ...@@ -5812,95 +5811,6 @@ static void fix_paths(void)
} }
/*
set how many open files we want to be able to handle
SYNOPSIS
set_maximum_open_files()
max_file_limit Files to open
NOTES
The request may not fulfilled becasue of system limitations
RETURN
Files available to open
*/
#ifdef SET_RLIMIT_NOFILE
#ifndef RLIM_INFINITY
#define RLIM_INFINITY ((uint) 0xffffffff)
#endif
static uint set_maximum_open_files(uint max_file_limit)
{
struct rlimit rlimit;
uint old_cur;
DBUG_ENTER("set_maximum_open_files");
DBUG_PRINT("enter",("files: %u", max_file_limit));
if (!getrlimit(RLIMIT_NOFILE,&rlimit))
{
old_cur= (uint) rlimit.rlim_cur;
DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
(uint) rlimit.rlim_cur,
(uint) rlimit.rlim_max));
if (rlimit.rlim_cur >= max_file_limit ||
rlimit.rlim_cur == RLIM_INFINITY)
DBUG_RETURN(rlimit.rlim_cur); /* purecov: inspected */
rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
if (setrlimit(RLIMIT_NOFILE,&rlimit))
{
if (global_system_variables.log_warnings)
sql_print_error("Warning: setrlimit couldn't increase number of open files to more than %u (request: %u)",
old_cur, max_file_limit); /* purecov: inspected */
max_file_limit= old_cur;
}
else
{
rlimit.rlim_cur= 0; // Safety if next call fails
(void) getrlimit(RLIMIT_NOFILE,&rlimit);
DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
if ((uint) rlimit.rlim_cur < max_file_limit &&
global_system_variables.log_warnings)
sql_print_error("Warning: setrlimit returned ok, but didn't change limits. Max open files is %u (request: %u)",
(uint) rlimit.rlim_cur,
max_file_limit); /* purecov: inspected */
max_file_limit= (uint) rlimit.rlim_cur;
}
}
DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
DBUG_RETURN(max_file_limit);
}
#endif
#ifdef OS2
static uint set_maximum_open_files(uint max_file_limit)
{
LONG cbReqCount;
ULONG cbCurMaxFH, cbCurMaxFH0;
APIRET ulrc;
DBUG_ENTER("set_maximum_open_files");
// get current limit
cbReqCount = 0;
DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH0);
// set new limit
cbReqCount = max_file_limit - cbCurMaxFH0;
ulrc = DosSetRelMaxFH( &cbReqCount, &cbCurMaxFH);
if (ulrc) {
sql_print_error("Warning: DosSetRelMaxFH couldn't increase number of open files to more than %d",
cbCurMaxFH0);
cbCurMaxFH = cbCurMaxFH0;
}
DBUG_RETURN(cbCurMaxFH);
}
#endif
/* /*
Return a bitfield from a string of substrings separated by ',' Return a bitfield from a string of substrings separated by ','
returns ~(ulong) 0 on error. returns ~(ulong) 0 on error.
......
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