List:Commits« Previous MessageNext Message »
From:rsomla Date:April 22 2008 11:35am
Subject:bk commit into 6.0 tree (rafal:1.2612) BUG#33023
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of rafal.  When rafal does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-04-22 11:35:52+02:00, rafal@quant.(none) +11 -0
  BUG#33023 (Online backup could mangle object names if non-std charset is used)
  
  The following problems are fixed by this patch:
  
  1. If during restore a connection character set different than at backup time 
  was used, object names were wrongly interpreted leading to failures.
  
  2. Character set and collation settings associated with a view were not stored 
  in backup image and not restored correctly.
  
  3. When errors were detected during restore of table data, the 
  Backup_restore_ctx object was not correctly set to error state.
  
  4. Tables in the list passed from backup kernel to backup/restore drivers were 
  not identified using the same convention as used by storage engines. The 
  internal table name representation uses only US-ascii characters and can handle 
  names written using any character set.
  
  The solutions are as follows.
  
  Ad 1) Charset settings are changed to system defaults inside obs::Obj::execute() 
  method and restored to previous values at the end.
  
  Ad 2) obs::TableObj::serialize() method is modified to prepend 
  "SET CHARACTER_SET_CLIENT" and "SET COLLATION_CONNECTION" statements in front of 
  view's serialization string.
  
  Ad 3) Backup_restore_ctx::fatal_error() method is used for reporting errors 
  which interrupt restore process.
  
  Ad 4) Method internal_name() is added to backup::Table_ref(). It can be used by 
  backup/restore drivers to obtain internal table name repesentation.

  mysql-test/r/backup_objects.result@stripped, 2008-04-22 11:35:44+02:00, rafal@quant.(none) +2 -2
    Correct results of the test (character_set_client should be restored to the original value).

  sql/backup/api_types.h@stripped, 2008-04-22 11:35:44+02:00, rafal@quant.(none) +9 -9
    Add Table_ref::interanl_name() method.

  sql/backup/backup_engine.h@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +24 -0
    Add implementation of Table_ref::internal_name() and Table_ref::describe().

  sql/backup/backup_info.cc@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +2 -2
    Rename type describe_buf -> name_buf.

  sql/backup/backup_kernel.h@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +2 -2
    Remove Logger parameter from {write,restore}_table_data() because now it 
    is given in a {Backup,Restore}_info object.

  sql/backup/data_backup.cc@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +17 -17
    - Remove Logger parameter from {write,restore}_table_data() because now it 
      is given in a {Backup,Restore}_info object.
    - Use fatal_error() for reporting errors which interrupt backup/restore process.

  sql/backup/image_info.h@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +1 -1
    Rename type describe_buf -> name_buf.

  sql/backup/kernel.cc@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +3 -3
    Remove Logger parameter from {write,restore}_table_data() because now it 
    is given in a {Backup,Restore}_info object.

  sql/backup/restore_info.h@stripped, 2008-04-22 11:35:45+02:00, rafal@quant.(none) +2 -2
    Remove Logger parameter from {write,restore}_table_data() because now it 
    is given in a {Backup,Restore}_info object.

  sql/si_objects.cc@stripped, 2008-04-22 11:35:44+02:00, rafal@quant.(none) +17 -1
    Store character_set_client and collaction_connection setting inside view's 
    serialization string.

  sql/si_objects.h@stripped, 2008-04-22 11:35:44+02:00, rafal@quant.(none) +12 -1
    In Obj::execute() method, where SQL statements are executed, set all THD character sets
    to the system default (utf8).  

