List:Internals« Previous MessageNext Message »
From:Sergei Golubchik Date:August 22 2003 12:27am
Subject:Re: new mysqldump features (patch)
View as plain text  
Hi!

On Aug 20, John David Duncan wrote:
> Hi,

Thanks for the patch!
The features look useful indeed!
See my comments below...
 
> In the attached patch I have implemented two new options in mysqldump.
> The -R (--rename-tables)  option loads all tables using temporary names
> and then renames them while holding a lock.  This can be useful when it is
> necessary to minimize lock time.  The output looks like this:
> 
> sh% mysqldump --rename-tables mydb zip city
> 
>   CREATE TABLE _new_zip ...
>   CREATE TABLE _new_city ...
>   INSERT ...
> 
>   LOCK TABLES zip city WRITE;
>   DROP TABLE zip;
>   ALTER TABLE _new_zip RENAME zip;
>   DROP TABLE city;
>   ALTER TABLE _new_city RENAME city;
>   UNLOCK TABLES;

I would agree with Tim here - it would be faster, simpler, and "more
atomic" to use RENAME TABLE here.

In your example it would be

  RENAME TABLE zip TO _old_zip, _new_zip TO zip,
               city TO _old_city, _new_city TO city;

Also, I would agree that it's better to rename the option, as Tim
suggested. And to add --atomic-prefix (or whatever the name is).

> The -U (--with-use-db) option assures that "USE db_name;" is always in the
> output; this is otherwise not true unless --databases or --all-databases
> is used.

Why do you think this option is necessary ?
I'm sure you need it, so you have a working scenario where this option
helps. Can you describe it briefly ?

> @@ -579,6 +606,9 @@
>  
>    sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted ||
> opt_keywords));
>    table_name=quote_name(table,table_buff);
> +  if(opt_rename_tables) 
> +    target_table=rename_and_quote(table,target_buff);
> +  else target_table=table_name;
>    if (!mysql_query(sock,insert_pat))
>    {
>      /* using SHOW CREATE statement */
> @@ -610,14 +640,26 @@
>          write_header(sql_file, db);
>        }
>        if (!opt_xml)
> -        fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n",
> -                table);
> +        fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n",table);
>        if (opt_drop)
> -        fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",table_name);
> +        fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",target_table);
>  
>        tableRes=mysql_store_result(sock);
>        row=mysql_fetch_row(tableRes);
> -      if (!opt_xml)
> +      if(opt_rename_tables) {
> +        char *s = row[1];
> +        if(!(bcmp(row[1],"CREATE TABLE ",13))) {

Pardon me ?
When this condition may ever fail ?

> +          fprintf(sql_file,"CREATE TABLE %s ",target_table);
> +          for(s+=13 ; *s++ != ' ' ; );

This is wrong, you cannot assume that table name won't contain spaces.

> +          fprintf(sql_file, "%s;\n", s);
> +        }
> +        else { 
> +          fprintf(sql_file,"-- Failed to use renamed table\n\n");
> +          target_table=table_name;
> +          opt_rename_tables=0;
> +        }
> +      }  
> +      else if (!opt_xml)
>          fprintf(sql_file, "%s;\n", row[1]);
>        mysql_free_result(tableRes);
>      }
> @@ -690,14 +732,14 @@
>          fprintf(sql_file, "\n--\n-- Table structure for table '%s'\n--\n\n",
>                  table);
>        if (opt_drop)
> -        fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",table_name);
> -      fprintf(sql_file, "CREATE TABLE %s (\n", table_name);
> +        fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",target_table);
> +      fprintf(sql_file, "CREATE TABLE %s (\n", target_table);

this is questionable.
I don't really know what to do when opt_drop is used together with your
opt_rename_tables.

Should it (opt_drop) apply to target_table or original table_name ?

>      }
>      if (cFlag)
> -      sprintf(insert_pat, "INSERT %sINTO %s (", delayed, table_name);
> +      sprintf(insert_pat, "INSERT %sINTO %s (", delayed, target_table);
>      else
>      {
> -      sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, table_name);
> +      sprintf(insert_pat, "INSERT %sINTO %s VALUES ", delayed, target_table);
>        if (!extended_insert)
>          strcat(insert_pat,"(");
>      }
>  static void dumpTable(uint numFields, char *table)
>  {
> -  char query[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3];
> +  char query[QUERY_LENGTH], *end, *target_table;
> +  char buff[256],table_buff[NAME_LEN+3],target_buff[NAME_LEN+3];  
>    MYSQL_RES     *res;
>    MYSQL_FIELD   *field;
>    MYSQL_ROW     row;
> @@ -909,6 +952,9 @@
>  
>    if (verbose)
>      fprintf(stderr, "-- Sending SELECT query...\n");
> +  if(opt_rename_tables) 
> +    target_table=rename_and_quote(table,target_buff);
> +  else target_table=quote_name(table,table_buff);

Why do it several times ? Isn't it better to pass it as a parameter ?

>    if (path)
>    {
>      char filename[FN_REFLEN], tmp_path[FN_REFLEN];
> @@ -1299,7 +1345,7 @@
>        DBerror(sock, "when doing refresh");
>             /* We shall continue here, if --force was given */
>    }
> -  while ((table = getTableName(0)))
> +  while ((table = getTableName(1)))

This way you removed mysql_free_result() call.
Better to do things clean.
That is to have  getTableName(opt_rename_tables) here
and getTableName(0) in rename_all_in_db().

>    {
>      numrows = getTableStructure(table, database);
>      if (!dFlag && numrows > 0)
> @@ -1309,6 +1355,8 @@
>      fprintf(md_result_file, "</database>\n");
>    if (lock_tables)
>      mysql_query(sock,"UNLOCK_TABLES");
> +  if (opt_rename_tables) 
> +    rename_all_in_db(database);
>    return 0;
>  } /* dump_all_tables_in_db */

Besides these minor comments, the patch is very good!

Regards,
Sergei

-- 
   __  ___     ___ ____  __
  /  |/  /_ __/ __/ __ \/ /   Sergei Golubchik <serg@stripped>
 / /|_/ / // /\ \/ /_/ / /__  MySQL AB, Senior Software Developer
/_/  /_/\_, /___/\___\_\___/  Osnabrueck, Germany
       <___/  www.mysql.com
Thread
new mysqldump features (patch)John David Duncan21 Aug
  • Re: new mysqldump features (patch)Tim Bunce21 Aug
    • Re: new mysqldump features (patch)John David Duncan21 Aug
      • Re: new mysqldump features (patch)Tim Bunce21 Aug
  • Re: new mysqldump features (patch)Sergei Golubchik22 Aug