Commit a9097ca3 authored by monty@donna.mysql.com's avatar monty@donna.mysql.com

changed to use IO_CACHE instead of FILE

parent b689a1a7
jcole@tetra.bedford.progress.com monty@donna.mysql.com
jcole@tetra.spaceapes.com
monty@narttu.mysql.fi
mwagner@evoq.home.mwagner.org
sasha@laptop.slkc.uswest.net
sasha@mysql.sashanet.com
sasha@work.mysql.com
serg@serg.mysql.com
yfaktoro@nslinuxw2.bedford.progress.com
...@@ -16867,7 +16867,7 @@ This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm". ...@@ -16867,7 +16867,7 @@ This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
@item LAST_INSERT_ID([expr]) @item LAST_INSERT_ID([expr])
Returns the last automatically generated value that was inserted into an Returns the last automatically generated value that was inserted into an
@code{AUTO_INCREMENT} column. @code{AUTO_INCREMENT} column.
@xref{mysql_insert_id,, @code{mysql_insert_id()}}: @xref{mysql_insert_id,, @code{mysql_insert_id()}}.
@example @example
mysql> select LAST_INSERT_ID(); mysql> select LAST_INSERT_ID();
...@@ -17086,7 +17086,7 @@ mysql> select student_name, AVG(test_score) ...@@ -17086,7 +17086,7 @@ mysql> select student_name, AVG(test_score)
@itemx MAX(expr) @itemx MAX(expr)
Returns the minimum or maximum value of @code{expr}. @code{MIN()} and Returns the minimum or maximum value of @code{expr}. @code{MIN()} and
@code{MAX()} may take a string argument; in such cases they return the @code{MAX()} may take a string argument; in such cases they return the
minimum or maximum string value. @xref{MySQL indexes}: minimum or maximum string value. @xref{MySQL indexes}.
@example @example
mysql> select student_name, MIN(test_score), MAX(test_score) mysql> select student_name, MIN(test_score), MAX(test_score)
...@@ -19753,8 +19753,8 @@ The status variables listed above have the following meaning: ...@@ -19753,8 +19753,8 @@ The status variables listed above have the following meaning:
@item @strong{Variable} @tab @strong{Meaning} @item @strong{Variable} @tab @strong{Meaning}
@item @code{Aborted_clients} @tab Number of connections that has been aborted because the client has died without closing the connection properly. @item @code{Aborted_clients} @tab Number of connections that has been aborted because the client has died without closing the connection properly.
@item @code{Aborted_connects} @tab Number of tries to connect to the @strong{MySQL} server that has failed. @item @code{Aborted_connects} @tab Number of tries to connect to the @strong{MySQL} server that has failed.
@item @code{Bytes_received} @tab Number of bytes received from the client @item @code{Bytes_received} @tab Number of bytes received from all clients
@item @code{Bytes_sent} @tab Number of bytes received from the client @item @code{Bytes_sent} @tab Number of bytes sent to all clients
@item @code{Connections} @tab Number of connection attempts to the @strong{MySQL} server. @item @code{Connections} @tab Number of connection attempts to the @strong{MySQL} server.
@item @code{Created_tmp_disk_tables} @tab Number of implicit temporary tables on disk that have been created while executing statements. @item @code{Created_tmp_disk_tables} @tab Number of implicit temporary tables on disk that have been created while executing statements.
@item @code{Created_tmp_tables} @tab Number of implicit temporary tables in memory that have been created while executing statements. @item @code{Created_tmp_tables} @tab Number of implicit temporary tables in memory that have been created while executing statements.
...@@ -417,6 +417,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, ...@@ -417,6 +417,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.dellink = HA_OFFSET_ERROR; share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid(); share.state.process= (ulong) getpid();
share.state.unique= (ulong) 0; share.state.unique= (ulong) 0;
share.state.update_count=(ulong) 0;
share.state.version= (ulong) time((time_t*) 0); share.state.version= (ulong) time((time_t*) 0);
share.state.sortkey= (ushort) ~0; share.state.sortkey= (ushort) ~0;
share.state.auto_increment=ci->auto_increment; share.state.auto_increment=ci->auto_increment;
......
...@@ -70,6 +70,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) ...@@ -70,6 +70,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
{ {
share->state.process= share->last_process=share->this_process; share->state.process= share->last_process=share->this_process;
share->state.unique= info->last_unique= info->this_unique; share->state.unique= info->last_unique= info->this_unique;
share->state.update_count= info->last_loop= ++info->this_loop;
if (mi_state_info_write(share->kfile, &share->state, 1)) if (mi_state_info_write(share->kfile, &share->state, 1))
error=my_errno; error=my_errno;
share->changed=0; share->changed=0;
...@@ -346,6 +347,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation) ...@@ -346,6 +347,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
{ /* Two threads can't be here */ { /* Two threads can't be here */
share->state.process= share->last_process= share->this_process; share->state.process= share->last_process= share->this_process;
share->state.unique= info->last_unique= info->this_unique; share->state.unique= info->last_unique= info->this_unique;
share->state.update_count= info->last_loop= ++info->this_loop;
if ((error=mi_state_info_write(share->kfile, &share->state, 1))) if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
olderror=my_errno; olderror=my_errno;
#ifdef __WIN__ #ifdef __WIN__
...@@ -377,12 +379,14 @@ int _mi_test_if_changed(register MI_INFO *info) ...@@ -377,12 +379,14 @@ int _mi_test_if_changed(register MI_INFO *info)
{ {
MYISAM_SHARE *share=info->s; MYISAM_SHARE *share=info->s;
if (share->state.process != share->last_process || if (share->state.process != share->last_process ||
share->state.unique != info->last_unique) share->state.unique != info->last_unique ||
share->state.update_count != info->last_loop)
{ /* Keyfile has changed */ { /* Keyfile has changed */
if (share->state.process != share->this_process) if (share->state.process != share->this_process)
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE)); VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
share->last_process=share->state.process; share->last_process=share->state.process;
info->last_unique= share->state.unique; info->last_unique= share->state.unique;
info->last_loop= share->state.update_count;
info->update|= HA_STATE_WRITTEN; /* Must use file on next */ info->update|= HA_STATE_WRITTEN; /* Must use file on next */
info->data_changed= 1; /* For mi_is_changed */ info->data_changed= 1; /* For mi_is_changed */
return 1; return 1;
......
...@@ -447,6 +447,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) ...@@ -447,6 +447,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
info.this_unique= share->state.unique; info.this_unique= share->state.unique;
info.this_loop=0; /* Update counter */ info.this_loop=0; /* Update counter */
info.last_unique= share->state.unique; info.last_unique= share->state.unique;
info.last_loop= share->state.update_count;
if (mode == O_RDONLY) if (mode == O_RDONLY)
share->options|=HA_OPTION_READ_ONLY_DATA; share->options|=HA_OPTION_READ_ONLY_DATA;
info.lock_type=F_UNLCK; info.lock_type=F_UNLCK;
...@@ -669,7 +670,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite) ...@@ -669,7 +670,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
mi_int4store(ptr,state->process); ptr +=4; mi_int4store(ptr,state->process); ptr +=4;
mi_int4store(ptr,state->unique); ptr +=4; mi_int4store(ptr,state->unique); ptr +=4;
mi_int4store(ptr,state->status); ptr +=4; mi_int4store(ptr,state->status); ptr +=4;
*ptr++=0; *ptr++=0; *ptr++=0; *ptr++=0; /* extra */ mi_int4store(ptr,state->update_count); ptr +=4;
ptr+=state->state_diff_length; ptr+=state->state_diff_length;
......
...@@ -1214,7 +1214,11 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo, ...@@ -1214,7 +1214,11 @@ int _mi_search_next(register MI_INFO *info, register MI_KEYDEF *keyinfo,
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length);); DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE,keyinfo->seg,key,key_length););
/* Force full read if we are at last key or if we are not on a leaf /* Force full read if we are at last key or if we are not on a leaf
and the key tree has changed since we used it last time */ and the key tree has changed since we used it last time
Note that even if the key tree has changed since last read, we can use
the last read data from the leaf if we haven't used the buffer for
something else.
*/
if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) || if (((nextflag & SEARCH_BIGGER) && info->int_keypos >= info->int_maxpos) ||
info->page_changed || info->page_changed ||
......
...@@ -64,6 +64,7 @@ typedef struct st_mi_state_info ...@@ -64,6 +64,7 @@ typedef struct st_mi_state_info
ulonglong auto_increment; ulonglong auto_increment;
ulong process; /* process that updated table last */ ulong process; /* process that updated table last */
ulong unique; /* Unique number for this process */ ulong unique; /* Unique number for this process */
ulong update_count; /* Updated for each write lock */
ulong status; ulong status;
my_off_t *key_root; /* Start of key trees */ my_off_t *key_root; /* Start of key trees */
my_off_t *key_del; /* delete links for trees */ my_off_t *key_del; /* delete links for trees */
......
...@@ -27,7 +27,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ ...@@ -27,7 +27,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_open.c my_create.c my_seek.c my_read.c \ my_open.c my_create.c my_seek.c my_read.c \
my_pread.c my_write.c \ my_pread.c my_write.c \
mf_keycache.c \ mf_keycache.c \
mf_iocache.c mf_cache.c mf_tempfile.c \ mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
my_lock.c mf_brkhant.c my_alarm.c \ my_lock.c mf_brkhant.c my_alarm.c \
my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \
my_alloc.c safemalloc.c my_fopen.c my_fstream.c \ my_alloc.c safemalloc.c my_fopen.c my_fstream.c \
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/*
More functions to be used with IO_CACHE files
*/
#define MAP_TO_USE_RAID
#include "mysys_priv.h"
#include <m_string.h>
#include <stdarg.h>
#include <m_ctype.h>
/*
** Fix that next read will be made at certain position
** This only works with READ_CACHE
*/
void my_b_seek(IO_CACHE *info,my_off_t pos)
{
info->seek_not_done=0;
info->pos_in_file=pos;
info->rc_pos=info->rc_end=info->buffer;
}
/*
** Fill buffer
** return: 0 on error or EOF (info->error = -1 on error)
** number of characters
*/
uint my_b_fill(IO_CACHE *info)
{
my_off_t pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
my_off_t max_length;
uint diff_length,length;
if (info->seek_not_done)
{ /* File touched, do seek */
if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
MY_FILEPOS_ERROR)
{
info->error= 0;
return 0;
}
info->seek_not_done=0;
}
diff_length=(uint) (pos_in_file & (IO_SIZE-1));
max_length= (my_off_t) (info->end_of_file - pos_in_file);
if (max_length > (my_off_t) (info->read_length-diff_length))
max_length=(my_off_t) (info->read_length-diff_length);
if (!max_length)
{
info->error= 0;
return 0; /* EOF */
}
else if ((length=my_read(info->file,info->buffer,(uint) max_length,
info->myflags)) == (uint) -1)
{
info->error= -1;
return 0;
}
info->rc_pos=info->buffer;
info->rc_end=info->buffer+length;
info->pos_in_file=pos_in_file;
return length;
}
/*
** Read a string ended by '\n' into a buffer of 'max_length' size.
** Returns number of characters read, 0 on error.
** last byte is set to '\0'
*/
uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
{
uint length;
max_length--; /* Save place for end \0 */
/* Calculate number of characters in buffer */
if (!(length= (uint) (info->rc_end - info->rc_pos)))
if (!(length=my_b_fill(info)))
return 0;
for (;;)
{
char *pos,*end;
if (length > max_length)
length=max_length;
for (pos=info->rc_pos,end=pos+length ; pos < end ;)
{
if ((*to++ = *pos++) == '\n')
{
length= (uint) (pos-info->rc_pos);
info->rc_pos=pos;
*to='\0';
return length;
}
}
if (!(max_length-=length))
{
/* Found enough charcters; Return found string */
info->rc_pos=pos;
*to='\0';
return length;
}
if (!(length=my_b_fill(info)))
return 0;
}
}
/*
Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
Used for logging in MySQL
returns number of written character, or (uint) -1 on error
*/
uint my_b_printf(IO_CACHE *info, const char* fmt, ...)
{
va_list args;
reg1 char *to= info->rc_pos;
char *end=info->rc_end;
uint out_length=0;
va_start(args,fmt);
for (; *fmt ; fmt++)
{
if (fmt[0] != '%')
{
/* Copy everything until '%' or end of string */
const char *start=fmt;
uint length;
for (fmt++ ; *fmt && *fmt != '%' ; fmt++ ) ;
length= (uint) (fmt - start);
out_length+=length;
if (my_b_write(info, start, length))
goto err;
if (!*fmt) /* End of format */
{
va_end(args);
return out_length;
}
/* Found one '%' */
}
/* Skipp if max size is used (to be compatible with printf) */
while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
fmt++;
if (*fmt == 's') /* String parameter */
{
reg2 char *par = va_arg(args, char *);
uint length = (uint) strlen(par);
out_length+=length;
if (my_b_write(info, par, length))
goto err;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{
register int iarg;
uint length;
char buff[17];
iarg = va_arg(args, int);
if (*fmt == 'd')
length= (uint) (int10_to_str((long) iarg,buff, -10) - buff);
else
length= (uint) (int10_to_str((long) (uint) iarg,buff,10)- buff);
out_length+=length;
if (my_b_write(info, buff, length))
goto err;
}
else if (*fmt == 'l' && fmt[1] == 'd' || fmt[1] == 'u')/* long parameter */
{
register long iarg;
uint length;
char buff[17];
iarg = va_arg(args, long);
if (*++fmt == 'd')
length= (uint) (int10_to_str(iarg,buff, -10) - buff);
else
length= (uint) (int10_to_str(iarg,buff,10)- buff);
out_length+=length;
if (my_b_write(info, buff, length))
goto err;
}
else
{
/* %% or unknown code */
if (my_b_write(info, "%", 1))
goto err;
out_length++;
}
}
va_end(args);
return out_length;
err:
return (uint) -1;
va_end(args);
}
...@@ -319,8 +319,8 @@ int MYSQL_LOG::find_next_log(LOG_INFO* linfo) ...@@ -319,8 +319,8 @@ int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{ {
if(!index_file) return LOG_INFO_INVALID; if (index_file < 0) return LOG_INFO_INVALID;
if(no_rotate) return LOG_INFO_PURGE_NO_ROTATE; if (no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
int error; int error;
char fname[FN_REFLEN]; char fname[FN_REFLEN];
char* fname_end, *p; char* fname_end, *p;
...@@ -329,23 +329,24 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) ...@@ -329,23 +329,24 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
DYNAMIC_ARRAY logs_to_purge, logs_to_keep; DYNAMIC_ARRAY logs_to_purge, logs_to_keep;
my_off_t purge_offset ; my_off_t purge_offset ;
LINT_INIT(purge_offset); LINT_INIT(purge_offset);
IO_CACHE io_cache;
pthread_mutex_lock(&LOCK_index); pthread_mutex_lock(&LOCK_index);
if(my_fseek(index_file, 0, MY_SEEK_SET, if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
MYF(MY_WME) ) == MY_FILEPOS_ERROR) 0, MYF(MY_WME)))
{ {
error = LOG_INFO_SEEK; error = LOG_INFO_MEM;
goto err; goto err;
} }
if (init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
if(init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
{ {
error = LOG_INFO_MEM; error = LOG_INFO_MEM;
goto err; goto err;
} }
logs_to_purge_inited = 1; logs_to_purge_inited = 1;
if(init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024)) if (init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
{ {
error = LOG_INFO_MEM; error = LOG_INFO_MEM;
goto err; goto err;
...@@ -355,42 +356,39 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) ...@@ -355,42 +356,39 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
for(;;) for(;;)
{ {
if(!fgets(fname, FN_REFLEN, index_file)) my_off_t init_purge_offset= my_b_tell(&io_cache);
if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
{ {
if(feof(index_file)) if(!io_cache.error)
break; break;
else
error = LOG_INFO_IO; error = LOG_INFO_IO;
goto err; goto err;
} }
*(fname_end = (strend(fname) - 1)) = 0; // kill \n fname[--fname_len]=0; // kill \n
fname_len = (uint)(fname_end - fname);
if(!memcmp(fname, to_log, fname_len + 1 )) if(!memcmp(fname, to_log, fname_len + 1 ))
{ {
found_log = 1; found_log = 1;
purge_offset = my_ftell(index_file, MYF(MY_WME)) - fname_len - 1; purge_offset = init_purge_offset;
} }
if(!found_log && log_in_use(fname))
// if one of the logs before the target is in use // if one of the logs before the target is in use
if(!found_log && log_in_use(fname))
{ {
error = LOG_INFO_IN_USE; error = LOG_INFO_IN_USE;
goto err; goto err;
} }
p = sql_memdup(fname, (uint)(fname_end - fname) + 1); if (!(p = sql_memdup(fname, (uint)(fname_end - fname) + 1)) ||
if((found_log) ? insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge,
insert_dynamic(&logs_to_keep, (gptr) &p) : (gptr) &p))
insert_dynamic(&logs_to_purge, (gptr) &p)
)
{ {
error = LOG_INFO_MEM; error = LOG_INFO_MEM;
goto err; goto err;
} }
} }
end_io_cache(&io_cache);
if(!found_log) if(!found_log)
{ {
error = LOG_INFO_EOF; error = LOG_INFO_EOF;
...@@ -401,15 +399,26 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) ...@@ -401,15 +399,26 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{ {
char* l; char* l;
get_dynamic(&logs_to_purge, (gptr)&l, i); get_dynamic(&logs_to_purge, (gptr)&l, i);
if(my_delete(l, MYF(MY_WME))) if (my_delete(l, MYF(MY_WME)))
sql_print_error("Error deleting %s during purge", l); sql_print_error("Error deleting %s during purge", l);
} }
// if we get killed -9 here, the sysadmin would have to do a small // if we get killed -9 here, the sysadmin would have to do a small
// vi job on the log index file after restart - otherwise, this should // vi job on the log index file after restart - otherwise, this should
// be safe // be safe
my_fclose(index_file, MYF(MY_WME)); #ifdef HAVE_FTRUNCATE
if(!(index_file = my_fopen(index_file_name, O_BINARY|O_WRONLY, if (ftruncate(index_file,0))
{
sql_print_error("Ouch! Could not truncate the binlog index file \
during log purge for write");
error = LOG_INFO_FATAL;
goto err;
}
my_seek(index_file, 0, MY_SEEK_CUR,MYF(MY_WME));
#else
my_close(index_file, MYF(MY_WME));
my_delete(index_file_name, MYF(MY_WME));
if(!(index_file = my_open(index_file_name, O_BINARY | O_RDWR | O_APPEND,
MYF(MY_WME)))) MYF(MY_WME))))
{ {
sql_print_error("Ouch! Could not re-open the binlog index file \ sql_print_error("Ouch! Could not re-open the binlog index file \
...@@ -417,37 +426,35 @@ during log purge for write"); ...@@ -417,37 +426,35 @@ during log purge for write");
error = LOG_INFO_FATAL; error = LOG_INFO_FATAL;
goto err; goto err;
} }
#endif
for(i = 0; i < logs_to_keep.elements; i++) for(i = 0; i < logs_to_keep.elements; i++)
{ {
char* l; char* l;
get_dynamic(&logs_to_keep, (gptr)&l, i); get_dynamic(&logs_to_keep, (gptr)&l, i);
fprintf(index_file, "%s\n", l); if (my_write(index_file, l, strlen(l), MYF(MY_WME)) ||
} my_write(index_file, "\n", 1, MYF(MY_WME)))
my_fclose(index_file, MYF(MY_WME));
if(!(index_file = my_fopen(index_file_name, O_BINARY|O_RDWR|O_APPEND,
MYF(MY_WME))))
{ {
sql_print_error("Ouch! Could not re-open the binlog index file \
during log purge for append");
error = LOG_INFO_FATAL; error = LOG_INFO_FATAL;
goto err; goto err;
} }
}
// now update offsets // now update offsets
adjust_linfo_offsets(purge_offset); adjust_linfo_offsets(purge_offset);
error = 0; error = 0;
err: err:
pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_index);
if(logs_to_purge_inited) if(logs_to_purge_inited)
delete_dynamic(&logs_to_purge); delete_dynamic(&logs_to_purge);
if(logs_to_keep_inited) if(logs_to_keep_inited)
delete_dynamic(&logs_to_keep); delete_dynamic(&logs_to_keep);
end_io_cache(&io_cache);
return error; return error;
} }
// we assume that buf has at least FN_REFLEN bytes alloced // we assume that buf has at least FN_REFLEN bytes alloced
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident) void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{ {
......
...@@ -98,7 +98,7 @@ class MYSQL_LOG { ...@@ -98,7 +98,7 @@ class MYSQL_LOG {
char* get_log_fname() { return log_file_name; } char* get_log_fname() { return log_file_name; }
void lock_index() { pthread_mutex_lock(&LOCK_index);} void lock_index() { pthread_mutex_lock(&LOCK_index);}
void unlock_index() { pthread_mutex_unlock(&LOCK_index);} void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
FILE* get_index_file() { return index_file;} File get_index_file() { return index_file;}
}; };
/* character conversion tables */ /* character conversion tables */
......
...@@ -720,11 +720,13 @@ int show_binlog_info(THD* thd) ...@@ -720,11 +720,13 @@ int show_binlog_info(THD* thd)
int show_binlogs(THD* thd) int show_binlogs(THD* thd)
{ {
const char* errmsg = 0; const char* errmsg = 0;
FILE* index_file; File index_file;
char fname[FN_REFLEN]; char fname[FN_REFLEN];
NET* net = &thd->net; NET* net = &thd->net;
List<Item> field_list; List<Item> field_list;
String* packet = &thd->packet; String* packet = &thd->packet;
IO_CACHE io_cache;
uint length;
if(!mysql_bin_log.is_open()) if(!mysql_bin_log.is_open())
{ {
...@@ -741,45 +743,43 @@ int show_binlogs(THD* thd) ...@@ -741,45 +743,43 @@ int show_binlogs(THD* thd)
mysql_bin_log.lock_index(); mysql_bin_log.lock_index();
index_file = mysql_bin_log.get_index_file(); index_file = mysql_bin_log.get_index_file();
if(!index_file) if (index_file < 0)
{ {
errmsg = "Uninitialized index file pointer"; errmsg = "Uninitialized index file pointer";
mysql_bin_log.unlock_index(); goto err2;
goto err;
} }
if(my_fseek(index_file, 0, MY_SEEK_SET, MYF(MY_WME))) if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, 0, 0,
MYF(MY_WME)))
{ {
errmsg = "Failed on fseek()"; errmsg = "Failed on init_io_cache()";
mysql_bin_log.unlock_index(); goto err2;
goto err;
} }
while ((length=my_b_gets(&io_cache, fname, sizeof(fname))))
while(fgets(fname, sizeof(fname), index_file))
{ {
char* fname_end; fname[--length]=0;
*(fname_end = (strend(fname) - 1)) = 0;
int dir_len = dirname_length(fname); int dir_len = dirname_length(fname);
packet->length(0); packet->length(0);
net_store_data(packet, fname + dir_len, (fname_end - fname)-dir_len); net_store_data(packet, fname + dir_len, length-dir_len);
if(my_net_write(net, (char*) packet->ptr(), packet->length())) if(my_net_write(net, (char*) packet->ptr(), packet->length()))
{ {
sql_print_error("Failed in my_net_write"); sql_print_error("Failed in my_net_write");
end_io_cache(&io_cache);
mysql_bin_log.unlock_index(); mysql_bin_log.unlock_index();
return 1; return 1;
} }
} }
mysql_bin_log.unlock_index(); mysql_bin_log.unlock_index();
end_io_cache(&io_cache);
send_eof(net); send_eof(net);
err: return 0;
if(errmsg)
{ err2:
mysql_bin_log.unlock_index();
end_io_cache(&io_cache);
err:
send_error(net, 0, errmsg); send_error(net, 0, errmsg);
return 1; return 1;
}
send_ok(net);
return 0;
} }
......
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