MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Rafal Somla Date:September 30 2008 8:14am
Subject:bzr push into mysql-6.0-backup branch (Rafal.Somla:2696 to 2697) Bug#35240
View as plain text  
 2697 Rafal Somla	2008-09-30 [merge]
      BUG#35240 - merge into team tree.
modified:
  mysql-test/r/backup.result
  mysql-test/t/backup.test
  sql/backup/data_backup.cc
  sql/backup/image_info.h
  sql/backup/kernel.cc
  sql/backup/logger.h
  sql/backup/stream_v1.c
  sql/si_logs.cc
  sql/si_logs.h

 2696 Chuck Bell	2008-09-29
      BUG#33352 Backup:crash if I use old set of mysql files. 
      
      The error message produced when the backup logs are missing or damaged is
      misleading. This patch changes the error to a more appropriate, instructional
      error message.
modified:
  mysql-test/lib/mtr_report.pl
  mysql-test/r/backup_errors.result
  mysql-test/t/backup_errors.test
  sql/log.cc
  sql/share/errmsg.txt

=== modified file 'mysql-test/r/backup.result'
--- a/mysql-test/r/backup.result	2008-07-01 20:32:27 +0000
+++ b/mysql-test/r/backup.result	2008-09-30 07:51:48 +0000
@@ -67,12 +67,20 @@ breakpoints: Sending finish signal to wa
 SET DEBUG_SYNC= 'now SIGNAL finish';
 backup_id
 #
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+SELECT validity_point_time FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_time;
+SELECT binlog_file FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_file;
+SELECT binlog_pos FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_pos;
 DROP DATABASE db1;
 DROP DATABASE db2;
 USE mysql;
 RESTORE FROM 'test.ba';
 backup_id
 #
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
 SHOW CREATE DATABASE db1;
 Database	Create Database
 db1	CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET latin1 */
@@ -132,6 +140,18 @@ tasking	CREATE TABLE `tasking` (
   `project_number` char(9) DEFAULT NULL,
   `hours_worked` double(10,2) DEFAULT NULL
 ) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1
+SELECT validity_point_time = @vp_time FROM mysql.backup_history
+WHERE backup_id = @bid;
+validity_point_time = @vp_time
+1
+SELECT binlog_file = @vp_file FROM mysql.backup_history
+WHERE backup_id = @bid;
+binlog_file = @vp_file
+1
+SELECT binlog_pos = @vp_pos FROM mysql.backup_history
+WHERE backup_id = @bid;
+binlog_pos = @vp_pos
+1
 DROP DATABASE db1;
 DROP DATABASE db2;
 DROP DATABASE db3;

=== modified file 'mysql-test/t/backup.test'
--- a/mysql-test/t/backup.test	2008-07-01 20:32:27 +0000
+++ b/mysql-test/t/backup.test	2008-09-30 07:51:48 +0000
@@ -1,6 +1,7 @@
 --source include/have_innodb.inc
 --source include/not_embedded.inc
 --source include/have_debug_sync.inc
+--source include/have_log_bin.inc
 
 SET DEBUG_SYNC= 'RESET';
 
@@ -132,6 +133,18 @@ connection backup;
 --replace_column 1 #
 reap;
 
+# get backup_id of the BACKUP operation. 
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+
+# store VP time and binlog position
+
+SELECT validity_point_time FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_time;
+SELECT binlog_file FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_file;
+SELECT binlog_pos FROM mysql.backup_history
+WHERE backup_id = @bid INTO @vp_pos;
+
 DROP DATABASE db1;
 DROP DATABASE db2;
 
@@ -140,9 +153,15 @@ DROP DATABASE db2;
 
 USE mysql;
 
+# wait few seconds so that restore time != backup time
+--sleep 2
+
 --replace_column 1 #
 RESTORE FROM 'test.ba';
 
+# determine id of RESTORE operation
+SELECT MAX(backup_id) FROM mysql.backup_history INTO @bid;
+
 --remove_file $MYSQLTEST_VARDIR/master-data/test.ba
 
 SHOW CREATE DATABASE db1;
@@ -167,6 +186,15 @@ CHECK TABLE staff EXTENDED;
 SELECT * FROM staff;
 SHOW CREATE TABLE tasking;
 
