Hello,
On Mon, Jul 07, 2008 at 12:22:51PM +0200, Ingo Struewing wrote:
> 2651 Ingo Struewing 2008-07-07
> Post-merge fixes: Due to changed meta data locking, the backup kernel
> needs to open and lock the MyISAM tables for restore. This instance of
> the MyISAM table takes a local copy of status information. It writes it
> back at unlock. The MyISAM restore driver bypasses MyISAM functions and
> writes directly to the files. So we need to read the status information
> from disk into the table share and update the other instance's copy at
> end of restore.
Here:
> === modified file 'storage/myisam/mi_examine_log.c'
> static int mi_close_care_state(MI_INFO *info)
> {
> if (!update_index_on_close)
> - info->s->mode= O_RDONLY;
> + {
> + MYISAM_SHARE *share;
> + my_bool old_myisam_single_user;
> +
> + share= info->s;
> + old_myisam_single_user= myisam_single_user;
> + myisam_single_user= FALSE;
> + (void) mi_state_info_read_dsk(share->kfile, &share->state, 1);
> + myisam_single_user= old_myisam_single_user;
> + }
> return mi_close(info);
> }
>
and here:
> === modified file 'storage/myisam/myisam_backup_engine.cc'
> @@ -1696,6 +1696,107 @@ result_t Table_restore::close()
> + */
> + {
> + MI_INFO *mi_info;
> + MYISAM_SHARE *share;
> + my_bool old_myisam_single_user;
> +
> + mi_info= mi_open(file_name.ptr(), O_RDWR, HA_OPEN_FOR_REPAIR);
> + if (mi_info == NULL)
> + goto err;
> + share= mi_info->s;
> + DBUG_PRINT("myisam_backup", ("share data_file: %lu",
> + (ulong) share->state.state.data_file_length));
> + old_myisam_single_user= myisam_single_user;
> + myisam_single_user= FALSE;
> + if (mi_state_info_read_dsk(share->kfile,&share->state,1))
> + {
> + myisam_single_user= old_myisam_single_user;
> + goto err;
> + }
> + myisam_single_user= old_myisam_single_user;
you have a slight chance of a race condition, if two threads are
allowed to do a RESTORE (of different backup files to different
databases) concurrently (I don't know if that's allowed now, but
logically it should be: different databases don't conflict).
Indeed there could be
T0: myisam_single_user is TRUE;
thread1 saves myisam_single_user in its old_myisam_single_user (so
this variable contains TRUE), sets myisam_single_user to FALSE
thread2 saves myisam_single_user in its old_myisam_single_user (so
this variable contains FALSE), sets myisam_single_user to FALSE
thread1 restores value: myisam_single_user is now TRUE
thread2 restores value: myisam_single_user is now FALSE and stays this
way forever: it has gone from TRUE initially to FALSE finally.
--
__ ___ ___ ____ __
/ |/ /_ __/ __/ __ \/ / Mr. Guilhem Bichot <guilhem@stripped>
/ /|_/ / // /\ \/ /_/ / /__ MySQL France, Lead Software Engineer
/_/ /_/\_, /___/\___\_\___/ Bordeaux, France
<___/ www.mysql.com