diff -Nrup a/mysql-test/r/backup_objects.result b/mysql-test/r/backup_objects.result
--- a/mysql-test/r/backup_objects.result	2008-02-13 12:40:24 +01:00
+++ b/mysql-test/r/backup_objects.result	2008-04-22 11:35:44 +02:00
@@ -197,12 +197,12 @@ Create Table	CREATE TABLE `t2` (
 SHOW CREATE VIEW bup_objects.v1;;
 View	v1
 Create View	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`col_a` AS `col_a`,`t1`.`col_b` AS `col_b` from `t1` where (`t1`.`col_a` < 5)
-character_set_client	latin1
+character_set_client	latin2
 collation_connection	latin1_swedish_ci
 SHOW CREATE VIEW bup_objects.v2;;
 View	v2
 Create View	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`col_a` AS `col_a`,`t1`.`col_b` AS `col_b` from `t1` where (`t1`.`col_a` >= 5)
-character_set_client	latin1
+character_set_client	latin2
 collation_connection	latin1_swedish_ci
 SHOW CREATE PROCEDURE bup_objects.p1;;
 Procedure	p1
diff -Nrup a/sql/backup/api_types.h b/sql/backup/api_types.h
--- a/sql/backup/api_types.h	2008-03-05 18:48:04 +01:00
+++ b/sql/backup/api_types.h	2008-04-22 11:35:44 +02:00
@@ -128,17 +128,17 @@ class Table_ref
   bool operator!=(const Table_ref &db) const
   { return ! this->operator==(db); }
 
-  typedef char describe_buf[512];
+  typedef char name_buf[FN_REFLEN+8];
 
-  /// Produce string identifying the table (e.g. for error reporting)
-  const char* describe(char *buf, size_t len) const
-  {
-    my_snprintf(buf, len, "`%s`.`%s`", db().name().ptr(), name().ptr());
-    return buf;
-  }
-
-  const char* describe(describe_buf &buf) const
+  // Produce string identifying the table (e.g. for error reporting)
+  const char* describe(char *buf, size_t len) const;
+  const char* describe(name_buf &buf) const
   { return describe(buf, sizeof(buf)); }
+
+  // Produce string identifying the table in internal format. 
+  const char* internal_name(char *buf, size_t len) const;
+  const char* internal_name(name_buf &buf) const
+  { return internal_name(buf, sizeof(buf)); };
   
  protected:
 
diff -Nrup a/sql/backup/backup_engine.h b/sql/backup/backup_engine.h
--- a/sql/backup/backup_engine.h	2008-03-04 17:06:22 +01:00
+++ b/sql/backup/backup_engine.h	2008-04-22 11:35:45 +02:00
@@ -524,6 +524,30 @@ class Restore_driver: public Driver
 }; // Restore_driver
 
 
+/** 
+  Produce string identifying the table in internal format (as used by 
+  storage engines).
+*/
+inline
+const char* Table_ref::internal_name(char *buf, size_t len) const
+{
+  uint plen= build_table_filename(buf, len, 
+                                  db().name().ptr(), name().ptr(), 
+                                  "", /* no extension */ 
+                                  0 /* not a temporary table - do conversions */);
+  buf[plen]='\0';
+  return buf;    
+}
+
+/// Produce human readable string identifying the table (e.g. for error reporting)
+inline
+const char* Table_ref::describe(char *buf, size_t len) const
+{
+  my_snprintf(buf, len, "`%s`.`%s`", db().name().ptr(), name().ptr());
+  return buf;
+}
+
+
 } // backup namespace
 
 // export Backup/Restore_driver classes to global namespace
