diff options
author | guilhem@mysql.com <> | 2003-08-21 10:24:37 +0200 |
---|---|---|
committer | guilhem@mysql.com <> | 2003-08-21 10:24:37 +0200 |
commit | 165dc895b3f90b96c67e7a72417d7c9dfd81238a (patch) | |
tree | 92c75b5455e45ec0570ee8cc437cd63ddb36bfe1 /sql/slave.cc | |
parent | ec280a51cac48d8d25a1ad55125faf07c31542f5 (diff) | |
download | mariadb-git-165dc895b3f90b96c67e7a72417d7c9dfd81238a.tar.gz |
Yesterday I removed process_io_create_file; I shouldn't have.
Let's say the lack of comments did not help me ;)
Copying it back again and adding comments; now 3.23->4.0
replication of LOAD DATA INFILE works again.
Diffstat (limited to 'sql/slave.cc')
-rw-r--r-- | sql/slave.cc | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/sql/slave.cc b/sql/slave.cc index 9b5066f5804..32ed228e119 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -57,6 +57,7 @@ typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE; void skip_load_data_infile(NET* net); static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev); +static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev); static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli); static inline bool io_slave_killed(THD* thd,MASTER_INFO* mi); static inline bool sql_slave_killed(THD* thd,RELAY_LOG_INFO* rli); @@ -2728,6 +2729,102 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ } +static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) +{ + int error = 1; + ulong num_bytes; + bool cev_not_written; + THD* thd; + NET* net = &mi->mysql->net; + DBUG_ENTER("process_io_create_file"); + + if (unlikely(!cev->is_valid())) + DBUG_RETURN(1); + /* + TODO: fix to honor table rules, not only db rules + */ + if (!db_ok(cev->db, replicate_do_db, replicate_ignore_db)) + { + skip_load_data_infile(net); + DBUG_RETURN(0); + } + DBUG_ASSERT(cev->inited_from_old); + thd = mi->io_thd; + thd->file_id = cev->file_id = mi->file_id++; + thd->server_id = cev->server_id; + cev_not_written = 1; + + if (unlikely(net_request_file(net,cev->fname))) + { + sql_print_error("Slave I/O: failed requesting download of '%s'", + cev->fname); + goto err; + } + + /* + This dummy block is so we could instantiate Append_block_log_event + once and then modify it slightly instead of doing it multiple times + in the loop + */ + { + Append_block_log_event aev(thd,0,0,0,0); + + for (;;) + { + if (unlikely((num_bytes=my_net_read(net)) == packet_error)) + { + sql_print_error("Network read error downloading '%s' from master", + cev->fname); + goto err; + } + if (unlikely(!num_bytes)) /* eof */ + { + send_ok(net); /* 3.23 master wants it */ + Execute_load_log_event xev(thd,0,0); + xev.log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(&xev))) + { + sql_print_error("Slave I/O: error writing Exec_load event to \ +relay log"); + goto err; + } + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + break; + } + if (unlikely(cev_not_written)) + { + cev->block = (char*)net->read_pos; + cev->block_len = num_bytes; + cev->log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(cev))) + { + sql_print_error("Slave I/O: error writing Create_file event to \ +relay log"); + goto err; + } + cev_not_written=0; + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + } + else + { + aev.block = (char*)net->read_pos; + aev.block_len = num_bytes; + aev.log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(&aev))) + { + sql_print_error("Slave I/O: error writing Append_block event to \ +relay log"); + goto err; + } + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ; + } + } + } + error=0; +err: + DBUG_RETURN(error); +} + /* Start using a new binary log on the master @@ -2803,6 +2900,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer buf = (const char*)tmp_buf; } + /* + This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to + send the loaded file, and write it to the relay log in the form of + Append_block/Exec_load (the SQL thread needs the data, as that thread is not + connected to the master). + */ Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg, 1 /*old format*/ ); if (unlikely(!ev)) @@ -2831,6 +2934,24 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, mi->ignore_stop_event=1; inc_pos= 0; break; + case CREATE_FILE_EVENT: + /* + Yes it's possible to have CREATE_FILE_EVENT here, even if we're in + queue_old_event() which is for 3.23 events which don't comprise + CREATE_FILE_EVENT. This is because read_log_event() above has just + transformed LOAD_EVENT into CREATE_FILE_EVENT. + */ + { + /* We come here when and only when tmp_buf != 0 */ + DBUG_ASSERT(tmp_buf); + int error = process_io_create_file(mi,(Create_file_log_event*)ev); + delete ev; + mi->master_log_pos += event_len; + DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); + pthread_mutex_unlock(&mi->data_lock); + my_free((char*)tmp_buf, MYF(0)); + DBUG_RETURN(error); + } default: mi->ignore_stop_event=0; inc_pos= event_len; |