summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2000-11-16 03:58:58 +0200
committerunknown <monty@donna.mysql.com>2000-11-16 03:58:58 +0200
commit3e6dac34cd5b8ef322d375f3af22137822656c8a (patch)
tree4b8f3df4d2aef33906b1e7e311b909e12f38539e
parentc7d2c59ceb4e3548eb74e5d8fba16e0f41ffc7d9 (diff)
downloadmariadb-git-3e6dac34cd5b8ef322d375f3af22137822656c8a.tar.gz
changed to use IO_CACHE instead of FILE
Docs/manual.texi: Type fixes myisam/mi_create.c: Fixed bug in update from different processes myisam/mi_locking.c: Fixed bug in update from different processes myisam/mi_open.c: Fixed bug in update from different processes myisam/mi_search.c: Fixed bug in update from different processes myisam/myisamdef.h: Fixed bug in update from different processes mysys/Makefile.am: Added mf_iocache2.c sql/log.cc: Changed to use IO_CACHE instead of FILE sql/sql_class.h: Changed to use IO_CACHE instead of FILE sql/sql_repl.cc: Changed to use IO_CACHE instead of FILE BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
-rw-r--r--BitKeeper/etc/logging_ok10
-rw-r--r--Docs/manual.texi8
-rw-r--r--myisam/mi_create.c1
-rw-r--r--myisam/mi_locking.c6
-rw-r--r--myisam/mi_open.c5
-rw-r--r--myisam/mi_search.c6
-rw-r--r--myisam/myisamdef.h1
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/mf_iocache2.c212
-rw-r--r--sql/log.cc161
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_repl.cc84
12 files changed, 360 insertions, 138 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 5bd9eb0bcf2..84bd71dbd9f 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -1,9 +1 @@
-jcole@tetra.bedford.progress.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
+monty@donna.mysql.com
diff --git a/Docs/manual.texi b/Docs/manual.texi
index cdad3c20627..85a363fac5a 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -16867,7 +16867,7 @@ This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
@item LAST_INSERT_ID([expr])
Returns the last automatically generated value that was inserted into an
@code{AUTO_INCREMENT} column.
-@xref{mysql_insert_id,, @code{mysql_insert_id()}}:
+@xref{mysql_insert_id,, @code{mysql_insert_id()}}.
@example
mysql> select LAST_INSERT_ID();
@@ -17086,7 +17086,7 @@ mysql> select student_name, AVG(test_score)
@itemx MAX(expr)
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
-minimum or maximum string value. @xref{MySQL indexes}:
+minimum or maximum string value. @xref{MySQL indexes}.
@example
mysql> select student_name, MIN(test_score), MAX(test_score)
@@ -19753,8 +19753,8 @@ The status variables listed above have the following 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_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_sent} @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 sent to all clients
@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_tables} @tab Number of implicit temporary tables in memory that have been created while executing statements.
diff --git a/myisam/mi_create.c b/myisam/mi_create.c
index 048bbb427a2..89bdcdf3fbc 100644
--- a/myisam/mi_create.c
+++ b/myisam/mi_create.c
@@ -417,6 +417,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
share.state.dellink = HA_OFFSET_ERROR;
share.state.process= (ulong) getpid();
share.state.unique= (ulong) 0;
+ share.state.update_count=(ulong) 0;
share.state.version= (ulong) time((time_t*) 0);
share.state.sortkey= (ushort) ~0;
share.state.auto_increment=ci->auto_increment;
diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c
index 4797584627a..45bb2cd7164 100644
--- a/myisam/mi_locking.c
+++ b/myisam/mi_locking.c
@@ -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.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))
error=my_errno;
share->changed=0;
@@ -346,6 +347,7 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
{ /* Two threads can't be here */
share->state.process= share->last_process= share->this_process;
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)))
olderror=my_errno;
#ifdef __WIN__
@@ -377,12 +379,14 @@ int _mi_test_if_changed(register MI_INFO *info)
{
MYISAM_SHARE *share=info->s;
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 */
if (share->state.process != share->this_process)
VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
share->last_process=share->state.process;
info->last_unique= share->state.unique;
+ info->last_loop= share->state.update_count;
info->update|= HA_STATE_WRITTEN; /* Must use file on next */
info->data_changed= 1; /* For mi_is_changed */
return 1;
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index aeaf9e5e9b4..c29a4a843ca 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -445,8 +445,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
info.this_unique= (ulong) info.dfile; /* Uniq number in process */
if (share->data_file_type == COMPRESSED_RECORD)
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_loop= share->state.update_count;
if (mode == O_RDONLY)
share->options|=HA_OPTION_READ_ONLY_DATA;
info.lock_type=F_UNLCK;
@@ -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->unique); 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;
diff --git a/myisam/mi_search.c b/myisam/mi_search.c
index eead2a84c29..3ffc348ca5c 100644
--- a/myisam/mi_search.c
+++ b/myisam/mi_search.c
@@ -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););
/* 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) ||
info->page_changed ||
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index a65694dbd94..ad153d58b70 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -64,6 +64,7 @@ typedef struct st_mi_state_info
ulonglong auto_increment;
ulong process; /* process that updated table last */
ulong unique; /* Unique number for this process */
+ ulong update_count; /* Updated for each write lock */
ulong status;
my_off_t *key_root; /* Start of key trees */
my_off_t *key_del; /* delete links for trees */
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 3d60716e358..9e9b4f8d9ed 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -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_pread.c my_write.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_malloc.c my_realloc.c my_once.c mulalloc.c \
my_alloc.c safemalloc.c my_fopen.c my_fstream.c \
diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c
new file mode 100644
index 00000000000..80cea47a80f
--- /dev/null
+++ b/mysys/mf_iocache2.c
@@ -0,0 +1,212 @@
+/* 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);
+}
diff --git a/sql/log.cc b/sql/log.cc
index 7172d043552..b3f730ce32a 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -319,8 +319,8 @@ err:
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{
- if(!index_file) return LOG_INFO_INVALID;
- if(no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
+ if (index_file < 0) return LOG_INFO_INVALID;
+ if (no_rotate) return LOG_INFO_PURGE_NO_ROTATE;
int error;
char fname[FN_REFLEN];
char* fname_end, *p;
@@ -329,125 +329,132 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
DYNAMIC_ARRAY logs_to_purge, logs_to_keep;
my_off_t purge_offset ;
LINT_INIT(purge_offset);
+ IO_CACHE io_cache;
+
pthread_mutex_lock(&LOCK_index);
- if(my_fseek(index_file, 0, MY_SEEK_SET,
- MYF(MY_WME) ) == MY_FILEPOS_ERROR)
- {
- error = LOG_INFO_SEEK;
- goto err;
- }
-
- if(init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
- {
- error = LOG_INFO_MEM;
- goto err;
- }
+ if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0,
+ 0, MYF(MY_WME)))
+ {
+ error = LOG_INFO_MEM;
+ goto err;
+ }
+ if (init_dynamic_array(&logs_to_purge, sizeof(char*), 1024, 1024))
+ {
+ error = LOG_INFO_MEM;
+ goto err;
+ }
logs_to_purge_inited = 1;
- if(init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
- {
- error = LOG_INFO_MEM;
- goto err;
- }
+ if (init_dynamic_array(&logs_to_keep, sizeof(char*), 1024, 1024))
+ {
+ error = LOG_INFO_MEM;
+ goto err;
+ }
logs_to_keep_inited = 1;
for(;;)
+ {
+ my_off_t init_purge_offset= my_b_tell(&io_cache);
+ if (!(fname_len=my_b_gets(&io_cache, fname, FN_REFLEN)))
{
- if(!fgets(fname, FN_REFLEN, index_file))
- {
- if(feof(index_file))
- break;
- else
- error = LOG_INFO_IO;
- goto err;
- }
+ if(!io_cache.error)
+ break;
+ error = LOG_INFO_IO;
+ goto err;
+ }
- *(fname_end = (strend(fname) - 1)) = 0; // kill \n
- fname_len = (uint)(fname_end - fname);
-
- if(!memcmp(fname, to_log, fname_len + 1 ))
- {
- found_log = 1;
- purge_offset = my_ftell(index_file, MYF(MY_WME)) - fname_len - 1;
- }
+ fname[--fname_len]=0; // kill \n
+ if(!memcmp(fname, to_log, fname_len + 1 ))
+ {
+ found_log = 1;
+ purge_offset = init_purge_offset;
+ }
- if(!found_log && log_in_use(fname))
- // if one of the logs before the target is in use
- {
- error = LOG_INFO_IN_USE;
- goto err;
- }
+ // if one of the logs before the target is in use
+ if(!found_log && log_in_use(fname))
+ {
+ error = LOG_INFO_IN_USE;
+ goto err;
+ }
- p = sql_memdup(fname, (uint)(fname_end - fname) + 1);
- if((found_log) ?
- insert_dynamic(&logs_to_keep, (gptr) &p) :
- insert_dynamic(&logs_to_purge, (gptr) &p)
- )
- {
- error = LOG_INFO_MEM;
- goto err;
- }
- }
-
- if(!found_log)
+ if (!(p = sql_memdup(fname, (uint)(fname_end - fname) + 1)) ||
+ insert_dynamic(found_log ? &logs_to_keep : &logs_to_purge,
+ (gptr) &p))
{
- error = LOG_INFO_EOF;
+ error = LOG_INFO_MEM;
goto err;
}
+ }
+
+ end_io_cache(&io_cache);
+ if(!found_log)
+ {
+ error = LOG_INFO_EOF;
+ goto err;
+ }
for(i = 0; i < logs_to_purge.elements; i++)
- {
- char* l;
- get_dynamic(&logs_to_purge, (gptr)&l, i);
- if(my_delete(l, MYF(MY_WME)))
- sql_print_error("Error deleting %s during purge", l);
- }
+ {
+ char* l;
+ get_dynamic(&logs_to_purge, (gptr)&l, i);
+ if (my_delete(l, MYF(MY_WME)))
+ sql_print_error("Error deleting %s during purge", l);
+ }
// 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
// be safe
- my_fclose(index_file, MYF(MY_WME));
- if(!(index_file = my_fopen(index_file_name, O_BINARY|O_WRONLY,
- MYF(MY_WME))))
+#ifdef HAVE_FTRUNCATE
+ 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))))
{
sql_print_error("Ouch! Could not re-open the binlog index file \
during log purge for write");
error = LOG_INFO_FATAL;
goto err;
}
+#endif
for(i = 0; i < logs_to_keep.elements; i++)
+ {
+ char* l;
+ get_dynamic(&logs_to_keep, (gptr)&l, i);
+ if (my_write(index_file, l, strlen(l), MYF(MY_WME)) ||
+ my_write(index_file, "\n", 1, MYF(MY_WME)))
{
- char* l;
- get_dynamic(&logs_to_keep, (gptr)&l, i);
- fprintf(index_file, "%s\n", l);
+ error = LOG_INFO_FATAL;
+ goto err;
}
- 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;
- goto err;
}
+
// now update offsets
adjust_linfo_offsets(purge_offset);
error = 0;
+
err:
pthread_mutex_unlock(&LOCK_index);
if(logs_to_purge_inited)
delete_dynamic(&logs_to_purge);
if(logs_to_keep_inited)
delete_dynamic(&logs_to_keep);
-
+ end_io_cache(&io_cache);
return error;
-
}
+
// we assume that buf has at least FN_REFLEN bytes alloced
void MYSQL_LOG::make_log_name(char* buf, const char* log_ident)
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2af98d6fbf0..1aef744445f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -98,7 +98,7 @@ public:
char* get_log_fname() { return log_file_name; }
void lock_index() { pthread_mutex_lock(&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 */
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 5cdb5ab0706..ba155c72e49 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -720,66 +720,66 @@ int show_binlog_info(THD* thd)
int show_binlogs(THD* thd)
{
const char* errmsg = 0;
- FILE* index_file;
+ File index_file;
char fname[FN_REFLEN];
NET* net = &thd->net;
List<Item> field_list;
String* packet = &thd->packet;
+ IO_CACHE io_cache;
+ uint length;
if(!mysql_bin_log.is_open())
- {
- errmsg = "binlog is not open";
- goto err;
- }
+ {
+ errmsg = "binlog is not open";
+ goto err;
+ }
field_list.push_back(new Item_empty_string("Log_name", 128));
if(send_fields(thd, field_list, 1))
- {
- sql_print_error("Failed in send_fields");
- return 1;
- }
+ {
+ sql_print_error("Failed in send_fields");
+ return 1;
+ }
mysql_bin_log.lock_index();
index_file = mysql_bin_log.get_index_file();
- if(!index_file)
- {
- errmsg = "Uninitialized index file pointer";
- mysql_bin_log.unlock_index();
- goto err;
- }
- if(my_fseek(index_file, 0, MY_SEEK_SET, MYF(MY_WME)))
- {
- errmsg = "Failed on fseek()";
- mysql_bin_log.unlock_index();
- goto err;
- }
-
- while(fgets(fname, sizeof(fname), index_file))
+ if (index_file < 0)
+ {
+ errmsg = "Uninitialized index file pointer";
+ goto err2;
+ }
+ if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ errmsg = "Failed on init_io_cache()";
+ goto err2;
+ }
+ while ((length=my_b_gets(&io_cache, fname, sizeof(fname))))
+ {
+ fname[--length]=0;
+ int dir_len = dirname_length(fname);
+ packet->length(0);
+ net_store_data(packet, fname + dir_len, length-dir_len);
+ if(my_net_write(net, (char*) packet->ptr(), packet->length()))
{
- char* fname_end;
- *(fname_end = (strend(fname) - 1)) = 0;
- int dir_len = dirname_length(fname);
- packet->length(0);
- net_store_data(packet, fname + dir_len, (fname_end - fname)-dir_len);
- if(my_net_write(net, (char*) packet->ptr(), packet->length()))
- {
- sql_print_error("Failed in my_net_write");
- mysql_bin_log.unlock_index();
- return 1;
- }
+ sql_print_error("Failed in my_net_write");
+ end_io_cache(&io_cache);
+ mysql_bin_log.unlock_index();
+ return 1;
}
+ }
mysql_bin_log.unlock_index();
+ end_io_cache(&io_cache);
send_eof(net);
- err:
- if(errmsg)
- {
- send_error(net, 0, errmsg);
- return 1;
- }
-
- send_ok(net);
return 0;
+
+err2:
+ mysql_bin_log.unlock_index();
+ end_io_cache(&io_cache);
+err:
+ send_error(net, 0, errmsg);
+ return 1;
}