diff options
author | unknown <guilhem@mysql.com> | 2003-04-24 15:29:25 +0200 |
---|---|---|
committer | unknown <guilhem@mysql.com> | 2003-04-24 15:29:25 +0200 |
commit | 9f4f19d9f77433e02e9985d9c2f3224d062173b3 (patch) | |
tree | 0264c0e9bae7ff461d619885e3e94778f1749a23 /sql/slave.h | |
parent | 4ac98ec5215dedff9e24b91d305e9eec5ee3b96f (diff) | |
download | mariadb-git-9f4f19d9f77433e02e9985d9c2f3224d062173b3.tar.gz |
Replication: new code to not modify in-memory log positions until the COMMIT
is executed, even if the transaction spans on >=2 relay logs (bug #53).
New variable relay_log_purge =0|1
New test to verify bug #53
sql/log.cc:
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT.
sql/log_event.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/mysql_priv.h:
new option relay_log_purge (the user can now decide himself
if he wants his relay logs to be automatically purged or not,
we don't make unsafe guesses like before)
sql/mysqld.cc:
new option --innodb (replaces --skip-innodb).
Useful for the test suite : we have skip-innodb in mysql-test-run,
but we can ('-opt.info' file) choose to start the server with
InnoDB for this test only.
New option --bdb
sql/repl_failsafe.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/set_var.cc:
new variable relay_log_purge
sql/slave.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Now we purge a relay log only when we are sure we won't need it,
i.e. we have executed the final query (if autocommit=1) or the COMMIT
sql/slave.h:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
sql/sql_class.h:
prototypes change
sql/sql_parse.cc:
removed thd argument (was not used in the function's body)
sql/sql_repl.cc:
Better tracking of the relay log's name and position
lastly executed, even if we are in a transaction which spans on
2 or more relay logs.
Turn relay_log_purge silently off when someone does CHANGE
MASTER TO RELAY_LOG_*
Diffstat (limited to 'sql/slave.h')
-rw-r--r-- | sql/slave.h | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/sql/slave.h b/sql/slave.h index a4db7388be5..16ba7f80471 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -92,12 +92,6 @@ typedef struct st_relay_log_info cur_log_fd - file descriptor of the current read relay log */ File info_fd,cur_log_fd; - /* name of current read relay log */ - char relay_log_name[FN_REFLEN]; - /* master log name corresponding to current read position */ - char master_log_name[FN_REFLEN]; - /* original log position of last processed event */ - volatile my_off_t master_log_pos; /* Protected with internal locks. @@ -142,20 +136,36 @@ typedef struct st_relay_log_info uint32 cur_log_old_open_count; /* - relay_log_pos - Current offset in the relay log. - pending - In some cases we do not increment offset immediately - after processing an event, because the following event - needs to be processed atomically together with this one - such as: - - Intvar_event - sets auto_increment value - Rand_event - sets the random seed - - However, once both events have been processed, we need to - increment by the cumulative offset. 'pending' stores the - extra offset to be added to the position. + Let's call a group (of events) : + - a transaction + or + - an autocommiting query + its associated events (INSERT_ID, + TIMESTAMP...) + We need these rli coordinates : + - relay log name and position of the beginning of the group we currently are + executing. Needed to know where we have to restart when replication has + stopped in the middle of a group (which has been rolled back by the slave). + - relay log name and position just after the event we have just + executed. This event is part of the current group. + Formerly we only had the immediately above coordinates, plus a 'pending' + variable, but this dealt wrong with the case of a transaction starting on a + relay log and finishing (commiting) on another relay log. Case which can + happen when, for example, the relay log gets rotated because of + max_binlog_size. + */ + char group_relay_log_name[FN_REFLEN]; + ulonglong group_relay_log_pos; + char event_relay_log_name[FN_REFLEN]; + ulonglong event_relay_log_pos; + /* + Original log name and position of the group we're currently executing + (whose coordinates are group_relay_log_name/pos in the relay log) + in the master's binlog. These concern the *group*, because in the master's + binlog the log_pos that comes with each event is the position of the + beginning of the group. */ - ulonglong relay_log_pos, pending; + char group_master_log_name[FN_REFLEN]; + volatile my_off_t group_master_log_pos; /* Handling of the relay_log_space_limit optional constraint. @@ -193,38 +203,39 @@ typedef struct st_relay_log_info /* if not set, the value of other members of the structure are undefined */ bool inited; volatile bool abort_slave, slave_running; - bool skip_log_purge; - bool inside_transaction; st_relay_log_info(); ~st_relay_log_info(); - inline void inc_pending(ulonglong val) + + inline void inc_event_relay_log_pos(ulonglong val) { - pending += val; + event_relay_log_pos+= val; } - /* TODO: this probably needs to be fixed */ - inline void inc_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0) + + void inc_group_relay_log_pos(ulonglong val, ulonglong log_pos, bool skip_lock=0) { if (!skip_lock) pthread_mutex_lock(&data_lock); - relay_log_pos += val+pending; - pending = 0; - if (log_pos) - master_log_pos = log_pos+ val; + inc_event_relay_log_pos(val); + group_relay_log_pos= event_relay_log_pos; + strmake(group_relay_log_name,event_relay_log_name, + sizeof(group_relay_log_name)-1); + /* + If the slave does not support transactions and replicates a transaction, + users should not trust group_master_log_pos (which they can display with + SHOW SLAVE STATUS or read from relay-log.info), because to compute + group_master_log_pos the slave relies on log_pos stored in the master's + binlog, but if we are in a master's transaction these positions are always + the BEGIN's one (excepted for the COMMIT), so group_master_log_pos does + not advance as it should on the non-transactional slave (it advances by + big leaps, whereas it should advance by small leaps). + */ + if (log_pos) // 3.23 binlogs don't have log_posx + group_master_log_pos= log_pos+ val; pthread_cond_broadcast(&data_cond); if (!skip_lock) pthread_mutex_unlock(&data_lock); } - /* - thread safe read of position - not needed if we are in the slave thread, - but required otherwise as var is a longlong - */ - inline void read_pos(ulonglong& var) - { - pthread_mutex_lock(&data_lock); - var = relay_log_pos; - pthread_mutex_unlock(&data_lock); - } int wait_for_pos(THD* thd, String* log_name, longlong log_pos, longlong timeout); @@ -334,7 +345,7 @@ typedef struct st_table_rule_ent #define TABLE_RULE_ARR_SIZE 16 #define MAX_SLAVE_ERRMSG 1024 -#define RPL_LOG_NAME (rli->master_log_name[0] ? rli->master_log_name :\ +#define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\ "FIRST") #define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\ "FIRST") |