diff -Nrup a/sql/backup/backup_info.cc b/sql/backup/backup_info.cc
--- a/sql/backup/backup_info.cc	2008-03-21 09:43:43 +01:00
+++ b/sql/backup/backup_info.cc	2008-04-22 11:35:45 +02:00
@@ -61,7 +61,7 @@ Backup_info::find_backup_engine(const ba
 {
   using namespace backup;
 
-  Table_ref::describe_buf buf;
+  Table_ref::name_buf buf;
   Snapshot_info *snap= NULL;
   
   DBUG_ENTER("Backup_info::find_backup_engine");
@@ -563,7 +563,7 @@ backup::Image_info::Table* Backup_info::
   
   if (!tbl)
   {
-    Tbl::describe_buf buf;
+    Tbl::name_buf buf;
     m_ctx.fatal_error(ER_BACKUP_CATALOG_ADD_TABLE, t.describe(buf));
     return NULL;
   }
diff -Nrup a/sql/backup/backup_kernel.h b/sql/backup/backup_kernel.h
--- a/sql/backup/backup_kernel.h	2008-04-17 12:43:01 +02:00
+++ b/sql/backup/backup_kernel.h	2008-04-22 11:35:45 +02:00
@@ -42,8 +42,8 @@ class Mem_allocator;
 class Stream;
 class Native_snapshot;
 
-int write_table_data(THD*, Logger&, Backup_info&, Output_stream&);
-int restore_table_data(THD*, Logger&, Restore_info&, Input_stream&);
+int write_table_data(THD*, Backup_info&, Output_stream&);
+int restore_table_data(THD*, Restore_info&, Input_stream&);
 
 }
 
diff -Nrup a/sql/backup/data_backup.cc b/sql/backup/data_backup.cc
--- a/sql/backup/data_backup.cc	2008-03-21 10:05:36 +01:00
+++ b/sql/backup/data_backup.cc	2008-04-22 11:35:45 +02:00
@@ -261,7 +261,7 @@ class Scheduler
   void remove_pump(Pump_iterator&);
   void cancel_backup();
 
-  friend int write_table_data(THD*, Logger&, Backup_info&, Output_stream&);
+  friend int write_table_data(THD*, Backup_info&, Output_stream&);
   friend class Pump_iterator;
 };
 
@@ -469,14 +469,14 @@ int unblock_commits(THD *thd)
 
   @returns 0 on success.
  */
