summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2000-11-16 00:24:11 +0200
committerunknown <monty@narttu.mysql.fi>2000-11-16 00:24:11 +0200
commitc7d2c59ceb4e3548eb74e5d8fba16e0f41ffc7d9 (patch)
tree31119bae32d48d3c415144eb5aed588455eefa1a /sql
parentdcf4e49369d91b78ab73b9de038d2729afb3a2a6 (diff)
parent9a846a52ae62f701c2d54d3f468e2ead393acf91 (diff)
downloadmariadb-git-c7d2c59ceb4e3548eb74e5d8fba16e0f41ffc7d9.tar.gz
merge
configure.in: Auto merged include/my_sys.h: Auto merged libmysql/libmysql.c: Auto merged sql/ha_berkeley.cc: Auto merged sql/handler.h: Auto merged sql/item_strfunc.cc: Auto merged sql/lex.h: Auto merged sql/mysqld.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_string.h: Auto merged BitKeeper/etc/logging_ok: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/filesort.cc22
-rw-r--r--sql/ha_berkeley.cc26
-rw-r--r--sql/ha_berkeley.h3
-rw-r--r--sql/handler.h1
-rw-r--r--sql/item_create.cc5
-rw-r--r--sql/item_create.h1
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/lex.h2
-rw-r--r--sql/lock.cc4
-rw-r--r--sql/log.cc439
-rw-r--r--sql/log_event.cc298
-rw-r--r--sql/log_event.h63
-rw-r--r--sql/mf_iocache.cc48
-rw-r--r--sql/mysqlbinlog.cc144
-rw-r--r--sql/mysqld.cc20
-rw-r--r--sql/net_pkg.cc10
-rw-r--r--sql/sql_class.cc13
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_insert.cc8
-rw-r--r--sql/sql_lex.h24
-rw-r--r--sql/sql_load.cc2
-rw-r--r--sql/sql_parse.cc36
-rw-r--r--sql/sql_repl.cc454
-rw-r--r--sql/sql_select.cc11
-rw-r--r--sql/sql_string.cc26
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_yacc.yy18
-rw-r--r--sql/time.cc10
-rw-r--r--sql/violite.c46
29 files changed, 900 insertions, 848 deletions
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 6d6bbe00182..220ff69a3e8 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -38,8 +38,8 @@ if (my_b_write((file),(byte*) (from),param->ref_length)) \
typedef struct st_buffpek { /* Struktur om sorteringsbuffrarna */
my_off_t file_pos; /* Where we are in the sort file */
- ha_rows count; /* Number of rows in table */
uchar *base,*key; /* key pointers */
+ ha_rows count; /* Number of rows in table */
ulong mem_count; /* numbers of keys in memory */
ulong max_keys; /* Max keys in buffert */
} BUFFPEK;
@@ -98,7 +98,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
BUFFPEK *buffpek;
ha_rows records;
uchar **sort_keys;
- gptr save_1,save_2;
IO_CACHE tempfile,*selected_records_file,*outfile;
SORTPARAM param;
DBUG_ENTER("filesort");
@@ -109,7 +108,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
outfile= table[0]->io_cache;
my_b_clear(&tempfile);
- save_1=save_2=0;
buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
param.ref_length= table[0]->file->ref_length;
@@ -148,7 +146,7 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
else
{
table[0]->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);/* Get record-count */
- records=table[0]->file->records+EXTRA_RECORDS;
+ records=table[0]->file->estimate_number_of_rows();
selected_records_file= 0;
}
if (param.sort_length == param.ref_length && records > param.max_rows)
@@ -160,16 +158,11 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
goto err;
#endif
- /* Reserve memory for IO_CACHE files */
- if (! (save_1=my_malloc(DISK_BUFFER_SIZE,MYF(MY_WME))) ||
- ! (save_2=my_malloc(DISK_BUFFER_SIZE,MYF(MY_WME))))
- goto err;
-
memavl=sortbuff_size;
while (memavl >= MIN_SORT_MEMORY)
{
- if ((records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
- (ulong) memavl)
+ if ((ulonglong) (records+1)*(param.sort_length+sizeof(char*))+sizeof(BUFFPEK)*10 <
+ (ulonglong) memavl)
param.keys=(uint) records+1;
else
{
@@ -207,10 +200,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
my_error(ER_OUTOFMEMORY,MYF(ME_ERROR+ME_WAITTANG),sortbuff_size);
goto err;
}
- my_free(save_1,MYF(0)); /* Free for later use */
- my_free(save_2,MYF(0));
- save_1=save_2=0;
-
param.sort_form= table[0];
param.end=(param.local_sortorder=sortorder)+s_length;
if ((records=find_all_keys(&param,select,sort_keys,buffpek,&maxbuffer,
@@ -252,8 +241,6 @@ ha_rows filesort(TABLE **table, SORT_FIELD *sortorder, uint s_length,
#endif
x_free((gptr) sort_keys);
x_free((gptr) buffpek);
- x_free(save_1);
- x_free(save_2);
close_cached_file(&tempfile);
if (my_b_inited(outfile))
{
@@ -382,6 +369,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
}
if (*killed)
{
+ DBUG_PRINT("info",("Sort killed by user"));
(void) file->extra(HA_EXTRA_NO_CACHE);
file->rnd_end();
DBUG_RETURN(HA_POS_ERROR); /* purecov: inspected */
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 6cf97f16bb8..490a6db89e5 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -25,8 +25,9 @@
We will need an updated Berkeley DB version for this.
- Killing threads that has got a 'deadlock'
- SHOW TABLE STATUS should give more information about the table.
- - Get a more accurate count of the number of rows.
- We could store the found number of rows when the table is scanned.
+ - Get a more accurate count of the number of rows (estimate_number_of_rows()).
+ We could store the found number of rows when the table is scanned and
+ then increment the counter for each attempted write.
- We will need a manager thread that calls flush_logs, removes old
logs and makes checkpoints at given intervals.
- When not using UPDATE IGNORE, don't make a sub transaction but abort
@@ -42,7 +43,6 @@
- LOCK TABLES
- CHAR keys
- BLOBS
- - delete from t1;
*/
@@ -60,6 +60,7 @@
#define HA_BERKELEY_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_BERKELEY_RANGE_COUNT 100
+#define HA_BERKELEY_MAX_ROWS 10000000 /* Max rows in table */
const char *ha_berkeley_ext=".db";
bool berkeley_skip=0;
@@ -1297,7 +1298,7 @@ void ha_berkeley::info(uint flag)
DBUG_ENTER("info");
if (flag & HA_STATUS_VARIABLE)
{
- records = HA_BERKELEY_ROWS_IN_TABLE; // Just to get optimisations right
+ records = estimate_number_of_rows(); // Just to get optimisations right
deleted = 0;
}
else if (flag & HA_STATUS_ERRKEY)
@@ -1607,4 +1608,21 @@ void ha_berkeley::update_auto_primary_key()
pthread_mutex_unlock(&share->mutex);
}
+/*
+ Return an estimated of the number of rows in the table.
+ Used when sorting to allocate buffers and by the optimizer.
+*/
+
+ha_rows ha_berkeley::estimate_number_of_rows()
+{
+ ulonglong max_ident;
+ ulonglong max_rows=table->max_rows ? table->max_rows : HA_BERKELEY_MAX_ROWS;
+ if (!hidden_primary_key)
+ return (ha_rows) max_rows;
+ pthread_mutex_lock(&share->mutex);
+ max_ident=share->auto_ident+EXTRA_RECORDS;
+ pthread_mutex_unlock(&share->mutex);
+ return (ha_rows) min(max_ident,max_rows);
+}
+
#endif /* HAVE_BERKELEY_DB */
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 84061ae09be..1d1de613ce0 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -91,7 +91,8 @@ class ha_berkeley: public handler
uint max_keys() const { return MAX_KEY-1; }
uint max_key_parts() const { return MAX_REF_PARTS; }
uint max_key_length() const { return MAX_KEY_LENGTH; }
- uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
+ uint extra_rec_buf_length() { return BDB_HIDDEN_PRIMARY_KEY_LENGTH; }
+ ha_rows estimate_number_of_rows();
bool fast_key_read() { return 1;}
bool has_transactions() { return 1;}
diff --git a/sql/handler.h b/sql/handler.h
index 84c14538f4b..bdc58ee7356 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -203,6 +203,7 @@ public:
virtual bool fast_key_read() { return 0;}
virtual bool has_transactions(){ return 0;}
virtual uint extra_rec_buf_length() { return 0; }
+ virtual ha_rows estimate_number_of_rows() { return records+EXTRA_RECORDS; }
virtual int index_init(uint idx) { active_index=idx; return 0;}
virtual int index_end() {return 0; }
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 8c62643b35a..8e6332d4e16 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -352,11 +352,6 @@ Item *create_func_to_days(Item* a)
return new Item_func_to_days(a);
}
-Item *create_func_truncate (Item *a, Item *b)
-{
- return new Item_func_round(a,b,1);
-}
-
Item *create_func_ucase(Item* a)
{
return new Item_func_ucase(a);
diff --git a/sql/item_create.h b/sql/item_create.h
index aa617946d98..de2726b32b0 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -81,7 +81,6 @@ Item *create_func_tan(Item* a);;
Item *create_func_time_format(Item *a, Item *b);
Item *create_func_time_to_sec(Item* a);
Item *create_func_to_days(Item* a);
-Item *create_func_truncate (Item *a, Item *b);
Item *create_func_ucase(Item* a);
Item *create_func_version(void);
Item *create_func_weekday(Item* a);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 6b8b3762aa1..39bbdcaff1f 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1598,7 +1598,7 @@ String *Item_load_file::val_str(String *str)
if (!(file_name= args[0]->val_str(str)) ||
!(current_thd->master_access & FILE_ACL) ||
- !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_FAE)))
+ !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_WME)))
goto err;
if (!(stat_info.st_mode & S_IROTH))
{
diff --git a/sql/lex.h b/sql/lex.h
index a75fa07c3b7..503ce6998bb 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -302,6 +302,7 @@ static SYMBOL symbols[] = {
{ "TINYTEXT", SYM(TINYTEXT),0,0},
{ "TINYINT", SYM(TINYINT),0,0},
{ "TRAILING", SYM(TRAILING),0,0},
+ { "TRUNCATE", SYM(TRUNCATE_SYM),0,0},
{ "TO", SYM(TO_SYM),0,0},
{ "TYPE", SYM(TYPE_SYM),0,0},
{ "UNION", SYM(UNION_SYM),0,0},
@@ -443,7 +444,6 @@ static SYMBOL sql_functions[] = {
{ "TIME_TO_SEC", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)},
{ "TO_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)},
{ "TRIM", SYM(TRIM),0,0},
- { "TRUNCATE", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_truncate )},
{ "UCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
{ "UNIQUE_USERS", SYM(UNIQUE_USERS),0,0},
diff --git a/sql/lock.cc b/sql/lock.cc
index 4c7ae8e950b..c85983b65d6 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -70,8 +70,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
thd->proc_info="Waiting for table";
pthread_mutex_unlock(&thd->mysys_var->mutex);
- while (global_read_lock && ! thd->killed ||
- thd->version != refresh_version)
+ while (global_read_lock && ! thd->killed &&
+ thd->version == refresh_version)
{
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
diff --git a/sql/log.cc b/sql/log.cc
index bf99bb32f09..7172d043552 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -25,8 +25,6 @@
#include <stdarg.h>
#include <m_ctype.h> // For test_if_number
-
-
MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern I_List<i_string> binlog_do_db, binlog_ignore_db;
@@ -75,26 +73,25 @@ static int find_uniq_filename(char *name)
DBUG_RETURN(0);
}
-
-
-MYSQL_LOG::MYSQL_LOG(): file(0),index_file(0),last_time(0),query_start(0),
- name(0), log_type(LOG_CLOSED),write_error(0),inited(0),
- no_rotate(0)
+MYSQL_LOG::MYSQL_LOG(): last_time(0), query_start(0),
+ name(0), log_type(LOG_CLOSED),write_error(0),
+ inited(0), opened(0), no_rotate(0)
{
/*
We don't want to intialize LOCK_Log here as the thread system may
not have been initailized yet. We do it instead at 'open'.
*/
- index_file_name[0] = 0;
+ index_file_name[0] = 0;
+ bzero((char*) &log_file,sizeof(log_file));
}
MYSQL_LOG::~MYSQL_LOG()
{
if (inited)
- {
- (void) pthread_mutex_destroy(&LOCK_log);
- (void) pthread_mutex_destroy(&LOCK_index);
- }
+ {
+ (void) pthread_mutex_destroy(&LOCK_log);
+ (void) pthread_mutex_destroy(&LOCK_index);
+ }
}
void MYSQL_LOG::set_index_file_name(const char* index_file_name)
@@ -106,6 +103,7 @@ void MYSQL_LOG::set_index_file_name(const char* index_file_name)
this->index_file_name[0] = 0;
}
+
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
{
if (log_type == LOG_NORMAL)
@@ -129,58 +127,60 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
const char *new_name)
{
+ MY_STAT tmp_stat;
+ char buff[512];
+ File file= -1;
+ bool do_magic;
if (!inited)
{
inited=1;
(void) pthread_mutex_init(&LOCK_log,NULL);
(void) pthread_mutex_init(&LOCK_index, NULL);
- if(log_type_arg == LOG_BIN && *fn_ext(log_name))
+ if (log_type_arg == LOG_BIN && *fn_ext(log_name))
no_rotate = 1;
}
-
+
log_type=log_type_arg;
- name=my_strdup(log_name,MYF(0));
+ if (!(name=my_strdup(log_name,MYF(MY_WME))))
+ goto err;
if (new_name)
strmov(log_file_name,new_name);
else if (generate_new_name(log_file_name, name))
- return;
+ goto err;
if (log_type == LOG_BIN && !index_file_name[0])
fn_format(index_file_name, name, mysql_data_home, ".index", 6);
db[0]=0;
- MY_STAT tmp_stat;
- bool do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
- &tmp_stat, MYF(0)));
+ do_magic = ((log_type == LOG_BIN) && !my_stat(log_file_name,
+ &tmp_stat, MYF(0)));
- file=my_fopen(log_file_name,O_APPEND | O_WRONLY | O_BINARY,
- MYF(MY_WME | ME_WAITTANG));
- if (!file)
- {
- my_free(name,MYF(0));
- name=0;
- log_type=LOG_CLOSED;
- return;
- }
+ if ((file=my_open(log_file_name,O_APPEND | O_WRONLY | O_BINARY,
+ MYF(MY_WME | ME_WAITTANG))) < 0 ||
+ init_io_cache(&log_file, file, IO_SIZE, WRITE_CACHE,
+ my_tell(file,MYF(MY_WME)), 0, MYF(MY_WME | MY_NABP)))
+ goto err;
if (log_type == LOG_NORMAL)
{
+ char *end;
#ifdef __NT__
- fprintf(file, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port);
+ sprintf(buff, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port);
#else
- fprintf(file, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
+ sprintf(buff, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
#endif
- fprintf(file,"Time Id Command Argument\n");
- (void) fflush(file);
+ end=strmov(strend(buff),"Time Id Command Argument\n");
+ if (my_b_write(&log_file,buff,(uint) (end-buff)) ||
+ flush_io_cache(&log_file))
+ goto err;
}
else if (log_type == LOG_NEW)
{
time_t skr=time(NULL);
struct tm tm_tmp;
localtime_r(&skr,&tm_tmp);
-
- fprintf(file,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
+ sprintf(buff,"# %s, Version: %s at %02d%02d%02d %2d:%02d:%02d\n",
my_progname,server_version,
tm_tmp.tm_year % 100,
tm_tmp.tm_mon+1,
@@ -188,45 +188,49 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
tm_tmp.tm_hour,
tm_tmp.tm_min,
tm_tmp.tm_sec);
- (void) fflush(file);
+ if (my_b_write(&log_file,buff,(uint) strlen(buff)) ||
+ flush_io_cache(&log_file))
+ goto err;
}
else if (log_type == LOG_BIN)
{
-
// Explanation of the boolean black magic:
//
// if we are supposed to write magic number try write
// clean up if failed
// then if index_file has not been previously opened, try to open it
// clean up if failed
- if((do_magic && my_fwrite(file, (byte*)BINLOG_MAGIC, 4,
- MYF(MY_NABP|MY_WME)) ||
- (!index_file &&
- !(index_file = my_fopen(index_file_name,O_APPEND | O_BINARY | O_RDWR,
- MYF(MY_WME))))))
- {
- my_fclose(file,MYF(MY_WME));
- my_free(name,MYF(0));
- name=0;
- file=0;
- log_type=LOG_CLOSED;
- return;
- }
+
+ if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) ||
+ (index_file < 0 &&
+ (index_file = my_open(index_file_name,O_APPEND | O_BINARY | O_RDWR,
+ MYF(MY_WME))) < 0))
+ goto err;
Start_log_event s;
- s.write(file);
+ s.write(&log_file);
pthread_mutex_lock(&LOCK_index);
- my_fseek(index_file, 0L, MY_SEEK_END, MYF(MY_WME));
- fprintf(index_file, "%s\n", log_file_name);
- fflush(index_file);
+ my_write(index_file, log_file_name,strlen(log_file_name), MYF(0));
+ my_write(index_file, "\n",1, MYF(0));
pthread_mutex_unlock(&LOCK_index);
}
+ return;
+
+err:
+ if (file >= 0)
+ my_close(file,MYF(0));
+ end_io_cache(&log_file);
+ x_free(name); name=0;
+ log_type=LOG_CLOSED;
+
+ return;
+
}
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
{
pthread_mutex_lock(&LOCK_log);
- strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name));
- linfo->pos = my_ftell(file, MYF(MY_WME));
+ strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1);
+ linfo->pos = my_b_tell(&log_file);
pthread_mutex_unlock(&LOCK_log);
return 0;
}
@@ -234,50 +238,85 @@ int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
// if log_name is "" we stop at the first entry
int MYSQL_LOG::find_first_log(LOG_INFO* linfo, const char* log_name)
{
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- if(!index_file) return LOG_INFO_INVALID;
+ if (index_file < 0)
+ return LOG_INFO_INVALID;
int error = 0;
char* fname = linfo->log_file_name;
int log_name_len = (uint) strlen(log_name);
+ IO_CACHE io_cache;
+ // mutex needed because we need to make sure the file pointer does not move
+ // from under our feet
pthread_mutex_lock(&LOCK_index);
- if(my_fseek(index_file, 0L, MY_SEEK_SET, MYF(MY_WME) ) == MY_FILEPOS_ERROR)
+ if (init_io_cache(&io_cache, index_file, IO_SIZE, READ_CACHE, (my_off_t) 0,
+ 0, MYF(MY_WME)))
+ {
+ error = LOG_INFO_SEEK;
+ goto err;
+ }
+ for(;;)
+ {
+ uint length;
+ if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
{
- error = LOG_INFO_SEEK;
+ error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
goto err;
}
- for(;;)
+ // if the log entry matches, empty string matching anything
+ if (!log_name_len ||
+ (log_name_len == length+1 && fname[log_name_len] == '\n' &&
+ !memcmp(fname, log_name, log_name_len)))
{
- if(!fgets(fname, FN_REFLEN, index_file))
- {
- error = feof(index_file) ? LOG_INFO_EOF : LOG_INFO_IO;
- goto err;
- }
-
- // if the log entry matches, empty string matching anything
- if(!log_name_len || (fname[log_name_len] == '\n' &&
- !memcmp(fname, log_name, log_name_len)))
- {
- if(log_name_len)
- fname[log_name_len] = 0; // to kill \n
- else
- {
- *(strend(fname) - 1) = 0;
- }
- linfo->index_file_offset = my_ftell(index_file, MYF(MY_WME));
- break;
- }
+ fname[length-1]=0; // remove last \n
+ linfo->index_file_offset = my_b_tell(&io_cache);
+ break;
}
-
+ }
error = 0;
+
err:
pthread_mutex_unlock(&LOCK_index);
+ end_io_cache(&io_cache);
return error;
}
+
+int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
+{
+ // mutex needed because we need to make sure the file pointer does not move
+ // from under our feet
+ if (!index_file) return LOG_INFO_INVALID;
+ int error = 0;
+ char* fname = linfo->log_file_name;
+ IO_CACHE io_cache;
+ uint length;
+
+ pthread_mutex_lock(&LOCK_index);
+ if (init_io_cache(&io_cache, index_file, IO_SIZE,
+ READ_CACHE, (my_off_t) linfo->index_file_offset, 0,
+ MYF(MY_WME)))
+ {
+ error = LOG_INFO_SEEK;
+ goto err;
+ }
+ if (!(length=my_b_gets(&io_cache, fname, FN_REFLEN)))
+ {
+ error = !io_cache.error ? LOG_INFO_EOF : LOG_INFO_IO;
+ goto err;
+ }
+ fname[length-1]=0; // kill /n
+ linfo->index_file_offset = my_b_tell(&io_cache);
+ error = 0;
+
+err:
+ pthread_mutex_unlock(&LOCK_index);
+ end_io_cache(&io_cache);
+ return error;
+}
+
+
int MYSQL_LOG::purge_logs(THD* thd, const char* to_log)
{
if(!index_file) return LOG_INFO_INVALID;
@@ -409,63 +448,21 @@ err:
}
-int MYSQL_LOG::find_next_log(LOG_INFO* linfo)
-{
- // mutex needed because we need to make sure the file pointer does not move
- // from under our feet
- if(!index_file) return LOG_INFO_INVALID;
- int error = 0;
- char* fname = linfo->log_file_name;
- char* end ;
-
- pthread_mutex_lock(&LOCK_index);
- if(linfo->fatal)
- {
- error = LOG_INFO_FATAL;
- goto err;
- }
-
- if(my_fseek(index_file, linfo->index_file_offset, MY_SEEK_SET, MYF(MY_WME) ) == MY_FILEPOS_ERROR)
- {
- error = LOG_INFO_SEEK;
- goto err;
- }
-
- if(!fgets(fname, FN_REFLEN, index_file))
- {
- error = feof(index_file) ? LOG_INFO_EOF : LOG_INFO_IO;
- goto err;
- }
-
- end = strend(fname) - 1;
- *end = 0; // kill /n
- linfo->index_file_offset = ftell(index_file);
- error = 0;
-err:
- pthread_mutex_unlock(&LOCK_index);
- 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)
{
- if(inited)
- {
- int dir_len = dirname_length(log_file_name);
- int ident_len = (uint) strlen(log_ident);
- if(dir_len + ident_len + 1 > FN_REFLEN)
- {
- buf[0] = 0;
- return; // protection agains malicious buffer overflow
- }
+ buf[0] = 0; // In case of error
+ if (inited)
+ {
+ int dir_len = dirname_length(log_file_name);
+ int ident_len = (uint) strlen(log_ident);
+ if (dir_len + ident_len + 1 > FN_REFLEN)
+ return; // protection agains malicious buffer overflow
- memcpy(buf, log_file_name, dir_len);
- memcpy(buf + dir_len, log_ident, ident_len + 1); // this takes care of \0
- // at the end
- }
- else
- buf[0] = 0;
+ memcpy(buf, log_file_name, dir_len);
+ // copy filename + end null
+ memcpy(buf + dir_len, log_ident, ident_len + 1);
+ }
}
bool MYSQL_LOG::is_active(const char* log_file_name)
@@ -475,15 +472,17 @@ bool MYSQL_LOG::is_active(const char* log_file_name)
void MYSQL_LOG::new_file()
{
- if (file)
+ // only rotate open logs that are marked non-rotatable
+ // (binlog with constant name are non-rotatable)
+ if (is_open() && ! no_rotate)
{
- if(no_rotate) // do not rotate logs that are marked non-rotatable
- return; // ( for binlog with constant name)
-
char new_name[FN_REFLEN], *old_name=name;
VOID(pthread_mutex_lock(&LOCK_log));
if (generate_new_name(new_name, name))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_log));
return; // Something went wrong
+ }
if (log_type == LOG_BIN)
{
/*
@@ -491,15 +490,13 @@ void MYSQL_LOG::new_file()
to change base names at some point.
*/
Rotate_log_event r(new_name+dirname_length(new_name));
- r.write(file);
+ r.write(&log_file);
VOID(pthread_cond_broadcast(&COND_binlog_update));
}
name=0;
close();
open(old_name, log_type, new_name);
my_free(old_name,MYF(0));
- if (!file) // Something went wrong
- log_type=LOG_CLOSED;
last_time=query_start=0;
write_error=0;
VOID(pthread_mutex_unlock(&LOCK_log));
@@ -514,7 +511,10 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
{
va_list args;
va_start(args,format);
+ char buff[32];
VOID(pthread_mutex_lock(&LOCK_log));
+
+ /* Test if someone closed after the is_open test */
if (log_type != LOG_CLOSED)
{
time_t skr;
@@ -544,28 +544,30 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
struct tm *start;
localtime_r(&skr,&tm_tmp);
start=&tm_tmp;
- if (fprintf(file,"%02d%02d%02d %2d:%02d:%02d\t",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec) < 0)
+ /* Note that my_b_write() assumes it knows the length for this */
+ sprintf(buff,"%02d%02d%02d %2d:%02d:%02d\t",
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec);
+ if (my_b_write(&log_file,buff,16))
error=errno;
}
- else if (fputs("\t\t",file) < 0)
+ else if (my_b_write(&log_file,"\t\t",2) < 0)
error=errno;
- if (fprintf(file,"%7ld %-10.10s",
- id,command_name[(uint) command]) < 0)
+ sprintf(buff,"%7ld %-10.10s", id,command_name[(uint) command]);
+ if (my_b_write(&log_file,buff,strlen(buff)))
error=errno;
if (format)
{
- if (fputc(' ',file) < 0 || vfprintf(file,format,args) < 0)
+ if (my_b_write(&log_file," ",1) ||
+ my_b_printf(&log_file,format,args) == (uint) -1)
error=errno;
}
- if (fputc('\n',file) < 0)
- error=errno;
- if (fflush(file) < 0)
+ if (my_b_write(&log_file,"\n",1) ||
+ flush_io_cache(&log_file))
error=errno;
if (error && ! write_error)
{
@@ -585,7 +587,7 @@ void MYSQL_LOG::write(Query_log_event* event_info)
if (is_open())
{
VOID(pthread_mutex_lock(&LOCK_log));
- if (file)
+ if (is_open())
{
THD *thd=event_info->thd;
if ((!(thd->options & OPTION_BIN_LOG) &&
@@ -599,43 +601,38 @@ void MYSQL_LOG::write(Query_log_event* event_info)
if (thd->last_insert_id_used)
{
Intvar_log_event e((uchar)LAST_INSERT_ID_EVENT, thd->last_insert_id);
- if (e.write(file))
+ if (e.write(&log_file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
}
-
if (thd->insert_id_used)
{
Intvar_log_event e((uchar)INSERT_ID_EVENT, thd->last_insert_id);
- if(e.write(file))
+ if (e.write(&log_file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
goto err;
}
}
-
- if(thd->convert_set)
+ if (thd->convert_set)
+ {
+ char buf[1024] = "SET CHARACTER SET ";
+ char* p = strend(buf);
+ p = strmov(p, thd->convert_set->name);
+ int save_query_length = thd->query_length;
+ // just in case somebody wants it later
+ thd->query_length = (uint)(p - buf);
+ Query_log_event e(thd, buf);
+ if (e.write(&log_file))
{
- char buf[1024] = "SET CHARACTER SET ";
- char* p = strend(buf);
- p = strmov(p, thd->convert_set->name);
- int save_query_length = thd->query_length;
- // just in case somebody wants it later
- thd->query_length = (uint)(p - buf);
- Query_log_event e(thd, buf);
- if(e.write(file))
- {
- sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
- goto err;
- }
-
- thd->query_length = save_query_length; // clean up
-
+ sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
+ goto err;
}
-
- if (event_info->write(file))
+ thd->query_length = save_query_length; // clean up
+ }
+ if (event_info->write(&log_file) || flush_io_cache(&log_file))
{
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
}
@@ -651,13 +648,13 @@ void MYSQL_LOG::write(Load_log_event* event_info)
if (is_open())
{
VOID(pthread_mutex_lock(&LOCK_log));
- if (file)
+ if (is_open())
{
THD *thd=event_info->thd;
if ((thd->options & OPTION_BIN_LOG) ||
!(thd->master_access & PROCESS_ACL))
{
- if (event_info->write(file))
+ if (event_info->write(&log_file) || flush_io_cache(&log_file))
sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
VOID(pthread_cond_broadcast(&COND_binlog_update));
}
@@ -676,7 +673,7 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
{
time_t current_time;
VOID(pthread_mutex_lock(&LOCK_log));
- if (file)
+ if (is_open())
{ // Safety agains reopen
int error=0;
char buff[80],*end;
@@ -695,37 +692,42 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
last_time=current_time;
struct tm tm_tmp;
struct tm *start;
+ char buff[32];
localtime_r(&current_time,&tm_tmp);
start=&tm_tmp;
- if (fprintf(file,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec) < 0)
+ /* Note that my_b_write() assumes it knows the length for this */
+ sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n",
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec);
+ if (my_b_write(&log_file,buff,24))
error=errno;
}
- if (fprintf(file, "# User@Host: %s [%s] @ %s [%s]\n",
- thd->priv_user,
- thd->user,
- thd->host ? thd->host : "",
- thd->ip ? thd->ip : "") < 0)
- error=errno;;
+ if (my_b_printf(&log_file, "# User@Host: %s [%s] @ %s [%s]\n",
+ thd->priv_user,
+ thd->user,
+ thd->host ? thd->host : "",
+ thd->ip ? thd->ip : ""))
+ error=errno;
}
if (query_start)
{
/* For slow query log */
if (!(specialflag & SPECIAL_LONG_LOG_FORMAT))
current_time=time(NULL);
- fprintf(file,"# Time: %lu Lock_time: %lu Rows_sent: %lu\n",
- (ulong) (current_time - query_start),
- (ulong) (thd->time_after_lock - query_start),
- (ulong) thd->sent_row_count);
+ if (my_b_printf(&log_file,
+ "# Time: %lu Lock_time: %lu Rows_sent: %lu\n",
+ (ulong) (current_time - query_start),
+ (ulong) (thd->time_after_lock - query_start),
+ (ulong) thd->sent_row_count))
+ error=errno;
}
if (thd->db && strcmp(thd->db,db))
{ // Database changed
- if (fprintf(file,"use %s;\n",thd->db) < 0)
+ if (my_b_printf(&log_file,"use %s;\n",thd->db))
error=errno;
strmov(db,thd->db);
}
@@ -757,7 +759,8 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
*end++=';';
*end++='\n';
*end=0;
- if (fputs("SET ",file) < 0 || fputs(buff+1,file) < 0)
+ if (my_b_write(&log_file,"SET ",4) ||
+ my_b_write(&log_file,buff+1,(uint) (end-buff)-1))
error=errno;
}
if (!query)
@@ -765,10 +768,9 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
query="#adminstrator command";
query_length=21;
}
- if (my_fwrite(file,(byte*) query,query_length,MYF(MY_NABP)) ||
- fputc(';',file) < 0 || fputc('\n',file) < 0)
- error=errno;
- if (fflush(file) < 0)
+ if (my_b_write(&log_file,(byte*) query,query_length) ||
+ my_b_write(&log_file,";\n",2) ||
+ flush_io_cache(&log_file))
error=errno;
if (error && ! write_error)
{
@@ -780,51 +782,48 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
}
}
-
-
+#ifdef TO_BE_REMOVED
void MYSQL_LOG::flush()
{
- if (file)
- if (fflush(file) < 0 && ! write_error)
+ if (is_open())
+ if (flush_io_cache(log_file) && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
}
}
+#endif
void MYSQL_LOG::close(bool exiting)
{ // One can't set log_type here!
- if (file)
+ if (is_open())
{
+ File file=log_file.file;
if (log_type == LOG_BIN)
{
Stop_log_event s;
- s.write(file);
+ s.write(&log_file);
VOID(pthread_cond_broadcast(&COND_binlog_update));
}
- if (my_fclose(file,MYF(0)) < 0 && ! write_error)
+ end_io_cache(&log_file);
+ if (my_close(file,MYF(0)) < 0 && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
}
- file=0;
- }
- if (name)
- {
- my_free(name,MYF(0));
- name=0;
+ log_type=LOG_CLOSED;
}
-
- if (exiting && index_file)
+ if (exiting && index_file >= 0)
{
- if (my_fclose(index_file,MYF(0)) < 0 && ! write_error)
+ if (my_close(index_file,MYF(0)) < 0 && ! write_error)
{
write_error=1;
sql_print_error(ER(ER_ERROR_ON_WRITE),name,errno);
}
index_file=0;
}
+ safeFree(name);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 62a3658bc9f..9e739da1c9d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -26,84 +26,78 @@
static void pretty_print_char(FILE* file, int c)
{
fputc('\'', file);
- switch(c)
- {
- case '\n': fprintf(file, "\\n"); break;
- case '\r': fprintf(file, "\\r"); break;
- case '\\': fprintf(file, "\\\\"); break;
- case '\b': fprintf(file, "\\b"); break;
- case '\'': fprintf(file, "\\'"); break;
- case 0 : fprintf(file, "\\0"); break;
- default:
- fputc(c, file);
- break;
- }
- fputc( '\'', file);
+ switch(c) {
+ case '\n': fprintf(file, "\\n"); break;
+ case '\r': fprintf(file, "\\r"); break;
+ case '\\': fprintf(file, "\\\\"); break;
+ case '\b': fprintf(file, "\\b"); break;
+ case '\'': fprintf(file, "\\'"); break;
+ case 0 : fprintf(file, "\\0"); break;
+ default:
+ fputc(c, file);
+ break;
+ }
+ fputc('\'', file);
}
-int Query_log_event::write(FILE* file)
+int Query_log_event::write(IO_CACHE* file)
{
return query ? Log_event::write(file) : -1;
}
-int Log_event::write(FILE* file)
+int Log_event::write(IO_CACHE* file)
{
- if (write_header(file)
- || write_data(file) || fflush(file)) return -1;
- return 0;
+ return (write_header(file) || write_data(file)) ? -1 : 0;
}
-int Log_event::write_header(FILE* file)
+int Log_event::write_header(IO_CACHE* file)
{
- char buf[LOG_EVENT_HEADER_LEN];
// make sure to change this when the header gets bigger
+ char buf[LOG_EVENT_HEADER_LEN];
char* pos = buf;
int4store(pos, when); // timestamp
pos += 4;
*pos++ = get_type_code(); // event type code
int4store(pos, server_id);
pos += 4;
- int4store(pos, get_data_size() + LOG_EVENT_HEADER_LEN);
+ long tmp=get_data_size() + LOG_EVENT_HEADER_LEN;
+ int4store(pos, tmp);
pos += 4;
- return (my_fwrite(file, (byte*) buf, (uint) (pos - buf),
- MYF(MY_NABP | MY_WME)));
+ return (my_b_write(file, (byte*) buf, (uint) (pos - buf)));
}
#ifndef MYSQL_CLIENT
-int Log_event::read_log_event(FILE* file, String* packet,
+int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
ulong data_len;
char buf[LOG_EVENT_HEADER_LEN];
- if(log_lock)
+ if (log_lock)
pthread_mutex_lock(log_lock);
- if (my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP)))
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return feof(file) ? LOG_READ_EOF: LOG_READ_IO;
- }
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
+ {
+ if (log_lock) pthread_mutex_unlock(log_lock);
+ return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
+ }
data_len = uint4korr(buf + EVENT_LEN_OFFSET);
if (data_len < LOG_EVENT_HEADER_LEN || data_len > MAX_EVENT_LEN)
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return LOG_READ_BOGUS;
- }
+ {
+ if (log_lock) pthread_mutex_unlock(log_lock);
+ return LOG_READ_BOGUS;
+ }
packet->append(buf, sizeof(buf));
data_len -= LOG_EVENT_HEADER_LEN;
- if (!data_len)
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return 0; // the event does not have a data section
- }
- if (packet->append(file, data_len, MYF(MY_WME|MY_NABP)))
+ if (data_len)
+ {
+ if (packet->append(file, data_len))
{
if(log_lock)
pthread_mutex_unlock(log_lock);
- return feof(file) ? LOG_READ_TRUNC: LOG_READ_IO;
+ return file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO;
}
-
- if(log_lock) pthread_mutex_unlock(log_lock);
+ }
+ if (log_lock) pthread_mutex_unlock(log_lock);
return 0;
}
@@ -111,18 +105,18 @@ int Log_event::read_log_event(FILE* file, String* packet,
// allocates memory - the caller is responsible for clean-up
-Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
+Log_event* Log_event::read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock)
{
time_t timestamp;
uint32 server_id;
char buf[LOG_EVENT_HEADER_LEN-4];
if(log_lock) pthread_mutex_lock(log_lock);
- if (my_fread(file, (byte *) buf, sizeof(buf), MY_NABP))
- {
- if(log_lock) pthread_mutex_unlock(log_lock);
- return NULL;
- }
+ if (my_b_read(file, (byte *) buf, sizeof(buf)))
+ {
+ if (log_lock) pthread_mutex_unlock(log_lock);
+ return NULL;
+ }
timestamp = uint4korr(buf);
server_id = uint4korr(buf + 5);
@@ -132,13 +126,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
{
Query_log_event* q = new Query_log_event(file, timestamp, server_id);
if(log_lock) pthread_mutex_unlock(log_lock);
-
if (!q->query)
{
delete q;
- return NULL;
+ q=NULL;
}
-
return q;
}
@@ -146,13 +138,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
{
Load_log_event* l = new Load_log_event(file, timestamp, server_id);
if(log_lock) pthread_mutex_unlock(log_lock);
-
if (!l->table_name)
{
delete l;
- return NULL;
+ l=NULL;
}
-
return l;
}
@@ -165,9 +155,8 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
if (!r->new_log_ident)
{
delete r;
- return NULL;
+ r=NULL;
}
-
return r;
}
@@ -179,9 +168,8 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
if (e->type == INVALID_INT_EVENT)
{
delete e;
- return NULL;
+ e=NULL;
}
-
return e;
}
@@ -198,12 +186,11 @@ Log_event* Log_event::read_log_event(FILE* file, pthread_mutex_t* log_lock)
return e;
}
default:
- if(log_lock) pthread_mutex_unlock(log_lock);
- return NULL;
+ break;
}
- //impossible
- if(log_lock) pthread_mutex_unlock(log_lock);
+ // default
+ if (log_lock) pthread_mutex_unlock(log_lock);
return NULL;
}
@@ -323,26 +310,24 @@ void Rotate_log_event::print(FILE* file, bool short_form)
fflush(file);
}
-Rotate_log_event::Rotate_log_event(FILE* file, time_t when_arg,
+Rotate_log_event::Rotate_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id):
Log_event(when_arg, 0, 0, server_id),new_log_ident(NULL),alloced(0)
{
char *tmp_ident;
char buf[4];
- if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
return;
-
ulong event_len;
event_len = uint4korr(buf);
- if(event_len < ROTATE_EVENT_OVERHEAD)
+ if (event_len < ROTATE_EVENT_OVERHEAD)
return;
ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD);
-
if (!(tmp_ident = (char*) my_malloc((uint)ident_len, MYF(MY_WME))))
return;
- if (my_fread( file, (byte*) tmp_ident, (uint)ident_len, MYF(MY_NABP | MY_WME)))
+ if (my_b_read( file, (byte*) tmp_ident, (uint) ident_len))
{
my_free((gptr) tmp_ident, MYF(0));
return;
@@ -376,21 +361,18 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len):
alloced = 1;
}
-int Rotate_log_event::write_data(FILE* file)
+int Rotate_log_event::write_data(IO_CACHE* file)
{
- if (my_fwrite(file, (byte*) new_log_ident, (uint) ident_len,
- MYF(MY_NABP | MY_WME)))
- return -1;
- return 0;
+ return my_b_write(file, (byte*) new_log_ident, (uint) ident_len) ? -1 :0;
}
-Query_log_event::Query_log_event(FILE* file, time_t when_arg,
+Query_log_event::Query_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id):
Log_event(when_arg,0,0,server_id),data_buf(0),query(NULL),db(NULL)
{
char buf[QUERY_HEADER_LEN + 4];
ulong data_len;
- if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
return; // query == NULL will tell the
// caller there was a problem
data_len = uint4korr(buf);
@@ -402,9 +384,10 @@ Query_log_event::Query_log_event(FILE* file, time_t when_arg,
db_len = (uint)buf[12];
error_code = uint2korr(buf + 13);
+ /* Allocate one byte extra for end \0 */
if (!(data_buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
return;
- if (my_fread( file, (byte*) data_buf, data_len, MYF(MY_NABP | MY_WME)))
+ if (my_b_read( file, (byte*) data_buf, data_len))
{
my_free((gptr) data_buf, MYF(0));
data_buf = 0;
@@ -415,7 +398,7 @@ Query_log_event::Query_log_event(FILE* file, time_t when_arg,
db = data_buf;
query=data_buf + db_len + 1;
q_len = data_len - 1 - db_len;
- *((char*)query + q_len) = 0;
+ *((char*) query + q_len) = 0; // Safety
}
Query_log_event::Query_log_event(const char* buf, int event_len):
@@ -430,7 +413,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len):
exec_time = uint4korr(buf + 8);
error_code = uint2korr(buf + 13);
- if (!(data_buf = (char*) my_malloc( data_len + 1, MYF(MY_WME))))
+ if (!(data_buf = (char*) my_malloc(data_len + 1, MYF(MY_WME))))
return;
memcpy(data_buf, buf + QUERY_HEADER_LEN + 4, data_len);
@@ -457,9 +440,9 @@ void Query_log_event::print(FILE* file, bool short_form)
fprintf(file, ";\n");
}
-int Query_log_event::write_data(FILE* file)
+int Query_log_event::write_data(IO_CACHE* file)
{
- if(!query) return -1;
+ if (!query) return -1;
char buf[QUERY_HEADER_LEN];
char* pos = buf;
@@ -471,23 +454,21 @@ int Query_log_event::write_data(FILE* file)
int2store(pos, error_code);
pos += 2;
- if (my_fwrite(file, (byte*) buf, (uint)(pos - buf), MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (db) ? (byte*) db : (byte*)"",
- db_len + 1, MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME)))
- return -1;
- return 0;
+ return (my_b_write(file, (byte*) buf, (uint)(pos - buf)) ||
+ my_b_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
+ my_b_write(file, (byte*) query, q_len)) ? -1 : 0;
}
-Intvar_log_event:: Intvar_log_event(FILE* file, time_t when_arg,
+Intvar_log_event:: Intvar_log_event(IO_CACHE* file, time_t when_arg,
uint32 server_id)
:Log_event(when_arg,0,0,server_id), type(INVALID_INT_EVENT)
{
- my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
- char buf[9];
- if(my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME))) return;
- type = buf[0];
- val = uint8korr(buf+1);
+ char buf[9+4];
+ if (!my_b_read(file, (byte*) buf, sizeof(buf)))
+ {
+ type = buf[4];
+ val = uint8korr(buf+1+4);
+ }
}
Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
@@ -497,12 +478,12 @@ Intvar_log_event::Intvar_log_event(const char* buf):Log_event(buf)
val = uint8korr(buf+1);
}
-int Intvar_log_event::write_data(FILE* file)
+int Intvar_log_event::write_data(IO_CACHE* file)
{
char buf[9];
buf[0] = type;
int8store(buf + 1, val);
- return my_fwrite(file, (byte*) buf, sizeof(buf), MYF(MY_NABP|MY_WME));
+ return my_b_write(file, (byte*) buf, sizeof(buf));
}
void Intvar_log_event::print(FILE* file, bool short_form)
@@ -529,7 +510,7 @@ void Intvar_log_event::print(FILE* file, bool short_form)
}
-int Load_log_event::write_data(FILE* file __attribute__((unused)))
+int Load_log_event::write_data(IO_CACHE* file)
{
char buf[LOAD_HEADER_LEN];
int4store(buf, thread_id);
@@ -539,77 +520,46 @@ int Load_log_event::write_data(FILE* file __attribute__((unused)))
buf[13] = (char)db_len;
int4store(buf + 14, num_fields);
- if(my_fwrite(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)&sql_ex, sizeof(sql_ex), MYF(MY_NABP|MY_WME)))
+ if(my_b_write(file, (byte*)buf, sizeof(buf)) ||
+ my_b_write(file, (byte*)&sql_ex, sizeof(sql_ex)))
return 1;
- if(num_fields && fields && field_lens)
- {
- if(my_fwrite(file, (byte*)field_lens, num_fields, MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)fields, field_block_len, MYF(MY_NABP|MY_WME)))
- return 1;
- }
-
- if(my_fwrite(file, (byte*)table_name, table_name_len + 1, MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)db, db_len + 1, MYF(MY_NABP|MY_WME)) ||
- my_fwrite(file, (byte*)fname, fname_len, MYF(MY_NABP|MY_WME)) )
+ if (num_fields && fields && field_lens)
+ {
+ if(my_b_write(file, (byte*)field_lens, num_fields) ||
+ my_b_write(file, (byte*)fields, field_block_len))
+ return 1;
+ }
+ if(my_b_write(file, (byte*)table_name, table_name_len + 1) ||
+ my_b_write(file, (byte*)db, db_len + 1) ||
+ my_b_write(file, (byte*)fname, fname_len))
return 1;
-
-
return 0;
}
-Load_log_event::Load_log_event(FILE* file, time_t when, uint32 server_id):
+Load_log_event::Load_log_event(IO_CACHE* file, time_t when, uint32 server_id):
Log_event(when,0,0,server_id),data_buf(0),num_fields(0),
fields(0),field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0)
-
{
char buf[LOAD_HEADER_LEN + 4];
ulong data_len;
- if(my_fread(file, (byte*)buf, sizeof(buf), MYF(MY_NABP|MY_WME)) ||
- my_fread(file, (byte*)&sql_ex, sizeof(sql_ex), MYF(MY_NABP|MY_WME)))
- return;
-
- data_len = uint4korr(buf);
- thread_id = uint4korr(buf+4);
- exec_time = uint4korr(buf+8);
- skip_lines = uint4korr(buf + 12);
- table_name_len = (uint)buf[16];
- db_len = (uint)buf[17];
- num_fields = uint4korr(buf + 18);
-
- data_len -= LOAD_EVENT_OVERHEAD;
- if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ if (my_b_read(file, (byte*)buf, sizeof(buf)) ||
+ my_b_read(file, (byte*)&sql_ex, sizeof(sql_ex)))
return;
- if(my_fread(file, (byte*)data_buf, data_len, MYF(MY_NABP|MY_WME)))
+ data_len = uint4korr(buf) - LOAD_EVENT_OVERHEAD;
+ if (!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
return;
-
- if(num_fields > data_len) // simple sanity check against corruption
+ if (my_b_read(file, (byte*)data_buf, data_len))
return;
-
- field_lens = (uchar*)data_buf;
-
- uint i;
- for(i = 0; i < num_fields; i++)
- {
- field_block_len += (uint)field_lens[i] + 1;
- }
- fields = (char*)field_lens + num_fields;
-
- *((char*)data_buf+data_len) = 0;
- table_name = fields + field_block_len;
- db = table_name + table_name_len + 1;
- fname = db + db_len + 1;
- fname_len = data_len - 2 - db_len - table_name_len - num_fields - field_block_len;
+ copy_log_event(buf,data_len);
}
Load_log_event::Load_log_event(const char* buf, int event_len):
Log_event(when,0,0,server_id),data_buf(0),num_fields(0),fields(0),
field_lens(0),field_block_len(0),
table_name(0),db(0),fname(0)
-
{
ulong data_len;
@@ -617,9 +567,16 @@ Load_log_event::Load_log_event(const char* buf, int event_len):
return;
buf += EVENT_LEN_OFFSET;
-
data_len = event_len;
+ if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ return;
+ memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
+ copy_log_event(buf, data_len);
+}
+
+void Load_log_event::copy_log_event(const char *buf, ulong data_len)
+{
thread_id = uint4korr(buf+4);
exec_time = uint4korr(buf+8);
skip_lines = uint4korr(buf + 12);
@@ -627,32 +584,23 @@ Load_log_event::Load_log_event(const char* buf, int event_len):
db_len = (uint)buf[17];
num_fields = uint4korr(buf + 18);
- data_len -= LOAD_EVENT_OVERHEAD;
- memcpy(&sql_ex, buf + 22, sizeof(sql_ex));
-
- if(!(data_buf = (char*)my_malloc(data_len + 1, MYF(MY_WME))))
+ if (num_fields > data_len) // simple sanity check against corruption
return;
- memcpy(data_buf, buf + 22 + sizeof(sql_ex), data_len);
-
- if(num_fields > data_len) // simple sanity check against corruption
- return;
-
- field_lens = (uchar*)data_buf;
-
+ field_lens = (uchar*) data_buf;
uint i;
- for(i = 0; i < num_fields; i++)
- {
- field_block_len += (uint)field_lens[i] + 1;
- }
+ for (i = 0; i < num_fields; i++)
+ {
+ field_block_len += (uint)field_lens[i] + 1;
+ }
fields = (char*)field_lens + num_fields;
*((char*)data_buf+data_len) = 0;
table_name = fields + field_block_len;
db = table_name + table_name_len + 1;
fname = db + db_len + 1;
- fname_len = data_len - 2 - db_len - table_name_len - num_fields - field_block_len;
-
+ fname_len = data_len - 2 - db_len - table_name_len - num_fields -
+ field_block_len;
}
@@ -711,21 +659,21 @@ void Load_log_event::print(FILE* file, bool short_form)
if((int)skip_lines > 0)
fprintf(file, " IGNORE %ld LINES ", skip_lines);
- if(num_fields)
+ if (num_fields)
+ {
+ uint i;
+ const char* field = fields;
+ fprintf( file, " (");
+ for(i = 0; i < num_fields; i++)
{
- uint i;
- const char* field = fields;
- fprintf( file, " (");
- for(i = 0; i < num_fields; i++)
- {
- if(i)
- fputc(',', file);
- fprintf(file, field);
+ if(i)
+ fputc(',', file);
+ fprintf(file, field);
- field += field_lens[i] + 1;
- }
- fputc(')', file);
+ field += field_lens[i] + 1;
}
+ fputc(')', file);
+ }
fprintf(file, ";\n");
}
diff --git a/sql/log_event.h b/sql/log_event.h
index 33fcab4fea9..3a571c0f9a4 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -65,9 +65,9 @@ public:
int valid_exec_time; // if false, the exec time setting is bogus
uint32 server_id;
- int write(FILE* file);
- int write_header(FILE* file);
- virtual int write_data(FILE* file __attribute__((unused))) { return 0; }
+ int write(IO_CACHE* file);
+ int write_header(IO_CACHE* file);
+ virtual int write_data(IO_CACHE* file __attribute__((unused))) { return 0; }
virtual Log_event_type get_type_code() = 0;
Log_event(time_t when_arg, ulong exec_time_arg = 0,
int valid_exec_time_arg = 0, uint32 server_id = 0): when(when_arg),
@@ -92,11 +92,11 @@ public:
void print_header(FILE* file);
// if mutex is 0, the read will proceed without mutex
- static Log_event* read_log_event(FILE* file, pthread_mutex_t* log_lock);
+ static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
static Log_event* read_log_event(const char* buf, int event_len);
#ifndef MYSQL_CLIENT
- static int read_log_event(FILE* file, String* packet,
+ static int read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock);
#endif
@@ -132,18 +132,18 @@ public:
}
#endif
- Query_log_event(FILE* file, time_t when, uint32 server_id);
+ Query_log_event(IO_CACHE* file, time_t when, uint32 server_id);
Query_log_event(const char* buf, int event_len);
~Query_log_event()
{
if (data_buf)
{
- my_free((gptr)data_buf, MYF(0));
+ my_free((gptr) data_buf, MYF(0));
}
}
Log_event_type get_type_code() { return QUERY_EVENT; }
- int write(FILE* file);
- int write_data(FILE* file); // returns 0 on success, -1 on error
+ int write(IO_CACHE* file);
+ int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
int get_data_size()
{
return q_len + db_len + 2 +
@@ -183,6 +183,8 @@ class Load_log_event: public Log_event
{
protected:
char* data_buf;
+ void Load_log_event::copy_log_event(const char *buf, ulong data_len);
+
public:
int thread_id;
uint32 table_name_len;
@@ -272,17 +274,17 @@ public:
void set_fields(List<Item> &fields);
#endif
- Load_log_event(FILE* file, time_t when, uint32 server_id);
+ Load_log_event(IO_CACHE * file, time_t when, uint32 server_id);
Load_log_event(const char* buf, int event_len);
~Load_log_event()
{
if (data_buf)
{
- my_free((gptr)data_buf, MYF(0));
+ my_free((gptr) data_buf, MYF(0));
}
}
Log_event_type get_type_code() { return LOAD_EVENT; }
- int write_data(FILE* file); // returns 0 on success, -1 on error
+ int write_data(IO_CACHE* file); // returns 0 on success, -1 on error
int get_data_size()
{
return table_name_len + 2 + db_len + 2 + fname_len
@@ -311,30 +313,26 @@ public:
created = (uint32) when;
memcpy(server_version, ::server_version, sizeof(server_version));
}
- Start_log_event(FILE* file, time_t when_arg, uint32 server_id) :
+ Start_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id) :
Log_event(when_arg, 0, 0, server_id)
{
char buf[sizeof(server_version) + sizeof(binlog_version) +
- sizeof(created)];
- my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
- if (my_fread(file, (byte*) buf, sizeof(buf), MYF(MY_NABP | MY_WME)))
+ sizeof(created)+4];
+ if (my_b_read(file, (byte*) buf, sizeof(buf)))
return;
- binlog_version = uint2korr(buf);
- memcpy(server_version, buf + 2, sizeof(server_version));
- created = uint4korr(buf + 2 + sizeof(server_version));
+ binlog_version = uint2korr(buf+4);
+ memcpy(server_version, buf + 6, sizeof(server_version));
+ created = uint4korr(buf + 6 + sizeof(server_version));
}
Start_log_event(const char* buf);
~Start_log_event() {}
Log_event_type get_type_code() { return START_EVENT;}
- int write_data(FILE* file)
+ int write_data(IO_CACHE* file)
{
- if(my_fwrite(file, (byte*) &binlog_version, sizeof(binlog_version),
- MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (byte*) server_version, sizeof(server_version),
- MYF(MY_NABP | MY_WME)) ||
- my_fwrite(file, (byte*) &created, sizeof(created),
- MYF(MY_NABP | MY_WME)))
+ if (my_b_write(file, (byte*) &binlog_version, sizeof(binlog_version)) ||
+ my_b_write(file, (byte*) server_version, sizeof(server_version)) ||
+ my_b_write(file, (byte*) &created, sizeof(created)))
return -1;
return 0;
}
@@ -354,12 +352,12 @@ public:
Intvar_log_event(uchar type_arg, ulonglong val_arg)
:Log_event(time(NULL)),val(val_arg),type(type_arg)
{}
- Intvar_log_event(FILE* file, time_t when, uint32 server_id);
+ Intvar_log_event(IO_CACHE* file, time_t when, uint32 server_id);
Intvar_log_event(const char* buf);
~Intvar_log_event() {}
Log_event_type get_type_code() { return INTVAR_EVENT;}
int get_data_size() { return sizeof(type) + sizeof(val);}
- int write_data(FILE* file);
+ int write_data(IO_CACHE* file);
void print(FILE* file, bool short_form = 0);
@@ -370,10 +368,11 @@ class Stop_log_event: public Log_event
public:
Stop_log_event() :Log_event(time(NULL))
{}
- Stop_log_event(FILE* file, time_t when_arg, uint32 server_id):
+ Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id):
Log_event(when_arg,0,0,server_id)
{
- my_fseek(file, 4L, MY_SEEK_CUR, MYF(MY_WME)); // skip the event length
+ char skip[4];
+ my_b_read(file, skip, sizeof(skip)); // skip the event length
}
Stop_log_event(const char* buf):Log_event(buf)
{
@@ -397,7 +396,7 @@ public:
alloced(0)
{}
- Rotate_log_event(FILE* file, time_t when, uint32 server_id) ;
+ Rotate_log_event(IO_CACHE* file, time_t when, uint32 server_id) ;
Rotate_log_event(const char* buf, int event_len);
~Rotate_log_event()
{
@@ -406,7 +405,7 @@ public:
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len;}
- int write_data(FILE* file);
+ int write_data(IO_CACHE* file);
void print(FILE* file, bool short_form = 0);
};
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index 49df40adaf6..47c00a8ac00 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -32,17 +32,19 @@
#define MAP_TO_USE_RAID
#include "mysql_priv.h"
-#include <mysys_err.h>
#ifdef HAVE_AIOWAIT
+#include <mysys_err.h>
#include <errno.h>
static void my_aiowait(my_aio_result *result);
#endif
- /* if cachesize == 0 then use default cachesize (from s-file) */
- /* returns 0 if we have enough memory */
-
extern "C" {
+ /*
+ ** if cachesize == 0 then use default cachesize (from s-file)
+ ** if file == -1 then real_open_cached_file() will be called.
+ ** returns 0 if ok
+ */
int init_io_cache(IO_CACHE *info, File file, uint cachesize,
enum cache_type type, my_off_t seek_offset,
@@ -60,20 +62,26 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
if (type == READ_CACHE)
{ /* Assume file isn't growing */
- my_off_t file_pos,end_of_file;
- if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
- DBUG_RETURN(1);
- end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
- if (end_of_file < seek_offset)
- end_of_file=seek_offset;
- VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
- if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
+ if (cache_myflags & MY_DONT_CHECK_FILESIZE)
+ {
+ cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
+ }
+ else
{
- cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
- use_async_io=0; /* No nead to use async */
+ my_off_t file_pos,end_of_file;
+ if ((file_pos=my_tell(file,MYF(0)) == MY_FILEPOS_ERROR))
+ DBUG_RETURN(1);
+ end_of_file=my_seek(file,0L,MY_SEEK_END,MYF(0));
+ if (end_of_file < seek_offset)
+ end_of_file=seek_offset;
+ VOID(my_seek(file,file_pos,MY_SEEK_SET,MYF(0)));
+ if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1)
+ {
+ cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1;
+ use_async_io=0; /* No nead to use async */
+ }
}
}
-
if ((int) type < (int) READ_NET)
{
for (;;)
@@ -167,7 +175,8 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
DBUG_ENTER("reinit_io_cache");
info->seek_not_done= test(info->file >= 0); /* Seek not done */
- if (!clear_cache && seek_offset >= info->pos_in_file &&
+ if (! clear_cache &&
+ seek_offset >= info->pos_in_file &&
seek_offset <= info->pos_in_file +
(uint) (info->rc_end - info->rc_request_pos))
{ /* use current buffer */
@@ -231,6 +240,7 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
{
uint length,diff_length,left_length;
my_off_t max_length, pos_in_file;
+
memcpy(Buffer,info->rc_pos,
(size_t) (left_length=(uint) (info->rc_end-info->rc_pos)));
Buffer+=left_length;
@@ -607,7 +617,9 @@ int flush_io_cache(IO_CACHE *info)
length=(uint) (info->rc_pos - info->buffer);
if (info->seek_not_done)
{ /* File touched, do seek */
- VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)));
+ if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ MY_FILEPOS_ERROR)
+ DBUG_RETURN((info->error= -1));
info->seek_not_done=0;
}
info->rc_pos=info->buffer;
@@ -644,4 +656,4 @@ int end_io_cache(IO_CACHE *info)
DBUG_RETURN(error);
} /* end_io_cache */
-}
+} /* extern "C" */
diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc
index 3756d8bf712..6c543d0bbf6 100644
--- a/sql/mysqlbinlog.cc
+++ b/sql/mysqlbinlog.cc
@@ -55,7 +55,7 @@ static struct option long_options[] =
{"password", required_argument,0, 'p'},
{"position", required_argument,0, 'j'},
#ifndef DBUG_OFF
- {"debug", required_argument, 0, '#'}
+ {"debug", optional_argument, 0, '#'}
#endif
};
@@ -151,7 +151,7 @@ static int parse_args(int *argc, char*** argv)
{
int c, opt_index = 0;
- while((c = getopt_long(*argc, *argv, "so:#:h:j:u:p:P:t:?", long_options,
+ while((c = getopt_long(*argc, *argv, "so:#::h:j:u:p:P:t:?", long_options,
&opt_index)) != EOF)
{
switch(c)
@@ -310,86 +310,106 @@ Unfortunately, no sweepstakes today, adjusted position to 4\n");
static void dump_local_log_entries(const char* logname)
{
- FILE* file;
- int rec_count = 0;
-
- if(logname && logname[0] != '-')
- file = my_fopen(logname, O_RDONLY|O_BINARY, MYF(MY_WME));
- else
- file = stdin;
-
- if(!file)
- die("Could not open log file %s", logname);
-
- if(my_fseek(file, position, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR)
- die("failed on my_fseek()");
-
- if(!position)
- {
- char magic[4];
- if (my_fread(file, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
- die("I/O error reading binlog magic number");
- if(memcmp(magic, BINLOG_MAGIC, 4))
- die("Bad magic number");
+ File fd;
+ IO_CACHE cache,*file= &cache;
+ int rec_count = 0;
+
+ if (logname && logname[0] != '-')
+ {
+ if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0)
+ exit(1);
+ if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0,
+ MYF(MY_WME | MY_NABP)))
+ exit(1);
+ }
+ else
+ {
+ if (init_io_cache(file, fileno(stdout), 0, READ_CACHE, (my_off_t) 0,
+ 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
+ exit(1);
+ if (position)
+ {
+ /* skip 'position' characters from stdout */
+ char buff[IO_SIZE];
+ my_off_t length,tmp;
+ for (length=position ; length > 0 ; length-=tmp)
+ {
+ tmp=min(length,sizeof(buff));
+ if (my_b_read(file,buff,tmp))
+ exit(1);
+ }
+ }
+ file->pos_in_file=position;
+ file->seek_not_done=0;
+ }
+
+ if (!position)
+ {
+ char magic[4];
+ if (my_b_read(file, (byte*) magic, sizeof(magic)))
+ die("I/O error reading binlog magic number");
+ if(memcmp(magic, BINLOG_MAGIC, 4))
+ die("Bad magic number");
}
- while(1)
- {
- Log_event* ev = Log_event::read_log_event(file, 0);
- if(!ev)
- if(!feof(file))
+ while(1)
+ {
+ Log_event* ev = Log_event::read_log_event(file, 0);
+ if (!ev)
+ {
+ if (file->error)
die("Could not read entry at offset %ld : Error in log format or \
read error",
- my_ftell(file, MYF(MY_WME)));
- else
- break;
-
- if(rec_count >= offset)
- ev->print(stdout, short_form);
- rec_count++;
- delete ev;
- }
-
- my_fclose(file, MYF(MY_WME));
+ my_b_tell(file));
+ break;
+ }
+ if (rec_count >= offset)
+ ev->print(stdout, short_form);
+ rec_count++;
+ delete ev;
+ }
+ my_close(fd, MYF(MY_WME));
+ end_io_cache(file);
}
+
int main(int argc, char** argv)
{
MY_INIT(argv[0]);
parse_args(&argc, (char***)&argv);
if(!argc && !table)
- {
- usage();
- return -1;
- }
+ {
+ usage();
+ return -1;
+ }
if(use_remote)
- {
- init_thr_alarm(10); // need to do this manually
- mysql = safe_connect();
- }
+ {
+ init_thr_alarm(10); // need to do this manually
+ mysql = safe_connect();
+ }
- if(table)
- {
- if(!use_remote)
- die("You must specify connection parameter to get table dump");
- char* db = (char*)table;
- char* tbl = (char*) strchr(table, '.');
- if(!tbl)
- die("You must use database.table syntax to specify the table");
- *tbl++ = 0;
- dump_remote_table(&mysql->net, db, tbl);
- }
+ if (table)
+ {
+ if(!use_remote)
+ die("You must specify connection parameter to get table dump");
+ char* db = (char*)table;
+ char* tbl = (char*) strchr(table, '.');
+ if(!tbl)
+ die("You must use database.table syntax to specify the table");
+ *tbl++ = 0;
+ dump_remote_table(&mysql->net, db, tbl);
+ }
else
- while(--argc >= 0)
+ {
+ while(--argc >= 0)
{
dump_log_entries(*(argv++));
}
-
- if(use_remote)
+ }
+ if (use_remote)
mc_mysql_close(mysql);
-
return 0;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e9389727e9a..db67eb1f6ea 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -131,7 +131,7 @@ extern "C" int gethostname(char *name, int namelen);
#ifndef DBUG_OFF
static const char* default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
- "d:t:i:o,/tmp/mysqld.trace");
+ "d:t:i:o,/tmp/mysqld.trace");
#endif
#ifdef __NT__
@@ -157,7 +157,7 @@ static pthread_t select_thread;
static pthread_t flush_thread; // Used when debugging
static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl,
opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0,
- opt_ansi_mode=0,opt_myisam_log=0;
+ opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4;
bool opt_sql_bin_update = 0, opt_log_slave_updates = 0;
extern MASTER_INFO glob_mi;
extern int init_master_info(MASTER_INFO* mi);
@@ -579,8 +579,8 @@ void unireg_abort(int exit_code)
{
if (exit_code)
sql_print_error("Aborting\n");
- (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
clean_up(); /* purecov: inspected */
+ (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
exit(exit_code); /* purecov: inspected */
}
@@ -2436,20 +2436,21 @@ struct show_var_st init_vars[]= {
#endif
{"character_set", default_charset, SHOW_CHAR},
{"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
- {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
{"concurrent_insert", (char*) &myisam_concurrent_insert, SHOW_MY_BOOL},
+ {"connect_timeout", (char*) &connect_timeout, SHOW_LONG},
{"datadir", mysql_real_data_home, SHOW_CHAR},
{"delay_key_write", (char*) &myisam_delay_key_write, SHOW_MY_BOOL},
{"delayed_insert_limit", (char*) &delayed_insert_limit, SHOW_LONG},
{"delayed_insert_timeout", (char*) &delayed_insert_timeout, SHOW_LONG},
{"delayed_queue_size", (char*) &delayed_queue_size, SHOW_LONG},
- {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
{"flush", (char*) &myisam_flush, SHOW_MY_BOOL},
{"flush_time", (char*) &flush_time, SHOW_LONG},
{"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
{"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
+ {"join_buffer_size", (char*) &join_buff_size, SHOW_LONG},
{"key_buffer_size", (char*) &keybuff_size, SHOW_LONG},
{"language", language, SHOW_CHAR},
+ {"large_files_support", (char*) &opt_large_files, SHOW_BOOL},
#ifdef HAVE_MLOCKALL
{"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
#endif
@@ -2472,12 +2473,15 @@ struct show_var_st init_vars[]= {
{"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR},
{"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size, SHOW_LONG},
{"net_buffer_length", (char*) &net_buffer_length, SHOW_LONG},
+ {"net_read_timeout", (char*) &net_read_timeout, SHOW_LONG},
{"net_retry_count", (char*) &mysqld_net_retry_count, SHOW_LONG},
+ {"net_write_timeout", (char*) &net_write_timeout, SHOW_LONG},
{"pid_file", (char*) pidfile_name, SHOW_CHAR},
{"port", (char*) &mysql_port, SHOW_INT},
{"protocol_version", (char*) &protocol_version, SHOW_INT},
{"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG},
- {"server_id", (char*) &server_id, SHOW_LONG},
+ {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG},
+ {"server_id", (char*) &server_id, SHOW_LONG},
{"skip_locking", (char*) &my_disable_locking, SHOW_MY_BOOL},
{"skip_networking", (char*) &opt_disable_networking, SHOW_BOOL},
{"skip_show_database", (char*) &opt_skip_show_db, SHOW_BOOL},
@@ -2486,11 +2490,11 @@ struct show_var_st init_vars[]= {
{"sort_buffer", (char*) &sortbuff_size, SHOW_LONG},
{"table_cache", (char*) &table_cache_size, SHOW_LONG},
{"table_type", (char*) &default_table_type_name, SHOW_CHAR_PTR},
+ {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
#ifdef HAVE_THR_SETCONCURRENCY
{"thread_concurrency", (char*) &concurrency, SHOW_LONG},
#endif
{"thread_stack", (char*) &thread_stack, SHOW_LONG},
- {"thread_cache_size", (char*) &thread_cache_size, SHOW_LONG},
#ifdef HAVE_TZNAME
{"timezone", time_zone, SHOW_CHAR},
#endif
@@ -3414,7 +3418,7 @@ static int get_service_parameters()
else if ( lstrcmp(szKeyValueName, TEXT("ShowDatabase")) == 0 )
{
CHECK_KEY_TYPE( REG_DWORD, szKeyValueName );
- opt_disable_networking = !(*lpdwValue);
+ opt_skip_show_db = !(*lpdwValue);
}
else if ( lstrcmp(szKeyValueName, TEXT("HostnameCaching")) == 0 )
{
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index 2308aa40d52..d412b71b363 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -319,11 +319,11 @@ bool net_store_data(String* packet, I_List<i_string>* str_list)
i_string* s;
while((s=it++))
- {
- if(tmp.length())
- tmp.append(',');
- tmp.append(s->ptr);
- }
+ {
+ if(tmp.length())
+ tmp.append(',');
+ tmp.append(s->ptr);
+ }
return net_store_data(packet, (char*)tmp.ptr(), tmp.length());
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f86c0cf7461..cd685cb3437 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -114,11 +114,17 @@ THD::THD()
ull=0;
system_thread=0;
bzero((char*) &mem_root,sizeof(mem_root));
+#if defined(HAVE_BDB) || defined(HAVE_INNOBASE) || defined(HAVE_GEMENI)
+ if (open_cached_file(&transactions.trans_log,
+ mysql_tempdir,LOG_PREFIX,0,MYF(MY_WME)))
+ killed=1;
+ transaction.bdb_lock_count=0;
+#endif
+ transaction.bdb_tid=0;
+
#ifdef __WIN__
real_id = 0 ;
#endif
- transaction.bdb_lock_count=0;
- transaction.bdb_tid=0;
}
THD::~THD()
@@ -137,6 +143,9 @@ THD::~THD()
close_thread_tables(this);
}
close_temporary_tables(this);
+#if defined(HAVE_BDB) || defined(HAVE_INNOBASE) || defined(HAVE_GEMENI)
+ close_cached_file(transactions.trans_log);
+#endif
if (global_read_lock)
{
pthread_mutex_lock(&LOCK_open);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index e53ce950c1f..2af98d6fbf0 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -52,16 +52,16 @@ typedef struct st_log_info
class MYSQL_LOG {
- public:
private:
pthread_mutex_t LOCK_log, LOCK_index;
- FILE *file, *index_file;
time_t last_time,query_start;
+ IO_CACHE log_file;
+ File index_file;
char *name;
- enum_log_type log_type;
+ volatile enum_log_type log_type;
char time_buff[20],db[NAME_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
- bool write_error,inited;
+ bool write_error,inited,opened;
bool no_rotate; // for binlog - if log name can never change
// we should not try to rotate it or write any rotation events
// the user should use FLUSH MASTER instead of FLUSH LOGS for
@@ -85,7 +85,6 @@ public:
void make_log_name(char* buf, const char* log_ident);
bool is_active(const char* log_file_name);
int purge_logs(THD* thd, const char* to_log);
- void flush(void);
void close(bool exiting = 0); // if we are exiting, we also want to close the
// index file
@@ -244,6 +243,7 @@ public:
thr_lock_type update_lock_default;
delayed_insert *di;
struct st_transactions {
+ IO_CACHE trans_log;
void *bdb_tid;
uint bdb_lock_count;
} transaction;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7195caca176..b552479bfe2 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -571,7 +571,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
thread_count++;
pthread_mutex_unlock(&LOCK_thread_count);
if (!(tmp->thd.db=my_strdup(table_list->db,MYF(MY_WME))) ||
- !(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_FAE))))
+ !(tmp->thd.query=my_strdup(table_list->real_name,MYF(MY_WME))))
{
delete tmp;
thd->fatal_error=1;
@@ -1325,7 +1325,8 @@ bool select_create::send_eof()
{
VOID(pthread_mutex_lock(&LOCK_open));
mysql_unlock_tables(thd, lock);
- hash_delete(&open_cache,(byte*) table);
+ if (!table->tmp_table)
+ hash_delete(&open_cache,(byte*) table);
lock=0; table=0;
VOID(pthread_mutex_unlock(&LOCK_open));
}
@@ -1343,7 +1344,8 @@ void select_create::abort()
if (table)
{
enum db_type table_type=table->db_type;
- hash_delete(&open_cache,(byte*) table);
+ if (!table->tmp_table)
+ hash_delete(&open_cache,(byte*) table);
quick_rm_table(table_type,db,name);
table=0;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 674da73ba5d..dd7e1cf7b30 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -34,19 +34,23 @@ class LEX_COLUMN;
#endif
enum enum_sql_command {
- SQLCOM_SELECT,SQLCOM_CREATE_TABLE,SQLCOM_CREATE_INDEX,SQLCOM_ALTER_TABLE,
- SQLCOM_UPDATE,SQLCOM_INSERT,SQLCOM_INSERT_SELECT,SQLCOM_DELETE,
- SQLCOM_DROP_TABLE,SQLCOM_DROP_INDEX,SQLCOM_SHOW_DATABASES,
- SQLCOM_SHOW_TABLES,SQLCOM_SHOW_FIELDS,SQLCOM_SHOW_KEYS,
+ SQLCOM_SELECT, SQLCOM_CREATE_TABLE, SQLCOM_CREATE_INDEX, SQLCOM_ALTER_TABLE,
+ SQLCOM_UPDATE, SQLCOM_INSERT, SQLCOM_INSERT_SELECT,
+ SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX,
+
+ SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS,
+ SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS,
+ SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT,
+ SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE,
+
SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES,
SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB,
- SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_SHOW_VARIABLES,
- SQLCOM_SHOW_STATUS, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
- SQLCOM_SHOW_PROCESSLIST,SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
- SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_SHOW_GRANTS, SQLCOM_ANALYZE,
+ SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT,
+ SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION,
+ SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK,
+ SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE,
SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP,
- SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_SHOW_CREATE,
- SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_CHANGE_MASTER,
+ SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER,
SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE,
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 633855a18fa..9bf3346e61d 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -158,7 +158,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
unpack_filename(name,ex->file_name);
#ifndef __WIN__
MY_STAT stat_info;
- if (!my_stat(name,&stat_info,MYF(MY_FAE)))
+ if (!my_stat(name,&stat_info,MYF(MY_WME)))
DBUG_RETURN(-1);
// the file must be:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 066885ef30a..b12bdcb4d98 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -71,6 +71,20 @@ static void init_signals(void)
}
#endif
+static inline bool end_active_trans(THD *thd)
+{
+ if (!(thd->options & OPTION_AUTO_COMMIT) ||
+ (thd->options & OPTION_BEGIN))
+ {
+ if (ha_commit(thd))
+ return 1;
+ thd->options&= ~OPTION_BEGIN;
+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
+ }
+ return 0;
+}
+
+
/*
** Check if user is ok
** Updates:
@@ -1150,8 +1164,7 @@ mysql_execute_command(void)
}
}
/* ALTER TABLE ends previous transaction */
- if ((!(thd->options & OPTION_AUTO_COMMIT) ||
- (thd->options & OPTION_BEGIN)) && ha_commit(thd))
+ if (end_active_trans(thd))
res= -1;
else
res= mysql_alter_table(thd, lex->db, lex->name,
@@ -1369,6 +1382,7 @@ mysql_execute_command(void)
break;
}
case SQLCOM_DELETE:
+ case SQLCOM_TRUNCATE:
{
if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
@@ -1376,11 +1390,12 @@ mysql_execute_command(void)
goto error;
// Set privilege for the WHERE clause
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
- res = mysql_delete(thd,tables,lex->where,lex->select_limit,
- lex->lock_option, lex->options);
-#ifdef DELETE_ITEMS
- delete lex->where;
-#endif
+ /* TRUNCATE ends previous transaction */
+ if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
+ res= -1;
+ else
+ res = mysql_delete(thd,tables,lex->where,lex->select_limit,
+ lex->lock_option, lex->options);
break;
}
case SQLCOM_DROP_TABLE:
@@ -1722,6 +1737,11 @@ mysql_execute_command(void)
send_ok(&thd->net);
break;
case SQLCOM_COMMIT:
+ /*
+ We don't use end_active_trans() here to ensure that this works
+ even if there is a problem with the OPTION_AUTO_COMMIT flag
+ (Which of course should never happen...)
+ */
thd->options&= ~OPTION_BEGIN;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (!ha_commit(thd))
@@ -2441,7 +2461,7 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
bool result=0;
select_errors=0; /* Write if more errors */
- mysql_log.flush(); // Flush log
+ // mysql_log.flush(); // Flush log
if (options & REFRESH_GRANT)
{
acl_reload();
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 4142c003d4d..5cdb5ab0706 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -93,6 +93,40 @@ static int send_file(THD *thd)
DBUG_RETURN(error);
}
+
+static File open_log(IO_CACHE *log, const char *log_file_name,
+ const char **errmsg)
+{
+ File file;
+ char magic[4];
+ if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
+ init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
+ MYF(MY_WME)))
+ {
+ *errmsg = "Could not open log file"; // This will not be sent
+ goto err;
+ }
+
+ if (my_b_read(log, (byte*) magic, sizeof(magic)))
+ {
+ *errmsg = "I/O error reading binlog magic number";
+ goto err;
+ }
+ if (memcmp(magic, BINLOG_MAGIC, 4))
+ {
+ *errmsg = "Binlog has bad magic number, fire your magician";
+ goto err;
+ }
+ return file;
+
+err:
+ if (file > 0)
+ my_close(file,MYF(0));
+ end_io_cache(log);
+ return -1;
+}
+
+
void adjust_linfo_offsets(my_off_t purge_offset)
{
THD *tmp;
@@ -119,6 +153,7 @@ void adjust_linfo_offsets(my_off_t purge_offset)
pthread_mutex_unlock(&LOCK_thread_count);
}
+
bool log_in_use(const char* log_name)
{
int log_name_len = strlen(log_name) + 1;
@@ -144,6 +179,7 @@ bool log_in_use(const char* log_name)
return result;
}
+
int purge_master_logs(THD* thd, const char* to_log)
{
char search_file_name[FN_REFLEN];
@@ -179,27 +215,29 @@ binlog purge"; break;
return 0;
}
+
void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
{
LOG_INFO linfo;
char *log_file_name = linfo.log_file_name;
char search_file_name[FN_REFLEN];
- char magic[4];
- FILE* log = NULL;
+ IO_CACHE log;
+ File file = -1;
String* packet = &thd->packet;
int error;
const char *errmsg = "Unknown error";
NET* net = &thd->net;
-
DBUG_ENTER("mysql_binlog_send");
+ bzero((char*) &log,sizeof(log));
+
if(!mysql_bin_log.is_open())
- {
- errmsg = "Binary log is not open";
- goto err;
- }
+ {
+ errmsg = "Binary log is not open";
+ goto err;
+ }
- if(log_ident[0])
+ if (log_ident[0])
mysql_bin_log.make_log_name(search_file_name, log_ident);
else
search_file_name[0] = 0;
@@ -207,251 +245,214 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
linfo.index_file_offset = 0;
thd->current_linfo = &linfo;
- if(mysql_bin_log.find_first_log(&linfo, search_file_name))
- {
- errmsg = "Could not find first log";
- goto err;
- }
- log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
+ if (mysql_bin_log.find_first_log(&linfo, search_file_name))
+ {
+ errmsg = "Could not find first log";
+ goto err;
+ }
- if(!log)
- {
- errmsg = "Could not open log file";
- goto err;
- }
-
- if(my_fread(log, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
- {
- errmsg = "I/O error reading binlog magic number";
- goto err;
- }
- if(memcmp(magic, BINLOG_MAGIC, 4))
- {
- errmsg = "Binlog has bad magic number, fire your magician";
- goto err;
- }
+ if ((file=open_log(&log, log_file_name, &errmsg)) < 0)
+ goto err;
if(pos < 4)
- {
- errmsg = "Congratulations! You have hit the magic number and can win \
+ {
+ errmsg = "Contratulations! You have hit the magic number and can win \
sweepstakes if you report the bug";
- goto err;
- }
-
- if(my_fseek(log, pos, MY_SEEK_SET, MYF(MY_WME)) == MY_FILEPOS_ERROR )
- {
- errmsg = "Error on fseek()";
- goto err;
- }
-
-
+ goto err;
+ }
+
+ my_b_seek(&log, pos); // Seek will done on next read
packet->length(0);
packet->append("\0", 1);
// we need to start a packet with something other than 255
// to distiquish it from error
while(!net->error && net->vio != 0 && !thd->killed)
- {
- pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+ {
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
- while(!(error = Log_event::read_log_event(log, packet, log_lock)))
- {
- if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
- {
- errmsg = "Failed on my_net_write()";
- goto err;
- }
- DBUG_PRINT("info", ("log event code %d",
- (*packet)[LOG_EVENT_OFFSET+1] ));
- if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
- {
- if(send_file(thd))
- {
- errmsg = "failed in send_file()";
- goto err;
- }
- }
- packet->length(0);
- packet->append("\0",1);
- }
- if(error != LOG_READ_EOF)
+ while (!(error = Log_event::read_log_event(&log, packet, log_lock)))
+ {
+ if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
+ {
+ errmsg = "Failed on my_net_write()";
+ goto err;
+ }
+ DBUG_PRINT("info", ("log event code %d",
+ (*packet)[LOG_EVENT_OFFSET+1] ));
+ if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ {
+ if(send_file(thd))
{
- switch(error)
- {
- case LOG_READ_BOGUS:
- errmsg = "bogus data in log event";
- break;
- case LOG_READ_IO:
- errmsg = "I/O error reading log event";
- break;
- case LOG_READ_MEM:
- errmsg = "memory allocation failed reading log event";
- break;
- case LOG_READ_TRUNC:
- errmsg = "binlog truncated in the middle of event";
- break;
- }
+ errmsg = "failed in send_file()";
goto err;
}
+ }
+ packet->length(0);
+ packet->append("\0",1);
+ }
+ if(error != LOG_READ_EOF)
+ {
+ switch(error)
+ {
+ case LOG_READ_BOGUS:
+ errmsg = "bogus data in log event";
+ break;
+ case LOG_READ_IO:
+ errmsg = "I/O error reading log event";
+ break;
+ case LOG_READ_MEM:
+ errmsg = "memory allocation failed reading log event";
+ break;
+ case LOG_READ_TRUNC:
+ errmsg = "binlog truncated in the middle of event";
+ break;
+ }
+ goto err;
+ }
- if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
- mysql_bin_log.is_active(log_file_name))
- // block until there is more data in the log
- // unless non-blocking mode requested
- {
- if(net_flush(net))
- {
- errmsg = "failed on net_flush()";
- goto err;
- }
+ if(!(flags & BINLOG_DUMP_NON_BLOCK) &&
+ mysql_bin_log.is_active(log_file_name))
+ // block until there is more data in the log
+ // unless non-blocking mode requested
+ {
+ if(net_flush(net))
+ {
+ errmsg = "failed on net_flush()";
+ goto err;
+ }
- // we may have missed the update broadcast from the log
- // that has just happened, let's try to catch it if it did
- // if we did not miss anything, we just wait for other threads
- // to signal us
- {
- clearerr(log);
-
- // tell the kill thread how to wake us up
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex = log_lock;
- thd->mysys_var->current_cond = &COND_binlog_update;
- const char* proc_info = thd->proc_info;
- thd->proc_info = "Waiting for update";
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- bool read_packet = 0, fatal_error = 0;
-
- // no one will update the log while we are reading
- // now, but we'll be quick and just read one record
- switch(Log_event::read_log_event(log, packet, log_lock))
- {
- case 0:
- read_packet = 1;
- // we read successfully, so we'll need to send it to the
- // slave
- break;
- case LOG_READ_EOF:
- pthread_mutex_lock(log_lock);
- pthread_cond_wait(&COND_binlog_update, log_lock);
- pthread_mutex_unlock(log_lock);
- break;
-
- default:
- fatal_error = 1;
- break;
- }
-
-
- pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->mysys_var->current_mutex= 0;
- thd->mysys_var->current_cond= 0;
- thd->proc_info= proc_info;
- pthread_mutex_unlock(&thd->mysys_var->mutex);
-
- if(read_packet)
- {
- thd->proc_info = "sending update to slave";
- if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
- {
- errmsg = "Failed on my_net_write()";
- goto err;
- }
-
- if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
- {
- if(send_file(thd))
- {
- errmsg = "failed in send_file()";
- goto err;
- }
- }
- packet->length(0);
- packet->append("\0",1);
- // no need to net_flush because we will get to flush later when
- // we hit EOF pretty quick
- }
+ // we may have missed the update broadcast from the log
+ // that has just happened, let's try to catch it if it did
+ // if we did not miss anything, we just wait for other threads
+ // to signal us
+ {
+ log.error=0;
- if(fatal_error)
- {
- errmsg = "error reading log entry";
- goto err;
- }
+ // tell the kill thread how to wake us up
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex = log_lock;
+ thd->mysys_var->current_cond = &COND_binlog_update;
+ const char* proc_info = thd->proc_info;
+ thd->proc_info = "Waiting for update";
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
- clearerr(log);
- }
- }
- else
+ bool read_packet = 0, fatal_error = 0;
+
+ // no one will update the log while we are reading
+ // now, but we'll be quick and just read one record
+ switch(Log_event::read_log_event(&log, packet, log_lock))
{
- bool loop_breaker = 0;
- // need this to break out of the for loop from switch
- thd->proc_info = "switching to next log";
- switch(mysql_bin_log.find_next_log(&linfo))
- {
- case LOG_INFO_EOF:
- loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
- break;
- case 0:
- break;
- default:
- errmsg = "could not find next log";
- goto err;
- }
+ case 0:
+ read_packet = 1;
+ // we read successfully, so we'll need to send it to the
+ // slave
+ break;
+ case LOG_READ_EOF:
+ pthread_mutex_lock(log_lock);
+ pthread_cond_wait(&COND_binlog_update, log_lock);
+ pthread_mutex_unlock(log_lock);
+ break;
+
+ default:
+ fatal_error = 1;
+ break;
+ }
- if(loop_breaker)
- break;
+ pthread_mutex_lock(&thd->mysys_var->mutex);
+ thd->mysys_var->current_mutex= 0;
+ thd->mysys_var->current_cond= 0;
+ thd->proc_info= proc_info;
+ pthread_mutex_unlock(&thd->mysys_var->mutex);
- (void) my_fclose(log, MYF(MY_WME));
- log = my_fopen(log_file_name, O_RDONLY|O_BINARY, MYF(MY_WME));
- if(!log)
- {
- errmsg = "Could not open next log";
- goto err;
- }
+ if(read_packet)
+ {
+ thd->proc_info = "sending update to slave";
+ if(my_net_write(net, (char*)packet->ptr(), packet->length()) )
+ {
+ errmsg = "Failed on my_net_write()";
+ goto err;
+ }
- //check the magic
- if(my_fread(log, (byte*) magic, sizeof(magic), MYF(MY_NABP|MY_WME)))
- {
- errmsg = "I/O error reading binlog magic number";
- goto err;
- }
- if(memcmp(magic, BINLOG_MAGIC, 4))
+ if((*packet)[LOG_EVENT_OFFSET+1] == LOAD_EVENT)
+ {
+ if(send_file(thd))
{
- errmsg = "Binlog has bad magic number, fire your magician";
+ errmsg = "failed in send_file()";
goto err;
}
-
- // fake Rotate_log event just in case it did not make it to the log
- // otherwise the slave make get confused about the offset
- {
- char header[LOG_EVENT_HEADER_LEN];
- memset(header, 0, 4); // when does not matter
- header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
- char* p = strrchr(log_file_name, FN_LIBCHAR);
- // find the last slash
- if(p)
- p++;
- else
- p = log_file_name;
-
- uint ident_len = (uint) strlen(p);
- ulong event_len = ident_len + sizeof(header);
- int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
- int4store(header + EVENT_LEN_OFFSET, event_len);
- packet->append(header, sizeof(header));
- packet->append(p,ident_len);
- if(my_net_write(net, (char*)packet->ptr(), packet->length()))
- {
- errmsg = "failed on my_net_write()";
- goto err;
- }
- packet->length(0);
- packet->append("\0",1);
}
+ packet->length(0);
+ packet->append("\0",1);
+ // no need to net_flush because we will get to flush later when
+ // we hit EOF pretty quick
+ }
+
+ if(fatal_error)
+ {
+ errmsg = "error reading log entry";
+ goto err;
}
+ log.error=0;
+ }
}
+ else
+ {
+ bool loop_breaker = 0;
+ // need this to break out of the for loop from switch
+ thd->proc_info = "switching to next log";
+ switch(mysql_bin_log.find_next_log(&linfo))
+ {
+ case LOG_INFO_EOF:
+ loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
+ break;
+ case 0:
+ break;
+ default:
+ errmsg = "could not find next log";
+ goto err;
+ }
+
+ if(loop_breaker)
+ break;
+
+ end_io_cache(&log);
+ (void) my_close(file, MYF(MY_WME));
+ if ((file=open_log(&log, log_file_name, &errmsg)) < 0)
+ goto err;
+
+ // fake Rotate_log event just in case it did not make it to the log
+ // otherwise the slave make get confused about the offset
+ {
+ char header[LOG_EVENT_HEADER_LEN];
+ memset(header, 0, 4); // when does not matter
+ header[EVENT_TYPE_OFFSET] = ROTATE_EVENT;
+ char* p = strrchr(log_file_name, FN_LIBCHAR);
+ // find the last slash
+ if(p)
+ p++;
+ else
+ p = log_file_name;
+
+ uint ident_len = (uint) strlen(p);
+ ulong event_len = ident_len + sizeof(header);
+ int4store(header + EVENT_TYPE_OFFSET + 1, server_id);
+ int4store(header + EVENT_LEN_OFFSET, event_len);
+ packet->append(header, sizeof(header));
+ packet->append(p,ident_len);
+ if(my_net_write(net, (char*)packet->ptr(), packet->length()))
+ {
+ errmsg = "failed on my_net_write()";
+ goto err;
+ }
+ packet->length(0);
+ packet->append("\0",1);
+ }
+ }
+ }
- (void)my_fclose(log, MYF(MY_WME));
+ end_io_cache(&log);
+ (void)my_close(file, MYF(MY_WME));
send_eof(&thd->net);
thd->proc_info = "waiting to finalize termination";
@@ -461,6 +462,7 @@ sweepstakes if you report the bug";
DBUG_VOID_RETURN;
err:
thd->proc_info = "waiting to finalize termination";
+ end_io_cache(&log);
pthread_mutex_lock(&LOCK_thread_count);
// exclude iteration through thread list
// this is needed for purge_logs() - it will iterate through
@@ -469,8 +471,8 @@ sweepstakes if you report the bug";
// after we return from this stack frame
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
- if(log)
- (void) my_fclose(log, MYF(MY_WME));
+ if (file >= 0)
+ (void) my_close(file, MYF(MY_WME));
send_error(&thd->net, my_errno, errmsg);
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c9de4998899..f38b1a52b65 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2735,7 +2735,7 @@ return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
{
for (TABLE_LIST *table=tables; table ; table=table->next)
mark_as_null_row(table->table); // All fields are NULL
- if (having && having->val_int() == 0.0)
+ if (having && having->val_int() == 0)
send_row=0;
}
if (!tables || !(result->send_fields(fields,1)))
@@ -3214,6 +3214,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
case Item::REAL_ITEM:
case Item::STRING_ITEM:
case Item::REF_ITEM:
+ case Item::NULL_ITEM:
{
bool maybe_null=item->maybe_null;
Field *new_field;
@@ -4499,7 +4500,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!end_of_records)
{
int error;
- if (join->having && join->having->val_int() == 0.0)
+ if (join->having && join->having->val_int() == 0)
DBUG_RETURN(0); // Didn't match having
if (join->procedure)
error=join->procedure->send_row(*join->fields);
@@ -4539,7 +4540,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error;
if (join->procedure)
{
- if (join->having && join->having->val_int() == 0.0)
+ if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
else
error=join->procedure->send_row(*join->fields) ? 1 : 0;
@@ -4550,7 +4551,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
if (!join->first_record)
clear_tables(join);
- if (join->having && join->having->val_int() == 0.0)
+ if (join->having && join->having->val_int() == 0)
error= -1; // Didn't satisfy having
else
error=join->result->send_data(*join->fields) ? 1 : 0;
@@ -5109,7 +5110,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
goto err; /* purecov: inspected */
/* It's not fatal if the following alloc fails */
table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
- MYF(MY_FAE | MY_ZEROFILL));
+ MYF(MY_WME | MY_ZEROFILL));
table->status=0; // May be wrong if quick_select
// If table has a range, move it to select
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 7ca2d3c419e..4b9ebef21f1 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -95,17 +95,6 @@ bool String::realloc(uint32 alloc_length)
return FALSE;
}
-
-#ifdef NOT_NEEDED
-bool String::set(long num)
-{
- if (alloc(14))
- return TRUE;
- str_length=(uint32) (int10_to_str(num,Ptr,-10)-Ptr);
- return FALSE;
-}
-#endif
-
bool String::set(longlong num)
{
if (alloc(21))
@@ -274,6 +263,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE;
}
+#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{
if (realloc(str_length+arg_length))
@@ -286,6 +276,20 @@ bool String::append(FILE* file, uint32 arg_length, myf my_flags)
str_length+=arg_length;
return FALSE;
}
+#endif
+
+bool String::append(IO_CACHE* file, uint32 arg_length)
+{
+ if (realloc(str_length+arg_length))
+ return TRUE;
+ if (my_b_read(file, (byte*) Ptr + str_length, arg_length))
+ {
+ shrink(str_length);
+ return TRUE;
+ }
+ str_length+=arg_length;
+ return FALSE;
+}
uint32 String::numchars()
{
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 1c9e822cce5..f327618ffdd 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -152,7 +152,7 @@ public:
bool copy(const char *s,uint32 arg_length); // Allocate new string
bool append(const String &s);
bool append(const char *s,uint32 arg_length=0);
- bool append(FILE* file, uint32 arg_length, myf my_flags);
+ bool append(IO_CACHE* file, uint32 arg_length);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const String &to);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 5d62fbe84ba..4923be08a49 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -111,6 +111,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SLAVE
%token START_SYM
%token STOP_SYM
+%token TRUNCATE_SYM
%token ROLLBACK_SYM
%token OPTIMIZE
%token SHOW
@@ -493,9 +494,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <NONE>
query verb_clause create change select drop insert replace insert2
- insert_values update delete show describe load alter optimize flush
+ insert_values update delete truncate rename
+ show describe load alter optimize flush
reset purge begin commit rollback slave master_def master_defs
- repair restore backup analyze check rename
+ repair restore backup analyze check
field_list field_list_item field_spec kill
select_item_list select_item values_list no_braces
limit_clause delete_limit_clause fields opt_values values
@@ -562,6 +564,7 @@ verb_clause:
| set
| slave
| show
+ | truncate
| unlock
| update
| use
@@ -789,7 +792,7 @@ field_list_item:
Lex->key_list.push_back(new Key($1,$2,Lex->col_list));
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
- | opt_constraint FOREIGN KEY_SYM '(' key_list ')' references
+ | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
Lex->col_list.empty(); /* Alloced by sql_alloc */
}
@@ -1559,7 +1562,8 @@ simple_expr:
{ $$= new Item_func_trim($6,$4); }
| TRIM '(' expr FROM expr ')'
{ $$= new Item_func_trim($5,$3); }
-
+ | TRUNCATE_SYM '(' expr ',' expr ')'
+ { $$= new Item_func_round($3,$5,1); }
| UDA_CHAR_SUM '(' udf_expr_list ')'
{
if ($3 != NULL)
@@ -2131,6 +2135,11 @@ opt_delete_option:
QUICK { Lex->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
+truncate:
+ TRUNCATE_SYM TABLE_SYM table
+ { Lex->sql_command= SQLCOM_TRUNCATE; Lex->options=0;
+ Lex->lock_option= current_thd->update_lock_default; }
+
/* Show things */
show: SHOW { Lex->wild=0;} show_param
@@ -2530,6 +2539,7 @@ keyword:
| STRING_SYM {}
| TEMPORARY {}
| TEXT_SYM {}
+ | TRUNCATE_SYM {}
| TIMESTAMP {}
| TIME_SYM {}
| TYPE_SYM {}
diff --git a/sql/time.cc b/sql/time.cc
index 17603d93dd4..ce4b5b0e30c 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -413,16 +413,6 @@ ulong convert_month_to_period(ulong month)
return year*100+month%12+1;
}
-#ifdef NOT_NEEDED
-
-ulong add_to_period(ulong period,int months)
-{
- if (period == 0L)
- return 0L;
- return convert_month_to_period(convert_period_to_month(period)+months);
-}
-#endif
-
/*****************************************************************************
** convert a timestamp string to a TIME value.
diff --git a/sql/violite.c b/sql/violite.c
index b18de053b5a..4efda9f3b90 100644
--- a/sql/violite.c
+++ b/sql/violite.c
@@ -1,18 +1,19 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ This 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ 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 General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ 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 */
/*
Note that we can't have assertion on file descriptors; The reason for
@@ -31,6 +32,9 @@
#include <my_sys.h>
#include <my_net.h>
#include <m_string.h>
+#ifdef HAVE_POLL
+#include <sys/poll.h>
+#endif
#if defined(__EMX__)
#include <sys/ioctl.h>
@@ -398,4 +402,26 @@ void vio_in_addr(Vio *vio, struct in_addr *in)
DBUG_VOID_RETURN;
}
+
+/* Return 0 if there is data to be read */
+
+my_bool vio_poll_read(Vio *vio,uint timeout)
+{
+#ifndef HAVE_POLL
+ return 0;
+#else
+ struct pollfd fds;
+ int res;
+ DBUG_ENTER("vio_poll");
+ fds.fd=vio->sd;
+ fds.events=POLLIN;
+ fds.revents=0;
+ if ((res=poll(&fds,1,(int) timeout*1000)) <= 0)
+ {
+ DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */
+ }
+ DBUG_RETURN(fds.revents & POLLIN ? 0 : 1);
+#endif
+}
+
#endif /* HAVE_VIO */