mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-new
into mysql.com:/home/kostja/mysql/mysql-5.1-merge client/mysqldump.c: Auto merged
This commit is contained in:
commit
5610e9ab82
37 changed files with 266 additions and 227 deletions
|
@ -45,22 +45,22 @@ CLEAN_FILES: $(TXT_FILES)
|
|||
GT = $(srcdir)/Support/generate-text-files.pl
|
||||
|
||||
../INSTALL-SOURCE: mysql.info $(GT)
|
||||
perl -w $(GT) $< "installing-source" "windows-source-build" > $@
|
||||
perl -w $(GT) mysql.info "installing-source" "windows-source-build" > $@
|
||||
|
||||
../INSTALL-WIN-SOURCE: mysql.info $(GT)
|
||||
perl -w $(GT) $< "windows-source-build" "post-installation" > $@
|
||||
perl -w $(GT) mysql.info "windows-source-build" "post-installation" > $@
|
||||
|
||||
# We put the description for the binary installation here so that
|
||||
# people who download source wont have to see it. It is moved up to
|
||||
# the toplevel by the script that makes the binary tar files.
|
||||
INSTALL-BINARY: mysql.info $(GT)
|
||||
perl -w $(GT) $< "installing-binary" "installing-source" > $@
|
||||
perl -w $(GT) mysql.info "installing-binary" "installing-source" > $@
|
||||
|
||||
../EXCEPTIONS-CLIENT: mysql.info $(GT)
|
||||
perl -w $(GT) $< "mysql-floss-license-exception" "function-index" > $@
|
||||
perl -w $(GT) mysql.info "mysql-floss-license-exception" "function-index" > $@
|
||||
|
||||
../support-files/MacOSX/ReadMe.txt: mysql.info $(GT)
|
||||
perl -w $(GT) $< "mac-os-x-installation" "netware-installation" > $@
|
||||
perl -w $(GT) mysql.info "mac-os-x-installation" "netware-installation" > $@
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
%::SCCS/s.%
|
||||
|
|
|
@ -569,6 +569,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
|
|||
return -1;
|
||||
}
|
||||
mysql_close(mysql); /* Close connection to avoid error messages */
|
||||
argc=1; /* force SHUTDOWN to be the last command */
|
||||
if (got_pidfile)
|
||||
{
|
||||
if (opt_verbose)
|
||||
|
|
|
@ -1293,12 +1293,13 @@ at offset %lu ; this could be a log format error or read error",
|
|||
}
|
||||
else if (buf[4] == ROTATE_EVENT)
|
||||
{
|
||||
Log_event *ev;
|
||||
my_b_seek(file, tmp_pos); /* seek back to event's start */
|
||||
if (!Log_event::read_log_event(file, *description_event))
|
||||
if (!(ev= Log_event::read_log_event(file, *description_event)))
|
||||
/* EOF can't be hit here normally, so it's a real error */
|
||||
die("Could not read a Rotate_log_event event \
|
||||
at offset %lu ; this could be a log format error or read error",
|
||||
tmp_pos);
|
||||
die("Could not read a Rotate_log_event event at offset %lu ;"
|
||||
" this could be a log format error or read error", tmp_pos);
|
||||
delete ev;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
|
|
@ -1316,7 +1316,7 @@ static uint dump_routines_for_db(char *db)
|
|||
fprintf(sql_file, "DELIMITER ;\n");
|
||||
|
||||
if (lock_tables)
|
||||
mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
|
||||
VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
@ -2139,7 +2139,10 @@ static void dump_table(char *table, char *db)
|
|||
else
|
||||
res=mysql_store_result(sock);
|
||||
if (!res)
|
||||
{
|
||||
DB_error(sock, "when retrieving data from server");
|
||||
goto err;
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr, "-- Retrieving rows...\n");
|
||||
if (mysql_num_fields(res) != num_fields)
|
||||
|
@ -2794,7 +2797,7 @@ static int dump_all_tables_in_db(char *database)
|
|||
check_io(md_result_file);
|
||||
}
|
||||
if (lock_tables)
|
||||
mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
|
||||
VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
|
||||
return 0;
|
||||
} /* dump_all_tables_in_db */
|
||||
|
||||
|
@ -2849,23 +2852,23 @@ static my_bool dump_all_views_in_db(char *database)
|
|||
check_io(md_result_file);
|
||||
}
|
||||
if (lock_tables)
|
||||
mysql_query(sock,"UNLOCK TABLES");
|
||||
VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
|
||||
return 0;
|
||||
} /* dump_all_tables_in_db */
|
||||
|
||||
|
||||
/*
|
||||
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
|
||||
table name from the server for the table name given on the command line.
|
||||
we do this because the table name given on the command line may be a
|
||||
get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
|
||||
table name from the server for the table name given on the command line.
|
||||
we do this because the table name given on the command line may be a
|
||||
different case (e.g. T1 vs t1)
|
||||
|
||||
|
||||
RETURN
|
||||
int - 0 if a tablename was retrieved. 1 if not
|
||||
*/
|
||||
|
||||
static int get_actual_table_name(const char *old_table_name,
|
||||
char *new_table_name,
|
||||
static int get_actual_table_name(const char *old_table_name,
|
||||
char *new_table_name,
|
||||
int buf_size)
|
||||
{
|
||||
int retval;
|
||||
|
@ -2877,7 +2880,7 @@ static int get_actual_table_name(const char *old_table_name,
|
|||
|
||||
/* Check memory for quote_for_like() */
|
||||
DBUG_ASSERT(2*sizeof(old_table_name) < sizeof(show_name_buff));
|
||||
my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
|
||||
my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
|
||||
quote_for_like(old_table_name, show_name_buff));
|
||||
|
||||
if (mysql_query_with_error_report(sock, 0, query))
|
||||
|
@ -2886,7 +2889,7 @@ static int get_actual_table_name(const char *old_table_name,
|
|||
}
|
||||
|
||||
retval = 1;
|
||||
|
||||
|
||||
if ((table_res= mysql_store_result(sock)))
|
||||
{
|
||||
my_ulonglong num_rows= mysql_num_rows(table_res);
|
||||
|
@ -3008,7 +3011,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
|
|||
check_io(md_result_file);
|
||||
}
|
||||
if (lock_tables)
|
||||
mysql_query_with_error_report(sock, 0, "UNLOCK TABLES");
|
||||
VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES"));
|
||||
DBUG_RETURN(0);
|
||||
} /* dump_selected_tables */
|
||||
|
||||
|
|
|
@ -676,8 +676,8 @@ history_load(History *h, const char *fname)
|
|||
(void) strunvis(ptr, line);
|
||||
line[sz] = c;
|
||||
if (HENTER(h, &ev, ptr) == -1) {
|
||||
h_free((ptr_t)ptr);
|
||||
return -1;
|
||||
i = -1;
|
||||
goto oomem;
|
||||
}
|
||||
}
|
||||
oomem:
|
||||
|
|
|
@ -426,7 +426,8 @@ enum ha_base_keytype {
|
|||
enum en_fieldtype {
|
||||
FIELD_LAST=-1,FIELD_NORMAL,FIELD_SKIP_ENDSPACE,FIELD_SKIP_PRESPACE,
|
||||
FIELD_SKIP_ZERO,FIELD_BLOB,FIELD_CONSTANT,FIELD_INTERVALL,FIELD_ZERO,
|
||||
FIELD_VARCHAR,FIELD_CHECK
|
||||
FIELD_VARCHAR,FIELD_CHECK,
|
||||
FIELD_enum_val_count
|
||||
};
|
||||
|
||||
enum data_file_type {
|
||||
|
|
|
@ -818,7 +818,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename)
|
|||
if ((*options->local_infile_init)(&li_ptr, net_filename,
|
||||
options->local_infile_userdata))
|
||||
{
|
||||
my_net_write(net,"",0); /* Server needs one packet */
|
||||
VOID(my_net_write(net,"",0)); /* Server needs one packet */
|
||||
net_flush(net);
|
||||
strmov(net->sqlstate, unknown_sqlstate);
|
||||
net->last_errno= (*options->local_infile_error)(li_ptr,
|
||||
|
|
|
@ -197,7 +197,7 @@ int modify_defaults_file(const char *file_location, const char *option,
|
|||
goto err;
|
||||
}
|
||||
if (my_fclose(cnf_file, MYF(MY_WME)))
|
||||
goto err;
|
||||
DBUG_RETURN(1);
|
||||
|
||||
my_free(file_buffer, MYF(0));
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
@ -79,7 +79,7 @@ my_off_t my_b_safe_tell(IO_CACHE *info)
|
|||
|
||||
void my_b_seek(IO_CACHE *info,my_off_t pos)
|
||||
{
|
||||
my_off_t offset;
|
||||
my_off_t offset;
|
||||
DBUG_ENTER("my_b_seek");
|
||||
DBUG_PRINT("enter",("pos: %lu", (ulong) pos));
|
||||
|
||||
|
@ -91,10 +91,10 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
|
|||
b) see if there is a better way to make it work
|
||||
*/
|
||||
if (info->type == SEQ_READ_APPEND)
|
||||
flush_io_cache(info);
|
||||
|
||||
VOID(flush_io_cache(info));
|
||||
|
||||
offset=(pos - info->pos_in_file);
|
||||
|
||||
|
||||
if (info->type == READ_CACHE || info->type == SEQ_READ_APPEND)
|
||||
{
|
||||
/* TODO: explain why this works if pos < info->pos_in_file */
|
||||
|
@ -119,7 +119,7 @@ void my_b_seek(IO_CACHE *info,my_off_t pos)
|
|||
info->write_pos = info->write_buffer + offset;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
flush_io_cache(info);
|
||||
VOID(flush_io_cache(info));
|
||||
/* Correct buffer end so that we write in increments of IO_SIZE */
|
||||
info->write_end=(info->write_buffer+info->buffer_length-
|
||||
(pos & (IO_SIZE-1)));
|
||||
|
|
|
@ -114,7 +114,7 @@ my_bool bitmap_init(MY_BITMAP *map, uint32 *buf, uint n_bits,
|
|||
#endif
|
||||
;
|
||||
if (!(buf= (uint32*) my_malloc(size_in_bytes, MYF(MY_WME))))
|
||||
return 1;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
#ifdef THREAD
|
||||
else
|
||||
|
|
|
@ -189,7 +189,10 @@ int my_error_register(const char **errmsgs, int first, int last)
|
|||
|
||||
/* Error numbers must be unique. No overlapping is allowed. */
|
||||
if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
|
||||
{
|
||||
my_free((gptr)meh_p, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Insert header into the chain. */
|
||||
meh_p->meh_next= *search_meh_pp;
|
||||
|
|
|
@ -107,7 +107,7 @@ Token shift_token(const char **text, uint *word_len)
|
|||
int get_text_id(const char **text, uint *word_len, const char **id)
|
||||
{
|
||||
get_word(text, word_len);
|
||||
if (word_len == 0)
|
||||
if (*word_len == 0)
|
||||
return 1;
|
||||
*id= *text;
|
||||
return 0;
|
||||
|
|
|
@ -599,7 +599,7 @@ net_safe_read(MYSQL *mysql)
|
|||
DBUG_PRINT("error",("Wrong connection or packet. fd: %s len: %d",
|
||||
vio_description(net->vio),len));
|
||||
#ifdef MYSQL_SERVER
|
||||
if (vio_was_interrupted(net->vio))
|
||||
if (net->vio && vio_was_interrupted(net->vio))
|
||||
return (packet_error);
|
||||
#endif /*MYSQL_SERVER*/
|
||||
end_server(mysql);
|
||||
|
|
26
sql/field.cc
26
sql/field.cc
|
@ -1565,7 +1565,6 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
|||
bool Field::quote_data(String *unquoted_string)
|
||||
{
|
||||
char escaped_string[IO_SIZE];
|
||||
char *unquoted_string_buffer= (char *)(unquoted_string->ptr());
|
||||
DBUG_ENTER("Field::quote_data");
|
||||
|
||||
if (!needs_quotes())
|
||||
|
@ -4545,8 +4544,6 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||
error= 1;
|
||||
}
|
||||
}
|
||||
if (error > 1)
|
||||
error= 2;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (table->s->db_low_byte_first)
|
||||
|
@ -7113,7 +7110,7 @@ void Field_blob::get_key_image(char *buff, uint length, imagetype type)
|
|||
}
|
||||
get_ptr(&blob);
|
||||
gobj= Geometry::construct(&buffer, blob, blob_length);
|
||||
if (gobj->get_mbr(&mbr, &dummy))
|
||||
if (!gobj || gobj->get_mbr(&mbr, &dummy))
|
||||
bzero(buff, SIZEOF_STORED_DOUBLE*4);
|
||||
else
|
||||
{
|
||||
|
@ -7442,7 +7439,7 @@ void Field_geom::get_key_image(char *buff, uint length, imagetype type)
|
|||
}
|
||||
get_ptr(&blob);
|
||||
gobj= Geometry::construct(&buffer, blob, blob_length);
|
||||
if (gobj->get_mbr(&mbr, &dummy))
|
||||
if (!gobj || gobj->get_mbr(&mbr, &dummy))
|
||||
bzero(buff, SIZEOF_STORED_DOUBLE*4);
|
||||
else
|
||||
{
|
||||
|
@ -8239,16 +8236,13 @@ const char *Field_bit::unpack(char *to, const char *from)
|
|||
*/
|
||||
|
||||
Field_bit_as_char::Field_bit_as_char(char *ptr_arg, uint32 len_arg,
|
||||
uchar *null_ptr_arg, uchar null_bit_arg,
|
||||
uchar *bit_ptr_arg, uchar bit_ofs_arg,
|
||||
enum utype unireg_check_arg,
|
||||
uchar *null_ptr_arg, uchar null_bit_arg,
|
||||
enum utype unireg_check_arg,
|
||||
const char *field_name_arg)
|
||||
:Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, bit_ptr_arg,
|
||||
bit_ofs_arg, unireg_check_arg, field_name_arg),
|
||||
:Field_bit(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, 0, 0,
|
||||
unireg_check_arg, field_name_arg),
|
||||
create_length(len_arg)
|
||||
{
|
||||
bit_ptr= 0;
|
||||
bit_ofs= 0;
|
||||
bit_len= 0;
|
||||
field_length= ((len_arg + 7) & ~7) / 8;
|
||||
}
|
||||
|
@ -8950,10 +8944,10 @@ Field *make_field(TABLE_SHARE *share, char *ptr, uint32 field_length,
|
|||
field_charset);
|
||||
case FIELD_TYPE_BIT:
|
||||
return f_bit_as_char(pack_flag) ?
|
||||
new Field_bit_as_char(ptr, field_length, null_pos, null_bit,
|
||||
bit_ptr, bit_offset, unireg_check, field_name) :
|
||||
new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
|
||||
bit_offset, unireg_check, field_name);
|
||||
new Field_bit_as_char(ptr, field_length, null_pos, null_bit,
|
||||
unireg_check, field_name) :
|
||||
new Field_bit(ptr, field_length, null_pos, null_bit, bit_ptr,
|
||||
bit_offset, unireg_check, field_name);
|
||||
|
||||
default: // Impossible (Wrong version)
|
||||
break;
|
||||
|
|
|
@ -1373,12 +1373,12 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Field_bit_as_char: public Field_bit {
|
||||
public:
|
||||
uchar create_length;
|
||||
Field_bit_as_char(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
|
||||
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
|
||||
uchar null_bit_arg,
|
||||
enum utype unireg_check_arg, const char *field_name_arg);
|
||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
|
||||
uint32 max_length() { return (uint32) create_length; }
|
||||
|
|
|
@ -286,7 +286,8 @@ int ha_myisam::dump(THD* thd, int fd)
|
|||
|
||||
if (fd < 0)
|
||||
{
|
||||
my_net_write(net, "", 0);
|
||||
if (my_net_write(net, "", 0))
|
||||
error = errno ? errno : EPIPE;
|
||||
net_flush(net);
|
||||
}
|
||||
|
||||
|
@ -420,12 +421,14 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
|
|||
{
|
||||
uint old_testflag=param.testflag;
|
||||
param.testflag|=T_MEDIUM;
|
||||
init_io_cache(¶m.read_cache, file->dfile,
|
||||
my_default_record_cache_size, READ_CACHE,
|
||||
share->pack.header_length, 1, MYF(MY_WME));
|
||||
error |= chk_data_link(¶m, file, param.testflag & T_EXTEND);
|
||||
end_io_cache(&(param.read_cache));
|
||||
param.testflag=old_testflag;
|
||||
if (!(error= init_io_cache(¶m.read_cache, file->dfile,
|
||||
my_default_record_cache_size, READ_CACHE,
|
||||
share->pack.header_length, 1, MYF(MY_WME))))
|
||||
{
|
||||
error= chk_data_link(¶m, file, param.testflag & T_EXTEND);
|
||||
end_io_cache(&(param.read_cache));
|
||||
}
|
||||
param.testflag= old_testflag;
|
||||
}
|
||||
}
|
||||
if (!error)
|
||||
|
|
|
@ -985,7 +985,7 @@ Item_case_expr::this_item_addr(THD *thd, Item **)
|
|||
|
||||
void Item_case_expr::print(String *str)
|
||||
{
|
||||
str->append(STRING_WITH_LEN("case_expr@"));
|
||||
VOID(str->append(STRING_WITH_LEN("case_expr@")));
|
||||
str->qs_append(m_case_expr_id);
|
||||
}
|
||||
|
||||
|
@ -3868,7 +3868,7 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table, bool fixed_length)
|
|||
name);
|
||||
break;
|
||||
case MYSQL_TYPE_BIT:
|
||||
field= new Field_bit_as_char(NULL, max_length, null_ptr, 0, NULL, 0,
|
||||
field= new Field_bit_as_char(NULL, max_length, null_ptr, 0,
|
||||
Field::NONE, name);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -3342,6 +3342,10 @@ void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
|||
case INSERT_ID_EVENT:
|
||||
msg="INSERT_ID";
|
||||
break;
|
||||
case INVALID_INT_EVENT:
|
||||
default: // cannot happen
|
||||
msg="INVALID_INT";
|
||||
break;
|
||||
}
|
||||
fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
|
||||
fflush(file);
|
||||
|
|
|
@ -753,7 +753,6 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
|||
table_map read_tables, COND *conds,
|
||||
bool allow_null_cond,
|
||||
int *error)
|
||||
|
||||
{
|
||||
SQL_SELECT *select;
|
||||
DBUG_ENTER("make_select");
|
||||
|
@ -7059,10 +7058,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
|||
if (!quick)
|
||||
return 0; /* no ranges found */
|
||||
if (quick->init())
|
||||
{
|
||||
delete quick;
|
||||
goto err;
|
||||
}
|
||||
quick->records= records;
|
||||
|
||||
if (cp_buffer_from_ref(thd,ref) && thd->is_fatal_error ||
|
||||
|
@ -8404,7 +8400,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
|||
ha_rows cur_records;
|
||||
SEL_ARG *cur_index_tree= NULL;
|
||||
ha_rows cur_quick_prefix_records= 0;
|
||||
uint cur_param_idx;
|
||||
uint cur_param_idx=MAX_KEY;
|
||||
key_map cur_used_key_parts;
|
||||
uint pk= param->table->s->primary_key;
|
||||
|
||||
|
@ -8620,6 +8616,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
|||
*/
|
||||
if (cur_read_cost < best_read_cost - (DBL_EPSILON * cur_read_cost))
|
||||
{
|
||||
DBUG_ASSERT(tree != 0 || cur_param_idx == MAX_KEY);
|
||||
index_info= cur_index_info;
|
||||
index= cur_index;
|
||||
best_read_cost= cur_read_cost;
|
||||
|
|
|
@ -706,7 +706,7 @@ class SQL_SELECT :public Sql_alloc {
|
|||
class FT_SELECT: public QUICK_RANGE_SELECT {
|
||||
public:
|
||||
FT_SELECT(THD *thd, TABLE *table, uint key) :
|
||||
QUICK_RANGE_SELECT (thd, table, key, 1) { init(); }
|
||||
QUICK_RANGE_SELECT (thd, table, key, 1) { VOID(init()); }
|
||||
~FT_SELECT() { file->ft_end(); }
|
||||
int init() { return error=file->ft_init(); }
|
||||
int reset() { return 0; }
|
||||
|
|
|
@ -930,7 +930,8 @@ bool load_master_data(THD* thd)
|
|||
host was specified; there could have been a problem when replication
|
||||
started, which led to relay log's IO_CACHE to not be inited.
|
||||
*/
|
||||
flush_master_info(active_mi, 0);
|
||||
if (flush_master_info(active_mi, 0))
|
||||
sql_print_error("Failed to flush master info file");
|
||||
}
|
||||
mysql_free_result(master_status_res);
|
||||
}
|
||||
|
|
|
@ -2495,7 +2495,6 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var)
|
|||
|
||||
bool sys_var_sync_binlog_period::update(THD *thd, set_var *var)
|
||||
{
|
||||
pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock();
|
||||
sync_binlog_period= (ulong) var->save_result.ulonglong_value;
|
||||
return 0;
|
||||
}
|
||||
|
|
38
sql/slave.cc
38
sql/slave.cc
|
@ -1742,7 +1742,8 @@ static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi)
|
|||
" to the relay log, "
|
||||
"SHOW SLAVE STATUS may be inaccurate");
|
||||
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
||||
flush_master_info(mi, 1);
|
||||
if (flush_master_info(mi, 1))
|
||||
sql_print_error("Failed to flush master info file");
|
||||
delete ev;
|
||||
}
|
||||
else
|
||||
|
@ -2233,7 +2234,7 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
|
|||
|
||||
pthread_mutex_unlock(&mi->rli.data_lock);
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
|
||||
|
||||
if (my_net_write(&thd->net, (char*)thd->packet.ptr(), packet->length()))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
@ -2241,8 +2242,13 @@ bool show_master_info(THD* thd, MASTER_INFO* mi)
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
|
||||
/*
|
||||
RETURN
|
||||
2 - flush relay log failed
|
||||
1 - flush master info failed
|
||||
0 - all ok
|
||||
*/
|
||||
int flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
|
||||
{
|
||||
IO_CACHE* file = &mi->file;
|
||||
char lbuf[22];
|
||||
|
@ -2261,8 +2267,9 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
|
|||
When we come to this place in code, relay log may or not be initialized;
|
||||
the caller is responsible for setting 'flush_relay_log_cache' accordingly.
|
||||
*/
|
||||
if (flush_relay_log_cache)
|
||||
flush_io_cache(mi->rli.relay_log.get_log_file());
|
||||
if (flush_relay_log_cache &&
|
||||
flush_io_cache(mi->rli.relay_log.get_log_file()))
|
||||
DBUG_RETURN(2);
|
||||
|
||||
/*
|
||||
We flushed the relay log BEFORE the master.info file, because if we crash
|
||||
|
@ -2274,13 +2281,13 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
|
|||
*/
|
||||
|
||||
/*
|
||||
In certain cases this code may create master.info files that seems
|
||||
corrupted, because of extra lines filled with garbage in the end
|
||||
file (this happens if new contents take less space than previous
|
||||
contents of file). But because of number of lines in the first line
|
||||
In certain cases this code may create master.info files that seems
|
||||
corrupted, because of extra lines filled with garbage in the end
|
||||
file (this happens if new contents take less space than previous
|
||||
contents of file). But because of number of lines in the first line
|
||||
of file we don't care about this garbage.
|
||||
*/
|
||||
|
||||
|
||||
my_b_seek(file, 0L);
|
||||
my_b_printf(file, "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n",
|
||||
LINES_IN_MASTER_INFO_WITH_SSL,
|
||||
|
@ -2289,8 +2296,7 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
|
|||
mi->password, mi->port, mi->connect_retry,
|
||||
(int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
|
||||
mi->ssl_cipher, mi->ssl_key);
|
||||
flush_io_cache(file);
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(-flush_io_cache(file));
|
||||
}
|
||||
|
||||
|
||||
|
@ -3355,7 +3361,11 @@ reconnect done to recover from failed read");
|
|||
sql_print_error("Slave I/O thread could not queue event from master");
|
||||
goto err;
|
||||
}
|
||||
flush_master_info(mi, 1); /* sure that we can flush the relay log */
|
||||
if (flush_master_info(mi, 1))
|
||||
{
|
||||
sql_print_error("Failed to flush master info file");
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
See if the relay logs take too much space.
|
||||
We don't lock mi->rli.log_space_lock here; this dirty read saves time
|
||||
|
|
|
@ -231,7 +231,7 @@ int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
|
|||
|
||||
int init_slave();
|
||||
void init_slave_skip_errors(const char* arg);
|
||||
bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache);
|
||||
int flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache);
|
||||
bool flush_relay_log_info(RELAY_LOG_INFO* rli);
|
||||
int register_slave_on_master(MYSQL* mysql);
|
||||
int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
|
||||
|
|
|
@ -951,7 +951,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
|
|||
|
||||
DBUG_PRINT("enter", ("Host: '%s', Ip: '%s', User: '%s', db: '%s'",
|
||||
(host ? host : "(NULL)"), (ip ? ip : "(NULL)"),
|
||||
(user ? user : "(NULL)"), (db ? db : "(NULL)")));
|
||||
user, (db ? db : "(NULL)")));
|
||||
sctx->user= user;
|
||||
sctx->host= host;
|
||||
sctx->ip= ip;
|
||||
|
@ -980,7 +980,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host,
|
|||
for (i=0 ; i < acl_users.elements ; i++)
|
||||
{
|
||||
acl_user= dynamic_element(&acl_users,i,ACL_USER*);
|
||||
if ((!acl_user->user && (!user || !user[0])) ||
|
||||
if ((!acl_user->user && !user[0]) ||
|
||||
(acl_user->user && strcmp(user, acl_user->user) == 0))
|
||||
{
|
||||
if (compare_hostname(&acl_user->host, host, ip))
|
||||
|
@ -4980,8 +4980,6 @@ static int handle_grant_struct(uint struct_no, bool drop,
|
|||
}
|
||||
if (! user)
|
||||
user= "";
|
||||
if (! host)
|
||||
host= "";
|
||||
#ifdef EXTRA_DEBUG
|
||||
DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'",
|
||||
struct_no, idx, user, host));
|
||||
|
|
114
sql/sql_db.cc
114
sql/sql_db.cc
|
@ -287,7 +287,7 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
Load database options file
|
||||
|
||||
load_db_opt()
|
||||
|
@ -313,68 +313,72 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
|
|||
|
||||
bzero((char*) create,sizeof(*create));
|
||||
create->default_table_charset= thd->variables.collation_server;
|
||||
|
||||
|
||||
/* Check if options for this database are already in the hash */
|
||||
if (!get_dbopt(path, create))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
/* Otherwise, load options from the .opt file */
|
||||
if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) >= 0)
|
||||
{
|
||||
IO_CACHE cache;
|
||||
init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0));
|
||||
DBUG_RETURN(0);
|
||||
|
||||
while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
|
||||
/* Otherwise, load options from the .opt file */
|
||||
if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
|
||||
goto err1;
|
||||
|
||||
IO_CACHE cache;
|
||||
if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
|
||||
goto err2;
|
||||
|
||||
while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
|
||||
{
|
||||
char *pos= buf+nbytes-1;
|
||||
/* Remove end space and control characters */
|
||||
while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
|
||||
pos--;
|
||||
*pos=0;
|
||||
if ((pos= strchr(buf, '=')))
|
||||
{
|
||||
char *pos= buf+nbytes-1;
|
||||
/* Remove end space and control characters */
|
||||
while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
|
||||
pos--;
|
||||
*pos=0;
|
||||
if ((pos= strchr(buf, '=')))
|
||||
if (!strncmp(buf,"default-character-set", (pos-buf)))
|
||||
{
|
||||
if (!strncmp(buf,"default-character-set", (pos-buf)))
|
||||
{
|
||||
/*
|
||||
Try character set name, and if it fails
|
||||
try collation name, probably it's an old
|
||||
4.1.0 db.opt file, which didn't have
|
||||
separate default-character-set and
|
||||
default-collation commands.
|
||||
*/
|
||||
if (!(create->default_table_charset=
|
||||
get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
|
||||
!(create->default_table_charset=
|
||||
get_charset_by_name(pos+1, MYF(0))))
|
||||
{
|
||||
sql_print_error("Error while loading database options: '%s':",path);
|
||||
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
|
||||
create->default_table_charset= default_charset_info;
|
||||
}
|
||||
}
|
||||
else if (!strncmp(buf,"default-collation", (pos-buf)))
|
||||
{
|
||||
if (!(create->default_table_charset= get_charset_by_name(pos+1,
|
||||
MYF(0))))
|
||||
{
|
||||
sql_print_error("Error while loading database options: '%s':",path);
|
||||
sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
|
||||
create->default_table_charset= default_charset_info;
|
||||
}
|
||||
}
|
||||
/*
|
||||
Try character set name, and if it fails
|
||||
try collation name, probably it's an old
|
||||
4.1.0 db.opt file, which didn't have
|
||||
separate default-character-set and
|
||||
default-collation commands.
|
||||
*/
|
||||
if (!(create->default_table_charset=
|
||||
get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
|
||||
!(create->default_table_charset=
|
||||
get_charset_by_name(pos+1, MYF(0))))
|
||||
{
|
||||
sql_print_error("Error while loading database options: '%s':",path);
|
||||
sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
|
||||
create->default_table_charset= default_charset_info;
|
||||
}
|
||||
}
|
||||
else if (!strncmp(buf,"default-collation", (pos-buf)))
|
||||
{
|
||||
if (!(create->default_table_charset= get_charset_by_name(pos+1,
|
||||
MYF(0))))
|
||||
{
|
||||
sql_print_error("Error while loading database options: '%s':",path);
|
||||
sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
|
||||
create->default_table_charset= default_charset_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
end_io_cache(&cache);
|
||||
my_close(file,MYF(0));
|
||||
/*
|
||||
Put the loaded value into the hash.
|
||||
Note that another thread could've added the same
|
||||
entry to the hash after we called get_dbopt(),
|
||||
but it's not an error, as put_dbopt() takes this
|
||||
possibility into account.
|
||||
*/
|
||||
error= put_dbopt(path, create);
|
||||
}
|
||||
/*
|
||||
Put the loaded value into the hash.
|
||||
Note that another thread could've added the same
|
||||
entry to the hash after we called get_dbopt(),
|
||||
but it's not an error, as put_dbopt() takes this
|
||||
possibility into account.
|
||||
*/
|
||||
error= put_dbopt(path, create);
|
||||
|
||||
end_io_cache(&cache);
|
||||
err2:
|
||||
my_close(file,MYF(0));
|
||||
err1:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
|
|||
|
||||
SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error);
|
||||
if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
|
||||
(res->quick && res->quick->reset()))
|
||||
(res && res->quick && res->quick->reset()))
|
||||
{
|
||||
delete res;
|
||||
res=0;
|
||||
|
|
|
@ -686,7 +686,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
|
|||
|
||||
DBUG_ASSERT(view->table != 0 && view->field_translation != 0);
|
||||
|
||||
bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0);
|
||||
VOID(bitmap_init(&used_fields, used_fields_buff, table->s->fields, 0));
|
||||
bitmap_clear_all(&used_fields);
|
||||
|
||||
view->contain_auto_increment= 0;
|
||||
|
|
|
@ -1615,6 +1615,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
statistic_increment(thd->status_var.com_other, &LOCK_status);
|
||||
thd->enable_slow_log= opt_log_slow_admin_statements;
|
||||
db= thd->alloc(db_len + tbl_len + 2);
|
||||
if (!db)
|
||||
{
|
||||
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
|
||||
break;
|
||||
}
|
||||
tbl_name= strmake(db, packet + 1, db_len)+1;
|
||||
strmake(tbl_name, packet + db_len + 2, tbl_len);
|
||||
mysql_table_dump(thd, db, tbl_name, -1);
|
||||
|
@ -1628,14 +1633,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
statistic_increment(thd->status_var.com_other, &LOCK_status);
|
||||
char *user= (char*) packet;
|
||||
char *passwd= strend(user)+1;
|
||||
/*
|
||||
/*
|
||||
Old clients send null-terminated string ('\0' for empty string) for
|
||||
password. New clients send the size (1 byte) + string (not null
|
||||
terminated, so also '\0' for empty string).
|
||||
*/
|
||||
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
|
||||
char db_buff[NAME_LEN+1]; // buffer to store db in utf8
|
||||
char *db= passwd;
|
||||
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
|
||||
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
|
||||
*passwd++ : strlen(passwd);
|
||||
db+= passwd_len + 1;
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
@ -6631,6 +6636,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
|
|||
#ifdef HAVE_REPLICATION
|
||||
if (options & REFRESH_MASTER)
|
||||
{
|
||||
DBUG_ASSERT(thd);
|
||||
tmp_write_to_binlog= 0;
|
||||
if (reset_master(thd))
|
||||
{
|
||||
|
|
|
@ -1201,7 +1201,12 @@ bool change_master(THD* thd, MASTER_INFO* mi)
|
|||
Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
|
||||
a slave before).
|
||||
*/
|
||||
flush_master_info(mi, 0);
|
||||
if (flush_master_info(mi, 0))
|
||||
{
|
||||
my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
|
||||
unlock_slave_threads(mi);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (need_relay_log_purge)
|
||||
{
|
||||
relay_log_purge= 1;
|
||||
|
@ -1311,14 +1316,15 @@ bool mysql_show_binlog_events(THD* thd)
|
|||
bool ret = TRUE;
|
||||
IO_CACHE log;
|
||||
File file = -1;
|
||||
Format_description_log_event *description_event= new
|
||||
Format_description_log_event(3); /* MySQL 4.0 by default */
|
||||
|
||||
Log_event::init_show_field_list(&field_list);
|
||||
if (protocol->send_fields(&field_list,
|
||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
Format_description_log_event *description_event= new
|
||||
Format_description_log_event(3); /* MySQL 4.0 by default */
|
||||
|
||||
/*
|
||||
Wait for handlers to insert any pending information
|
||||
into the binlog. For e.g. ndb which updates the binlog asynchronously
|
||||
|
|
|
@ -781,7 +781,7 @@ append_identifier(THD *thd, String *packet, const char *name, uint length)
|
|||
it's a keyword
|
||||
*/
|
||||
|
||||
packet->reserve(length*2 + 2);
|
||||
VOID(packet->reserve(length*2 + 2));
|
||||
quote_char= (char) q;
|
||||
packet->append("e_char, 1, system_charset_info);
|
||||
|
||||
|
@ -1097,13 +1097,13 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
|||
if (key_part->field)
|
||||
append_identifier(thd,packet,key_part->field->field_name,
|
||||
strlen(key_part->field->field_name));
|
||||
if (!key_part->field ||
|
||||
if (key_part->field &&
|
||||
(key_part->length !=
|
||||
table->field[key_part->fieldnr-1]->key_length() &&
|
||||
!(key_info->flags & HA_FULLTEXT)))
|
||||
{
|
||||
buff[0] = '(';
|
||||
char* end=int10_to_str((long) key_part->length /
|
||||
char* end=int10_to_str((long) key_part->length /
|
||||
key_part->field->charset()->mbmaxlen,
|
||||
buff + 1,10);
|
||||
*end++ = ')';
|
||||
|
@ -1856,7 +1856,8 @@ LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
|
|||
{
|
||||
MEM_ROOT *mem= thd->mem_root;
|
||||
if (allocate_lex_string)
|
||||
lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING));
|
||||
if (!(lex_str= (LEX_STRING *)thd->alloc(sizeof(LEX_STRING))))
|
||||
return 0;
|
||||
lex_str->str= strmake_root(mem, str, length);
|
||||
lex_str->length= length;
|
||||
return lex_str;
|
||||
|
@ -3115,7 +3116,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
|
|||
/*
|
||||
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
|
||||
rather than in SHOW KEYS
|
||||
*/
|
||||
*/
|
||||
if (!tables->view)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
thd->net.last_errno, thd->net.last_error);
|
||||
|
@ -3128,7 +3129,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
|
|||
{
|
||||
TABLE *show_table= tables->table;
|
||||
KEY *key_info=show_table->key_info;
|
||||
show_table->file->info(HA_STATUS_VARIABLE |
|
||||
show_table->file->info(HA_STATUS_VARIABLE |
|
||||
HA_STATUS_NO_LOCK |
|
||||
HA_STATUS_TIME);
|
||||
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
|
||||
|
@ -3140,7 +3141,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
|
|||
restore_record(table, s->default_values);
|
||||
table->field[1]->store(base_name, strlen(base_name), cs);
|
||||
table->field[2]->store(file_name, strlen(file_name), cs);
|
||||
table->field[3]->store((longlong) ((key_info->flags &
|
||||
table->field[3]->store((longlong) ((key_info->flags &
|
||||
HA_NOSAME) ? 0 : 1), TRUE);
|
||||
table->field[4]->store(base_name, strlen(base_name), cs);
|
||||
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
|
||||
|
@ -3163,12 +3164,12 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables,
|
|||
table->field[9]->store((longlong) records, TRUE);
|
||||
table->field[9]->set_notnull();
|
||||
}
|
||||
if (!(key_info->flags & HA_FULLTEXT) &&
|
||||
(!key_part->field ||
|
||||
key_part->length !=
|
||||
if (!(key_info->flags & HA_FULLTEXT) &&
|
||||
(key_part->field &&
|
||||
key_part->length !=
|
||||
show_table->field[key_part->fieldnr-1]->key_length()))
|
||||
{
|
||||
table->field[10]->store((longlong) key_part->length /
|
||||
table->field[10]->store((longlong) key_part->length /
|
||||
key_part->field->charset()->mbmaxlen);
|
||||
table->field[10]->set_notnull();
|
||||
}
|
||||
|
|
|
@ -450,7 +450,7 @@ void mysql_print_status()
|
|||
|
||||
calc_sum_of_all_status(&tmp);
|
||||
printf("\nStatus information:\n\n");
|
||||
my_getwd(current_dir, sizeof(current_dir),MYF(0));
|
||||
VOID(my_getwd(current_dir, sizeof(current_dir),MYF(0)));
|
||||
printf("Current dir: %s\n", current_dir);
|
||||
printf("Running threads: %d Stack size: %ld\n", thread_count,
|
||||
(long) thread_stack);
|
||||
|
|
|
@ -1640,7 +1640,10 @@ ulong get_form_pos(File file, uchar *head, TYPELIB *save_names)
|
|||
ret_value=uint4korr(pos);
|
||||
}
|
||||
if (! save_names)
|
||||
my_free((gptr) buf,MYF(0));
|
||||
{
|
||||
if (names)
|
||||
my_free((gptr) buf,MYF(0));
|
||||
}
|
||||
else if (!names)
|
||||
bzero((char*) save_names,sizeof(save_names));
|
||||
else
|
||||
|
|
122
sql/uniques.cc
122
sql/uniques.cc
|
@ -38,8 +38,8 @@
|
|||
int unique_write_to_file(gptr key, element_count count, Unique *unique)
|
||||
{
|
||||
/*
|
||||
Use unique->size (size of element stored in the tree) and not
|
||||
unique->tree.size_of_element. The latter is different from unique->size
|
||||
Use unique->size (size of element stored in the tree) and not
|
||||
unique->tree.size_of_element. The latter is different from unique->size
|
||||
when tree implementation chooses to store pointer to key in TREE_ELEMENT
|
||||
(instead of storing the element itself there)
|
||||
*/
|
||||
|
@ -63,27 +63,27 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
|
|||
comp_func_fixed_arg);
|
||||
/* If the following fail's the next add will also fail */
|
||||
my_init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
|
||||
/*
|
||||
/*
|
||||
If you change the following, change it in get_max_elements function, too.
|
||||
*/
|
||||
max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
|
||||
open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
|
||||
MYF(MY_WME));
|
||||
VOID(open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE,
|
||||
MYF(MY_WME)));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Calculate log2(n!)
|
||||
|
||||
|
||||
NOTES
|
||||
Stirling's approximate formula is used:
|
||||
|
||||
n! ~= sqrt(2*M_PI*n) * (n/M_E)^n
|
||||
|
||||
|
||||
n! ~= sqrt(2*M_PI*n) * (n/M_E)^n
|
||||
|
||||
Derivation of formula used for calculations is as follows:
|
||||
|
||||
log2(n!) = log(n!)/log(2) = log(sqrt(2*M_PI*n)*(n/M_E)^n) / log(2) =
|
||||
|
||||
|
||||
= (log(2*M_PI*n)/2 + n*log(n/M_E)) / log(2).
|
||||
*/
|
||||
|
||||
|
@ -94,7 +94,7 @@ inline double log2_n_fact(double x)
|
|||
|
||||
|
||||
/*
|
||||
Calculate cost of merge_buffers function call for given sequence of
|
||||
Calculate cost of merge_buffers function call for given sequence of
|
||||
input stream lengths and store the number of rows in result stream in *last.
|
||||
|
||||
SYNOPSIS
|
||||
|
@ -103,21 +103,21 @@ inline double log2_n_fact(double x)
|
|||
elem_size Size of element stored in buffer
|
||||
first Pointer to first merged element size
|
||||
last Pointer to last merged element size
|
||||
|
||||
|
||||
RETURN
|
||||
Cost of merge_buffers operation in disk seeks.
|
||||
|
||||
|
||||
NOTES
|
||||
It is assumed that no rows are eliminated during merge.
|
||||
The cost is calculated as
|
||||
|
||||
The cost is calculated as
|
||||
|
||||
cost(read_and_write) + cost(merge_comparisons).
|
||||
|
||||
All bytes in the sequences is read and written back during merge so cost
|
||||
|
||||
All bytes in the sequences is read and written back during merge so cost
|
||||
of disk io is 2*elem_size*total_buf_elems/IO_SIZE (2 is for read + write)
|
||||
|
||||
|
||||
For comparisons cost calculations we assume that all merged sequences have
|
||||
the same length, so each of total_buf_size elements will be added to a sort
|
||||
the same length, so each of total_buf_size elements will be added to a sort
|
||||
heap with (n_buffers-1) elements. This gives the comparison cost:
|
||||
|
||||
total_buf_elems* log2(n_buffers) / TIME_FOR_COMPARE_ROWID;
|
||||
|
@ -125,16 +125,16 @@ inline double log2_n_fact(double x)
|
|||
|
||||
static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
|
||||
uint *first, uint *last)
|
||||
{
|
||||
{
|
||||
uint total_buf_elems= 0;
|
||||
for (uint *pbuf= first; pbuf <= last; pbuf++)
|
||||
total_buf_elems+= *pbuf;
|
||||
*last= total_buf_elems;
|
||||
|
||||
|
||||
int n_buffers= last - first + 1;
|
||||
|
||||
/* Using log2(n)=log(n)/log(2) formula */
|
||||
return 2*((double)total_buf_elems*elem_size) / IO_SIZE +
|
||||
return 2*((double)total_buf_elems*elem_size) / IO_SIZE +
|
||||
total_buf_elems*log((double) n_buffers) / (TIME_FOR_COMPARE_ROWID * M_LN2);
|
||||
}
|
||||
|
||||
|
@ -142,13 +142,13 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
|
|||
/*
|
||||
Calculate cost of merging buffers into one in Unique::get, i.e. calculate
|
||||
how long (in terms of disk seeks) the two calls
|
||||
merge_many_buffs(...);
|
||||
merge_buffers(...);
|
||||
merge_many_buffs(...);
|
||||
merge_buffers(...);
|
||||
will take.
|
||||
|
||||
SYNOPSIS
|
||||
get_merge_many_buffs_cost()
|
||||
buffer buffer space for temporary data, at least
|
||||
buffer buffer space for temporary data, at least
|
||||
Unique::get_cost_calc_buff_size bytes
|
||||
maxbuffer # of full buffers
|
||||
max_n_elems # of elements in first maxbuffer buffers
|
||||
|
@ -156,12 +156,12 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
|
|||
elem_size size of buffer element
|
||||
|
||||
NOTES
|
||||
maxbuffer+1 buffers are merged, where first maxbuffer buffers contain
|
||||
maxbuffer+1 buffers are merged, where first maxbuffer buffers contain
|
||||
max_n_elems elements each and last buffer contains last_n_elems elements.
|
||||
|
||||
The current implementation does a dumb simulation of merge_many_buffs
|
||||
function actions.
|
||||
|
||||
|
||||
RETURN
|
||||
Cost of merge in disk seeks.
|
||||
*/
|
||||
|
@ -173,17 +173,17 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
register int i;
|
||||
double total_cost= 0.0;
|
||||
uint *buff_elems= buffer; /* #s of elements in each of merged sequences */
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
Set initial state: first maxbuffer sequences contain max_n_elems elements
|
||||
each, last sequence contains last_n_elems elements.
|
||||
*/
|
||||
for (i = 0; i < (int)maxbuffer; i++)
|
||||
buff_elems[i]= max_n_elems;
|
||||
buff_elems[i]= max_n_elems;
|
||||
buff_elems[maxbuffer]= last_n_elems;
|
||||
|
||||
/*
|
||||
Do it exactly as merge_many_buff function does, calling
|
||||
/*
|
||||
Do it exactly as merge_many_buff function does, calling
|
||||
get_merge_buffers_cost to get cost of merge_buffers.
|
||||
*/
|
||||
if (maxbuffer >= MERGEBUFF2)
|
||||
|
@ -194,17 +194,17 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
for (i = 0; i <= (int) maxbuffer - MERGEBUFF*3/2; i += MERGEBUFF)
|
||||
{
|
||||
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
|
||||
buff_elems + i,
|
||||
buff_elems + i,
|
||||
buff_elems + i + MERGEBUFF-1);
|
||||
lastbuff++;
|
||||
}
|
||||
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
|
||||
buff_elems + i,
|
||||
buff_elems + i,
|
||||
buff_elems + maxbuffer);
|
||||
maxbuffer= lastbuff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Simulate final merge_buff call. */
|
||||
total_cost += get_merge_buffers_cost(buff_elems, elem_size,
|
||||
buff_elems, buff_elems + maxbuffer);
|
||||
|
@ -213,7 +213,7 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
|
||||
|
||||
/*
|
||||
Calculate cost of using Unique for processing nkeys elements of size
|
||||
Calculate cost of using Unique for processing nkeys elements of size
|
||||
key_size using max_in_memory_size memory.
|
||||
|
||||
SYNOPSIS
|
||||
|
@ -223,12 +223,12 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
nkeys #of elements in Unique
|
||||
key_size size of each elements in bytes
|
||||
max_in_memory_size amount of memory Unique will be allowed to use
|
||||
|
||||
|
||||
RETURN
|
||||
Cost in disk seeks.
|
||||
|
||||
|
||||
NOTES
|
||||
cost(using_unqiue) =
|
||||
cost(using_unqiue) =
|
||||
cost(create_trees) + (see #1)
|
||||
cost(merge) + (see #2)
|
||||
cost(read_result) (see #3)
|
||||
|
@ -237,42 +237,42 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
For each Unique::put operation there will be 2*log2(n+1) elements
|
||||
comparisons, where n runs from 1 tree_size (we assume that all added
|
||||
elements are different). Together this gives:
|
||||
|
||||
|
||||
n_compares = 2*(log2(2) + log2(3) + ... + log2(N+1)) = 2*log2((N+1)!)
|
||||
|
||||
|
||||
then cost(tree_creation) = n_compares*ROWID_COMPARE_COST;
|
||||
|
||||
Total cost of creating trees:
|
||||
(n_trees - 1)*max_size_tree_cost + non_max_size_tree_cost.
|
||||
|
||||
Approximate value of log2(N!) is calculated by log2_n_fact function.
|
||||
|
||||
|
||||
2. Cost of merging.
|
||||
If only one tree is created by Unique no merging will be necessary.
|
||||
Otherwise, we model execution of merge_many_buff function and count
|
||||
#of merges. (The reason behind this is that number of buffers is small,
|
||||
while size of buffers is big and we don't want to loose precision with
|
||||
#of merges. (The reason behind this is that number of buffers is small,
|
||||
while size of buffers is big and we don't want to loose precision with
|
||||
O(x)-style formula)
|
||||
|
||||
|
||||
3. If only one tree is created by Unique no disk io will happen.
|
||||
Otherwise, ceil(key_len*n_keys) disk seeks are necessary. We assume
|
||||
Otherwise, ceil(key_len*n_keys) disk seeks are necessary. We assume
|
||||
these will be random seeks.
|
||||
*/
|
||||
|
||||
double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
||||
double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
||||
ulong max_in_memory_size)
|
||||
{
|
||||
ulong max_elements_in_tree;
|
||||
ulong last_tree_elems;
|
||||
int n_full_trees; /* number of trees in unique - 1 */
|
||||
double result;
|
||||
|
||||
max_elements_in_tree=
|
||||
|
||||
max_elements_in_tree=
|
||||
max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size);
|
||||
|
||||
n_full_trees= nkeys / max_elements_in_tree;
|
||||
last_tree_elems= nkeys % max_elements_in_tree;
|
||||
|
||||
|
||||
/* Calculate cost of creating trees */
|
||||
result= 2*log2_n_fact(last_tree_elems + 1.0);
|
||||
if (n_full_trees)
|
||||
|
@ -285,13 +285,13 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
|||
|
||||
if (!n_full_trees)
|
||||
return result;
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
There is more then one tree and merging is necessary.
|
||||
First, add cost of writing all trees to disk, assuming that all disk
|
||||
writes are sequential.
|
||||
*/
|
||||
result += DISK_SEEK_BASE_COST * n_full_trees *
|
||||
result += DISK_SEEK_BASE_COST * n_full_trees *
|
||||
ceil(((double) key_size)*max_elements_in_tree / IO_SIZE);
|
||||
result += DISK_SEEK_BASE_COST * ceil(((double) key_size)*last_tree_elems / IO_SIZE);
|
||||
|
||||
|
@ -303,8 +303,8 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
|||
return merge_cost;
|
||||
|
||||
result += merge_cost;
|
||||
/*
|
||||
Add cost of reading the resulting sequence, assuming there were no
|
||||
/*
|
||||
Add cost of reading the resulting sequence, assuming there were no
|
||||
duplicate elements.
|
||||
*/
|
||||
result += ceil((double)key_size*nkeys/IO_SIZE);
|
||||
|
@ -320,7 +320,7 @@ Unique::~Unique()
|
|||
}
|
||||
|
||||
|
||||
/* Write tree to disk; clear tree */
|
||||
/* Write tree to disk; clear tree */
|
||||
bool Unique::flush()
|
||||
{
|
||||
BUFFPEK file_ptr;
|
||||
|
@ -359,7 +359,7 @@ Unique::reset()
|
|||
}
|
||||
elements= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The comparison function, passed to queue_init() in merge_walk() must
|
||||
use comparison function of Uniques::tree, but compare members of struct
|
||||
|
@ -386,7 +386,7 @@ C_MODE_END
|
|||
|
||||
/*
|
||||
DESCRIPTION
|
||||
Function is very similar to merge_buffers, but instead of writing sorted
|
||||
Function is very similar to merge_buffers, but instead of writing sorted
|
||||
unique keys to the output file, it invokes walk_action for each key.
|
||||
This saves I/O if you need to pass through all unique keys only once.
|
||||
SYNOPSIS
|
||||
|
@ -601,7 +601,7 @@ bool Unique::get(TABLE *table)
|
|||
bool error=1;
|
||||
|
||||
/* Open cached file if it isn't open */
|
||||
outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||
outfile=table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_ZEROFILL));
|
||||
|
||||
if (!outfile || ! my_b_inited(outfile) &&
|
||||
|
@ -618,7 +618,7 @@ bool Unique::get(TABLE *table)
|
|||
sort_param.keys= max_in_memory_size / sort_param.sort_length;
|
||||
sort_param.not_killable=1;
|
||||
|
||||
if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
|
||||
if (!(sort_buffer=(uchar*) my_malloc((sort_param.keys+1) *
|
||||
sort_param.sort_length,
|
||||
MYF(0))))
|
||||
return 1;
|
||||
|
@ -633,7 +633,7 @@ bool Unique::get(TABLE *table)
|
|||
goto err;
|
||||
if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr,
|
||||
file_ptr, file_ptr+maxbuffer,0))
|
||||
goto err;
|
||||
goto err;
|
||||
error=0;
|
||||
err:
|
||||
x_free((gptr) sort_buffer);
|
||||
|
|
|
@ -276,7 +276,8 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||
if (subkeys == -1)
|
||||
{
|
||||
/* the last entry in sub-tree */
|
||||
_mi_dispose(info, keyinfo, root,DFLT_INIT_HITS);
|
||||
if (_mi_dispose(info, keyinfo, root,DFLT_INIT_HITS))
|
||||
DBUG_RETURN(-1);
|
||||
/* fall through to normal delete */
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1159,7 +1159,7 @@ static int compare_huff_elements(void *not_used __attribute__((unused)),
|
|||
static void check_counts(HUFF_COUNTS *huff_counts, uint trees,
|
||||
my_off_t records)
|
||||
{
|
||||
uint space_fields,fill_zero_fields,field_count[(int) FIELD_VARCHAR+1];
|
||||
uint space_fields,fill_zero_fields,field_count[(int) FIELD_enum_val_count];
|
||||
my_off_t old_length,new_length,length;
|
||||
DBUG_ENTER("check_counts");
|
||||
|
||||
|
|
|
@ -376,7 +376,10 @@ pthread_handler_t thr_find_all_keys(void *arg)
|
|||
{
|
||||
if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK),
|
||||
maxbuffer, maxbuffer/2))
|
||||
{
|
||||
my_free((gptr) sort_keys,MYF(0));
|
||||
sort_keys= (uchar **) NULL; /* for err: label */
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue