List:Commits« Previous MessageNext Message »
From:Stewart Smith Date:August 14 2008 7:23am
Subject:bzr commit into mysql-5.1 branch (stewart:2678)
View as plain text  
#At file:///home/stewart/mysql/soc-review/

 2678 Stewart Smith	2008-08-14 [merge]
      merge in SoC work
modified:
  client/Makefile.am
  client/mysqldump.c

=== modified file 'client/Makefile.am'
--- a/client/Makefile.am	2008-08-01 15:10:06 +0000
+++ b/client/Makefile.am	2008-08-14 07:23:25 +0000
@@ -70,6 +70,11 @@ mysqldump_SOURCES=              mysqldum
 				my_user.c \
 	                        $(top_srcdir)/mysys/mf_getdate.c
 
+mysqldump_LDADD =		$(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+				@CLIENT_EXTRA_LDFLAGS@ \
+				$(LIBMYSQLCLIENT_LA) \
+				$(top_builddir)/mysys/libmysys.a
+
 mysqlimport_SOURCES=		mysqlimport.c
 
 mysqlimport_LDADD =		$(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \

=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c	2008-04-24 14:50:38 +0000
+++ b/client/mysqldump.c	2008-08-09 03:30:57 +0000
@@ -45,6 +45,7 @@
 #include <m_ctype.h>
 #include <hash.h>
 #include <stdarg.h>
+#include <pthread.h>
 
 #include "client_priv.h"
 #include "mysql.h"
@@ -100,10 +101,9 @@ static my_bool  verbose= 0, opt_no_creat
                 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
                 opt_events= 0,
                 opt_alltspcs=0, opt_notspcs= 0;
-static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
+static my_bool debug_info_flag= 0, debug_check_flag= 0;
 static ulong opt_max_allowed_packet, opt_net_buffer_length;
 static MYSQL mysql_connection,*mysql=0;
-static DYNAMIC_STRING insert_pat;
 static char  *opt_password=0,*current_user=0,
              *current_host=0,*path=0,*fields_terminated=0,
              *lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
@@ -118,13 +118,14 @@ static my_bool server_supports_switching
 static ulong opt_compatible_mode= 0;
 #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
-static uint opt_mysql_port= 0, opt_master_data;
+static uint opt_mysql_port= 0, opt_master_data, opt_use_threads=0;
 static uint my_end_arg;
 static char * opt_mysql_unix_port=0;
 static int   first_error=0;
-static DYNAMIC_STRING extended_row;
 #include <sslopt-vars.h>
 FILE *md_result_file= 0;
+static char* md_result_file_path;
+int md_result_file_path_length;
 FILE *stderror_file=0;
 
 #ifdef HAVE_SMEM
@@ -445,12 +446,16 @@ static struct my_option my_long_options[
    (uchar**) &path, (uchar**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"tables", OPT_TABLES, "Overrides option --databases (-B).",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-   {"triggers", OPT_TRIGGERS, "Dump triggers for each dumped table",
-     (uchar**) &opt_dump_triggers, (uchar**) &opt_dump_triggers, 0, GET_BOOL,
-     NO_ARG, 1, 0, 0, 0, 0, 0},
+  {"triggers", OPT_TRIGGERS, "Dump triggers for each dumped table",
+   (uchar**) &opt_dump_triggers, (uchar**) &opt_dump_triggers, 0, GET_BOOL,
+   NO_ARG, 1, 0, 0, 0, 0, 0},
   {"tz-utc", OPT_TZ_UTC,
-    "SET TIME_ZONE='+00:00' at top of dump to allow dumping of TIMESTAMP data when a server has data in different time zones or data is being moved between servers with different time zones.",
-    (uchar**) &opt_tz_utc, (uchar**) &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+   "SET TIME_ZONE='+00:00' at top of dump to allow dumping of TIMESTAMP data when a server has data in different time zones or data is being moved between servers with different time zones.",
+   (uchar**) &opt_tz_utc, (uchar**) &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+  {"use-threads", OPT_USE_THREADS,
+   "Dump in parallel. The argument is the number of threads to use for dumping data.",
+   (uchar**) &opt_use_threads, (uchar**) &opt_use_threads, 0, GET_UINT, REQUIRED_ARG,
+   0, 0, 0, 0, 0, 0},
 #ifndef DONT_ALLOW_USER_CHANGE
   {"user", 'u', "User for login if not current user.",
    (uchar**) &current_user, (uchar**) &current_user, 0, GET_STR, REQUIRED_ARG,
@@ -469,6 +474,25 @@ static struct my_option my_long_options[
 
 static const char *load_default_groups[]= { "mysqldump","client",0 };
 
+struct thread_data
+{
+  unsigned t_id;                  /* Thread id */
+  char *db;                       /* Database */
+  char ***tables;                 /* Pointer to the list of tables */
+  unsigned noof_tables;           /* Total number of threads */
+  unsigned *count_tables;         /* Shared index to the next table to be dumped */
+  pthread_mutex_t *tables_mutex;  /* Mutex to acess shared resources */
+
+  /* TODO This can be removed when dump_all_tables_in_db is done */
+  FILE *md_result_file;
+  char *table;
+  MYSQL *mysql_con;
+
+  /* Variables below are used only by dump_all_tables_in_db method */
+  char *hash_key;
+  char *afterdot;
+};
+
 static void maybe_exit(int error);
 static void die(int error, const char* reason, ...);
 static void maybe_die(int error, const char* reason, ...);
@@ -476,22 +500,22 @@ static void write_header(FILE *sql_file,
 static void print_value(FILE *file, MYSQL_RES  *result, MYSQL_ROW row,
                         const char *prefix,const char *name,
                         int string_value);
-static int dump_selected_tables(char *db, char **table_names, int tables);
-static int dump_all_tables_in_db(char *db);
-static int init_dumping_views(char *);
-static int init_dumping_tables(char *);
-static int init_dumping(char *, int init_func(char*));
-static int dump_databases(char **);
-static int dump_all_databases();
+static int dump_selected_tables(MYSQL *mysql_con, char *db, char **table_names, int tables);
+static int dump_all_tables_in_db(MYSQL *, char *db);
+static int init_dumping_views(char *, MYSQL *);
+static int init_dumping_tables(char *, MYSQL *);
+static int init_dumping(MYSQL *, char *, int init_func(char*, MYSQL *));
+static int dump_databases(MYSQL *, char **);
+static int dump_all_databases(MYSQL *mysql_con);
 static char *quote_name(const char *name, char *buff, my_bool force);
-char check_if_ignore_table(const char *table_name, char *table_type);
-static char *primary_key_fields(const char *table_name);
-static my_bool get_view_structure(char *table, char* db);
-static my_bool dump_all_views_in_db(char *database);
-static int dump_all_tablespaces();
-static int dump_tablespaces_for_tables(char *db, char **table_names, int tables);
-static int dump_tablespaces_for_databases(char** databases);
-static int dump_tablespaces(char* ts_where);
+char check_if_ignore_table(const char *table_name, char *table_type, MYSQL *mysql_con);
+static char *primary_key_fields(MYSQL *mysql_con, const char *table_name);
+static my_bool get_view_structure(MYSQL *mysql_con, char *table, char* db);
+static my_bool dump_all_views_in_db(MYSQL *mysql_con, char *database);
+static int dump_all_tablespaces(MYSQL *mysql_con);
+static int dump_tablespaces_for_tables(MYSQL *mysql_con, char *db, char **table_names, int tables);
+static int dump_tablespaces_for_databases(MYSQL *mysql_con, char** databases);
+static int dump_tablespaces(MYSQL *mysql_con, char* ts_where);
 
 #include <help_start.h>
 
@@ -579,7 +603,7 @@ static void write_header(FILE *sql_file,
   {
     fputs("<?xml version=\"1.0\"?>\n", sql_file);
     /*
-      Schema reference.  Allows use of xsi:nil for NULL values and 
+      Schema reference.  Allows use of xsi:nil for NULL values and
       xsi:type to define an element's data type.
     */
     fputs("<mysqldump ", sql_file);
@@ -716,6 +740,8 @@ get_one_option(int optid, const struct m
       tty_password=1;
     break;
   case 'r':
+    md_result_file_path = argument;
+    md_result_file_path_length=strlen(md_result_file_path);
     if (!(md_result_file= my_fopen(argument, O_WRONLY | FILE_BINARY,
                                     MYF(MY_WME))))
       exit(1);
@@ -955,7 +981,7 @@ static void DB_error(MYSQL *mysql_arg, c
     error_num   - process return value
     fmt_reason  - a format string for use by my_vsnprintf.
     ...         - variable arguments for above fmt_reason string
-  
+
   DESCRIPTION
     This call prints out the formatted error message to stderr and then
     terminates the process.
@@ -984,15 +1010,15 @@ static void die(int error_num, const cha
     error_num   - process return value
     fmt_reason  - a format string for use by my_vsnprintf.
     ...         - variable arguments for above fmt_reason string
-  
+
   DESCRIPTION
     This call prints out the formatted error message to stderr and then
     terminates the process, unless the --force command line option is used.
-    
+
     This call should be used for non-fatal errors (such as database
     errors) that the code may still be able to continue to the next unit
     of work.
-    
+
 */
 static void maybe_die(int error_num, const char* fmt_reason, ...)
 {
@@ -1040,7 +1066,8 @@ static int mysql_query_with_error_report
 }
 
 
-static int fetch_db_collation(const char *db_name,
+static int fetch_db_collation(MYSQL *mysql_con,
+                              const char *db_name,
                               char *db_cl_name,
                               int db_cl_size)
 {
@@ -1053,10 +1080,10 @@ static int fetch_db_collation(const char
 
   my_snprintf(query, sizeof (query), "use %s", qdatabase);
 
-  if (mysql_query_with_error_report(mysql, NULL, query))
+  if (mysql_query_with_error_report(mysql_con, NULL, query))
     return 1;
 
-  if (mysql_query_with_error_report(mysql, &db_cl_res,
+  if (mysql_query_with_error_report(mysql_con, &db_cl_res,
                                     "select @@collation_database"))
     return 1;
 
@@ -1418,10 +1445,6 @@ static void free_resources()
   my_free(opt_password, MYF(MY_ALLOW_ZERO_PTR));
   if (hash_inited(&ignore_table))
     hash_free(&ignore_table);
-  if (extended_insert)
-    dynstr_free(&extended_row);
-  if (insert_pat_inited)
-    dynstr_free(&insert_pat);
   if (defaults_argv)
     free_defaults(defaults_argv);
   my_end(my_end_arg);
@@ -1445,53 +1468,53 @@ static void maybe_exit(int error)
   db_connect -- connects to the host and selects DB.
 */
 
-static int connect_to_db(char *host, char *user,char *passwd)
+static MYSQL *connect_to_db(MYSQL *mysql_con, char *host, char *user,char *passwd)
 {
   char buff[20+FN_REFLEN];
   DBUG_ENTER("connect_to_db");
 
   verbose_msg("-- Connecting to %s...\n", host ? host : "localhost");
-  mysql_init(&mysql_connection);
+  mysql_init(mysql_con);
   if (opt_compress)
-    mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS);
+    mysql_options(mysql_con,MYSQL_OPT_COMPRESS,NullS);
 #ifdef HAVE_OPENSSL
   if (opt_use_ssl)
-    mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
+    mysql_ssl_set(mysql_con, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
                   opt_ssl_capath, opt_ssl_cipher);
-  mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
+  mysql_options(mysql_con,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
                 (char*)&opt_ssl_verify_server_cert);
 #endif
   if (opt_protocol)
-    mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+    mysql_options(mysql_con,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
 #ifdef HAVE_SMEM
   if (shared_memory_base_name)
-    mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+    mysql_options(mysql_con,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
 #endif
-  mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
-  if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
+  mysql_options(mysql_con, MYSQL_SET_CHARSET_NAME, default_charset);
+  if (!(mysql_con= mysql_real_connect(mysql_con,host,user,passwd,
                                   NULL,opt_mysql_port,opt_mysql_unix_port,
                                   0)))
   {
-    DB_error(&mysql_connection, "when trying to connect");
-    DBUG_RETURN(1);
+    DB_error(mysql_con, "when trying to connect");
+    DBUG_RETURN(0);
   }
-  if (mysql_get_server_version(&mysql_connection) < 40100)
+  if (mysql_get_server_version(mysql_con) < 40100)
   {
     /* Don't dump SET NAMES with a pre-4.1 server (bug#7997).  */
     opt_set_charset= 0;
 
     /* Don't switch charsets for 4.1 and earlier.  (bug#34192). */
     server_supports_switching_charsets= FALSE;
-  } 
+  }
   /*
     As we're going to set SQL_MODE, it would be lost on reconnect, so we
     cannot reconnect.
   */
-  mysql->reconnect= 0;
+  mysql_con->reconnect= 0;
   my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */",
               compatible_mode_normal_str);
-  if (mysql_query_with_error_report(mysql, 0, buff))
-    DBUG_RETURN(1);
+  if (mysql_query_with_error_report(mysql_con, 0, buff))
+    DBUG_RETURN(0);
   /*
     set time_zone to UTC to allow dumping date types between servers with
     different time zone settings
@@ -1499,10 +1522,10 @@ static int connect_to_db(char *host, cha
   if (opt_tz_utc)
   {
     my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */");
-    if (mysql_query_with_error_report(mysql, 0, buff))
-      DBUG_RETURN(1);
+    if (mysql_query_with_error_report(mysql_con, 0, buff))
+      DBUG_RETURN(0);
   }
-  DBUG_RETURN(0);
+  DBUG_RETURN(mysql_con);
 } /* connect_to_db */
 
 
@@ -1546,7 +1569,7 @@ static my_bool test_if_special_chars(con
 
 
 /*
-  quote_name(name, buff, force)
+	quote_name(name, buff, force)
 
   Quotes char string, taking into account compatible mode
 
@@ -1670,7 +1693,7 @@ static void print_quoted_xml(FILE *xml_f
   Print xml tag. Optionally add attribute(s).
 
   SYNOPSIS
-    print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name, 
+    print_xml_tag(xml_file, sbeg, send, tag_name, first_attribute_name,
                     ..., attribute_name_n, attribute_value_n, NullS)
     xml_file              - output file
     sbeg                  - line beginning
@@ -1685,7 +1708,7 @@ static void print_quoted_xml(FILE *xml_f
     Print XML tag with any number of attribute="value" pairs to the xml_file.
 
     Format is:
-      sbeg<tag_name first_attribute_name="first_attribute_value" ... 
+      sbeg<tag_name first_attribute_name="first_attribute_value" ...
       attribute_name_n="attribute_value_n">send
   NOTE
     Additional arguments must be present in attribute/value pairs.
@@ -1695,8 +1718,8 @@ static void print_quoted_xml(FILE *xml_f
 */
 
 static void print_xml_tag(FILE * xml_file, const char* sbeg,
-                          const char* line_end, 
-                          const char* tag_name, 
+                          const char* line_end,
+                          const char* tag_name,
                           const char* first_attribute_name, ...)
 {
   va_list arg_list;
@@ -1704,7 +1727,7 @@ static void print_xml_tag(FILE * xml_fil
 
   fputs(sbeg, xml_file);
   fputc('<', xml_file);
-  fputs(tag_name, xml_file);  
+  fputs(tag_name, xml_file);
 
   va_start(arg_list, first_attribute_name);
   attribute_name= first_attribute_name;
@@ -1714,9 +1737,9 @@ static void print_xml_tag(FILE * xml_fil
     DBUG_ASSERT(attribute_value != NullS);
 
     fputc(' ', xml_file);
-    fputs(attribute_name, xml_file);    
+    fputs(attribute_name, xml_file);
     fputc('\"', xml_file);
-    
+
     print_quoted_xml(xml_file, attribute_value, strlen(attribute_value));
     fputc('\"', xml_file);
 
@@ -1810,10 +1833,10 @@ static void print_xml_row(FILE *xml_file
 
 /*
  create_delimiter
- Generate a new (null-terminated) string that does not exist in  query 
+ Generate a new (null-terminated) string that does not exist in  query
  and is therefore suitable for use as a query delimiter.  Store this
  delimiter in  delimiter_buff .
- 
+
  This is quite simple in that it doesn't even try to parse statements as an
  interpreter would.  It merely returns a string that is not in the query, which
  is much more than adequate for constructing a delimiter.
@@ -1822,15 +1845,15 @@ static void print_xml_row(FILE *xml_file
    ptr to the delimiter  on Success
    NULL                  on Failure
 */
-static char *create_delimiter(char *query, char *delimiter_buff, 
-                              int delimiter_max_size) 
+static char *create_delimiter(char *query, char *delimiter_buff,
+                              int delimiter_max_size)
 {
   int proposed_length;
   char *presence;
 
   delimiter_buff[0]= ';';  /* start with one semicolon, and */
 
-  for (proposed_length= 2; proposed_length < delimiter_max_size; 
+  for (proposed_length= 2; proposed_length < delimiter_max_size;
       delimiter_max_size++) {
 
     delimiter_buff[proposed_length-1]= ';';  /* add semicolons, until */
@@ -1855,7 +1878,7 @@ static char *create_delimiter(char *quer
     0  Success
     1  Error
 */
-static uint dump_events_for_db(char *db)
+static uint dump_events_for_db(MYSQL *mysql_con, char *db)
 {
   char       query_buff[QUERY_LENGTH];
   char       db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
@@ -1871,7 +1894,7 @@ static uint dump_events_for_db(char *db)
   DBUG_ENTER("dump_events_for_db");
   DBUG_PRINT("enter", ("db: '%s'", db));
 
-  mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
+  mysql_real_escape_string(mysql_con, db_name_buff, db, strlen(db));
 
   /* nice comments */
   if (opt_comments)
@@ -1882,9 +1905,9 @@ static uint dump_events_for_db(char *db)
     enough privileges to lock mysql.events.
   */
   if (lock_tables)
-    mysql_query(mysql, "LOCK TABLES mysql.event READ");
+    mysql_query(mysql_con, "LOCK TABLES mysql.event READ");
 
-  if (mysql_query_with_error_report(mysql, &event_list_res, "show events"))
+  if (mysql_query_with_error_report(mysql_con, &event_list_res, "show events"))
     DBUG_RETURN(0);
 
   strcpy(delimiter, ";");
@@ -1894,20 +1917,20 @@ static uint dump_events_for_db(char *db)
 
     /* Get database collation. */
 
-    if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name)))
+    if (fetch_db_collation(mysql_con, db_name_buff, db_cl_name, sizeof (db_cl_name)))
       DBUG_RETURN(1);
 
-    if (switch_character_set_results(mysql, "binary"))
+    if (switch_character_set_results(mysql_con, "binary"))
       DBUG_RETURN(1);
 
     while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
     {
       event_name= quote_name(event_list_row[1], name_buff, 0);
       DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff));
-      my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s", 
+      my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s",
           event_name);
 
-      if (mysql_query_with_error_report(mysql, &event_res, query_buff))
+      if (mysql_query_with_error_report(mysql_con, &event_res, query_buff))
         DBUG_RETURN(1);
 
       while ((row= mysql_fetch_row(event_res)) != NULL)
@@ -1919,7 +1942,7 @@ static uint dump_events_for_db(char *db)
         if (strlen(row[3]) != 0)
         {
           if (opt_drop)
-            fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n", 
+            fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n",
                 event_name, delimiter);
 
           if (create_delimiter(row[3], delimiter, sizeof(delimiter)) == NULL)
@@ -1993,13 +2016,13 @@ static uint dump_events_for_db(char *db)
     fprintf(sql_file, "DELIMITER ;\n");
     fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n");
 
-    if (switch_character_set_results(mysql, default_charset))
+    if (switch_character_set_results(mysql_con, default_charset))
       DBUG_RETURN(1);
   }
   mysql_free_result(event_list_res);
 
   if (lock_tables)
-    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+    VOID(mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"));
   DBUG_RETURN(0);
 }
 
@@ -2039,7 +2062,7 @@ static void print_blob_as_hex(FILE *outp
     1  Error
 */
 
-static uint dump_routines_for_db(char *db)
+static uint dump_routines_for_db(MYSQL *mysql_con, char *db)
 {
   char       query_buff[QUERY_LENGTH];
   const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
@@ -2056,7 +2079,7 @@ static uint dump_routines_for_db(char *d
   DBUG_ENTER("dump_routines_for_db");
   DBUG_PRINT("enter", ("db: '%s'", db));
 
-  mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
+  mysql_real_escape_string(mysql_con, db_name_buff, db, strlen(db));
 
   /* nice comments */
   if (opt_comments)
@@ -2067,14 +2090,14 @@ static uint dump_routines_for_db(char *d
     enough privileges to lock mysql.proc.
   */
   if (lock_tables)
-    mysql_query(mysql, "LOCK TABLES mysql.proc READ");
+    mysql_query(mysql_con, "LOCK TABLES mysql.proc READ");
 
   /* Get database collation. */
 
-  if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name)))
+  if (fetch_db_collation(mysql_con, db_name_buff, db_cl_name, sizeof (db_cl_name)))
     DBUG_RETURN(1);
 
-  if (switch_character_set_results(mysql, "binary"))
+  if (switch_character_set_results(mysql_con, "binary"))
     DBUG_RETURN(1);
 
   /* 0, retrieve and dump functions, 1, procedures */
@@ -2084,7 +2107,7 @@ static uint dump_routines_for_db(char *d
                 "SHOW %s STATUS WHERE Db = '%s'",
                 routine_type[i], db_name_buff);
 
-    if (mysql_query_with_error_report(mysql, &routine_list_res, query_buff))
+    if (mysql_query_with_error_report(mysql_con, &routine_list_res, query_buff))
       DBUG_RETURN(1);
 
     if (mysql_num_rows(routine_list_res))
@@ -2098,7 +2121,7 @@ static uint dump_routines_for_db(char *d
         my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
                     routine_type[i], routine_name);
 
-        if (mysql_query_with_error_report(mysql, &routine_res, query_buff))
+        if (mysql_query_with_error_report(mysql_con, &routine_res, query_buff))
           DBUG_RETURN(1);
 
         while ((row= mysql_fetch_row(routine_res)))
@@ -2189,11 +2212,11 @@ static uint dump_routines_for_db(char *d
     mysql_free_result(routine_list_res);
   } /* end of for i (0 .. 1)  */
 
-  if (switch_character_set_results(mysql, default_charset))
+  if (switch_character_set_results(mysql_con, default_charset))
     DBUG_RETURN(1);
 
   if (lock_tables)
-    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+    VOID(mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"));
   DBUG_RETURN(0);
 }
 
@@ -2205,15 +2228,19 @@ static uint dump_routines_for_db(char *d
   ARGS
     table       - table name
     db          - db name
+    mysql_con   - MySQL connection
     table_type  - table type, e.g. "MyISAM" or "InnoDB", but also "VIEW"
     ignore_flag - what we must particularly ignore - see IGNORE_ defines above
+    table_md_result_file - table output file
+    insert_pat  - string containing INSERT INTO values
 
   RETURN
     number of fields in table, 0 if error
 */
 
-static uint get_table_structure(char *table, char *db, char *table_type,
-                                char *ignore_flag)
+static uint get_table_structure(char *table, char *db, MYSQL *mysql_con, char *table_type,
+                                char *ignore_flag, FILE *table_md_result_file,
+                                DYNAMIC_STRING *insert_pat)
 {
   my_bool    init=0, delayed, write_data, complete_insert;
   my_ulonglong num_fields;
@@ -2221,14 +2248,14 @@ static uint get_table_structure(char *ta
   const char *insert_option;
   char	     name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3];
   char       table_buff2[NAME_LEN*2+3], query_buff[QUERY_LENGTH];
-  FILE       *sql_file= md_result_file;
+  FILE       *sql_file= table_md_result_file;
   int        len;
   MYSQL_RES  *result;
   MYSQL_ROW  row;
   DBUG_ENTER("get_table_structure");
   DBUG_PRINT("enter", ("db: %s  table: %s", db, table));
 
-  *ignore_flag= check_if_ignore_table(table, table_type);
+  *ignore_flag= check_if_ignore_table(table, table_type, mysql_con);
 
   delayed= opt_delayed;
   if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED))
@@ -2242,13 +2269,6 @@ static uint get_table_structure(char *ta
   if ((write_data= !(*ignore_flag & IGNORE_DATA)))
   {
     complete_insert= opt_complete_insert;
-    if (!insert_pat_inited)
-    {
-      insert_pat_inited= 1;
-      init_dynamic_string_checked(&insert_pat, "", 1024, 1024);
-    }
-    else
-      dynstr_set_checked(&insert_pat, "");
   }
 
   insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " :
@@ -2267,9 +2287,9 @@ static uint get_table_structure(char *ta
   opt_quoted_table= quote_name(table, table_buff2, 0);
 
   if (opt_order_by_primary)
-    order_by= primary_key_fields(result_table);
+    order_by= primary_key_fields(mysql_con, result_table);
 
-  if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff))
+  if (!opt_xml && !mysql_query_with_error_report(mysql_con, 0, query_buff))
   {
     /* using SHOW CREATE statement */
     if (!opt_no_create_info)
@@ -2280,9 +2300,9 @@ static uint get_table_structure(char *ta
 
       my_snprintf(buff, sizeof(buff), "show create table %s", result_table);
 
-      if (switch_character_set_results(mysql, "binary") ||
-          mysql_query_with_error_report(mysql, &result, buff) ||
-          switch_character_set_results(mysql, default_charset))
+      if (switch_character_set_results(mysql_con, "binary") ||
+          mysql_query_with_error_report(mysql_con, &result, buff) ||
+          switch_character_set_results(mysql_con, default_charset))
         DBUG_RETURN(0);
 
       if (path)
@@ -2339,9 +2359,9 @@ static uint get_table_structure(char *ta
         */
         my_snprintf(query_buff, sizeof(query_buff),
                     "SHOW FIELDS FROM %s", result_table);
-        if (switch_character_set_results(mysql, "binary") ||
-            mysql_query_with_error_report(mysql, &result, query_buff) ||
-            switch_character_set_results(mysql, default_charset))
+        if (switch_character_set_results(mysql_con, "binary") ||
+            mysql_query_with_error_report(mysql_con, &result, query_buff) ||
+            switch_character_set_results(mysql_con, default_charset))
         {
           /*
             View references invalid or privileged table/col/fun (err 1356),
@@ -2349,7 +2369,7 @@ static uint get_table_structure(char *ta
             a comment with the view's 'show create' statement. (Bug #17371)
           */
 
-          if (mysql_errno(mysql) == ER_VIEW_INVALID)
+          if (mysql_errno(mysql_con) == ER_VIEW_INVALID)
             fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : "");
 
           my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR));
@@ -2426,7 +2446,7 @@ static uint get_table_structure(char *ta
     }
     my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
                 result_table);
-    if (mysql_query_with_error_report(mysql, &result, query_buff))
+    if (mysql_query_with_error_report(mysql_con, &result, query_buff))
     {
       if (path)
         my_fclose(sql_file, MYF(MY_WME));
@@ -2442,21 +2462,21 @@ static uint get_table_structure(char *ta
     if (write_data)
     {
       if (opt_replace_into)
-        dynstr_append_checked(&insert_pat, "REPLACE ");
+        dynstr_append_checked(insert_pat, "REPLACE ");
       else
-        dynstr_append_checked(&insert_pat, "INSERT ");
-      dynstr_append_checked(&insert_pat, insert_option);
-      dynstr_append_checked(&insert_pat, "INTO ");
-      dynstr_append_checked(&insert_pat, opt_quoted_table);
+        dynstr_append_checked(insert_pat, "INSERT ");
+      dynstr_append_checked(insert_pat, insert_option);
+      dynstr_append_checked(insert_pat, "INTO ");
+      dynstr_append_checked(insert_pat, opt_quoted_table);
       if (complete_insert)
       {
-        dynstr_append_checked(&insert_pat, " (");
+        dynstr_append_checked(insert_pat, " (");
       }
       else
       {
-        dynstr_append_checked(&insert_pat, " VALUES ");
+        dynstr_append_checked(insert_pat, " VALUES ");
         if (!extended_insert)
-          dynstr_append_checked(&insert_pat, "(");
+          dynstr_append_checked(insert_pat, "(");
       }
     }
 
@@ -2466,10 +2486,10 @@ static uint get_table_structure(char *ta
       {
         if (init)
         {
-          dynstr_append_checked(&insert_pat, ", ");
+          dynstr_append_checked(insert_pat, ", ");
         }
         init=1;
-        dynstr_append_checked(&insert_pat,
+        dynstr_append_checked(insert_pat,
                       quote_name(row[SHOW_FIELDNAME], name_buff, 0));
       }
     }
@@ -2479,11 +2499,11 @@ static uint get_table_structure(char *ta
   else
   {
     verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n",
-                my_progname, mysql_error(mysql));
+                my_progname, mysql_error(mysql_con));
 
     my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
                 result_table);
-    if (mysql_query_with_error_report(mysql, &result, query_buff))
+    if (mysql_query_with_error_report(mysql_con, &result, query_buff))
       DBUG_RETURN(0);
 
     /* Make an sql-file, if path was given iow. option -T was given */
@@ -2503,7 +2523,7 @@ static uint get_table_structure(char *ta
       if (!opt_xml)
         fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
       else
-        print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table, 
+        print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table,
                 NullS);
       check_io(sql_file);
     }
@@ -2511,19 +2531,19 @@ static uint get_table_structure(char *ta
     if (write_data)
     {
       if (opt_replace_into)
-        dynstr_append_checked(&insert_pat, "REPLACE ");
+        dynstr_append_checked(insert_pat, "REPLACE ");
       else
-        dynstr_append_checked(&insert_pat, "INSERT ");
-      dynstr_append_checked(&insert_pat, insert_option);
-      dynstr_append_checked(&insert_pat, "INTO ");
-      dynstr_append_checked(&insert_pat, result_table);
+        dynstr_append_checked(insert_pat, "INSERT ");
+      dynstr_append_checked(insert_pat, insert_option);
+      dynstr_append_checked(insert_pat, "INTO ");
+      dynstr_append_checked(insert_pat, result_table);
       if (complete_insert)
-        dynstr_append_checked(&insert_pat, " (");
+        dynstr_append_checked(insert_pat, " (");
       else
       {
-        dynstr_append_checked(&insert_pat, " VALUES ");
+        dynstr_append_checked(insert_pat, " VALUES ");
         if (!extended_insert)
-          dynstr_append_checked(&insert_pat, "(");
+          dynstr_append_checked(insert_pat, "(");
       }
     }
 
@@ -2538,11 +2558,11 @@ static uint get_table_structure(char *ta
           check_io(sql_file);
         }
         if (complete_insert)
-          dynstr_append_checked(&insert_pat, ", ");
+          dynstr_append_checked(insert_pat, ", ");
       }
       init=1;
       if (complete_insert)
-        dynstr_append_checked(&insert_pat,
+        dynstr_append_checked(insert_pat,
                       quote_name(row[SHOW_FIELDNAME], name_buff, 0));
       if (!opt_no_create_info)
       {
@@ -2580,16 +2600,16 @@ static uint get_table_structure(char *ta
       char buff[20+FN_REFLEN];
       uint keynr,primary_key;
       my_snprintf(buff, sizeof(buff), "show keys from %s", result_table);
-      if (mysql_query_with_error_report(mysql, &result, buff))
+      if (mysql_query_with_error_report(mysql_con, &result, buff))
       {
-        if (mysql_errno(mysql) == ER_WRONG_OBJECT)
+        if (mysql_errno(mysql_con) == ER_WRONG_OBJECT)
         {
           /* it is VIEW */
           fputs("\t\t<options Comment=\"view\" />\n", sql_file);
           goto continue_xml;
         }
         fprintf(stderr, "%s: Can't get keys for table %s (%s)\n",
-                my_progname, result_table, mysql_error(mysql));
+                my_progname, result_table, mysql_error(mysql_con));
         if (path)
           my_fclose(sql_file, MYF(MY_WME));
         DBUG_RETURN(0);
@@ -2662,19 +2682,19 @@ static uint get_table_structure(char *ta
         my_snprintf(buff, sizeof(buff), "show table status like %s",
                     quote_for_like(table, show_name_buff));
 
-        if (mysql_query_with_error_report(mysql, &result, buff))
+        if (mysql_query_with_error_report(mysql_con, &result, buff))
         {
-          if (mysql_errno(mysql) != ER_PARSE_ERROR)
+          if (mysql_errno(mysql_con) != ER_PARSE_ERROR)
           {                                     /* If old MySQL version */
             verbose_msg("-- Warning: Couldn't get status information for " \
-                        "table %s (%s)\n", result_table,mysql_error(mysql));
+                        "table %s (%s)\n", result_table,mysql_error(mysql_con));
           }
         }
         else if (!(row= mysql_fetch_row(result)))
         {
           fprintf(stderr,
                   "Error: Couldn't read status information for table %s (%s)\n",
-                  result_table,mysql_error(mysql));
+                  result_table,mysql_error(mysql_con));
         }
         else
         {
@@ -2702,11 +2722,11 @@ continue_xml:
   }
   if (complete_insert)
   {
-    dynstr_append_checked(&insert_pat, ") VALUES ");
+    dynstr_append_checked(insert_pat, ") VALUES ");
     if (!extended_insert)
-      dynstr_append_checked(&insert_pat, "(");
+      dynstr_append_checked(insert_pat, "(");
   }
-  if (sql_file != md_result_file)
+  if (sql_file != table_md_result_file)
   {
     fputs("\n", sql_file);
     write_footer(sql_file);
@@ -2841,13 +2861,14 @@ static int dump_trigger(MYSQL_RES *show_
 
   @param[in] table_name
   @param[in] db_name
+  @param[in] mysql_con
 
   @return Error status.
     @retval TRUE error has occurred.
     @retval FALSE operation succeed.
 */
 
-static int dump_triggers_for_table(char *table_name, char *db_name)
+static int dump_triggers_for_table(char *table_name, char *db_name, MYSQL *mysql_con)
 {
   char       name_buff[NAME_LEN*4+3];
   char       query_buff[QUERY_LENGTH];
@@ -2865,10 +2886,10 @@ static int dump_triggers_for_table(char 
 
   /* Get database collation. */
 
-  if (switch_character_set_results(mysql, "binary"))
+  if (switch_character_set_results(mysql_con, "binary"))
     DBUG_RETURN(TRUE);
 
-  if (fetch_db_collation(db_name, db_cl_name, sizeof (db_cl_name)))
+  if (fetch_db_collation(mysql_con, db_name, db_cl_name, sizeof (db_cl_name)))
     DBUG_RETURN(TRUE);
 
   /* Get list of triggers. */
@@ -2877,7 +2898,7 @@ static int dump_triggers_for_table(char 
               "SHOW TRIGGERS LIKE %s",
               quote_for_like(table_name, name_buff));
 
-  if (mysql_query_with_error_report(mysql, &show_triggers_rs, query_buff))
+  if (mysql_query_with_error_report(mysql_con, &show_triggers_rs, query_buff))
     DBUG_RETURN(TRUE);
 
   /* Dump triggers. */
@@ -2889,7 +2910,7 @@ static int dump_triggers_for_table(char 
                 "SHOW CREATE TRIGGER %s",
                 quote_name(row[0], name_buff, TRUE));
 
-    if (mysql_query(mysql, query_buff))
+    if (mysql_query(mysql_con, query_buff))
     {
       /*
         mysqldump is being run against old server, that does not support
@@ -2903,7 +2924,7 @@ static int dump_triggers_for_table(char 
     }
     else
     {
-      MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql);
+      MYSQL_RES *show_create_trigger_rs= mysql_store_result(mysql_con);
 
       if (!show_create_trigger_rs ||
           dump_trigger(show_create_trigger_rs, db_name, db_cl_name))
@@ -2918,7 +2939,7 @@ static int dump_triggers_for_table(char 
 
   mysql_free_result(show_triggers_rs);
 
-  if (switch_character_set_results(mysql, default_charset))
+  if (switch_character_set_results(mysql_con, default_charset))
     DBUG_RETURN(TRUE);
 
   /*
@@ -2940,7 +2961,7 @@ static void add_load_option(DYNAMIC_STRI
   }
 
   dynstr_append_checked(str, option);
-  
+
   if (strncmp(option_value, "0x", sizeof("0x")-1) == 0)
   {
     /* It's a hex constant, don't escape */
@@ -2963,7 +2984,7 @@ static void add_load_option(DYNAMIC_STRI
 
 static void field_escape(DYNAMIC_STRING* in, const char *from)
 {
-  uint end_backslashes= 0; 
+  uint end_backslashes= 0;
 
   dynstr_append_checked(in, "'");
 
@@ -2987,7 +3008,7 @@ static void field_escape(DYNAMIC_STRING*
   /* Add missing backslashes if user has specified odd number of backs.*/
   if (end_backslashes)
     dynstr_append_checked(in, "\\");
-  
+
   dynstr_append_checked(in, "'");
 }
 
@@ -3020,11 +3041,11 @@ static char *alloc_query_str(ulong size)
 */
 
 
-static void dump_table(char *table, char *db)
+static void dump_table(char *table, char *db, MYSQL *mysql_con, FILE *table_md_result_file)
 {
   char ignore_flag;
   char buf[200], table_buff[NAME_LEN+3];
-  DYNAMIC_STRING query_string;
+  DYNAMIC_STRING query_string, insert_pat, extended_row;
   char table_type[NAME_LEN];
   char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table;
   int error= 0;
@@ -3035,23 +3056,30 @@ static void dump_table(char *table, char
   MYSQL_ROW     row;
   DBUG_ENTER("dump_table");
 
+  init_dynamic_string_checked(&insert_pat, "", 1024, 1024);
+
   /*
     Make sure you get the create table info before the following check for
     --no-data flag below. Otherwise, the create table info won't be printed.
   */
-  num_fields= get_table_structure(table, db, table_type, &ignore_flag);
+  num_fields= get_table_structure(table, db, mysql_con, table_type, &ignore_flag,
+                                  table_md_result_file, &insert_pat);
 
   /*
     The "table" could be a view.  If so, we don't do anything here.
   */
   if (strcmp(table_type, "VIEW") == 0)
+  {
+    dynstr_free(&insert_pat);
     DBUG_VOID_RETURN;
+  }
 
   /* Check --no-data flag */
   if (opt_no_data)
   {
     verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n",
                 table);
+    dynstr_free(&insert_pat);
     DBUG_VOID_RETURN;
   }
 
@@ -3066,6 +3094,7 @@ static void dump_table(char *table, char
   {
     verbose_msg("-- Warning: Skipping data for table '%s' because " \
                 "it's of type %s\n", table, table_type);
+    dynstr_free(&insert_pat);
     DBUG_VOID_RETURN;
   }
   /* Check that there are any fields in the table */
@@ -3073,6 +3102,7 @@ static void dump_table(char *table, char
   {
     verbose_msg("-- Skipping dump data for table '%s', it has no fields\n",
                 table);
+    dynstr_free(&insert_pat);
     DBUG_VOID_RETURN;
   }
 
@@ -3085,6 +3115,7 @@ static void dump_table(char *table, char
       !my_strcasecmp(&my_charset_latin1, table, "event"))
   {
     verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n");
+    dynstr_free(&insert_pat);
     DBUG_VOID_RETURN;
   }
 
@@ -3103,7 +3134,7 @@ static void dump_table(char *table, char
       Convert the path to native os format
       and resolve to the full filepath.
     */
-    convert_dirname(tmp_path,path,NullS);    
+    convert_dirname(tmp_path,path,NullS);
     my_load_path(tmp_path, tmp_path, NULL);
     fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME));
 
@@ -3121,7 +3152,7 @@ static void dump_table(char *table, char
 
     if (fields_terminated || enclosed || opt_enclosed || escaped)
       dynstr_append_checked(&query_string, " FIELDS");
-    
+
     add_load_option(&query_string, " TERMINATED BY ", fields_terminated);
     add_load_option(&query_string, " ENCLOSED BY ", enclosed);
     add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed);
@@ -3143,10 +3174,11 @@ static void dump_table(char *table, char
       dynstr_append_checked(&query_string, order_by);
     }
 
-    if (mysql_real_query(mysql, query_string.str, query_string.length))
+    if (mysql_real_query(mysql_con, query_string.str, query_string.length))
     {
-      DB_error(mysql, "when executing 'SELECT INTO OUTFILE'");
+      DB_error(mysql_con, "when executing 'SELECT INTO OUTFILE'");
       dynstr_free(&query_string);
+      dynstr_free(&insert_pat);
       DBUG_VOID_RETURN;
     }
   }
@@ -3154,11 +3186,11 @@ static void dump_table(char *table, char
   {
     if (!opt_xml && opt_comments)
     {
-      fprintf(md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
+      fprintf(table_md_result_file,"\n--\n-- Dumping data for table %s\n--\n",
               result_table);
-      check_io(md_result_file);
+      check_io(table_md_result_file);
     }
-    
+
     dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
     dynstr_append_checked(&query_string, result_table);
 
@@ -3166,10 +3198,10 @@ static void dump_table(char *table, char
     {
       if (!opt_xml && opt_comments)
       {
-        fprintf(md_result_file, "-- WHERE:  %s\n", where);
-        check_io(md_result_file);
+        fprintf(table_md_result_file, "-- WHERE:  %s\n", where);
+        check_io(table_md_result_file);
       }
-      
+
       dynstr_append_checked(&query_string, " WHERE ");
       dynstr_append_checked(&query_string, where);
     }
@@ -3177,8 +3209,8 @@ static void dump_table(char *table, char
     {
       if (!opt_xml && opt_comments)
       {
-        fprintf(md_result_file, "-- ORDER BY:  %s\n", order_by);
-        check_io(md_result_file);
+        fprintf(table_md_result_file, "-- ORDER BY:  %s\n", order_by);
+        check_io(table_md_result_file);
       }
       dynstr_append_checked(&query_string, " ORDER BY ");
       dynstr_append_checked(&query_string, order_by);
@@ -3186,21 +3218,21 @@ static void dump_table(char *table, char
 
     if (!opt_xml && !opt_compact)
     {
-      fputs("\n", md_result_file);
-      check_io(md_result_file);
+      fputs("\n", table_md_result_file);
+      check_io(table_md_result_file);
     }
-    if (mysql_query_with_error_report(mysql, 0, query_string.str))
+    if (mysql_query_with_error_report(mysql_con, 0, query_string.str))
     {
-      DB_error(mysql, "when retrieving data from server");
+      DB_error(mysql_con, "when retrieving data from server");
       goto err;
     }
     if (quick)
-      res=mysql_use_result(mysql);
+      res=mysql_use_result(mysql_con);
     else
-      res=mysql_store_result(mysql);
+      res=mysql_store_result(mysql_con);
     if (!res)
     {
-      DB_error(mysql, "when retrieving data from server");
+      DB_error(mysql_con, "when retrieving data from server");
       goto err;
     }
 
@@ -3215,15 +3247,16 @@ static void dump_table(char *table, char
 
     if (opt_lock)
     {
-      fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
-      check_io(md_result_file);
+      fprintf(table_md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table);
+      check_io(table_md_result_file);
     }
+
     /* Moved disable keys to after lock per bug 15977 */
     if (opt_disable_keys)
     {
-      fprintf(md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
+      fprintf(table_md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
 	      opt_quoted_table);
-      check_io(md_result_file);
+      check_io(table_md_result_file);
     }
 
     total_length= opt_net_buffer_length;                /* Force row break */
@@ -3231,12 +3264,13 @@ static void dump_table(char *table, char
     rownr=0;
     init_length=(uint) insert_pat.length+4;
     if (opt_xml)
-      print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table,
+      print_xml_tag(table_md_result_file, "\t", "\n", "table_data", "name=", table,
               NullS);
+
     if (opt_autocommit)
     {
-      fprintf(md_result_file, "set autocommit=0;\n");
-      check_io(md_result_file);
+      fprintf(table_md_result_file, "set autocommit=0;\n");
+      check_io(table_md_result_file);
     }
 
     while ((row= mysql_fetch_row(res)))
@@ -3246,17 +3280,20 @@ static void dump_table(char *table, char
       rownr++;
       if (!extended_insert && !opt_xml)
       {
-        fputs(insert_pat.str,md_result_file);
-        check_io(md_result_file);
+        fputs(insert_pat.str,table_md_result_file);
+        check_io(table_md_result_file);
       }
       mysql_field_seek(res,0);
 
       if (opt_xml)
       {
-        fputs("\t<row>\n", md_result_file);
-        check_io(md_result_file);
+        fputs("\t<row>\n", table_md_result_file);
+        check_io(table_md_result_file);
       }
 
+      if (rownr==1 && extended_insert)
+        init_dynamic_string_checked(&extended_row, "", 1024, 1024);
+
       for (i= 0; i < mysql_num_fields(res); i++)
       {
         int is_blob;
@@ -3317,7 +3354,7 @@ static void dump_table(char *table, char
                 {
                   dynstr_append_checked(&extended_row,"'");
                   extended_row.length +=
-                  mysql_real_escape_string(&mysql_connection,
+                  mysql_real_escape_string(mysql_con,
                                            &extended_row.str[extended_row.length],
                                            row[i],length);
                   extended_row.str[extended_row.length]='\0';
@@ -3355,8 +3392,8 @@ static void dump_table(char *table, char
         {
           if (i && !opt_xml)
           {
-            fputc(',', md_result_file);
-            check_io(md_result_file);
+            fputc(',', table_md_result_file);
+            check_io(table_md_result_file);
           }
           if (row[i])
           {
@@ -3367,25 +3404,25 @@ static void dump_table(char *table, char
                 if (opt_hex_blob && is_blob && length)
                 {
                   /* Define xsi:type="xs:hexBinary" for hex encoded data */
-                  print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+                  print_xml_tag(table_md_result_file, "\t\t", "", "field", "name=",
                                 field->name, "xsi:type=", "xs:hexBinary", NullS);
-                  print_blob_as_hex(md_result_file, row[i], length);
+                  print_blob_as_hex(table_md_result_file, row[i], length);
                 }
                 else
                 {
-                  print_xml_tag(md_result_file, "\t\t", "", "field", "name=", 
+                  print_xml_tag(table_md_result_file, "\t\t", "", "field", "name=",
                                 field->name, NullS);
-                  print_quoted_xml(md_result_file, row[i], length);
+                  print_quoted_xml(table_md_result_file, row[i], length);
                 }
-                fputs("</field>\n", md_result_file);
+                fputs("</field>\n", table_md_result_file);
               }
               else if (opt_hex_blob && is_blob && length)
               {
-                fputs("0x", md_result_file);
-                print_blob_as_hex(md_result_file, row[i], length);
+                fputs("0x", table_md_result_file);
+                print_blob_as_hex(table_md_result_file, row[i], length);
               }
               else
-                unescape(md_result_file, row[i], length);
+                unescape(table_md_result_file, row[i], length);
             }
             else
             {
@@ -3393,43 +3430,43 @@ static void dump_table(char *table, char
               char *ptr= row[i];
               if (opt_xml)
               {
-                print_xml_tag(md_result_file, "\t\t", "", "field", "name=",
+                print_xml_tag(table_md_result_file, "\t\t", "", "field", "name=",
                         field->name, NullS);
                 fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL",
-                      md_result_file);
-                fputs("</field>\n", md_result_file);
+                      table_md_result_file);
+                fputs("</field>\n", table_md_result_file);
               }
               else if (my_isalpha(charset_info, *ptr) ||
                        (*ptr == '-' && my_isalpha(charset_info, ptr[1])))
-                fputs("NULL", md_result_file);
+                fputs("NULL", table_md_result_file);
               else if (field->type == MYSQL_TYPE_DECIMAL)
               {
                 /* add " signs around */
-                fputc('\'', md_result_file);
-                fputs(ptr, md_result_file);
-                fputc('\'', md_result_file);
+                fputc('\'', table_md_result_file);
+                fputs(ptr, table_md_result_file);
+                fputc('\'', table_md_result_file);
               }
               else
-                fputs(ptr, md_result_file);
+                fputs(ptr, table_md_result_file);
             }
           }
           else
           {
             /* The field value is NULL */
             if (!opt_xml)
-              fputs("NULL", md_result_file);
+              fputs("NULL", table_md_result_file);
             else
-              print_xml_null_tag(md_result_file, "\t\t", "field name=",
+              print_xml_null_tag(table_md_result_file, "\t\t", "field name=",
                                  field->name, "\n");
           }
-          check_io(md_result_file);
+          check_io(table_md_result_file);
         }
       }
 
       if (opt_xml)
       {
-        fputs("\t</row>\n", md_result_file);
-        check_io(md_result_file);
+        fputs("\t</row>\n", table_md_result_file);
+        check_io(table_md_result_file);
       }
 
       if (extended_insert)
@@ -3440,42 +3477,43 @@ static void dump_table(char *table, char
         if (total_length + row_length < opt_net_buffer_length)
         {
           total_length+= row_length;
-          fputc(',',md_result_file);            /* Always row break */
-          fputs(extended_row.str,md_result_file);
+          fputc(',',table_md_result_file);            /* Always row break */
+          fputs(extended_row.str,table_md_result_file);
         }
         else
         {
           if (row_break)
-            fputs(";\n", md_result_file);
+            fputs(";\n", table_md_result_file);
           row_break=1;                          /* This is first row */
 
-          fputs(insert_pat.str,md_result_file);
-          fputs(extended_row.str,md_result_file);
+          fputs(insert_pat.str,table_md_result_file);
+          fputs(extended_row.str,table_md_result_file);
           total_length= row_length+init_length;
         }
-        check_io(md_result_file);
+        check_io(table_md_result_file);
+        dynstr_set(&extended_row,"");
       }
       else if (!opt_xml)
       {
-        fputs(");\n", md_result_file);
-        check_io(md_result_file);
+        fputs(");\n", table_md_result_file);
+        check_io(table_md_result_file);
       }
     }
 
     /* XML - close table tag and supress regular output */
     if (opt_xml)
-        fputs("\t</table_data>\n", md_result_file);
+        fputs("\t</table_data>\n", table_md_result_file);
     else if (extended_insert && row_break)
-      fputs(";\n", md_result_file);             /* If not empty table */
-    fflush(md_result_file);
-    check_io(md_result_file);
-    if (mysql_errno(mysql))
+      fputs(";\n", table_md_result_file);             /* If not empty table */
+    fflush(table_md_result_file);
+    check_io(table_md_result_file);
+    if (mysql_errno(mysql_con))
     {
       my_snprintf(buf, sizeof(buf),
                   "%s: Error %d: %s when dumping table %s at row: %ld\n",
                   my_progname,
-                  mysql_errno(mysql),
-                  mysql_error(mysql),
+                  mysql_errno(mysql_con),
+                  mysql_error(mysql_con),
                   result_table,
                   rownr);
       fputs(buf,stderr);
@@ -3486,40 +3524,46 @@ static void dump_table(char *table, char
     /* Moved enable keys to before unlock per bug 15977 */
     if (opt_disable_keys)
     {
-      fprintf(md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
+      fprintf(table_md_result_file,"/*!40000 ALTER TABLE %s ENABLE KEYS */;\n",
               opt_quoted_table);
-      check_io(md_result_file);
+      check_io(table_md_result_file);
     }
     if (opt_lock)
     {
-      fputs("UNLOCK TABLES;\n", md_result_file);
-      check_io(md_result_file);
+      fputs("UNLOCK TABLES;\n", table_md_result_file);
+      check_io(table_md_result_file);
     }
     if (opt_autocommit)
     {
-      fprintf(md_result_file, "commit;\n");
-      check_io(md_result_file);
+      fprintf(table_md_result_file, "commit;\n");
+      check_io(table_md_result_file);
     }
     mysql_free_result(res);
   }
   dynstr_free(&query_string);
+  dynstr_free(&insert_pat);
+  if (extended_insert)
+    dynstr_free(&extended_row);
   DBUG_VOID_RETURN;
 
 err:
   dynstr_free(&query_string);
+  dynstr_free(&insert_pat);
+  if (extended_insert)
+    dynstr_free(&extended_row);
   maybe_exit(error);
   DBUG_VOID_RETURN;
 } /* dump_table */
 
 
-static char *getTableName(int reset)
+static char *getTableName(MYSQL *mysql_con, int reset)
 {
   static MYSQL_RES *res= NULL;
   MYSQL_ROW    row;
 
   if (!res)
   {
-    if (!(res= mysql_list_tables(mysql,NullS)))
+    if (!(res= mysql_list_tables(mysql_con,NullS)))
       return(NULL);
   }
   if ((row= mysql_fetch_row(res)))
@@ -3540,19 +3584,19 @@ static char *getTableName(int reset)
   dump all logfile groups and tablespaces
 */
 
-static int dump_all_tablespaces()
+static int dump_all_tablespaces(MYSQL *mysql_con)
 {
-  return dump_tablespaces(NULL);
+  return dump_tablespaces(mysql_con, NULL);
 }
 
-static int dump_tablespaces_for_tables(char *db, char **table_names, int tables)
+static int dump_tablespaces_for_tables(MYSQL *mysql_con, char *db, char **table_names, int tables)
 {
   DYNAMIC_STRING where;
   int r;
   int i;
   char name_buff[NAME_LEN*2+3];
 
-  mysql_real_escape_string(mysql, name_buff, db, strlen(db));
+  mysql_real_escape_string(mysql_con, name_buff, db, strlen(db));
 
   init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
                       "SELECT DISTINCT TABLESPACE_NAME FROM"
@@ -3564,7 +3608,7 @@ static int dump_tablespaces_for_tables(c
 
   for (i=0 ; i<tables ; i++)
   {
-    mysql_real_escape_string(mysql, name_buff,
+    mysql_real_escape_string(mysql_con, name_buff,
                              table_names[i], strlen(table_names[i]));
 
     dynstr_append_checked(&where, "'");
@@ -3575,12 +3619,12 @@ static int dump_tablespaces_for_tables(c
   dynstr_append_checked(&where,"))");
 
   DBUG_PRINT("info",("Dump TS for Tables where: %s",where.str));
-  r= dump_tablespaces(where.str);
+  r= dump_tablespaces(mysql_con, where.str);
   dynstr_free(&where);
   return r;
 }
 
-static int dump_tablespaces_for_databases(char** databases)
+static int dump_tablespaces_for_databases(MYSQL *mysql_con, char** databases)
 {
   DYNAMIC_STRING where;
   int r;
@@ -3595,7 +3639,7 @@ static int dump_tablespaces_for_database
   for (i=0 ; databases[i]!=NULL ; i++)
   {
     char db_name_buff[NAME_LEN*2+3];
-    mysql_real_escape_string(mysql, db_name_buff,
+    mysql_real_escape_string(mysql_con, db_name_buff,
                              databases[i], strlen(databases[i]));
     dynstr_append_checked(&where, "'");
     dynstr_append_checked(&where, db_name_buff);
@@ -3605,12 +3649,12 @@ static int dump_tablespaces_for_database
   dynstr_append_checked(&where,"))");
 
   DBUG_PRINT("info",("Dump TS for DBs where: %s",where.str));
-  r= dump_tablespaces(where.str);
+  r= dump_tablespaces(mysql_con, where.str);
   dynstr_free(&where);
   return r;
 }
 
-static int dump_tablespaces(char* ts_where)
+static int dump_tablespaces(MYSQL *mysql_con, char* ts_where)
 {
   MYSQL_ROW row;
   MYSQL_RES *tableres;
@@ -3652,13 +3696,13 @@ static int dump_tablespaces(char* ts_whe
                 ", ENGINE"
                 " ORDER BY LOGFILE_GROUP_NAME");
 
-  if (mysql_query(mysql, sqlbuf.str) ||
-      !(tableres = mysql_store_result(mysql)))
+  if (mysql_query(mysql_con, sqlbuf.str) ||
+      !(tableres = mysql_store_result(mysql_con)))
   {
     dynstr_free(&sqlbuf);
-    if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR ||
-        mysql_errno(mysql) == ER_BAD_DB_ERROR ||
-        mysql_errno(mysql) == ER_UNKNOWN_TABLE)
+    if (mysql_errno(mysql_con) == ER_BAD_TABLE_ERROR ||
+        mysql_errno(mysql_con) == ER_BAD_DB_ERROR ||
+        mysql_errno(mysql_con) == ER_UNKNOWN_TABLE)
     {
       fprintf(md_result_file,
               "\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES"
@@ -3668,7 +3712,7 @@ static int dump_tablespaces(char* ts_whe
     }
 
     my_printf_error(0, "Error: '%s' when trying to dump tablespaces",
-                    MYF(0), mysql_error(mysql));
+                    MYF(0), mysql_error(mysql_con));
     DBUG_RETURN(1);
   }
 
@@ -3738,7 +3782,7 @@ static int dump_tablespaces(char* ts_whe
 
   dynstr_append_checked(&sqlbuf, " ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME");
 
-  if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
+  if (mysql_query_with_error_report(mysql_con, &tableres, sqlbuf.str))
   {
     dynstr_free(&sqlbuf);
     DBUG_RETURN(1);
@@ -3793,31 +3837,31 @@ static int dump_tablespaces(char* ts_whe
   DBUG_RETURN(0);
 }
 
-static int dump_all_databases()
+static int dump_all_databases(MYSQL *mysql_con)
 {
   MYSQL_ROW row;
   MYSQL_RES *tableres;
   int result=0;
 
-  if (mysql_query_with_error_report(mysql, &tableres, "SHOW DATABASES"))
+  if (mysql_query_with_error_report(mysql_con, &tableres, "SHOW DATABASES"))
     return 1;
   while ((row= mysql_fetch_row(tableres)))
   {
-    if (dump_all_tables_in_db(row[0]))
+    if (dump_all_tables_in_db(mysql_con, row[0]))
       result=1;
   }
   if (seen_views)
   {
-    if (mysql_query(mysql, "SHOW DATABASES") ||
-        !(tableres= mysql_store_result(mysql)))
+    if (mysql_query(mysql_con, "SHOW DATABASES") ||
+        !(tableres= mysql_store_result(mysql_con)))
     {
       my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
-                      MYF(0), mysql_error(mysql));
+                      MYF(0), mysql_error(mysql_con));
       return 1;
     }
     while ((row= mysql_fetch_row(tableres)))
     {
-      if (dump_all_views_in_db(row[0]))
+      if (dump_all_views_in_db(mysql_con, row[0]))
         result=1;
     }
   }
@@ -3826,7 +3870,7 @@ static int dump_all_databases()
 /* dump_all_databases */
 
 
-static int dump_databases(char **db_names)
+static int dump_databases(MYSQL *mysql_con, char **db_names)
 {
   int result=0;
   char **db;
@@ -3834,14 +3878,14 @@ static int dump_databases(char **db_name
 
   for (db= db_names ; *db ; db++)
   {
-    if (dump_all_tables_in_db(*db))
+    if (dump_all_tables_in_db(mysql_con, *db))
       result=1;
   }
   if (!result && seen_views)
   {
     for (db= db_names ; *db ; db++)
     {
-      if (dump_all_views_in_db(*db))
+      if (dump_all_views_in_db(mysql_con, *db))
         result=1;
     }
   }
@@ -3855,12 +3899,13 @@ View Specific database initalization.
 SYNOPSIS
   init_dumping_views
   qdatabase      quoted name of the database
+  mysql_con      MySQL connection
 
 RETURN VALUES
   0        Success.
   1        Failure.
 */
-int init_dumping_views(char *qdatabase __attribute__((unused)))
+int init_dumping_views(char *qdatabase __attribute__((unused)), MYSQL *mysql_con __attribute__((unused)))
 {
     return 0;
 } /* init_dumping_views */
@@ -3872,13 +3917,14 @@ Table Specific database initalization.
 SYNOPSIS
   init_dumping_tables
   qdatabase      quoted name of the database
+  mysql_con      MySQL connection
 
 RETURN VALUES
   0        Success.
   1        Failure.
 */
 
-int init_dumping_tables(char *qdatabase)
+int init_dumping_tables(char *qdatabase, MYSQL *mysql_con )
 {
   DBUG_ENTER("init_dumping_tables");
 
@@ -3892,7 +3938,7 @@ int init_dumping_tables(char *qdatabase)
                 "SHOW CREATE DATABASE IF NOT EXISTS %s",
                 qdatabase);
 
-    if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
+    if (mysql_query(mysql_con, qbuf) || !(dbinfo = mysql_store_result(mysql_con)))
     {
       /* Old server version, dump generic CREATE DATABASE */
       if (opt_drop_database)
@@ -3921,15 +3967,15 @@ int init_dumping_tables(char *qdatabase)
 } /* init_dumping_tables */
 
 
-static int init_dumping(char *database, int init_func(char*))
+static int init_dumping(MYSQL *mysql_con, char *database, int init_func(char*,MYSQL*))
 {
-  if (mysql_get_server_version(mysql) >= 50003 &&
+  if (mysql_get_server_version(mysql_con) >= 50003 &&
       !my_strcasecmp(&my_charset_latin1, database, "information_schema"))
     return 1;
 
-  if (mysql_select_db(mysql, database))
+  if (mysql_select_db(mysql_con, database))
   {
-    DB_error(mysql, "when selecting the database");
+    DB_error(mysql_con, "when selecting the database");
     return 1;                   /* If --force */
   }
   if (!path && !opt_xml)
@@ -3948,14 +3994,12 @@ static int init_dumping(char *database, 
       }
 
       /* Call the view or table specific function */
-      init_func(qdatabase);
+      init_func(qdatabase, mysql_con);
 
       fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
       check_io(md_result_file);
     }
   }
-  if (extended_insert)
-    init_dynamic_string_checked(&extended_row, "", 1024, 1024);
   return 0;
 } /* init_dumping */
 
@@ -3967,21 +4011,64 @@ my_bool include_table(const uchar *hash_
   return !hash_search(&ignore_table, hash_key, len);
 }
 
+static void *dump_all_tables_in_db_parallel(void *thread_data)
+{
+  struct thread_data *t_data = (struct thread_data *)thread_data;
+
+  char *database = (char *)t_data->db;
+  MYSQL *mysql_con = (MYSQL *)t_data->mysql_con;
+  FILE *md_result_file = (FILE *)t_data->md_result_file;
+  char *table = (char *)t_data->table;
+  char *hash_key = (char *)t_data->hash_key;
+  char *afterdot = (char *)t_data->afterdot;
 
-static int dump_all_tables_in_db(char *database)
+  // order_by ???
+
+  /* Dump every table */
+  while ((table= getTableName(mysql_con, 0)))
+  {
+    char *end= strmov(afterdot, table);
+    if (include_table((uchar*) hash_key, end - hash_key))
+    {
+      dump_table(table, database, mysql_con, md_result_file);
+      my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
+      order_by= 0;
+      if (opt_dump_triggers && ! opt_xml &&
+          mysql_get_server_version(mysql_con) >= 50009)
+      {
+        if (dump_triggers_for_table(table, database, mysql_con))
+        {
+          if (path)
+            my_fclose(md_result_file, MYF(MY_WME));
+          maybe_exit(EX_MYSQLERR);
+        }
+      }
+    }
+  }
+  return 0;
+}
+
+static int dump_all_tables_in_db(MYSQL *mysql_con, char *database)
 {
   char *table;
   uint numrows;
   char table_buff[NAME_LEN*2+3];
   char hash_key[2*NAME_LEN+2];  /* "db.tablename" */
   char *afterdot;
+
+  const int NOOF_THREADS = 1;
+  pthread_t thread[NOOF_THREADS];
+  pthread_attr_t threads_attr;
+  struct thread_data thread_data[NOOF_THREADS];
+  int i, err;
+
   int using_mysql_db= my_strcasecmp(&my_charset_latin1, database, "mysql");
   DBUG_ENTER("dump_all_tables_in_db");
 
   afterdot= strmov(hash_key, database);
   *afterdot++= '.';
 
-  if (init_dumping(database, init_dumping_tables))
+  if (init_dumping(mysql_con, database, init_dumping_tables))
     DBUG_RETURN(1);
   if (opt_xml)
     print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
@@ -3989,7 +4076,7 @@ static int dump_all_tables_in_db(char *d
   {
     DYNAMIC_STRING query;
     init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
-    for (numrows= 0 ; (table= getTableName(1)) ; )
+    for (numrows= 0 ; (table= getTableName(mysql_con, 1)) ; )
     {
       char *end= strmov(afterdot, table);
       if (include_table((uchar*) hash_key,end - hash_key))
@@ -3999,48 +4086,51 @@ static int dump_all_tables_in_db(char *d
         dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
       }
     }
-    if (numrows && mysql_real_query(mysql, query.str, query.length-1))
-      DB_error(mysql, "when using LOCK TABLES");
+    if (numrows && mysql_real_query(mysql_con, query.str, query.length-1))
+      DB_error(mysql_con, "when using LOCK TABLES");
             /* We shall continue here, if --force was given */
     dynstr_free(&query);
   }
   if (flush_logs)
   {
-    if (mysql_refresh(mysql, REFRESH_LOG))
-      DB_error(mysql, "when doing refresh");
+    if (mysql_refresh(mysql_con, REFRESH_LOG))
+      DB_error(mysql_con, "when doing refresh");
            /* We shall continue here, if --force was given */
   }
-  while ((table= getTableName(0)))
+
+  pthread_attr_init(&threads_attr);
+  pthread_attr_setdetachstate(&threads_attr, PTHREAD_CREATE_JOINABLE);
+
+  thread_data[0].db = database;
+  thread_data[0].mysql_con = mysql_con;
+  thread_data[0].md_result_file = md_result_file;
+  thread_data[0].table = table;
+  thread_data[0].hash_key = hash_key;
+  thread_data[0].afterdot = afterdot;
+
+  /* Create and start each thread */
+  for (i = 0; i < NOOF_THREADS; i++)
   {
-    char *end= strmov(afterdot, table);
-    if (include_table((uchar*) hash_key, end - hash_key))
-    {
-      dump_table(table,database);
-      my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
-      order_by= 0;
-      if (opt_dump_triggers && ! opt_xml &&
-          mysql_get_server_version(mysql) >= 50009)
-      {
-        if (dump_triggers_for_table(table, database))
-        {
-          if (path)
-            my_fclose(md_result_file, MYF(MY_WME));
-          maybe_exit(EX_MYSQLERR);
-        }
-      }
-    }
+    err = pthread_create(&thread[i], &threads_attr, dump_all_tables_in_db_parallel, (void *)thread_data);
   }
+
+  pthread_attr_destroy(&threads_attr);
+
+  /* Wait until each thread finish */
+  for (i = 0; i < NOOF_THREADS; i++)
+    err = pthread_join(thread[i], NULL);
+
   if (opt_events && !opt_xml &&
-      mysql_get_server_version(mysql) >= 50106)
+      mysql_get_server_version(mysql_con) >= 50106)
   {
     DBUG_PRINT("info", ("Dumping events for database %s", database));
-    dump_events_for_db(database);
+    dump_events_for_db(mysql_con, database);
   }
   if (opt_routines && !opt_xml &&
-      mysql_get_server_version(mysql) >= 50009)
+      mysql_get_server_version(mysql_con) >= 50009)
   {
     DBUG_PRINT("info", ("Dumping routines for database %s", database));
-    dump_routines_for_db(database);
+    dump_routines_for_db(mysql_con, database);
   }
   if (opt_xml)
   {
@@ -4048,7 +4138,7 @@ static int dump_all_tables_in_db(char *d
     check_io(md_result_file);
   }
   if (lock_tables)
-    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+    VOID(mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"));
   if (flush_privileges && using_mysql_db == 0)
   {
     fprintf(md_result_file,"\n--\n-- Flush Grant Tables \n--\n");
@@ -4070,7 +4160,7 @@ static int dump_all_tables_in_db(char *d
     1 ERROR
 */
 
-static my_bool dump_all_views_in_db(char *database)
+static my_bool dump_all_views_in_db(MYSQL *mysql_con, char *database)
 {
   char *table;
   uint numrows;
@@ -4081,7 +4171,7 @@ static my_bool dump_all_views_in_db(char
   afterdot= strmov(hash_key, database);
   *afterdot++= '.';
 
-  if (init_dumping(database, init_dumping_views))
+  if (init_dumping(mysql_con, database, init_dumping_views))
     return 1;
   if (opt_xml)
     print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
@@ -4089,7 +4179,7 @@ static my_bool dump_all_views_in_db(char
   {
     DYNAMIC_STRING query;
     init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
-    for (numrows= 0 ; (table= getTableName(1)); )
+    for (numrows= 0 ; (table= getTableName(mysql_con, 1)); )
     {
       char *end= strmov(afterdot, table);
       if (include_table((uchar*) hash_key,end - hash_key))
@@ -4099,22 +4189,22 @@ static my_bool dump_all_views_in_db(char
         dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
       }
     }
-    if (numrows && mysql_real_query(mysql, query.str, query.length-1))
-      DB_error(mysql, "when using LOCK TABLES");
+    if (numrows && mysql_real_query(mysql_con, query.str, query.length-1))
+      DB_error(mysql_con, "when using LOCK TABLES");
             /* We shall continue here, if --force was given */
     dynstr_free(&query);
   }
   if (flush_logs)
   {
-    if (mysql_refresh(mysql, REFRESH_LOG))
-      DB_error(mysql, "when doing refresh");
+    if (mysql_refresh(mysql_con, REFRESH_LOG))
+      DB_error(mysql_con, "when doing refresh");
            /* We shall continue here, if --force was given */
   }
-  while ((table= getTableName(0)))
+  while ((table= getTableName(mysql_con, 0)))
   {
     char *end= strmov(afterdot, table);
     if (include_table((uchar*) hash_key, end - hash_key))
-      get_view_structure(table, database);
+      get_view_structure(mysql_con, table, database);
   }
   if (opt_xml)
   {
@@ -4122,7 +4212,7 @@ static my_bool dump_all_views_in_db(char
     check_io(md_result_file);
   }
   if (lock_tables)
-    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+    VOID(mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"));
   return 0;
 } /* dump_all_tables_in_db */
 
@@ -4138,7 +4228,7 @@ static my_bool dump_all_views_in_db(char
     0 if error
 */
 
-static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root)
+static char *get_actual_table_name(MYSQL *mysql_con, const char *old_table_name, MEM_ROOT *root)
 {
   char *name= 0;
   MYSQL_RES  *table_res;
@@ -4152,10 +4242,10 @@ static char *get_actual_table_name(const
   my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s",
               quote_for_like(old_table_name, show_name_buff));
 
-  if (mysql_query_with_error_report(mysql, 0, query))
+  if (mysql_query_with_error_report(mysql_con, 0, query))
     return NullS;
 
-  if ((table_res= mysql_store_result(mysql)))
+  if ((table_res= mysql_store_result(mysql_con)))
   {
     my_ulonglong num_rows= mysql_num_rows(table_res);
     if (num_rows > 0)
@@ -4175,16 +4265,119 @@ static char *get_actual_table_name(const
   DBUG_RETURN(name);
 }
 
+static void *dump_selected_tables_parallel(void *thread_data)
+{
+  struct thread_data *t_data = (struct thread_data *)thread_data;
+  unsigned t_id = (unsigned)t_data->t_id;
+  char *db = (char *)t_data->db;
+  char ***tables = (char ***)t_data->tables;
+  pthread_mutex_t *tables_mutex = (pthread_mutex_t *)t_data->tables_mutex;
+  unsigned *count_tables = (unsigned*)t_data->count_tables;
+  unsigned noof_tables = (unsigned)t_data->noof_tables;
+
+  unsigned i;
+  MYSQL *mysql_con;
+  FILE *table_md_result_file;
+  char *table_md_result_file_path;
+  char *table;
+  my_bool finished=FALSE;
+
+  mysql_con = (MYSQL *) my_malloc(sizeof(MYSQL), MYF(MY_WME));
+  mysql_con = connect_to_db(mysql_con, current_host, current_user, opt_password);
+
+  if (!mysql_con)
+  {
+    /* TODO handle this correctly */
+    printf("ERROR: Thread %d couldn't create mysql connection!!!\n", t_id);
+    exit(1);
+  }
+
+  if (init_dumping(mysql_con, db, init_dumping_tables))
+  {
+    /* TODO handle this correctly */
+    printf("ERROR: Couldn't init dumping for thread %d!!!\n", t_id);
+    exit(1);
+  }
+
+  while(!finished)
+  {
+    pthread_mutex_lock(tables_mutex);
+    if (*count_tables < noof_tables)
+    {
+      table=**tables;
+      i=*count_tables;
+      (*tables)++;
+      (*count_tables)++;
+    }
+    else
+    {
+      finished=TRUE;
+    }
+    pthread_mutex_unlock(tables_mutex);
+
+    if (finished)
+      break;
+
+    /* TODO use a DYNAMIC_STRING here could be better */
+    /* Allocate path for table result file and open it */
+    table_md_result_file_path = (char*) my_malloc(sizeof(char)*md_result_file_path_length + 10, MYF(MY_WME));
+    sprintf(table_md_result_file_path, "%s.%d", md_result_file_path, i);
+    table_md_result_file=my_fopen(table_md_result_file_path, O_WRONLY | FILE_BINARY, MYF(MY_WME));
+
+    if (!table_md_result_file)
+    {
+      /* TODO handle this correctly */
+      printf("ERROR: Couldn't open result file for thread %d!!!\n", t_id);
+      exit(1);
+    }
+    write_header(table_md_result_file, db);
+
+    DBUG_PRINT("info",("Dumping table %s [thread %d]", table, t_id));
+    dump_table(table, db, mysql_con, table_md_result_file);
+    if (opt_dump_triggers &&
+        mysql_get_server_version(mysql_con) >= 50009)
+    {
+      if (dump_triggers_for_table(table, db, mysql_con))
+      {
+        if (path)
+        {
+          my_fclose(table_md_result_file, MYF(MY_WME));
+          /* TODO CHECK THIS. it's right to close conn here??? maybe_exit only closes the conn if ignore_error is not set */
+          /* mysql_close(mysql_con); */
+          /* my_free(mysql_con, MYF(MY_WME)); */
+        }
+        maybe_exit(EX_MYSQLERR);
+      }
+    }
+    write_footer(table_md_result_file);
+    my_fclose(table_md_result_file, MYF(MY_WME));
+    my_free(table_md_result_file_path, MYF(MY_WME));
+  }
+
+  mysql_close(mysql_con);
+  my_free(mysql_con, MYF(MY_WME));
 
-static int dump_selected_tables(char *db, char **table_names, int tables)
+  pthread_exit(NULL);
+}
+
+static int dump_selected_tables(MYSQL *mysql_con, char *db, char **table_names, int tables)
 {
   char table_buff[NAME_LEN*2+3];
   DYNAMIC_STRING lock_tables_query;
   MEM_ROOT root;
   char **dump_tables, **pos, **end;
+
+  pthread_t *thread;
+  struct thread_data *thread_data;
+  pthread_attr_t threads_attr;
+  pthread_mutex_t tables_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+  int err;
+  unsigned i, noof_tables, noof_threads, count_tables;
+
   DBUG_ENTER("dump_selected_tables");
 
-  if (init_dumping(db, init_dumping_tables))
+  if (init_dumping(mysql_con, db, init_dumping_tables))
     DBUG_RETURN(1);
 
   init_alloc_root(&root, 8192, 0);
@@ -4195,7 +4388,7 @@ static int dump_selected_tables(char *db
   for (; tables > 0 ; tables-- , table_names++)
   {
     /* the table name passed on commandline may be wrong case */
-    if ((*pos= get_actual_table_name(*table_names, &root)))
+    if ((*pos= get_actual_table_name(mysql_con, *table_names, &root)))
     {
       /* Add found table name to lock_tables_query */
       if (lock_tables)
@@ -4220,7 +4413,7 @@ static int dump_selected_tables(char *db
 
   if (lock_tables)
   {
-    if (mysql_real_query(mysql, lock_tables_query.str,
+    if (mysql_real_query(mysql_con, lock_tables_query.str,
                          lock_tables_query.length-1))
     {
       if (!ignore_errors)
@@ -4228,59 +4421,106 @@ static int dump_selected_tables(char *db
         dynstr_free(&lock_tables_query);
         free_root(&root, MYF(0));
       }
-      DB_error(mysql, "when doing LOCK TABLES");
-       /* We shall countinue here, if --force was given */
+      DB_error(mysql_con, "when doing LOCK TABLES");
+      /* We shall countinue here, if --force was given */
     }
   }
   dynstr_free(&lock_tables_query);
   if (flush_logs)
   {
-    if (mysql_refresh(mysql, REFRESH_LOG))
+    if (mysql_refresh(mysql_con, REFRESH_LOG))
     {
       if (!ignore_errors)
         free_root(&root, MYF(0));
-      DB_error(mysql, "when doing refresh");
+      DB_error(mysql_con, "when doing refresh");
     }
      /* We shall countinue here, if --force was given */
   }
   if (opt_xml)
     print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS);
 
-  /* Dump each selected table */
-  for (pos= dump_tables; pos < end; pos++)
+  pos=dump_tables;
+  noof_tables=end-dump_tables;
+
+  if (!opt_use_threads)
   {
-    DBUG_PRINT("info",("Dumping table %s", *pos));
-    dump_table(*pos, db);
-    if (opt_dump_triggers &&
-        mysql_get_server_version(mysql) >= 50009)
+    DBUG_PRINT("info", ("Serial dumping. Running single-threaded"));
+
+    /* Dump each selected table */
+    for (pos= dump_tables; pos < end; pos++)
     {
-      if (dump_triggers_for_table(*pos, db))
+      DBUG_PRINT("info",("Dumping table %s", *pos));
+      dump_table(*pos, db, mysql, md_result_file);
+      if (opt_dump_triggers &&
+          mysql_get_server_version(mysql) >= 50009)
       {
-        if (path)
-          my_fclose(md_result_file, MYF(MY_WME));
-        maybe_exit(EX_MYSQLERR);
+        if (dump_triggers_for_table(*pos, db, mysql))
+        {
+          if (path)
+            my_fclose(md_result_file, MYF(MY_WME));
+          maybe_exit(EX_MYSQLERR);
+        }
       }
     }
   }
+  else
+  {
+    DBUG_PRINT("info", ("Parallel dumping. Running with %d thread(s)", opt_use_threads));
+    noof_threads = (noof_tables < noof_threads ? noof_tables : opt_use_threads);
+
+    /* Allocate threads and thread_data. One for each thread */
+    thread=(pthread_t*) my_malloc(sizeof(pthread_t)*noof_threads, MYF(MY_WME));
+    thread_data=(struct thread_data*) my_malloc(sizeof(struct thread_data)*noof_threads, MYF(MY_WME));
+
+    pthread_attr_init(&threads_attr);
+    pthread_attr_setdetachstate(&threads_attr, PTHREAD_CREATE_JOINABLE);
+
+    count_tables = 0;
+    /* Create and start each thread */
+    for (i = 0; i < noof_threads; i++)
+    {
+      thread_data[i].t_id = i;
+      thread_data[i].db = db;
+      thread_data[i].tables_mutex = &tables_mutex;
+      thread_data[i].count_tables = &count_tables;
+      thread_data[i].tables = &dump_tables;
+      thread_data[i].noof_tables = noof_tables;
+
+      err = pthread_create(&thread[i], &threads_attr, dump_selected_tables_parallel,
+                           (void *)&thread_data[i]);
+      /* TODO handle err */
+    }
+    pthread_attr_destroy(&threads_attr);
+
+    /* Wait until each thread finish */
+    for (i = 0; i < noof_threads; i++)
+    {
+      err = pthread_join(thread[i], NULL);
+      /* TODO handle err */
+    }
+    my_free(thread, MYF(MY_WME));
+    my_free(thread_data, MYF(MY_WME));
+    pthread_mutex_destroy(&tables_mutex);
+  }
 
   /* Dump each selected view */
   if (seen_views)
   {
     for (pos= dump_tables; pos < end; pos++)
-      get_view_structure(*pos, db);
+      get_view_structure(mysql_con, *pos, db);
   }
   if (opt_events && !opt_xml &&
-      mysql_get_server_version(mysql) >= 50106)
+      mysql_get_server_version(mysql_con) >= 50106)
   {
     DBUG_PRINT("info", ("Dumping events for database %s", db));
-    dump_events_for_db(db);
+    dump_events_for_db(mysql_con, db);
   }
   /* obtain dump of routines (procs/functions) */
   if (opt_routines  && !opt_xml &&
-      mysql_get_server_version(mysql) >= 50009)
+      mysql_get_server_version(mysql_con) >= 50009)
   {
     DBUG_PRINT("info", ("Dumping routines for database %s", db));
-    dump_routines_for_db(db);
+    dump_routines_for_db(mysql_con, db);
   }
   free_root(&root, MYF(0));
   my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
@@ -4291,11 +4531,10 @@ static int dump_selected_tables(char *db
     check_io(md_result_file);
   }
   if (lock_tables)
-    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
+    VOID(mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES"));
   DBUG_RETURN(0);
 } /* dump_selected_tables */
 
-
 static int do_show_master_status(MYSQL *mysql_con)
 {
   MYSQL_ROW row;
@@ -4347,9 +4586,9 @@ static int do_flush_tables_read_lock(MYS
     update starts between the two FLUSHes, we have that bad stall.
   */
   return
-    ( mysql_query_with_error_report(mysql_con, 0, 
-                                    ((opt_master_data != 0) ? 
-                                        "FLUSH /*!40101 LOCAL */ TABLES" : 
+    ( mysql_query_with_error_report(mysql_con, 0,
+                                    ((opt_master_data != 0) ?
+                                        "FLUSH /*!40101 LOCAL */ TABLES" :
                                         "FLUSH TABLES")) ||
       mysql_query_with_error_report(mysql_con, 0,
                                     "FLUSH TABLES WITH READ LOCK") );
@@ -4368,7 +4607,7 @@ static int get_bin_log_name(MYSQL *mysql
   MYSQL_ROW row;
 
   if (mysql_query(mysql_con, "SHOW MASTER STATUS") ||
-      !(res= mysql_store_result(mysql)))
+      !(res= mysql_store_result(mysql_con)))
     return 1;
 
   if (!(row= mysql_fetch_row(res)))
@@ -4516,16 +4755,16 @@ static void print_value(FILE *file, MYSQ
     check_if_ignore_table()
     table_name                  Table name to check
     table_type                  Type of table
+    mysql_con                   MySQL connection
 
   GLOBAL VARIABLES
-    mysql                       MySQL connection
     verbose                     Write warning messages
 
   RETURN
     char (bit value)            See IGNORE_ values at top
 */
 
-char check_if_ignore_table(const char *table_name, char *table_type)
+char check_if_ignore_table(const char *table_name, char *table_type, MYSQL *mysql_con)
 {
   char result= IGNORE_NONE;
   char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN];
@@ -4537,12 +4776,12 @@ char check_if_ignore_table(const char *t
   DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff));
   my_snprintf(buff, sizeof(buff), "show table status like %s",
               quote_for_like(table_name, show_name_buff));
-  if (mysql_query_with_error_report(mysql, &res, buff))
+  if (mysql_query_with_error_report(mysql_con, &res, buff))
   {
-    if (mysql_errno(mysql) != ER_PARSE_ERROR)
+    if (mysql_errno(mysql_con) != ER_PARSE_ERROR)
     {                                   /* If old MySQL version */
       verbose_msg("-- Warning: Couldn't get status information for "
-                  "table %s (%s)\n", table_name, mysql_error(mysql));
+                  "table %s (%s)\n", table_name, mysql_error(mysql_con));
       DBUG_RETURN(result);                       /* assume table is ok */
     }
   }
@@ -4550,7 +4789,7 @@ char check_if_ignore_table(const char *t
   {
     fprintf(stderr,
             "Error: Couldn't read status information for table %s (%s)\n",
-            table_name, mysql_error(mysql));
+            table_name, mysql_error(mysql_con));
     mysql_free_result(res);
     DBUG_RETURN(result);                         /* assume table is ok */
   }
@@ -4606,7 +4845,7 @@ char check_if_ignore_table(const char *t
     the table unsorted, rather than exit without dumping the data.
 */
 
-static char *primary_key_fields(const char *table_name)
+static char *primary_key_fields(MYSQL *mysql_con, const char *table_name)
 {
   MYSQL_RES  *res= NULL;
   MYSQL_ROW  row;
@@ -4619,12 +4858,12 @@ static char *primary_key_fields(const ch
 
   my_snprintf(show_keys_buff, sizeof(show_keys_buff),
               "SHOW KEYS FROM %s", table_name);
-  if (mysql_query(mysql, show_keys_buff) ||
-      !(res= mysql_store_result(mysql)))
+  if (mysql_query(mysql_con, show_keys_buff) ||
+      !(res= mysql_store_result(mysql_con)))
   {
     fprintf(stderr, "Warning: Couldn't read keys from table %s;"
             " records are NOT sorted (%s)\n",
-            table_name, mysql_error(mysql));
+            table_name, mysql_error(mysql_con));
     /* Don't exit, because it's better to print out unsorted records */
     goto cleanup;
   }
@@ -4715,15 +4954,16 @@ static int replace(DYNAMIC_STRING *ds_st
 
   SYNOPSIS
     get_view_structure()
-    table   view name
-    db      db name
+    mysql_con        MySQL connection
+    table            view name
+    db               db name
 
   RETURN
     0 OK
     1 ERROR
 */
 
-static my_bool get_view_structure(char *table, char* db)
+static my_bool get_view_structure(MYSQL *mysql_con, char *table, char* db)
 {
   MYSQL_RES  *table_res;
   MYSQL_ROW  row;
@@ -4741,21 +4981,22 @@ static my_bool get_view_structure(char *
   verbose_msg("-- Retrieving view structure for table %s...\n", table);
 
 #ifdef NOT_REALLY_USED_YET
-  sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
-          (opt_quoted || opt_keywords));
+// TODO When this will be used, modify method to receive insert_pat as a parameter
+//   sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
+//           (opt_quoted || opt_keywords));
 #endif
 
   result_table=     quote_name(table, table_buff, 1);
   opt_quoted_table= quote_name(table, table_buff2, 0);
 
-  if (switch_character_set_results(mysql, "binary"))
+  if (switch_character_set_results(mysql_con, "binary"))
     DBUG_RETURN(1);
 
   my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table);
 
-  if (mysql_query_with_error_report(mysql, &table_res, query))
+  if (mysql_query_with_error_report(mysql_con, &table_res, query))
   {
-    switch_character_set_results(mysql, default_charset);
+    switch_character_set_results(mysql_con, default_charset);
     DBUG_RETURN(0);
   }
 
@@ -4763,7 +5004,7 @@ static my_bool get_view_structure(char *
   field= mysql_fetch_field_direct(table_res, 0);
   if (strcmp(field->name, "View") != 0)
   {
-    switch_character_set_results(mysql, default_charset);
+    switch_character_set_results(mysql_con, default_charset);
     verbose_msg("-- It's base table, skipped\n");
     DBUG_RETURN(0);
   }
@@ -4798,7 +5039,7 @@ static my_bool get_view_structure(char *
               "FROM information_schema.views "
               "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
 
-  if (mysql_query(mysql, query))
+  if (mysql_query(mysql_con, query))
   {
     /*
       Use the raw output from SHOW CREATE TABLE if
@@ -4824,13 +5065,13 @@ static my_bool get_view_structure(char *
     mysql_free_result(table_res);
 
     /* Get the result from "select ... information_schema" */
-    if (!(table_res= mysql_store_result(mysql)) ||
+    if (!(table_res= mysql_store_result(mysql_con)) ||
         !(row= mysql_fetch_row(table_res)))
     {
       if (table_res)
         mysql_free_result(table_res);
       dynstr_free(&ds_view);
-      DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view.");
+      DB_error(mysql_con, "when trying to save the result of SHOW CREATE TABLE in ds_view.");
       DBUG_RETURN(1);
     }
 
@@ -4908,7 +5149,7 @@ static my_bool get_view_structure(char *
     dynstr_free(&ds_view);
   }
 
-  if (switch_character_set_results(mysql, default_charset))
+  if (switch_character_set_results(mysql_con, default_charset))
     DBUG_RETURN(1);
 
   /* If a separate .sql file was opened, close it now */
@@ -4987,7 +5228,7 @@ int main(int argc, char **argv)
     }
   }
 
-  if (connect_to_db(current_host, current_user, opt_password))
+  if (!(mysql=connect_to_db(&mysql_connection, current_host, current_user, opt_password)))
   {
     free_resources(0);
     exit(EX_MYSQLERR);
@@ -5019,27 +5260,27 @@ int main(int argc, char **argv)
     goto err;
 
   if (opt_alltspcs)
-    dump_all_tablespaces();
+    dump_all_tablespaces(mysql);
 
   if (opt_alldbs)
   {
     if (!opt_alltspcs && !opt_notspcs)
-      dump_all_tablespaces();
-    dump_all_databases();
+      dump_all_tablespaces(mysql);
+    dump_all_databases(mysql);
   }
   else if (argc > 1 && !opt_databases)
   {
     /* Only one database and selected table(s) */
     if (!opt_alltspcs && !opt_notspcs)
-      dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
-    dump_selected_tables(*argv, (argv + 1), (argc - 1));
+      dump_tablespaces_for_tables(mysql, *argv, (argv + 1), (argc -1));
+    dump_selected_tables(mysql, *argv, (argv + 1), (argc - 1));
   }
   else
   {
     /* One or more databases, all tables */
     if (!opt_alltspcs && !opt_notspcs)
-      dump_tablespaces_for_databases(argv);
-    dump_databases(argv);
+      dump_tablespaces_for_databases(mysql, argv);
+    dump_databases(mysql, argv);
   }
 
   /* ensure dumped data flushed */

Thread
bzr commit into mysql-5.1 branch (stewart:2678) Stewart Smith14 Aug