So, ran into a problem with using mysqlhotcopy to build a backup capable of starting a new replicant. The current option (record_log_pos) attempts to get master info from show master status, regardless of whether running on master or slave. It also uses show slave status to see where the slave is in processing master logs. I have found two problems with this ...

- seems show master status returns nothing if you are not a master (and not logging a binlog)
- takes the log position from the Read_Master_Log_Pos, which is only what the IO thread has read, and not what has been applied


I have patched to add a new option --on_slave, which changes the behavior a bit. It now does not run show master, but instead gets all data from show slave status. It uses the Exec_master_log_pos to get the current log position and dies if Slave_IO_Running is not Yes.

See attached patch. Any comments? Does this make sense to people? Any better ideas? I can say that this works, whereas the default does not. Meaning, I am able to take a snapshot, and build a new replicant off of that using the data retrieved from (record_log_pos).

Greg
--
Greg Whalin
Meetup.com
[EMAIL PROTECTED]
--- /usr/local/mysql/bin/mysqlhotcopy	2004-10-23 12:15:09.000000000 -0400
+++ mysqlhotcopy	2004-12-07 13:17:12.780790784 -0500
@@ -75,6 +75,7 @@
   --resetslave         reset the master.info once all tables are locked
   --tmpdir=#	       temporary directory (instead of $opt_tmpdir)
   --record_log_pos=#   record slave and master status in specified db.table
+  --on_slave           tells record_log_pos that this is a slave box
   --chroot=#           base directory of chroot jail in which mysqld operates
 
   Try \'perldoc $0\' for more complete documentation
@@ -115,6 +116,7 @@
     "suffix=s",
     "checkpoint=s",
     "record_log_pos=s",
+    "on_slave",
     "flushlog",
     "resetmaster",
     "resetslave",
@@ -478,8 +480,8 @@
     $dbh->do( "RESET SLAVE" ) if ( $opt{resetslave} );
 
     if ( $opt{record_log_pos} ) {
-	record_log_pos( $dbh, $opt{record_log_pos} );
-	$dbh->do("FLUSH TABLES /*!32323 $hc_tables */");
+		record_log_pos( $dbh, $opt{record_log_pos}, $opt{on_slave} );
+		$dbh->do("FLUSH TABLES /*!32323 $hc_tables */");
     }
 }
 
@@ -743,28 +745,41 @@
 }
 
 sub record_log_pos {
-    my ( $dbh, $table_name ) = @_;
-
+    my ( $dbh, $table_name, $on_slave ) = @_;
     eval {
-	my ($file,$position) = get_row( $dbh, "show master status" );
-	die "master status is undefined" if !defined $file || !defined $position;
-	
-	my ($master_host, undef, undef, undef, $log_file, $log_pos ) 
-	    = get_row( $dbh, "show slave status" );
-	
-	my $hostname = hostname();
-	
-	$dbh->do( qq{ replace into $table_name 
-			  set host=?, log_file=?, log_pos=?, 
-                          master_host=?, master_log_file=?, master_log_pos=? }, 
-		  undef, 
-		  $hostname, $file, $position, 
-		  $master_host, $log_file, $log_pos  );
-	
+		my ($file, $position, $master_host, $log_file, $log_pos);
+		my $hostname = hostname();
+		
+		if (defined $on_slave) {
+			## try to get from slave status
+			my $io_running;
+			($master_host, undef, undef, undef, $file, $position, undef, undef, $log_file, $io_running, undef, undef, undef, undef, undef, undef, $log_pos, undef)
+				= get_row( $dbh, "show slave status" );
+
+			if ($io_running ne 'Yes') {
+				die "IO thread is not running, so can't get reliable master info";
+			}
+		}
+		else {
+			## try to get from master and slave status
+			($file,$position) = get_row( $dbh, "show master status" );
+			die "master status is undefined" if !defined $file || !defined $position;
+			
+			($master_host, undef, undef, undef, $log_file, $log_pos ) 
+				= get_row( $dbh, "show slave status" );
+		}
+
+		## update the log table
+		$dbh->do( qq{ replace into $table_name 
+				  set host=?, log_file=?, log_pos=?, 
+				  master_host=?, master_log_file=?, master_log_pos=? }, 
+			  undef, 
+			  $hostname, $file, $position, 
+			  $master_host, $log_file, $log_pos  );
     };
     
     if ( $@ ) {
-	warn "Failed to store master position: [EMAIL PROTECTED]";
+		warn "Failed to store master position: [EMAIL PROTECTED]";
     }
 }
 
@@ -887,6 +902,13 @@
 The name of the log-pos table should be supplied in database.table format.
 A sample log-pos table definition:
 
+=item --on_slave
+
+This changes behavior of --record_log_pos to only check slave status.
+This allows us to get an indication of the actual position in the master
+log file we are at on this slave at the time of the hot copy so that you
+can use this data to build another replicant from this running slave.
+
 =over 4
 
 CREATE TABLE log_pos (

-- 
MySQL General Mailing List
For list archives: http://lists.mysql.com/mysql
To unsubscribe:    http://lists.mysql.com/[EMAIL PROTECTED]

Reply via email to