+# check that VP info was correctly read and reported
+
+SELECT validity_point_time = @vp_time FROM mysql.backup_history
+WHERE backup_id = @bid; 
+SELECT binlog_file = @vp_file FROM mysql.backup_history
+WHERE backup_id = @bid; 
+SELECT binlog_pos = @vp_pos FROM mysql.backup_history
+WHERE backup_id = @bid; 
+
 DROP DATABASE db1;
 DROP DATABASE db2;
 DROP DATABASE db3;

=== modified file 'sql/backup/data_backup.cc'
--- a/sql/backup/data_backup.cc	2008-09-02 07:44:28 +0000
+++ b/sql/backup/data_backup.cc	2008-09-30 07:51:48 +0000
@@ -623,7 +623,7 @@ int write_table_data(THD* thd, Backup_in
     // Report and save information about VP
 
     info.save_vp_time(vp_time);
-    info.m_ctx.report_vp_time(vp_time);
+    info.m_ctx.report_vp_time(vp_time, TRUE); // TRUE = also write to progress log
 
     if (mysql_bin_log.is_open())
     {

=== modified file 'sql/backup/image_info.h'
--- a/sql/backup/image_info.h	2008-09-15 12:27:32 +0000
+++ b/sql/backup/image_info.h	2008-09-30 07:51:48 +0000
@@ -120,6 +120,8 @@ public: // public interface
 
    void save_binlog_pos(const ::LOG_INFO&);
 
+   time_t get_vp_time() const;
+
  protected: // internal interface
   
   // Populate the catalogue
@@ -742,6 +744,25 @@ Image_info::Ts* Image_info::get_ts(uint 
 }
 
 
+inline
+time_t Image_info::get_vp_time() const
+{
+  struct tm time;
+
+  time.tm_year= vp_time.year;
+  time.tm_mon= vp_time.mon;
+  time.tm_mday= vp_time.mday;
+  time.tm_hour= vp_time.hour;
+  time.tm_min= vp_time.min;
+  time.tm_sec= vp_time.sec;  
+
+  /*
+    Note: mktime() assumes that time is expressed as local time hence
+    we must correct the result to get UTC time.
+   */ 
+  return mktime(&time) - timezone;
+}
+
 /**
   Save time inside a @c bstream_time_t structure (helper function).
  */ 

=== modified file 'sql/backup/kernel.cc'
--- a/sql/backup/kernel.cc	2008-09-26 15:47:35 +0000
+++ b/sql/backup/kernel.cc	2008-09-30 07:51:48 +0000
@@ -577,6 +577,21 @@ Backup_restore_ctx::prepare_for_backup(S
   if (!info->is_valid())
     return NULL;
 
+  /*
+    If binlog is enabled, set BSTREAM_FLAG_BINLOG in the header to indicate
+    that validity point's binlog position will be stored in the image 
+    (in its summary section).
+    
+    This is not completely safe because theoretically even if now binlog is 
+    active, it can be disabled before we reach the validity point and then we 
+    will not store binlog position even though the flag is set. To fix this 
+    problem the format of backup image must be changed (some flags must be 
+    stored in the summary section which is written at the end of backup 
+    operation).
+  */
+  if (mysql_bin_log.is_open())
+    info->flags|= BSTREAM_FLAG_BINLOG; 
+
   info->save_start_time(when);
   m_catalog= info;
   m_state= PREPARED_FOR_BACKUP;
@@ -820,18 +835,6 @@ int Backup_restore_ctx::close()
   if (m_catalog)
     m_catalog->save_end_time(when); // Note: no errors.
 
-  // destroy backup stream's memory allocator (this frees memory)
-
-  delete mem_alloc;
-  mem_alloc= NULL;
-  
-  // deregister this operation if it was running
-  pthread_mutex_lock(&run_lock);
-  if (current_op == this) {
-    current_op= NULL;
-  }
-  pthread_mutex_unlock(&run_lock);
-
   /* 
     Remove the location, if asked for.
     
@@ -858,6 +861,24 @@ int Backup_restore_ctx::close()
   if (!m_error)
     report_stop(when, TRUE);
 
+  /* 
+    Destroy backup stream's memory allocator (this frees memory)
+  
+    Note that from now on data stored in this object might be corrupted. For 
+    example the binlog file name is a string stored in memory allocated by
+    the allocator which will be freed now.
+  */
+  
+  delete mem_alloc;
+  mem_alloc= NULL;
+  
+  // deregister this operation if it was running
+  pthread_mutex_lock(&run_lock);
+  if (current_op == this) {
+    current_op= NULL;
+  }
+  pthread_mutex_unlock(&run_lock);
+
   m_state= CLOSED;
   return m_error;
 }
@@ -1110,6 +1131,15 @@ int Backup_restore_ctx::do_restore()
   // FIXME: error logging.
   m_thd->main_da.reset_diagnostics_area();
 
+  /*
+    Report validity point time and binlog position stored in the backup image
+    (in the summary section).
+   */ 
+
+  report_vp_time(info.get_vp_time(), FALSE); // FALSE = do not write to progress log
+  if (info.flags & BSTREAM_FLAG_BINLOG)
+    report_binlog_pos(info.binlog_pos);
+
   // FIXME: detect errors if reported.
   // FIXME: error logging.
   report_stats_post(info);

=== modified file 'sql/backup/logger.h'
--- a/sql/backup/logger.h	2008-08-28 15:13:31 +0000
+++ b/sql/backup/logger.h	2008-09-30 07:51:48 +0000
@@ -54,7 +54,7 @@ class Logger
    void report_start(time_t);
    void report_stop(time_t, bool);
    void report_state(enum_backup_state);
-   void report_vp_time(time_t);
+   void report_vp_time(time_t, bool);
    void report_binlog_pos(const st_bstream_binlog_pos&);
    void report_driver(const char *driver);
    void report_stats_pre(const Image_info&);
@@ -237,13 +237,19 @@ void Logger::report_state(enum_backup_st
   backup_log->state(state);
 }
 
-/// Report validity point creation time.
+/** 
+  Report validity point creation time.
+
+  @param[IN] when   the time of validity point
+  @param[IN] report determines if VP time should be also reported in the
+                    backup_progress log
+*/
 inline
-void Logger::report_vp_time(time_t when)
+void Logger::report_vp_time(time_t when, bool report)
 {
   DBUG_ASSERT(m_state == RUNNING);
   DBUG_ASSERT(backup_log);
-  backup_log->vp_time(when);
+  backup_log->vp_time(when, report);
 }
 
 /** 

=== modified file 'sql/backup/stream_v1.c'
--- a/sql/backup/stream_v1.c	2008-09-16 16:09:18 +0000
+++ b/sql/backup/stream_v1.c	2008-09-30 08:08:16 +0000
@@ -1969,10 +1969,10 @@ int bstream_rd_int4(backup_stream *s, un
   if (ret == BSTREAM_ERROR)
     return BSTREAM_ERROR;
 
-  *x = buf[0];
-  *x += (buf[1] << 8);
-  *x += (buf[1] << 2*8);
-  *x += (buf[1] << 3*8);
+  *x = (unsigned long int)buf[0];
+  *x += ((unsigned long int)buf[1] << 8);
+  *x += ((unsigned long int)buf[2] << 2*8);
+  *x += ((unsigned long int)buf[3] << 3*8);
 
   return ret;
 }

=== modified file 'sql/si_logs.cc'
--- a/sql/si_logs.cc	2008-08-28 15:13:31 +0000
+++ b/sql/si_logs.cc	2008-09-30 07:51:48 +0000
@@ -138,16 +138,19 @@ void Backup_log::state(enum_backup_state
   a message to the progress log.
 
   @param[IN]  when  Time of validity point.
+  @param[IN]  report Determines if an entry should be written to the 
+                     backup_progress log.
 
   @note If the time is 0|NULL, nothing is saved in the history data.
 */
-void Backup_log::vp_time(time_t when)
+void Backup_log::vp_time(time_t when, bool report)
 {
   if (when)
   {
-    m_op_hist.vp_time= when; 
-    logger.backup_progress_log_write(m_thd, m_op_hist.backup_id, "backup kernel", 
-                                     when, 0, 0, 0, 0, "vp time");
+    m_op_hist.vp_time= when;
+    if (report)
+      logger.backup_progress_log_write(m_thd, m_op_hist.backup_id, "backup kernel", 
+                                       when, 0, 0, 0, 0, "vp time");
   }
 }
 

=== modified file 'sql/si_logs.h'
--- a/sql/si_logs.h	2008-08-27 17:30:49 +0000
+++ b/sql/si_logs.h	2008-09-30 07:51:48 +0000
@@ -130,7 +130,7 @@ public:
   void size(longlong s) { m_op_hist.size= s; }
   void start(time_t when);
   void stop(time_t when);
-  void vp_time(time_t when);
+  void vp_time(time_t when, bool report);
   void add_driver(const char* driver);
 
 private:

Thread
bzr push into mysql-6.0-backup branch (Rafal.Somla:2696 to 2697) Bug#35240Rafal Somla30 Sep