-int write_table_data(THD* thd, Logger &log, Backup_info &info, Output_stream &s)
+int write_table_data(THD* thd, Backup_info &info, Output_stream &s)
 {
   DBUG_ENTER("backup::write_table_data");
 
   if (info.snap_count() == 0 || info.table_count() == 0) // nothing to backup
     DBUG_RETURN(0);
 
-  Scheduler   sch(s, &log);          // scheduler instance
+  Scheduler   sch(s, &info.m_ctx);          // scheduler instance
   List<Scheduler::Pump>  inactive;  // list of images not yet being created
 
   // keeps maximal init size for images in inactive list
@@ -499,7 +499,7 @@ int write_table_data(THD* thd, Logger &l
 
     if (!p || !p->is_valid())
     {
-      log.report_error(ER_OUT_OF_RESOURCES);
+      info.m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
       goto error;
     }
 
@@ -607,7 +607,7 @@ int write_table_data(THD* thd, Logger &l
 
     LOG_INFO binlog_pos;
     
-    log.report_state(BUP_VALIDITY_POINT);
+    info.m_ctx.report_state(BUP_VALIDITY_POINT);
     /*
       This breakpoint is used to assist in testing state changes for
       the backup progress. It is not to be used to indicate actual
@@ -658,15 +658,15 @@ int write_table_data(THD* thd, Logger &l
     // Report and save information about VP
 
     info.save_vp_time(vp_time);
-    log.report_vp_time(vp_time);
+    info.m_ctx.report_vp_time(vp_time);
 
     if (mysql_bin_log.is_open())
     {
       info.save_binlog_pos(binlog_pos);
-      log.report_binlog_pos(info.binlog_pos);
+      info.m_ctx.report_binlog_pos(info.binlog_pos);
     }
 
-    log.report_state(BUP_RUNNING);
+    info.m_ctx.report_state(BUP_RUNNING);
     BACKUP_BREAKPOINT("bp_running_state");
 
     /**** VP creation (end) ********************************************/
@@ -1364,7 +1364,7 @@ namespace backup {
 /**
   Read backup image data from a backup stream and forward it to restore drivers.
  */
-int restore_table_data(THD*, Logger &log, Restore_info &info, Input_stream &s)
+int restore_table_data(THD*, Restore_info &info, Input_stream &s)
 {
   DBUG_ENTER("restore::restore_table_data");
 
@@ -1380,7 +1380,7 @@ int restore_table_data(THD*, Logger &log
 
   if (info.snap_count() > 256)
   {
-    log.report_error(ER_BACKUP_TOO_MANY_IMAGES, info.snap_count(), 256);
+    info.m_ctx.fatal_error(ER_BACKUP_TOO_MANY_IMAGES, info.snap_count(), 256);
     DBUG_RETURN(ERROR);
   }
 
@@ -1400,7 +1400,7 @@ int restore_table_data(THD*, Logger &log
     res= snap->get_restore_driver(drv[n]);
     if (res == backup::ERROR)
     {
-      log.report_error(ER_BACKUP_CREATE_RESTORE_DRIVER, snap->name());
+      info.m_ctx.fatal_error(ER_BACKUP_CREATE_RESTORE_DRIVER, snap->name());
       goto error;
     };
     
@@ -1423,7 +1423,7 @@ int restore_table_data(THD*, Logger &log
     query_cache.invalidate_locked_for_write(table_list);
     if (open_and_lock_tables(::current_thd, table_list))
     {
-      log.report_error(ER_BACKUP_OPEN_TABLES, "restore");
+      info.m_ctx.fatal_error(ER_BACKUP_OPEN_TABLES, "restore");
       DBUG_RETURN(backup::ERROR);
     }
     if (table_list_last)
@@ -1436,7 +1436,7 @@ int restore_table_data(THD*, Logger &log
     res= drv[n]->begin(0);
     if (res == backup::ERROR)
     {
-      log.report_error(ER_BACKUP_INIT_RESTORE_DRIVER, info.m_snap[n]->name());
+      info.m_ctx.fatal_error(ER_BACKUP_INIT_RESTORE_DRIVER, info.m_snap[n]->name());
       goto error;
     }
   }
@@ -1478,7 +1478,7 @@ int restore_table_data(THD*, Logger &log
           break;
 
         case BSTREAM_ERROR:
-          log.report_error(ER_BACKUP_READ_DATA);
+          info.m_ctx.fatal_error(ER_BACKUP_READ_DATA);
         default:
           state= ERROR;
           goto error;
@@ -1533,7 +1533,7 @@ int restore_table_data(THD*, Logger &log
         case backup::ERROR:
           if( errors > MAX_ERRORS )
           {
-            log.report_error(ER_BACKUP_SEND_DATA, buf.table_num, snap->name());
+            info.m_ctx.fatal_error(ER_BACKUP_SEND_DATA, buf.table_num, snap->name());
             state= ERROR;
             goto error;
           }
@@ -1545,7 +1545,7 @@ int restore_table_data(THD*, Logger &log
         default:
           if( repeats > MAX_REPEATS )
           {
-            log.report_error(ER_BACKUP_SEND_DATA_RETRY, repeats, snap->name());
+            info.m_ctx.fatal_error(ER_BACKUP_SEND_DATA_RETRY, repeats, snap->name());
             state= ERROR;
             goto error;
           }
@@ -1588,7 +1588,7 @@ int restore_table_data(THD*, Logger &log
     }
 
     if (!bad_drivers.is_empty())
-      log.report_error(ER_BACKUP_STOP_RESTORE_DRIVERS, bad_drivers.c_ptr());
+      info.m_ctx.report_error(ER_BACKUP_STOP_RESTORE_DRIVERS, bad_drivers.c_ptr());
   }
 
   /*
diff -Nrup a/sql/backup/image_info.h b/sql/backup/image_info.h
--- a/sql/backup/image_info.h	2008-04-17 12:44:07 +02:00
+++ b/sql/backup/image_info.h	2008-04-22 11:35:45 +02:00
@@ -332,7 +332,7 @@ class Image_info::Obj: public Sql_alloc
    */ 
   virtual obs::Obj *materialize(uint ver, const ::String&) =0;
 
-  typedef Table_ref::describe_buf describe_buf;
+  typedef Table_ref::name_buf describe_buf;
   virtual const char* describe(describe_buf&) const =0;
 
  protected:
diff -Nrup a/sql/backup/kernel.cc b/sql/backup/kernel.cc
--- a/sql/backup/kernel.cc	2008-04-17 15:28:22 +02:00
+++ b/sql/backup/kernel.cc	2008-04-22 11:35:45 +02:00
@@ -743,7 +743,7 @@ int Backup_restore_ctx::do_backup()
 
   BACKUP_BREAKPOINT("backup_data");
 
-  if (write_table_data(m_thd, *this, info, s)) // reports errors
+  if (write_table_data(m_thd, info, s)) // reports errors
     DBUG_RETURN(send_error(*this, ER_BACKUP_BACKUP));
 
   DBUG_PRINT("backup",("Writing summary"));
@@ -812,8 +812,8 @@ int Backup_restore_ctx::do_restore()
   m_thd->main_da.reset_diagnostics_area();
 
   // Here restore drivers are created to restore table data
-  if (restore_table_data(m_thd, *this, info, s)) // reports errors
-    DBUG_RETURN(send_error(*this, ER_BACKUP_RESTORE));
+  if (restore_table_data(m_thd, info, s)) // reports errors
+    DBUG_RETURN(ER_BACKUP_RESTORE);
 
   DBUG_PRINT("restore",("Done."));
 
diff -Nrup a/sql/backup/restore_info.h b/sql/backup/restore_info.h
--- a/sql/backup/restore_info.h	2008-03-04 17:06:24 +01:00
+++ b/sql/backup/restore_info.h	2008-04-22 11:35:45 +02:00
@@ -12,7 +12,7 @@ namespace backup {
 class Logger;
 class Input_stream;
 
-int restore_table_data(THD*, backup::Logger&, Restore_info&, 
+int restore_table_data(THD*, Restore_info&, 
                        backup::Input_stream&);
 
 } // backup namespace
@@ -42,7 +42,7 @@ class Restore_info: public backup::Image
 
  private:
 
-  friend int backup::restore_table_data(THD*, backup::Logger&, Restore_info&, 
+  friend int backup::restore_table_data(THD*, Restore_info&, 
                                         backup::Input_stream&);
   friend int ::bcat_add_item(st_bstream_image_header*,
                              struct st_bstream_item_info*);
diff -Nrup a/sql/si_objects.cc b/sql/si_objects.cc
--- a/sql/si_objects.cc	2008-04-21 15:09:58 +02:00
+++ b/sql/si_objects.cc	2008-04-22 11:35:44 +02:00
@@ -1751,8 +1751,24 @@ bool TableObj::do_serialize(THD *thd, St
   */
   if (m_table_is_view)
   {
+    View_creation_ctx *creation_ctx= table_list->view_creation_ctx;
+
+    /*
+      append character set client charset information
+    */
+    serialization->append("SET CHARACTER_SET_CLIENT = '");
+    serialization->append(creation_ctx->get_client_cs()->csname);
+    serialization->append("'; ");
+
+    /*
+      append collation_connection information
+    */
+    serialization->append("SET COLLATION_CONNECTION = '");
+    serialization->append(creation_ctx->get_connection_cl()->name);
+    serialization->append("'; ");
+
     table_list->view_db= dbname;
-    serialization->set_charset(table_list->view_creation_ctx->get_client_cs());
+    serialization->set_charset(creation_ctx->get_client_cs());
   }
 
   /*
diff -Nrup a/sql/si_objects.h b/sql/si_objects.h
--- a/sql/si_objects.h	2008-04-17 12:42:27 +02:00
+++ b/sql/si_objects.h	2008-04-22 11:35:44 +02:00
@@ -136,9 +136,20 @@ bool Obj::execute(THD *thd)
 {
   ulong saved_sql_mode= thd->variables.sql_mode;
   thd->variables.sql_mode= 0;
-  
+
+  set_var_collation_client saved_charset_settings(
+                             thd->variables.character_set_client,
+                             thd->variables.character_set_results,
+                             thd->variables.collation_connection);
+
+  set_var_collation_client new_charset_settings(::system_charset_info,
+                                                ::system_charset_info,
+                                                ::system_charset_info);
+  new_charset_settings.update(thd);
+
   bool ret= do_execute(thd);
 
+  saved_charset_settings.update(thd);
   thd->variables.sql_mode= saved_sql_mode;
 
   return ret;
Thread
bk commit into 6.0 tree (rafal:1.2612) BUG#33023rsomla22 Apr