diff options
-rw-r--r-- | include/my_global.h | 16 | ||||
-rw-r--r-- | include/my_sys.h | 5 | ||||
-rw-r--r-- | mysql-test/mysql-test-run.sh | 1 | ||||
-rw-r--r-- | mysql-test/r/rpl000014.result | 8 | ||||
-rw-r--r-- | mysql-test/r/rpl000015.result | 6 | ||||
-rw-r--r-- | mysql-test/r/rpl000016.result | 6 | ||||
-rw-r--r-- | mysql-test/r/rpl_log.result | 2 | ||||
-rwxr-xr-x | mysql-test/t/rpl000017-slave.sh | 3 | ||||
-rw-r--r-- | mysys/mf_iocache.c | 29 | ||||
-rw-r--r-- | mysys/mf_iocache2.c | 24 | ||||
-rw-r--r-- | sql/log.cc | 9 | ||||
-rw-r--r-- | sql/slave.cc | 63 | ||||
-rw-r--r-- | sql/slave.h | 3 |
13 files changed, 131 insertions, 44 deletions
diff --git a/include/my_global.h b/include/my_global.h index 7277bdcd715..40e70c521eb 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -51,6 +51,22 @@ #endif #endif /* _WIN32... */ +/* The macros below are borrowed from include/linux/compiler.h in the + Linux kernel. Use them to indicate the likelyhood of the truthfulness + of a condition. This serves two purposes - newer versions of gcc will be + able to optimize for branch predication, which could yield siginficant + performance gains in frequently executed sections of the code, and the + other reason to use them is for documentation +*/ + +#if __GNUC__ == 2 && __GNUC_MINOR__ < 96 +#define __builtin_expect(x, expected_value) (x) +#endif + +#define likely(x) __builtin_expect((x),1) +#define unlikely(x) __builtin_expect((x),0) + + /* Fix problem with S_ISLNK() on Linux */ #if defined(HAVE_LINUXTHREADS) #undef _GNU_SOURCE diff --git a/include/my_sys.h b/include/my_sys.h index 1d7c0b7ddb1..61f93d665cd 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -436,8 +436,9 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); #define my_b_tell(info) ((info)->pos_in_file + \ (uint) (*(info)->current_pos - (info)->request_pos)) -#define my_b_append_tell(info) ((info)->end_of_file + \ - (uint) ((info)->write_pos - (info)->write_buffer)) + +/* tell write offset in the SEQ_APPEND cache */ +my_off_t my_b_append_tell(IO_CACHE* info); #define my_b_bytes_in_cache(info) (uint) (*(info)->current_end - \ *(info)->current_pos) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index b9ebac4445d..c36e4e532af 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -832,6 +832,7 @@ start_slave() slave_args="--no-defaults $master_info \ --exit-info=256 \ --log-bin=$MYSQL_TEST_DIR/var/log/$slave_ident-bin \ + --relay-log=$MYSQL_TEST_DIR/var/log/$slave_ident-relay-bin \ --log-slave-updates \ --log=$slave_log \ --basedir=$MY_BASEDIR \ diff --git a/mysql-test/r/rpl000014.result b/mysql-test/r/rpl000014.result index 78e44d824e5..7a691119e5c 100644 --- a/mysql-test/r/rpl000014.result +++ b/mysql-test/r/rpl000014.result @@ -8,21 +8,21 @@ File Position Binlog_do_db Binlog_ignore_db master-bin.001 79 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 1 master-bin.001 79 mysql-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 +127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 change master to master_log_pos=73; slave stop; change master to master_log_pos=73; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 1 master-bin.001 73 mysql-relay-bin.001 4 master-bin.001 No No 0 0 73 +127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No No 0 0 73 slave start; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 1 master-bin.001 73 mysql-relay-bin.001 4 master-bin.001 Yes Yes 0 0 73 +127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 Yes Yes 0 0 73 change master to master_log_pos=173; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 1 master-bin.001 173 mysql-relay-bin.001 4 master-bin.001 Yes Yes 0 0 173 +127.0.0.1 root MASTER_PORT 1 master-bin.001 173 slave-relay-bin.001 4 master-bin.001 Yes Yes 0 0 173 show master status; File Position Binlog_do_db Binlog_ignore_db master-bin.001 79 diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result index 23f90ecde1f..03370bc6b0d 100644 --- a/mysql-test/r/rpl000015.result +++ b/mysql-test/r/rpl000015.result @@ -9,16 +9,16 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo change master to master_host='127.0.0.1'; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 test MASTER_PORT 60 4 mysql-relay-bin.001 4 No No 0 0 0 +127.0.0.1 test MASTER_PORT 60 4 slave-relay-bin.001 4 No No 0 0 0 change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 60 4 mysql-relay-bin.001 4 No No 0 0 0 +127.0.0.1 root MASTER_PORT 60 4 slave-relay-bin.001 4 No No 0 0 0 slave start; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 60 master-bin.001 79 mysql-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79 +127.0.0.1 root MASTER_PORT 60 master-bin.001 79 slave-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79 drop table if exists t1; create table t1 (n int); insert into t1 values (10),(45),(90); diff --git a/mysql-test/r/rpl000016.result b/mysql-test/r/rpl000016.result index aab3635ea52..6a91309c29c 100644 --- a/mysql-test/r/rpl000016.result +++ b/mysql-test/r/rpl000016.result @@ -15,7 +15,7 @@ create table t1 (s text); insert into t1 values('Could not break slave'),('Tried hard'); show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 60 master-bin.001 234 mysql-relay-bin.001 275 master-bin.001 Yes Yes 0 0 234 +127.0.0.1 root MASTER_PORT 60 master-bin.001 234 slave-relay-bin.001 275 master-bin.001 Yes Yes 0 0 234 select * from t1; s Could not break slave @@ -42,7 +42,7 @@ master-bin.003 insert into t2 values (65); show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 60 master-bin.003 155 mysql-relay-bin.001 793 master-bin.003 Yes Yes 0 0 155 +127.0.0.1 root MASTER_PORT 60 master-bin.003 155 slave-relay-bin.001 755 master-bin.003 Yes Yes 0 0 155 select * from t2; m 34 @@ -65,7 +65,7 @@ slave stop; slave start; show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 60 master-bin.006 445 mysql-relay-bin.004 1376 master-bin.006 Yes Yes 0 0 445 +127.0.0.1 root MASTER_PORT 60 master-bin.006 445 slave-relay-bin.004 1229 master-bin.006 Yes Yes 0 0 445 lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 9b7ff276828..e91d17426c8 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -75,7 +75,7 @@ slave-bin.002 115 Query 1 62 use test; insert into t1 values (1) slave-bin.002 175 Query 1 122 use test; drop table t1 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos -127.0.0.1 root MASTER_PORT 1 master-bin.002 170 mysql-relay-bin.002 935 master-bin.002 Yes Yes 0 0 170 +127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 916 master-bin.002 Yes Yes 0 0 170 show new master for slave with master_log_file='master-bin.001' and master_log_pos=4 and master_server_id=1; Log_name Log_pos diff --git a/mysql-test/t/rpl000017-slave.sh b/mysql-test/t/rpl000017-slave.sh index 555427a2376..066b4880cc1 100755 --- a/mysql-test/t/rpl000017-slave.sh +++ b/mysql-test/t/rpl000017-slave.sh @@ -1,4 +1,5 @@ -rm -f $MYSQL_TEST_DIR/var/slave-data/*relay* +rm -f $MYSQL_TEST_DIR/var/log/*relay* +rm -f $MYSQL_TEST_DIR/var/slave-data/relay-log.info cat > $MYSQL_TEST_DIR/var/slave-data/master.info <<EOF master-bin.001 4 diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 34de5dfd7f3..6095cc23716 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -542,7 +542,7 @@ read_append_buffer: DBUG_ASSERT(info->append_read_pos <= info->write_pos); /* - TODO: figure out if the below assert is needed or correct. + TODO: figure out if the assert below is needed or correct. */ DBUG_ASSERT(pos_in_file == info->end_of_file); copy_len=min(Count, len_in_buff); @@ -889,6 +889,17 @@ int my_block_write(register IO_CACHE *info, const byte *Buffer, uint Count, /* Flush write cache */ +#ifdef THREAD +#define LOCK_APPEND_BUFFER if (need_append_buffer_lock) \ + lock_append_buffer(info); +#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \ + unlock_append_buffer(info); +#else +#define LOCK_APPEND_BUFFER +#define UNLOCK_APPEND_BUFFER +#endif + + int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) { uint length; @@ -906,8 +917,8 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) if (real_open_cached_file(info)) DBUG_RETURN((info->error= -1)); } - if (need_append_buffer_lock) - lock_append_buffer(info); + LOCK_APPEND_BUFFER; + if ((length=(uint) (info->write_pos - info->write_buffer))) { pos_in_file=info->pos_in_file; @@ -919,8 +930,7 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) == MY_FILEPOS_ERROR) { - if (need_append_buffer_lock) - unlock_append_buffer(info); + UNLOCK_APPEND_BUFFER; DBUG_RETURN((info->error= -1)); } if (!append_cache) @@ -941,11 +951,13 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) set_if_bigger(info->end_of_file,(pos_in_file+length)); } else + { info->end_of_file+=(info->write_pos-info->append_read_pos); + DBUG_ASSERT(info->end_of_file == my_tell(info->file,MYF(0))); + } info->append_read_pos=info->write_pos=info->write_buffer; - if (need_append_buffer_lock) - unlock_append_buffer(info); + UNLOCK_APPEND_BUFFER; DBUG_RETURN(info->error); } } @@ -956,8 +968,7 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) info->inited=0; } #endif - if (need_append_buffer_lock) - unlock_append_buffer(info); + UNLOCK_APPEND_BUFFER; DBUG_RETURN(0); } diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index ca9c9938cd2..a343829d32e 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -23,10 +23,30 @@ #include <m_string.h> #include <stdarg.h> #include <m_ctype.h> +#include <assert.h> + +my_off_t my_b_append_tell(IO_CACHE* info) +{ + my_off_t res; +/* we need to lock the append buffer mutex to keep flush_io_cache() + from messing with the variables that we need in order to provide the + answer to the question. +*/ +#ifdef THREAD + pthread_mutex_lock(&info->append_buffer_lock); +#endif + DBUG_ASSERT(info->end_of_file - (info->append_read_pos-info->write_buffer) + == my_tell(info->file,MYF(0))); + res = info->end_of_file + (info->write_pos-info->append_read_pos); +#ifdef THREAD + pthread_mutex_unlock(&info->append_buffer_lock); +#endif + return res; +} /* - Fix that next read will be made at certain position - For write cache, make next write happen at a certain position + Make next read happen at the given position + For write cache, make next write happen at the given position */ void my_b_seek(IO_CACHE *info,my_off_t pos) diff --git a/sql/log.cc b/sql/log.cc index d3ad4564a73..17b6ef4344c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -742,12 +742,13 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) error = 1; break; } - if ((uint)my_b_append_tell(&log_file) > max_binlog_size) - { - new_file(1); - } } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); + if ((uint)my_b_append_tell(&log_file) > max_binlog_size) + { + new_file(1); + } + if (!error) signal_update(); pthread_mutex_unlock(&LOCK_log); diff --git a/sql/slave.cc b/sql/slave.cc index 97efbf6036c..59e07040528 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1057,6 +1057,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, if (init_relay_log_info(&mi->rli, slave_info_fname)) return 1; mi->rli.mi = mi; + mi->ignore_stop_event=0; int fd,length,error; MY_STAT stat_area; char fname[FN_REFLEN+128]; @@ -1275,10 +1276,6 @@ int flush_master_info(MASTER_INFO* mi) return 0; } -/* TODO: the code below needs to be re-written almost from scratch - Main issue is how to find out if we have reached a certain position - in the master log my knowing the offset in the relay log. - */ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, ulonglong log_pos) { @@ -1921,6 +1918,7 @@ the slave SQL thread with \"mysqladmin start-slave\". We stopped at log \ DBUG_RETURN(0); // Can't return anything here } +// We assume we already locked mi->data_lock static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev) { if (!rev->is_valid()) @@ -1941,77 +1939,112 @@ static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev) return 0; } +// TODO: verify the issue with stop events, see if we need them at all +// in the relay log +// TODO: test this code before release - it has to be tested on a separte +// setup with 3.23 master static int queue_old_event(MASTER_INFO* mi, const char* buf, uint event_len) { const char* errmsg = 0; bool inc_pos = 1; + bool processed_stop_event = 0; Log_event* ev = Log_event::read_log_event(buf,event_len, &errmsg, 1/*old format*/); - if (!ev) + if (unlikely(!ev)) { sql_print_error("Read invalid event from master: '%s',\ master could be corrupt but a more likely cause of this is a bug", errmsg); return 1; } + pthread_mutex_lock(&mi->data_lock); ev->log_pos = mi->master_log_pos; switch (ev->get_type_code()) { case ROTATE_EVENT: - if (process_io_rotate(mi,(Rotate_log_event*)ev)) + if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev))) { delete ev; + pthread_mutex_unlock(&mi->data_lock); return 1; } + mi->ignore_stop_event=1; inc_pos = 0; break; + case STOP_EVENT: + processed_stop_event=1; + break; case LOAD_EVENT: // TODO: actually process it mi->master_log_pos += event_len; + delete ev; + pthread_mutex_unlock(&mi->data_lock); return 0; - break; default: + mi->ignore_stop_event=0; break; } - if (mi->rli.relay_log.append(ev)) + if (likely(!processed_stop_event || !mi->ignore_stop_event)) { - delete ev; - return 1; + if (unlikely(mi->rli.relay_log.append(ev))) + { + delete ev; + pthread_mutex_unlock(&mi->data_lock); + return 1; + } } delete ev; - if (inc_pos) + if (likely(inc_pos)) mi->master_log_pos += event_len; + if (unlikely(processed_stop_event)) + mi->ignore_stop_event=1; + pthread_mutex_lock(&mi->data_lock); return 0; } +// TODO: verify the issue with stop events, see if we need them at all +// in the relay log int queue_event(MASTER_INFO* mi,const char* buf,uint event_len) { - int error; + int error=0; bool inc_pos = 1; + bool processed_stop_event = 0; if (mi->old_format) return queue_old_event(mi,buf,event_len); + + pthread_mutex_lock(&mi->data_lock); + // TODO: figure out if other events in addition to Rotate // require special processing switch (buf[EVENT_TYPE_OFFSET]) { + case STOP_EVENT: + processed_stop_event=1; + break; case ROTATE_EVENT: { Rotate_log_event rev(buf,event_len,0); - if (process_io_rotate(mi,&rev)) + if (unlikely(process_io_rotate(mi,&rev))) return 1; inc_pos=0; + mi->ignore_stop_event=1; break; } default: + mi->ignore_stop_event=0; break; } - if (!(error = mi->rli.relay_log.appendv(buf,event_len,0))) + if (likely((!processed_stop_event || !mi->ignore_stop_event) && + !(error = mi->rli.relay_log.appendv(buf,event_len,0)))) { - if (inc_pos) + if (likely(inc_pos)) mi->master_log_pos += event_len; } + if (unlikely(processed_stop_event)) + mi->ignore_stop_event=1; + pthread_mutex_unlock(&mi->data_lock); return error; } diff --git a/sql/slave.h b/sql/slave.h index f1dd0130500..9632b108ab5 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -240,6 +240,9 @@ typedef struct st_master_info int events_till_abort; #endif volatile bool abort_slave, slave_running; + + bool ignore_stop_event; + THD* io_thd; st_master_info():fd(-1),inited(0), |