maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #04004
Re: [Commits] Rev 2864: MWL#136: Cross-engine consistency for START TRANSACTION WITH CONSISTENT SNAPSHOT in http://bazaar.launchpad.net/~maria-captains/maria/5.1
Hi!
>>>>> "knielsen" == knielsen <knielsen@xxxxxxxxxxxxxxx> writes:
knielsen> At http://bazaar.launchpad.net/~maria-captains/maria/5.1
knielsen> ------------------------------------------------------------
knielsen> revno: 2864
knielsen> revision-id: knielsen@xxxxxxxxxxxxxxx-20101107213743-3luszsivft2vt7t6
knielsen> parent: knielsen@xxxxxxxxxxxxxxx-20101103155438-vdou0fngj6hpgpsd
knielsen> committer: knielsen@xxxxxxxxxxxxxxx
knielsen> branch nick: work-5.1-mwl136
knielsen> timestamp: Sun 2010-11-07 22:37:43 +0100
knielsen> message:
knielsen> MWL#136: Cross-engine consistency for START TRANSACTION WITH CONSISTENT SNAPSHOT
<cut>
knielsen> === modified file 'client/mysqldump.c'
<cut>
knielsen> -static int do_show_master_status(MYSQL *mysql_con)
knielsen> +static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos)
knielsen> {
knielsen> MYSQL_ROW row;
knielsen> MYSQL_RES *master;
knielsen> + char binlog_pos_file[FN_REFLEN];
knielsen> + char binlog_pos_offset[LONGLONG_LEN+1];
knielsen> + char *file, *offset;
knielsen> const char *comment_prefix=
knielsen> (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : "";
knielsen> - if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
knielsen> +
knielsen> + if (consistent_binlog_pos)
knielsen> {
knielsen> - return 1;
knielsen> + if(!check_consistent_binlog_pos(binlog_pos_file, binlog_pos_offset))
knielsen> + return 1;
knielsen> + file= binlog_pos_file;
knielsen> + offset= binlog_pos_offset;
knielsen> }
knielsen> else
knielsen> {
knielsen> + if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS"))
knielsen> + return 1;
knielsen> +
knielsen> row= mysql_fetch_row(master);
knielsen> if (row && row[0] && row[1])
knielsen> {
knielsen> + file= row[0];
knielsen> + offset= row[1];
knielsen> }
knielsen> + else
knielsen> {
You need a mysql_free_result(master) here.
knielsen> + if (!ignore_errors)
knielsen> + {
knielsen> + /* SHOW MASTER STATUS reports nothing and --force is not enabled */
knielsen> + my_printf_error(0, "Error: Binlogging on server not active",
knielsen> + MYF(0));
knielsen> + maybe_exit(EX_MYSQLERR);
knielsen> + return 1;
knielsen> + }
knielsen> + else
knielsen> + {
knielsen> + return 0;
knielsen> + }
knielsen> }
knielsen> }
<cut>
knielsen> === modified file 'sql/log.cc'
knielsen> --- a/sql/log.cc 2010-11-02 07:40:27 +0000
knielsen> +++ b/sql/log.cc 2010-11-07 21:37:43 +0000
knielsen> @@ -62,6 +62,7 @@ static int binlog_savepoint_rollback(han
knielsen> static int binlog_commit(handlerton *hton, THD *thd, bool all);
knielsen> static int binlog_rollback(handlerton *hton, THD *thd, bool all);
knielsen> static int binlog_prepare(handlerton *hton, THD *thd, bool all);
knielsen> +static int binlog_start_consistent_snapshot(handlerton *hton, THD *thd);
knielsen> /**
knielsen> Silence all errors and warnings reported when performing a write
knielsen> @@ -155,9 +156,10 @@ class binlog_trx_data {
knielsen> public:
knielsen> binlog_trx_data()
knielsen> : at_least_one_stmt_committed(0), incident(FALSE), m_pending(0),
knielsen> - before_stmt_pos(MY_OFF_T_UNDEF), commit_bin_log_file_pos(0), using_xa(0)
knielsen> + before_stmt_pos(MY_OFF_T_UNDEF), last_commit_pos_offset(0), using_xa(0)
knielsen> {
knielsen> trans_log.end_of_file= max_binlog_cache_size;
knielsen> + strcpy(last_commit_pos_file, "");
strcpy() -> strmov() or even better
last_commit_pos_file[0]= 0;
(I want to get rid of all strcpy() and replace with strmov() as
strcpy() is often used wrongly; I would like to have this thing
changed to not get 'false positives' when searching for strcpy() to remove.
knielsen> }
knielsen> ~binlog_trx_data()
knielsen> @@ -215,7 +217,8 @@ public:
knielsen> incident= FALSE;
knielsen> trans_log.end_of_file= max_binlog_cache_size;
knielsen> using_xa= FALSE;
knielsen> - commit_bin_log_file_pos= 0;
knielsen> + strcpy(last_commit_pos_file, "");
strcpy -> strmov or last_commit_pos_file[0]= 0;
knielsen> + last_commit_pos_offset= 0;
knielsen> DBUG_ASSERT(empty());
knielsen> }
knielsen> /*
knielsen> Write a table map to the binary log.
knielsen> @@ -4337,6 +4369,9 @@ MYSQL_BIN_LOG::flush_and_set_pending_row
knielsen> rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
knielsen> }
Add a comment that this mutex is a protection for partial reads of
last_commit_pos_offset on 32 bit systems. (at least I can't come up
with any better reason for this mutex).
Maybe we should introduce
pthread_mutex_lock_for_32_bit() that would be void on 64 bit systems
in cases like this.
knielsen> + pthread_mutex_lock(&LOCK_commit_ordered);
knielsen> + last_commit_pos_offset= my_b_tell(&log_file);
knielsen> + pthread_mutex_unlock(&LOCK_commit_ordered);
knielsen> pthread_mutex_unlock(&LOCK_log);
knielsen> }
knielsen> @@ -4526,7 +4561,12 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
knielsen> err_unlock:
knielsen> if (file == &log_file)
knielsen> + {
knielsen> + pthread_mutex_lock(&LOCK_commit_ordered);
knielsen> + last_commit_pos_offset= my_b_tell(&log_file);
knielsen> + pthread_mutex_unlock(&LOCK_commit_ordered);
knielsen> pthread_mutex_unlock(&LOCK_log);
knielsen> + }
Same comment needed for this.
knielsen> err:
knielsen> if (error)
knielsen> @@ -4827,6 +4867,9 @@ bool MYSQL_BIN_LOG::write_incident(THD *
knielsen> signal_update();
knielsen> rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
knielsen> }
knielsen> + pthread_mutex_lock(&LOCK_commit_ordered);
knielsen> + last_commit_pos_offset= my_b_tell(&log_file);
knielsen> + pthread_mutex_unlock(&LOCK_commit_ordered);
knielsen> pthread_mutex_unlock(&LOCK_log);
and here...
knielsen> static ulonglong binlog_status_var_num_commits;
knielsen> static ulonglong binlog_status_var_num_group_commits;
knielsen> +static char binlog_trx_file[FN_REFLEN];
knielsen> +static ulonglong binlog_trx_position;
knielsen> static SHOW_VAR binlog_status_vars_detail[]=
knielsen> {
knielsen> @@ -6562,12 +6609,16 @@ static SHOW_VAR binlog_status_vars_detai
knielsen> (char *)&binlog_status_var_num_commits, SHOW_LONGLONG},
knielsen> {"group_commits",
knielsen> (char *)&binlog_status_var_num_group_commits, SHOW_LONGLONG},
knielsen> + {"trx_file",
knielsen> + (char *)&binlog_trx_file, SHOW_CHAR},
knielsen> + {"trx_position",
knielsen> + (char *)&binlog_trx_position, SHOW_LONGLONG},
knielsen> {NullS, NullS, SHOW_LONG}
knielsen> };
knielsen> static int show_binlog_vars(THD *thd, SHOW_VAR *var, char *buff)
knielsen> {
knielsen> - mysql_bin_log.set_status_variables();
knielsen> + mysql_bin_log.set_status_variables(thd);
knielsen> var->type= SHOW_ARRAY;
knielsen> var->value= (char *)&binlog_status_vars_detail;
knielsen> return 0;
knielsen> @@ -6606,17 +6657,31 @@ static struct st_mysql_sys_var *binlog_s
knielsen> This is called only under LOCK_status, so we can fill in a static array.
knielsen> */
knielsen> void
knielsen> -TC_LOG_BINLOG::set_status_variables()
knielsen> +TC_LOG_BINLOG::set_status_variables(THD *thd)
knielsen> {
knielsen> - ulonglong num_commits, num_group_commits;
knielsen> + binlog_trx_data *trx_data;
knielsen> +
knielsen> + if (thd)
knielsen> + trx_data= (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
knielsen> + else
knielsen> + trx_data= NULL;
knielsen> pthread_mutex_lock(&LOCK_commit_ordered);
knielsen> - num_commits= this->num_commits;
knielsen> - num_group_commits= this->num_group_commits;
knielsen> + binlog_status_var_num_commits= this->num_commits;
knielsen> + binlog_status_var_num_group_commits= this->num_group_commits;
knielsen> + if (!trx_data || 0 == strcmp(trx_data->last_commit_pos_file, ""))
-> if (!trx_data || trx_data->last_commit_pos_file[0] == 0)
knielsen> + {
knielsen> + strmake(binlog_trx_file, last_commit_pos_file, sizeof(binlog_trx_file)-1);
knielsen> + binlog_trx_position= last_commit_pos_offset;
knielsen> + }
knielsen> pthread_mutex_unlock(&LOCK_commit_ordered);
knielsen> + if (trx_data && 0 != strcmp(trx_data->last_commit_pos_file, ""))
-> if (trx_data && trx_data->last_commit_pos_file[0] != 0)
It was a bit tricky to see that this was a negative test for the
earlier one. I would sugges to change first to:
-> if ((binlog_pos_set= (!trx_data || trx_data->last_commit_pos_file[0] == 0))
and the later to
if (!binlog_pos_set)
knielsen> + {
knielsen> + strmake(binlog_trx_file, trx_data->last_commit_pos_file,
knielsen> + sizeof(binlog_trx_file)-1);
knielsen> + binlog_trx_position= trx_data->last_commit_pos_offset;
knielsen> + }
knielsen> }
<cut>
Regards,
Monty
Follow ups