Commit 6226e45b authored by unknown's avatar unknown

Merge abotchkov@bk-internal.mysql.com:/home/bk/mysql-4.1

into deer.(none):/home/hf/work/mysql-4.1.2237

parents 3711e24a 2b5020e1
......@@ -43,4 +43,5 @@ enum options_client
OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL,
OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION,
OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH,
OPT_OPEN_FILES_LIMIT
};
......@@ -33,6 +33,7 @@ ulong server_id = 0;
// needed by net_serv.c
ulong bytes_sent = 0L, bytes_received = 0L;
ulong mysqld_net_retry_count = 10L;
ulong open_files_limit;
uint test_flags = 0;
static uint opt_protocol= 0;
static FILE *result_file;
......@@ -68,7 +69,7 @@ static MYSQL* safe_connect();
class Load_log_processor
{
char target_dir_name[MY_NFILE];
char target_dir_name[FN_REFLEN];
int target_dir_name_len;
DYNAMIC_ARRAY file_names;
......@@ -429,6 +430,10 @@ static struct my_option my_long_options[] =
{"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,
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.",
(gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
......@@ -878,6 +883,7 @@ int main(int argc, char** argv)
exit(1);
}
my_set_max_open_files(open_files_limit);
if (remote_opt)
mysql = safe_connect();
......@@ -915,6 +921,7 @@ int main(int argc, char** argv)
mysql_close(mysql);
cleanup();
free_defaults(defaults_argv);
my_free_open_file_info();
my_end(0);
exit(exit_value);
DBUG_RETURN(exit_value); // Keep compilers happy
......
......@@ -323,7 +323,7 @@ inline double ulonglong2double(ulonglong value)
#define FN_ROOTDIR "\\"
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
#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 thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
......
......@@ -535,7 +535,10 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_LIBCHAR '/'
#define FN_ROOTDIR "/"
#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
/* #define EXT_IN_LIBNAME */
......
......@@ -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 (*fatal_error_handler_hook)(uint my_err, const char *str,
myf MyFlags);
extern uint my_file_limit;
/* charsets */
extern CHARSET_INFO *default_charset_info;
extern CHARSET_INFO *all_charsets[256];
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 */
extern ulong my_cache_w_requests, my_cache_write, my_cache_r_requests,
my_cache_read;
......@@ -288,14 +275,16 @@ enum file_type
FILE_BY_MKSTEMP, FILE_BY_DUP
};
extern struct my_file_info
struct st_my_file_info
{
my_string name;
enum file_type type;
#if defined(THREAD) && !defined(HAVE_PREAD)
pthread_mutex_t mutex;
#endif
} my_file_info[MY_NFILE];
};
extern struct st_my_file_info *my_file_info;
typedef struct st_my_tmpdir
{
......@@ -747,6 +736,23 @@ extern uint my_bit_log2(ulong value);
extern uint my_count_bits(ulonglong v);
extern void my_sleep(ulong m_seconds);
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__
extern my_bool have_tcpip; /* Is set if tcpip is used */
......
......@@ -12,6 +12,13 @@ Created 1/16/1996 Heikki Tuuri
#include "data0type.ic"
#endif
/* At the database startup we store the default-charset collation number of
this MySQL installation to this global variable. If we have < 4.1.2 format
column definitions, or records in the insert buffer, we use this
charset-collation code for them. */
ulint data_mysql_default_charset_coll = 99999999;
dtype_t dtype_binary_val = {DATA_BINARY, 0, 0, 0, 0};
dtype_t* dtype_binary = &dtype_binary_val;
......
......@@ -1315,7 +1315,7 @@ loop:
if (error == DB_DUPLICATE_KEY) {
mutex_enter(&dict_foreign_err_mutex);
ut_sprintf_timestamp(dict_foreign_err_buf);
ut_sprintf_timestamp(ebuf);
sprintf(ebuf + strlen(ebuf),
" Error in foreign key constraint creation for table %.500s.\n"
"A foreign key constraint of name %.500s\n"
......
......@@ -360,6 +360,15 @@ dict_load_columns(
field = rec_get_nth_field(rec, 6, &len);
prtype = mach_read_from_4(field);
if (dtype_is_non_binary_string_type(mtype, prtype)
&& dtype_get_charset_coll(prtype) == 0) {
/* This is a non-binary string type, and the table
was created with < 4.1.2. Use the default charset. */
prtype = dtype_form_prtype(prtype,
data_mysql_default_charset_coll);
}
field = rec_get_nth_field(rec, 7, &len);
col_len = mach_read_from_4(field);
......
......@@ -11,6 +11,8 @@ Created 1/16/1996 Heikki Tuuri
#include "univ.i"
extern ulint data_mysql_default_charset_coll;
/* SQL data type struct */
typedef struct dtype_struct dtype_t;
......@@ -18,31 +20,62 @@ typedef struct dtype_struct dtype_t;
data type */
extern dtype_t* dtype_binary;
/* Data main types of SQL data */
#define DATA_VARCHAR 1 /* character varying */
#define DATA_CHAR 2 /* fixed length character */
/*-------------------------------------------*/
/* The 'MAIN TYPE' of a column */
#define DATA_VARCHAR 1 /* character varying of the
latin1_swedish_ci charset-collation */
#define DATA_CHAR 2 /* fixed length character of the
latin1_swedish_ci charset-collation */
#define DATA_FIXBINARY 3 /* binary string of fixed length */
#define DATA_BINARY 4 /* binary string */
#define DATA_BLOB 5 /* binary large object, or a TEXT type; if
prtype & DATA_NONLATIN1 != 0 the data must
be compared by MySQL as a whole field; if
prtype & DATA_BINARY_TYPE == 0, then this is
actually a TEXT column */
#define DATA_BLOB 5 /* binary large object, or a TEXT type;
if prtype & DATA_BINARY_TYPE == 0, then this is
actually a TEXT column; see also below about
the flag DATA_NONLATIN1 */
#define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */
#define DATA_SYS_CHILD 7 /* address of the child page in node pointer */
#define DATA_SYS 8 /* system column */
/* Data types >= DATA_FLOAT must be compared using the whole field, not as
binary strings */
#define DATA_FLOAT 9
#define DATA_DOUBLE 10
#define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */
#define DATA_VARMYSQL 12 /* non-latin1 varying length char */
#define DATA_MYSQL 13 /* non-latin1 fixed length char */
#define DATA_VARMYSQL 12 /* any charset varying length char */
#define DATA_MYSQL 13 /* any charset fixed length char */
/* NOTE that 4.1.1 used DATA_MYSQL and
DATA_VARMYSQL for all character sets, and the
charset-collation for tables created with it
can also be latin1_swedish_ci */
#define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size()
requires the values are <= 63 */
/*-------------------------------------------*/
/* In the lowest byte in the precise type we store the MySQL type code
(not applicable for system columns). */
/* The 'PRECISE TYPE' of a column */
/*
Tables created by a MySQL user have the following convention:
- In the least significant byte in the precise type we store the MySQL type
code (not applicable for system columns).
- In the second least significant byte we OR flags DATA_NOT_NULL,
DATA_UNSIGNED, DATA_BINARY_TYPE, DATA_NONLATIN1.
- In the third least significant byte of the precise type of string types we
store the MySQL charset-collation code. In DATA_BLOB columns created with
< 4.0.14 we do not actually know if it is a BLOB or a TEXT column. Since there
are no indexes on prefixes of BLOB or TEXT columns in < 4.0.14, this is no
problem, though.
Note that versions < 4.1.2 or < 5.0.1 did not store the charset code to the
precise type, since the charset was always the default charset of the MySQL
installation. If the stored charset code is 0 in the system table SYS_COLUMNS
of InnoDB, that means that the default charset of this MySQL installation
should be used.
InnoDB's own internal system tables have different precise types for their
columns, and for them the precise type is usually not used at all.
*/
#define DATA_ENGLISH 4 /* English language character string: this
is a relic from pre-MySQL time and only used
......@@ -69,7 +102,7 @@ be less than 256 */
#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
compressed dulint form) */
#define DATA_N_SYS_COLS 4 /* number of system columns defined above */
/*-------------------------------------------*/
/* Flags ORed to the precise data type */
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when
the column is declared as NOT NULL */
......@@ -79,19 +112,57 @@ be less than 256 */
string, this is ORed to the precise type:
this only holds for tables created with
>= MySQL-4.0.14 */
#define DATA_NONLATIN1 2048 /* if the data type is a DATA_BLOB (actually
TEXT) of a non-latin1 type, this is ORed to
the precise type: this only holds for tables
created with >= MySQL-4.0.14 */
#define DATA_NONLATIN1 2048 /* If the data type is DATA_BLOB with
the prtype & DATA_BINARY_TYPE == 0, that is,
TEXT, then in versions 4.0.14 - 4.0.xx this
flag is set to 1, if the charset is not
latin1. In version 4.1.1 this was set
to 1 for all TEXT columns. In versions >= 4.1.2
this is set to 1 if the charset-collation of a
TEXT column is not latin1_swedish_ci. */
/*-------------------------------------------*/
/* This many bytes we need to store the type information affecting the
alphabetical order for a single field and decide the storage size of an
SQL null*/
#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4
/* In the >= 4.1.x storage format we need 2 bytes more for the charset */
#define DATA_ORDER_NULL_TYPE_BUF_SIZE 4
/* In the >= 4.1.x storage format we add 2 bytes more so that we can also
store the charset-collation number; one byte is left unused, though */
#define DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE 6
/*************************************************************************
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
UNIV_INLINE
ibool
dtype_is_string_type(
/*=================*/
/* out: TRUE if string type */
ulint mtype); /* in: InnoDB main data type code: DATA_CHAR, ... */
/*************************************************************************
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE. */
UNIV_INLINE
ibool
dtype_is_binary_string_type(
/*========================*/
/* out: TRUE if binary string type */
ulint mtype, /* in: main data type */
ulint prtype);/* in: precise type */
/*************************************************************************
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns TRUE. */
UNIV_INLINE
ibool
dtype_is_non_binary_string_type(
/*============================*/
/* out: TRUE if non-binary string type */
ulint mtype, /* in: main data type */
ulint prtype);/* in: precise type */
/*************************************************************************
Sets a data type structure. */
UNIV_INLINE
......@@ -126,6 +197,22 @@ dtype_get_prtype(
/*=============*/
dtype_t* type);
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
ulint prtype);/* in: precise data type */
/*************************************************************************
Forms a precise type from the < 4.1.2 format precise type plus the
charset-collation code. */
ulint
dtype_form_prtype(
/*==============*/
ulint old_prtype, /* in: the MySQL type code and the flags
DATA_NONLATIN1 etc. */
ulint charset_coll); /* in: MySQL charset-collation code */
/*************************************************************************
Gets the type length. */
UNIV_INLINE
ulint
......@@ -225,9 +312,8 @@ dtype_print(
struct dtype_struct{
ulint mtype; /* main data type */
ulint prtype; /* precise type; MySQL data type */
ulint chrset; /* MySQL character set code */
/* remaining two fields do not affect alphabetical ordering: */
/* the remaining two fields do not affect alphabetical ordering: */
ulint len; /* length */
ulint prec; /* precision */
......
......@@ -8,6 +8,70 @@ Created 1/16/1996 Heikki Tuuri
#include "mach0data.h"
/*************************************************************************
Checks if a data main type is a string type. Also a BLOB is considered a
string type. */
ibool
dtype_is_string_type(
/*=================*/
/* out: TRUE if string type */
ulint mtype) /* in: InnoDB main data type code: DATA_CHAR, ... */
{
if (mtype <= DATA_BLOB
|| mtype == DATA_MYSQL
|| mtype == DATA_VARMYSQL) {
return(TRUE);
}
return(FALSE);
}
/*************************************************************************
Checks if a type is a binary string type. Note that for tables created with
< 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column. For
those DATA_BLOB columns this function currently returns FALSE. */
UNIV_INLINE
ibool
dtype_is_binary_string_type(
/*========================*/
/* out: TRUE if binary string type */
ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */
{
if ((mtype == DATA_FIXBINARY)
|| (mtype == DATA_BINARY)
|| (mtype == DATA_BLOB && (prtype & DATA_BINARY_TYPE))) {
return(TRUE);
}
return(FALSE);
}
/*************************************************************************
Checks if a type is a non-binary string type. That is, dtype_is_string_type is
TRUE and dtype_is_binary_string_type is FALSE. Note that for tables created
with < 4.0.14, we do not know if a DATA_BLOB column is a BLOB or a TEXT column.
For those DATA_BLOB columns this function currently returns TRUE. */
UNIV_INLINE
ibool
dtype_is_non_binary_string_type(
/*============================*/
/* out: TRUE if non-binary string type */
ulint mtype, /* in: main data type */
ulint prtype) /* in: precise type */
{
if (dtype_is_string_type(mtype) == TRUE
&& dtype_is_binary_string_type(mtype, prtype) == FALSE) {
return(TRUE);
}
return(FALSE);
}
/*************************************************************************
Sets a data type structure. */
UNIV_INLINE
......@@ -27,7 +91,6 @@ dtype_set(
type->prtype = prtype;
type->len = len;
type->prec = prec;
type->chrset = 0;
ut_ad(dtype_validate(type));
}
......@@ -72,6 +135,33 @@ dtype_get_prtype(
return(type->prtype);
}
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
UNIV_INLINE
ulint
dtype_get_charset_coll(
/*===================*/
ulint prtype) /* in: precise data type */
{
return((prtype >> 16) & 0xFF);
}
/*************************************************************************
Forms a precise type from the < 4.1.2 format precise type plus the
charset-collation code. */
ulint
dtype_form_prtype(
/*==============*/
ulint old_prtype, /* in: the MySQL type code and the flags
DATA_NONLATIN1 etc. */
ulint charset_coll) /* in: MySQL charset-collation code */
{
ut_a(old_prtype < 256 * 256);
ut_a(charset_coll < 256);
return(old_prtype + (charset_coll << 16));
}
/*************************************************************************
Gets the type length. */
UNIV_INLINE
......@@ -155,12 +245,16 @@ dtype_new_store_for_order_and_null_size(
mach_write_to_2(buf + 2, type->len & 0xFFFFUL);
mach_write_to_2(buf + 4, type->chrset & 0xFFFFUL);
mach_write_to_2(buf + 4, dtype_get_charset_coll(type->prtype));
/* Note that the second last byte is left unused, because the
charset-collation code is always < 256 */
}
/**************************************************************************
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
ordering and the storage size of an SQL NULL value. This is the < 4.1.x
storage format. */
UNIV_INLINE
void
dtype_read_for_order_and_null_size(
......@@ -182,12 +276,15 @@ dtype_read_for_order_and_null_size(
}
type->len = mach_read_from_2(buf + 2);
type->prtype = dtype_form_prtype(type->prtype,
data_mysql_default_charset_coll);
}
/**************************************************************************
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. This is the 4.1.x storage
format. */
ordering and the storage size of an SQL NULL value. This is the >= 4.1.x
storage format. */
UNIV_INLINE
void
dtype_new_read_for_order_and_null_size(
......@@ -195,6 +292,8 @@ dtype_new_read_for_order_and_null_size(
dtype_t* type, /* in: type struct */
byte* buf) /* in: buffer for stored type order info */
{
ulint charset_coll;
ut_ad(6 == DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
type->mtype = buf[0] & 63;
......@@ -210,8 +309,26 @@ dtype_new_read_for_order_and_null_size(
type->len = mach_read_from_2(buf + 2);
type->chrset = mach_read_from_2(buf + 4);
}
mach_read_from_2(buf + 4);
charset_coll = mach_read_from_2(buf + 4);
if (dtype_is_string_type(type->mtype)) {
ut_a(charset_coll < 256);
if (charset_coll == 0) {
/* This insert buffer record was inserted with MySQL
version < 4.1.2, and the charset-collation code was not
explicitly stored to dtype->prtype at that time. It
must be the default charset-collation of this MySQL
installation. */
charset_coll = data_mysql_default_charset_coll;
}
type->prtype = dtype_form_prtype(type->prtype, charset_coll);
}
}
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
......
......@@ -61,10 +61,11 @@ must be a copy of the the one in ha_innobase.cc! */
int
innobase_mysql_cmp(
/*===============*/
/*===============*/
/* out: 1, 0, -1, if a is greater,
equal, less than b, respectively */
int mysql_type, /* in: MySQL type */
int mysql_type, /* in: MySQL type */
uint charset_number, /* in: number of the charset */
unsigned char* a, /* in: data field */
unsigned int a_length, /* in: data field length,
not UNIV_SQL_NULL */
......@@ -97,16 +98,28 @@ cmp_types_are_equal(
dtype_t* type1, /* in: type 1 */
dtype_t* type2) /* in: type 2 */
{
if ((type1->mtype == DATA_VARCHAR && type2->mtype == DATA_CHAR)
|| (type1->mtype == DATA_CHAR && type2->mtype == DATA_VARCHAR)
|| (type1->mtype == DATA_FIXBINARY && type2->mtype == DATA_BINARY)
|| (type1->mtype == DATA_BINARY && type2->mtype == DATA_FIXBINARY)
|| (type1->mtype == DATA_MYSQL && type2->mtype == DATA_VARMYSQL)
|| (type1->mtype == DATA_VARMYSQL && type2->mtype == DATA_MYSQL)) {
return(TRUE);
if (dtype_is_non_binary_string_type(type1->mtype, type1->prtype)
&& dtype_is_non_binary_string_type(type2->mtype, type2->prtype)) {
/* Both are non-binary string types: they can be compared if
and only if the charset-collation is the same */
if (dtype_get_charset_coll(type1->prtype)
== dtype_get_charset_coll(type2->prtype)) {
return(TRUE);
}
return(FALSE);
}
if (dtype_is_binary_string_type(type1->mtype, type1->prtype)
&& dtype_is_binary_string_type(type2->mtype, type2->prtype)) {
/* Both are binary string types: they can be compared */
return(TRUE);
}
if (type1->mtype != type2->mtype) {
return(FALSE);
......@@ -128,11 +141,6 @@ cmp_types_are_equal(
return(FALSE);
}
if (type1->mtype == DATA_BLOB && (type1->prtype & DATA_BINARY_TYPE)
!= (type2->prtype & DATA_BINARY_TYPE)) {
return(FALSE);
}
return(TRUE);
}
......@@ -269,6 +277,7 @@ cmp_whole_field(
return(innobase_mysql_cmp(
(int)(type->prtype & DATA_MYSQL_TYPE_MASK),
(uint)dtype_get_charset_coll(type->prtype),
a, a_length, b, b_length));
default:
fprintf(stderr,
......
......@@ -45,43 +45,6 @@ or there was no master log position info inside InnoDB. */
char trx_sys_mysql_master_log_name[TRX_SYS_MYSQL_LOG_NAME_LEN];
ib_longlong trx_sys_mysql_master_log_pos = -1;
/* Do NOT merge this to the 4.1 code base! */
ibool trx_sys_downgrading_from_4_1_1 = FALSE;
/********************************************************************
Do NOT merge this to the 4.1 code base!
Marks the trx sys header when we have successfully downgraded from the >= 4.1.1
multiple tablespace format back to the 4.0 format. */
void
trx_sys_mark_downgraded_from_4_1_1(void)
/*====================================*/
{
page_t* page;
byte* doublewrite;
mtr_t mtr;
/* Let us mark to the trx_sys header that the downgrade has been
done. */
mtr_start(&mtr);
page = buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO, RW_X_LATCH, &mtr);
buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK);
doublewrite = page + TRX_SYS_DOUBLEWRITE;
mlog_write_ulint(doublewrite + TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED,
TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N + 1,
MLOG_4BYTES, &mtr);
mtr_commit(&mtr);
/* Flush the modified pages to disk and make a checkpoint */
log_make_checkpoint_at(ut_dulint_max, TRUE);
trx_sys_downgrading_from_4_1_1 = FALSE;
}
/********************************************************************
Determines if a page number is located inside the doublewrite buffer. */
......@@ -388,31 +351,6 @@ trx_sys_doublewrite_init_or_restore_pages(
== TRX_SYS_DOUBLEWRITE_MAGIC_N) {
/* The doublewrite buffer has been created */
/* Do NOT merge to the 4.1 code base! */
if (mach_read_from_4(doublewrite
+ TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED)
== TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N) {
fprintf(stderr,
"InnoDB: You are downgrading from the multiple tablespace format of\n"
"InnoDB: >= MySQL-4.1.1 back to the old format of MySQL-4.0.\n"
"InnoDB:\n"
"InnoDB: MAKE SURE that the mysqld server is idle, and purge and the insert\n"
"InnoDB: buffer merge have run to completion under >= 4.1.1 before trying to\n"
"InnoDB: downgrade! You can determine this by looking at SHOW INNODB STATUS:\n"
"InnoDB: if the Main thread is 'waiting for server activity' and SHOW\n"
"InnoDB: PROCESSLIST shows that you have ended all other connections\n"
"InnoDB: to mysqld, then purge and the insert buffer merge have been\n"
"InnoDB: completed.\n"
"InnoDB: If you have already created tables in >= 4.1.1, then those\n"
"InnoDB: tables cannot be used under 4.0.\n"
"InnoDB: NOTE THAT this downgrade procedure has not been properly tested!\n"
"InnoDB: The safe way to downgrade is to dump all InnoDB tables and recreate\n"
"InnoDB: the whole tablespace.\n");
trx_sys_downgrading_from_4_1_1 = TRUE;
}
trx_doublewrite_init(doublewrite);
block1 = trx_doublewrite->block1;
......
......@@ -50,7 +50,7 @@ mysysheaders = mysys_priv.h my_static.h
vioheaders = vio_priv.h
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_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 \
mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.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);
static int test_if_open(struct file_info *key,element_count count,
struct test_if_open_param *param);
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,
struct st_access_param *access_param);
static void file_info_free(struct file_info *info);
......@@ -89,9 +88,8 @@ int main(int argc, char **argv)
log_filename=myisam_log_filename;
get_options(&argc,&argv);
/* Nr of isam-files */
max_files=(set_maximum_open_files(min(max_files,8))-6)/2;
/* Number of MyISAM files we can have open at one time */
max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
if (update)
printf("Trying to %s MyISAM files according to log '%s'\n",
(recover ? "recover" : "update"),log_filename);
......@@ -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",
re_open_count);
VOID(mi_panic(HA_PANIC_CLOSE));
my_free_open_file_info();
my_end(test_info ? MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(error);
return 0; /* No compiler warning */
......@@ -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 */
/* ARGSUSED */
......
......@@ -25,8 +25,8 @@ noinst_HEADERS = mysys_priv.h my_static.h \
my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \
my_os2dlfcn.c my_os2file64.c my_os2mutex.c \
my_os2thread.c my_os2tls.c
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
mf_path.c mf_loadpath.c\
libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.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_pread.c my_write.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,
*/
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;
#if !(defined(HAVE_purify) && defined(EXTRA_DEBUG))
......
......@@ -27,7 +27,7 @@
my_string my_filename(File fd)
{
DBUG_ENTER("my_filename");
if (fd >= MY_NFILE)
if ((uint) fd >= (uint) my_file_limit)
DBUG_RETURN((char*) "UNKNOWN");
if (fd >= 0 && my_file_info[fd].type != UNOPEN)
{
......
......@@ -32,7 +32,7 @@ File my_dup(File file, myf MyFlags)
DBUG_ENTER("my_dup");
DBUG_PRINT("my",("file: %d MyFlags: %d", MyFlags));
fd = dup(file);
filename= (((int) file < MY_NFILE) ?
filename= (((uint) file < my_file_limit) ?
my_file_info[(int) file].name : "Unknown");
DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
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)
on some OS (SUNOS). Actually the filename save isn't that important
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);
DBUG_RETURN(fd); /* safeguard */
......@@ -91,7 +91,7 @@ int my_fclose(FILE *fd, myf MyFlags)
}
else
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_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)
{
pthread_mutex_lock(&THR_LOCK_open);
my_stream_opened++;
if (Filedes < MY_NFILE)
if ((uint) Filedes < (uint) my_file_limit)
{
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
{
......
......@@ -86,7 +86,7 @@ int my_close(File fd, myf MyFlags)
if (MyFlags & (MY_FAE | MY_WME))
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));
#if defined(THREAD) && !defined(HAVE_PREAD)
......@@ -115,7 +115,7 @@ File my_register_filename(File fd, const char *FileName, enum file_type
{
if ((int) fd >= 0)
{
if ((int) fd >= MY_NFILE)
if ((uint) fd >= my_file_limit)
{
#if defined(THREAD) && !defined(HAVE_PREAD)
(void) my_close(fd,MyFlags);
......
......@@ -34,7 +34,9 @@ int NEAR my_umask=0664, NEAR my_umask_dir=0777;
#ifndef THREAD
int NEAR my_errno=0;
#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 */
int NEAR my_dont_interrupt=0;
......
......@@ -68,6 +68,8 @@ extern byte *sf_min_adress,*sf_max_adress;
extern uint sf_malloc_count;
extern struct st_irem *sf_malloc_root;
extern struct st_my_file_info my_file_info_default[MY_NFILE];
#if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
#endif
......@@ -290,7 +290,7 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
return(HA_ERR_ROW_IS_REFERENCED);
return(HA_ERR_ROW_IS_REFERENCED);
} else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
......@@ -756,6 +756,11 @@ innobase_init(void)
srv_query_thread_priority = QUERY_PRIOR;
}
/* Store the default charset-collation number of this MySQL
installation */
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
/* Set InnoDB initialization parameters according to the values
read from MySQL .cnf file */
......@@ -870,16 +875,14 @@ innobase_init(void)
srv_print_verbose_log = mysql_embedded ? 0 : 1;
if (strcmp(default_charset_info->name, "latin1") == 0) {
/* Store the character ordering table to InnoDB.
For non-latin1 charsets we use the MySQL comparison
functions, and consequently we do not need to know
the ordering internally in InnoDB. */
/* Store the latin1_swedish_ci character ordering table to InnoDB. For
non-latin1_swedish_ci charsets we use the MySQL comparison functions,
and consequently we do not need to know the ordering internally in
InnoDB. */
memcpy(srv_latin1_ordering,
default_charset_info->sort_order, 256);
}
ut_a(0 == ut_strcmp((char*)my_charset_latin1.name,
(char*)"latin1_swedish_ci"));
memcpy(srv_latin1_ordering, my_charset_latin1.sort_order, 256);
/* Since we in this module access directly the fields of a trx
struct, and due to different headers and flags it might happen that
......@@ -1661,10 +1664,10 @@ reset_null_bits(
extern "C" {
/*****************************************************************
InnoDB uses this function is to compare two data fields for which the
data type is such that we must use MySQL code to compare them. NOTE that the
prototype of this function is in rem0cmp.c in InnoDB source code!
If you change this function, remember to update the prototype there! */
InnoDB uses this function to compare two data fields for which the data type
is such that we must use MySQL code to compare them. NOTE that the prototype
of this function is in rem0cmp.c in InnoDB source code! If you change this
function, remember to update the prototype there! */
int
innobase_mysql_cmp(
......@@ -1672,6 +1675,7 @@ innobase_mysql_cmp(
/* out: 1, 0, -1, if a is greater,
equal, less than b, respectively */
int mysql_type, /* in: MySQL type */
uint charset_number, /* in: number of the charset */
unsigned char* a, /* in: data field */
unsigned int a_length, /* in: data field length,
not UNIV_SQL_NULL */
......@@ -1679,6 +1683,7 @@ innobase_mysql_cmp(
unsigned int b_length) /* in: data field length,
not UNIV_SQL_NULL */
{
CHARSET_INFO* charset;
enum_field_types mysql_tp;
int ret;
......@@ -1695,9 +1700,27 @@ innobase_mysql_cmp(
case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_BLOB:
case FIELD_TYPE_LONG_BLOB:
// BAR TODO: Discuss with heikki.tuuri@innodb.com
// so that he sends CHARSET_INFO for the field to this function.
ret = my_strnncoll(default_charset_info,
/* Use the charset number to pick the right charset struct for
the comparison. Since the MySQL function get_charset may be
slow before Bar removes the mutex operation there, we first
look at 2 common charsets directly. */
if (charset_number == default_charset_info->number) {
charset = default_charset_info;
} else if (charset_number == my_charset_latin1.number) {
charset = &my_charset_latin1;
} else {
charset = get_charset(charset_number, MYF(MY_WME));
if (charset == NULL) {
fprintf(stderr,
"InnoDB: fatal error: InnoDB needs charset %lu for doing a comparison,\n"
"InnoDB: but MySQL cannot find that charset.\n", (ulong)charset_number);
ut_a(0);
}
}
ret = my_strnncoll(charset,
a, a_length,
b, b_length);
if (ret < 0) {
......@@ -1724,9 +1747,9 @@ get_innobase_type_from_mysql_type(
/* out: DATA_BINARY, DATA_VARCHAR, ... */
Field* field) /* in: MySQL field */
{
/* The following asserts check that the MySQL type code fits in
8 bits: this is used in ibuf and also when DATA_NOT_NULL is
ORed to the type */
/* The following asserts try to check that the MySQL type code fits in
8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to
the type */
DBUG_ASSERT((ulint)FIELD_TYPE_STRING < 256);
DBUG_ASSERT((ulint)FIELD_TYPE_VAR_STRING < 256);
......@@ -1741,8 +1764,8 @@ get_innobase_type_from_mysql_type(
return(DATA_BINARY);
} else if (strcmp(
default_charset_info->name,
"latin1") == 0) {
field->charset()->name,
"latin1_swedish_ci") == 0) {
return(DATA_VARCHAR);
} else {
return(DATA_VARMYSQL);
......@@ -1751,8 +1774,8 @@ get_innobase_type_from_mysql_type(
return(DATA_FIXBINARY);
} else if (strcmp(
default_charset_info->name,
"latin1") == 0) {
field->charset()->name,
"latin1_swedish_ci") == 0) {
return(DATA_CHAR);
} else {
return(DATA_MYSQL);
......@@ -3238,6 +3261,7 @@ create_table_def(
ulint unsigned_type;
ulint binary_type;
ulint nonlatin1_type;
ulint charset_no;
ulint i;
DBUG_ENTER("create_table_def");
......@@ -3267,7 +3291,8 @@ create_table_def(
}
if (col_type == DATA_BLOB
&& strcmp(default_charset_info->name, "latin1") != 0) {
&& strcmp(field->charset()->name,
"latin1_swedish_ci") != 0) {
nonlatin1_type = DATA_NONLATIN1;
} else {
nonlatin1_type = 0;
......@@ -3280,10 +3305,22 @@ create_table_def(
binary_type = 0;
}
charset_no = 0;
if (dtype_is_string_type(col_type)) {
charset_no = (ulint)field->charset()->number;
ut_a(charset_no < 256); /* in ut0type.h we assume that
the number fits in one byte */
}
dict_mem_table_add_col(table, (char*) field->field_name,
col_type, (ulint)field->type()
col_type, dtype_form_prtype(
(ulint)field->type()
| nulls_allowed | unsigned_type
| nonlatin1_type | binary_type,
+ charset_no),
field->pack_length(), 0);
}
......@@ -3467,7 +3504,7 @@ ha_innobase::create(
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
but we play safe here */
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
}
/* Get the transaction associated with the current thd, or create one
......@@ -3681,7 +3718,7 @@ ha_innobase::delete_table(
int error;
trx_t* parent_trx;
trx_t* trx;
THD *thd= current_thd;
THD *thd= current_thd;
char norm_name[1000];
DBUG_ENTER("ha_innobase::delete_table");
......@@ -4408,7 +4445,7 @@ ha_innobase::get_foreign_key_create_info(void)
prebuilt->trx->op_info = (char*)"";
return(str);
}
}
/***********************************************************************
Checks if a table is referenced by a foreign key. The MySQL manual states that
......@@ -4649,10 +4686,10 @@ ha_innobase::external_lock(
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
&& prebuilt->select_lock_type == LOCK_NONE
&& (thd->options
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
/* To get serializable execution, we let InnoDB
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
/* To get serializable execution, we let InnoDB
conceptually add 'LOCK IN SHARE MODE' to all SELECTs
which otherwise would have been consistent reads. An
exception is consistent reads in the AUTOCOMMIT=1 mode:
we know that they are read-only transactions, and they
......
......@@ -183,9 +183,6 @@ inline void reset_floating_point_exceptions()
#else
#include <my_pthread.h> // For thr_setconcurency()
#endif
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) && !defined(HAVE_mit_thread)
#define SET_RLIMIT_NOFILE
#endif
#ifdef SOLARIS
extern "C" int gethostname(char *name, int namelen);
......@@ -493,9 +490,6 @@ extern "C" pthread_handler_decl(handle_connections_namedpipes,arg);
static pthread_handler_decl(handle_connections_shared_memory,arg);
#endif
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 void clean_up(bool print_message);
static void clean_up_mutexes(void);
......@@ -920,6 +914,7 @@ void clean_up(bool print_message)
#ifdef USE_RAID
end_raid();
#endif
my_free_open_file_info();
my_free((char*) global_system_variables.date_format,
MYF(MY_ALLOW_ZERO_PTR));
my_free((char*) global_system_variables.time_format,
......@@ -2109,28 +2104,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,
server_version, SYSTEM_TYPE,MACHINE_TYPE));
#if defined( SET_RLIMIT_NOFILE) || defined( OS2)
/* connections and databases needs lots of files */
{
uint wanted_files=10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
uint files, wanted_files;
wanted_files= 10+(uint) max(max_connections*5,
max_connections+table_cache_size*2);
set_if_bigger(wanted_files, open_files_limit);
// Note that some system returns 0 if we succeed here:
uint files=set_maximum_open_files(wanted_files);
if (files && files < wanted_files && ! open_files_limit)
files= my_set_max_open_files(wanted_files);
if (files < wanted_files)
{
max_connections= (ulong) min((files-10),max_connections);
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
DBUG_PRINT("warning",
("Changed limits: max_connections: %ld table_cache: %ld",
max_connections,table_cache_size));
sql_print_error("Warning: Changed limits: max_connections: %ld table_cache: %ld",max_connections,table_cache_size);
if (!open_files_limit)
{
max_connections= (ulong) min((files-10),max_connections);
table_cache_size= (ulong) max((files-10-max_connections)/2,64);
DBUG_PRINT("warning",
("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;
}
#else
open_files_limit= 0; /* Can't set or detect limit */
#endif
unireg_init(opt_specialflag); /* Set up extern variabels */
if (init_errmessage()) /* Read error messages from file */
return 1;
......@@ -4512,7 +4511,7 @@ The minimum value for this variable is 4096.",
{"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.",
(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,
"The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size,
......@@ -5620,7 +5619,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
fprintf(stderr, "Invalid ft-boolean-syntax string: %s\n", argument);
exit(1);
}
strnmov(opt_ft_boolean_syntax, argument, sizeof(ft_boolean_syntax));
strmake(opt_ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
break;
case OPT_SKIP_SAFEMALLOC:
#ifdef SAFEMALLOC
......@@ -5669,7 +5668,8 @@ static void get_options(int argc,char **argv)
int ho_error;
my_getopt_register_get_addr(mysql_getopt_value);
strnmov(opt_ft_boolean_syntax, ft_boolean_syntax, sizeof(ft_boolean_syntax));
strmake(opt_ft_boolean_syntax, ft_boolean_syntax,
sizeof(ft_boolean_syntax)-1);
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error);
if (argc > 0)
......@@ -5725,7 +5725,8 @@ static void get_options(int argc,char **argv)
table_alias_charset= (lower_case_table_names ?
files_charset_info :
&my_charset_bin);
strnmov(ft_boolean_syntax, opt_ft_boolean_syntax, sizeof(ft_boolean_syntax));
strmake(ft_boolean_syntax, opt_ft_boolean_syntax,
sizeof(ft_boolean_syntax)-1);
if (opt_short_log_format)
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
......@@ -5826,95 +5827,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 ','
returns ~(ulong) 0 on error.
......
......@@ -860,8 +860,8 @@ static void sys_default_init_slave(THD* thd, enum_var_type type)
static int sys_check_ftb_syntax(THD *thd, set_var *var)
{
if (thd->master_access & SUPER_ACL)
return ft_boolean_check_syntax_string(var->value->str_value.ptr()) ?
-1 : 0;
return ft_boolean_check_syntax_string(var->value->str_value.c_ptr()) ?
-1 : 0;
else
{
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
......@@ -871,13 +871,15 @@ static int sys_check_ftb_syntax(THD *thd, set_var *var)
static bool sys_update_ftb_syntax(THD *thd, set_var * var)
{
strnmov(ft_boolean_syntax, var->value->str_value.ptr(), sizeof(ft_boolean_syntax));
strmake(ft_boolean_syntax, var->value->str_value.c_ptr(),
sizeof(ft_boolean_syntax)-1);
return 0;
}
static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
{
strnmov(ft_boolean_syntax, opt_ft_boolean_syntax, sizeof(ft_boolean_syntax));
strmake(ft_boolean_syntax, opt_ft_boolean_syntax,
sizeof(ft_boolean_syntax)-1);
}
/*
......
......@@ -58,9 +58,9 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
{
ulong length;
CHARSET_INFO *cs= (create && create->default_table_charset) ?
create->default_table_charset :
thd->variables.collation_server;
CHARSET_INFO *cs= ((create && create->default_table_charset) ?
create->default_table_charset :
thd->variables.collation_server);
length= my_sprintf(buf,(buf,
"default-character-set=%s\ndefault-collation=%s\n",
cs->csname,cs->name));
......@@ -116,9 +116,10 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
{
if (!strncmp(buf,"default-character-set", (pos-buf)))
{
if (!(create->default_table_charset= get_charset_by_csname(pos+1,
MY_CS_PRIMARY,
MYF(0))))
if (!(create->default_table_charset=
get_charset_by_csname(pos+1,
MY_CS_PRIMARY,
MYF(0))))
{
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
}
......
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