summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorunknown <dlenev@mysql.com>2005-03-16 17:00:13 +0300
committerunknown <dlenev@mysql.com>2005-03-16 17:00:13 +0300
commitd5ec9ed899bc7ea7d0888dcbe96bb6841b7275af (patch)
treec37246cec6d64728e31fd8f7e53303f750317d1c /client
parentf21905e066ab4aa5da817f87586660f4bcddfd45 (diff)
parentec919d742838f491556cb98a894bffab79957cd5 (diff)
downloadmariadb-git-d5ec9ed899bc7ea7d0888dcbe96bb6841b7275af.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/dlenev/src/mysql-5.0-eld-exp
Diffstat (limited to 'client')
-rw-r--r--client/mysqlbinlog.cc244
1 files changed, 196 insertions, 48 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index f564ee31fed..c296447def9 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -103,6 +103,22 @@ class Load_log_processor
{
char target_dir_name[FN_REFLEN];
int target_dir_name_len;
+
+ /*
+ When we see first event corresponding to some LOAD DATA statement in
+ binlog, we create temporary file to store data to be loaded.
+ We add name of this file to file_names array using its file_id as index.
+ If we have Create_file event (i.e. we have binary log in pre-5.0.3
+ format) we also store save event object to be able which is needed to
+ emit LOAD DATA statement when we will meet Exec_load_data event.
+ If we have Begin_load_query event we simply store 0 in
+ File_name_record::event field.
+ */
+ struct File_name_record
+ {
+ char *fname;
+ Create_file_log_event *event;
+ };
DYNAMIC_ARRAY file_names;
/*
@@ -144,7 +160,7 @@ public:
int init()
{
- return init_dynamic_array(&file_names,sizeof(Create_file_log_event*),
+ return init_dynamic_array(&file_names, sizeof(File_name_record),
100,100 CALLER_INFO);
}
@@ -161,33 +177,91 @@ public:
}
void destroy()
{
- Create_file_log_event **ptr= (Create_file_log_event**)file_names.buffer;
- Create_file_log_event **end= ptr + file_names.elements;
+ File_name_record *ptr= (File_name_record *)file_names.buffer;
+ File_name_record *end= ptr + file_names.elements;
for (; ptr<end; ptr++)
{
- if (*ptr)
+ if (ptr->fname)
{
- my_free((char*)(*ptr)->fname,MYF(MY_WME));
- delete *ptr;
- *ptr= 0;
+ my_free(ptr->fname, MYF(MY_WME));
+ delete ptr->event;
+ bzero((char *)ptr, sizeof(File_name_record));
}
}
}
+
+ /*
+ Obtain Create_file event for LOAD DATA statement by its file_id.
+
+ SYNOPSIS
+ grab_event()
+ file_id - file_id identifiying LOAD DATA statement
+
+ DESCRIPTION
+ Checks whenever we have already seen Create_file event for this file_id.
+ If yes then returns pointer to it and removes it from array describing
+ active temporary files. Since this moment caller is responsible for
+ freeing memory occupied by this event and associated file name.
+
+ RETURN VALUES
+ Pointer to Create_file event or 0 if there was no such event
+ with this file_id.
+ */
Create_file_log_event *grab_event(uint file_id)
{
+ File_name_record *ptr;
+ Create_file_log_event *res;
+
if (file_id >= file_names.elements)
return 0;
- Create_file_log_event **ptr=
- (Create_file_log_event**)file_names.buffer + file_id;
- Create_file_log_event *res= *ptr;
- *ptr= 0;
+ ptr= dynamic_element(&file_names, file_id, File_name_record*);
+ if ((res= ptr->event))
+ bzero((char *)ptr, sizeof(File_name_record));
+ return res;
+ }
+
+ /*
+ Obtain file name of temporary file for LOAD DATA statement by its file_id.
+
+ SYNOPSIS
+ grab_fname()
+ file_id - file_id identifiying LOAD DATA statement
+
+ DESCRIPTION
+ Checks whenever we have already seen Begin_load_query event for this
+ file_id. If yes then returns file name of corresponding temporary file.
+ Removes record about this file from the array of active temporary files.
+ Since this moment caller is responsible for freeing memory occupied by
+ this name.
+
+ RETURN VALUES
+ String with name of temporary file or 0 if we have not seen Begin_load_query
+ event with this file_id.
+ */
+ char *grab_fname(uint file_id)
+ {
+ File_name_record *ptr;
+ char *res= 0;
+
+ if (file_id >= file_names.elements)
+ return 0;
+ ptr= dynamic_element(&file_names, file_id, File_name_record*);
+ if (!ptr->event)
+ {
+ res= ptr->fname;
+ bzero((char *)ptr, sizeof(File_name_record));
+ }
return res;
}
int process(Create_file_log_event *ce);
+ int process(Begin_load_query_log_event *ce);
int process(Append_block_log_event *ae);
File prepare_new_file_for_old_format(Load_log_event *le, char *filename);
int load_old_format_file(NET* net, const char *server_fname,
uint server_fname_len, File file);
+ int process_first_event(const char *bname, uint blen, const char *block,
+ uint block_len, uint file_id,
+ Create_file_log_event *ce);
};
@@ -265,22 +339,42 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname,
}
-int Load_log_processor::process(Create_file_log_event *ce)
+/*
+ Process first event in the sequence of events representing LOAD DATA
+ statement.
+
+ SYNOPSIS
+ process_first_event()
+ bname - base name for temporary file to be created
+ blen - base name length
+ block - first block of data to be loaded
+ block_len - first block length
+ file_id - identifies LOAD DATA statement
+ ce - pointer to Create_file event object if we are processing
+ this type of event.
+
+ DESCRIPTION
+ Creates temporary file to be used in LOAD DATA and writes first block of
+ data to it. Registers its file name (and optional Create_file event)
+ in the array of active temporary files.
+
+ RETURN VALUES
+ 0 - success
+ non-0 - error
+*/
+
+int Load_log_processor::process_first_event(const char *bname, uint blen,
+ const char *block, uint block_len,
+ uint file_id,
+ Create_file_log_event *ce)
{
- const char *bname= ce->fname+dirname_length(ce->fname);
- uint blen= ce->fname_len - (bname-ce->fname);
uint full_len= target_dir_name_len + blen + 9 + 9 + 1;
int error= 0;
char *fname, *ptr;
File file;
- DBUG_ENTER("Load_log_processor::process");
+ File_name_record rec;
+ DBUG_ENTER("Load_log_processor::process_first_event");
- if (set_dynamic(&file_names,(gptr)&ce,ce->file_id))
- {
- sql_print_error("Could not construct local filename %s%s",
- target_dir_name,bname);
- DBUG_RETURN(-1);
- }
if (!(fname= my_malloc(full_len,MYF(MY_WME))))
DBUG_RETURN(-1);
@@ -288,7 +382,7 @@ int Load_log_processor::process(Create_file_log_event *ce)
ptr= fname + target_dir_name_len;
memcpy(ptr,bname,blen);
ptr+= blen;
- ptr+= my_sprintf(ptr,(ptr,"-%x",ce->file_id));
+ ptr+= my_sprintf(ptr, (ptr, "-%x", file_id));
if ((file= create_unique_file(fname,ptr)) < 0)
{
@@ -296,9 +390,21 @@ int Load_log_processor::process(Create_file_log_event *ce)
target_dir_name,bname);
DBUG_RETURN(-1);
}
- ce->set_fname_outside_temp_buf(fname,strlen(fname));
- if (my_write(file,(byte*) ce->block,ce->block_len,MYF(MY_WME|MY_NABP)))
+ rec.fname= fname;
+ rec.event= ce;
+
+ if (set_dynamic(&file_names, (gptr)&rec, file_id))
+ {
+ sql_print_error("Could not construct local filename %s%s",
+ target_dir_name, bname);
+ DBUG_RETURN(-1);
+ }
+
+ if (ce)
+ ce->set_fname_outside_temp_buf(fname, strlen(fname));
+
+ if (my_write(file, (byte*)block, block_len, MYF(MY_WME|MY_NABP)))
error= -1;
if (my_close(file, MYF(MY_WME)))
error= -1;
@@ -306,19 +412,35 @@ int Load_log_processor::process(Create_file_log_event *ce)
}
+int Load_log_processor::process(Create_file_log_event *ce)
+{
+ const char *bname= ce->fname + dirname_length(ce->fname);
+ uint blen= ce->fname_len - (bname-ce->fname);
+
+ return process_first_event(bname, blen, ce->block, ce->block_len,
+ ce->file_id, ce);
+}
+
+
+int Load_log_processor::process(Begin_load_query_log_event *blqe)
+{
+ return process_first_event("SQL_LOAD_MB", 11, blqe->block, blqe->block_len,
+ blqe->file_id, 0);
+}
+
+
int Load_log_processor::process(Append_block_log_event *ae)
{
DBUG_ENTER("Load_log_processor::process");
- Create_file_log_event* ce= ((ae->file_id < file_names.elements) ?
- *((Create_file_log_event**)file_names.buffer +
- ae->file_id) :
- 0);
+ const char* fname= ((ae->file_id < file_names.elements) ?
+ dynamic_element(&file_names, ae->file_id,
+ File_name_record*)->fname : 0);
- if (ce)
+ if (fname)
{
File file;
int error= 0;
- if (((file= my_open(ce->fname,
+ if (((file= my_open(fname,
O_APPEND|O_BINARY|O_WRONLY,MYF(MY_WME))) < 0))
DBUG_RETURN(-1);
if (my_write(file,(byte*)ae->block,ae->block_len,MYF(MY_WME|MY_NABP)))
@@ -342,6 +464,14 @@ Create_file event for file_id: %u\n",ae->file_id);
Load_log_processor load_processor;
+static bool check_database(const char *log_dbname)
+{
+ return one_database &&
+ (log_dbname != NULL) &&
+ strcmp(log_dbname, database);
+}
+
+
/*
Process an event
@@ -395,29 +525,21 @@ int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev,
switch (ev_type) {
case QUERY_EVENT:
- if (one_database)
- {
- const char * log_dbname = ((Query_log_event*)ev)->db;
- if ((log_dbname != NULL) && (strcmp(log_dbname, database)))
- goto end;
- }
+ if (check_database(((Query_log_event*)ev)->db))
+ goto end;
ev->print(result_file, short_form, last_event_info);
break;
case CREATE_FILE_EVENT:
{
Create_file_log_event* ce= (Create_file_log_event*)ev;
- if (one_database)
- {
- /*
- We test if this event has to be ignored. If yes, we don't save
- this event; this will have the good side-effect of ignoring all
- related Append_block and Exec_load.
- Note that Load event from 3.23 is not tested.
- */
- const char * log_dbname = ce->db;
- if ((log_dbname != NULL) && (strcmp(log_dbname, database)))
- goto end; // Next event
- }
+ /*
+ We test if this event has to be ignored. If yes, we don't save
+ this event; this will have the good side-effect of ignoring all
+ related Append_block and Exec_load.
+ Note that Load event from 3.23 is not tested.
+ */
+ if (check_database(ce->db))
+ goto end; // Next event
/*
We print the event, but with a leading '#': this is just to inform
the user of the original command; the command we want to execute
@@ -473,6 +595,32 @@ Create_file event for file_id: %u\n",exv->file_id);
*/
ev= 0;
break;
+ case BEGIN_LOAD_QUERY_EVENT:
+ ev->print(result_file, short_form, last_event_info);
+ load_processor.process((Begin_load_query_log_event*) ev);
+ break;
+ case EXECUTE_LOAD_QUERY_EVENT:
+ {
+ Execute_load_query_log_event *exlq= (Execute_load_query_log_event*)ev;
+ char *fname= load_processor.grab_fname(exlq->file_id);
+
+ if (check_database(exlq->db))
+ {
+ if (fname)
+ my_free(fname, MYF(MY_WME));
+ goto end;
+ }
+
+ if (fname)
+ {
+ exlq->print(result_file, short_form, last_event_info, fname);
+ my_free(fname, MYF(MY_WME));
+ }
+ else
+ fprintf(stderr,"Warning: ignoring Execute_load_query as there is no \
+Begin_load_query event for file_id: %u\n", exlq->file_id);
+ break;
+ }
default:
ev->print(result_file, short_form, last_event_info);
}