List:Commits« Previous MessageNext Message »
From:Chuck Bell Date:November 29 2007 3:28pm
Subject:RE: bk commit into 6.0 tree (cbell:1.2691) WL#4116
View as plain text  
Rafal,

I have committed 2 new patches with the changes. 

The original patch for the locking thread code (1 of 3) remains unchanged.

The patch for the code (2 of 3) has changed. See
http://lists.mysql.com/commits/38834.
- I too out the method from the Pump class and called report_ob directly.
- I renamed all of the bp_* breakpoints to bp_*_state to make it a bit more
obvious what they are
- I added a comment to the bp_vp_state breakpoint to clarify that it is not
indicating the VP on that the state for the reporting has changed

The patch for the tests (3 of 3) has changed. See
http://lists.mysql.com/commits/38837. 
- There is a modified backup_progress test for the _state additions
- A new result file for above for same reason.

If you're OK with these changes and can give me tentative approval to push I
will bug Lars for the same and wait until you've done your push to merge
that in to my code and have a happy time merging... Whee!!!!

I plan to make a separate patch for the writes to online_backup_progress.
This will make it easier to review and hopefully we can do that later today
or tomorrow morning at the latest. So much to do...

Chuck

> -----Original Message-----
> From: Rafal Somla [mailto:rsomla@stripped] 
> Sent: Thursday, November 29, 2007 5:05 AM
> To: cbell@stripped
> Cc: commits@stripped
> Subject: Re: bk commit into 6.0 tree (cbell:1.2691) WL#4116
> 
> Hi Chuck,
> 
> I have one main concern with this patch. Each time one of 
> your report_ob_*() 
> functions is called these things happen:
> 
> - the locking thread is spawned,
> - appropriate table is opened,
> - data is inserted or updated,
> - table is closed,
> - locking thread is shut-down.
> 
> Concern 1: Efficiency - creating and destroying a thread each 
> time single update 
> is done seems too expensive. Similar with opening and closing 
> table each time. 
> This means that the report_ob_*() functions should not be 
> called too often, but 
> on the other hand they are supposed to be used in that way.
> 
> Concern 2: Because of the above, I think we can't call any 
> report_ob_*() 
> function during the synchronization phase (between lock() and 
> unlock() calls). 
> Recall that we are struggling to make this phase as short as 
> possible and here 
> it is even possible that a disk access will happen.
> 
> The first concern is (perhaps) not crucial as it is just 
> efficiency issue. 
> However something must be done with the second concern.
> 
> I think a possible solution for the first concern is to spawn 
> the locking thread 
> and open all (two) tables used only once, at the beginning of 
> backup/restore 
> operation. Then the reporting functions would need access to 
> the opened tables. 
> Therefore I'd turn them into methods of a class whose 
> instance contains (and 
> maintains) all necessary context (i.e., the locking thread, 
> pointers to TABLE 
> structures and so on). Actually, there is already a Logger 
> class which seems 
> perfect for that purpose.
> 
> See below for some more detailed comments.
> 
> cbell@stripped wrote:
> > Below is the list of changes that have just been committed 
> into a local
> > 6.0 repository of cbell. When cbell does a push these changes will
> > be propagated to the main repository and, within 24 hours after the
> > push, to the public repository.
> > For information on how to access the public repository
> > see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
> > 
> > ChangeSet@stripped, 2007-11-28 23:31:29-05:00, 
> cbell@mysql_cab_desk. +9 -0
> >   WL#4116 : Online Backup: Record Online Backup Progress
> >   
> >   Patch 2 of 3
> >   
> >   This patch contains the online backup progress methods. Output of
> >   the backup process is now recorded and can be queried at a later
> >   time.
> > 
> >   scripts/mysql_system_tables.sql@stripped, 2007-11-28 
> 23:31:19-05:00, cbell@mysql_cab_desk. +6 -0
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Adds the online backup tables to the create mysql 
> database script.
> > 
> >   sql/backup/CMakeLists.txt@stripped, 2007-11-28 23:31:19-05:00, 
> cbell@mysql_cab_desk. +1 -1
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Add the backup progress files to the Windows build for cmake.
> > 
> >   sql/backup/Makefile.am@stripped, 2007-11-28 23:31:20-05:00, 
> cbell@mysql_cab_desk. +3 -1
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Add the backup progress files to the make file.
> > 
> >   sql/backup/archive.h@stripped, 2007-11-28 23:31:21-05:00, 
> cbell@mysql_cab_desk. +1 -0
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Add the backup_id for use in updating the progress.
> > 
> >   sql/backup/backup_engine.h@stripped, 2007-11-28 
> 23:31:22-05:00, cbell@mysql_cab_desk. +2 -0
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Add the backup_id for use in updating the progress.
> > 
> >   sql/backup/backup_progress.cc@stripped, 2007-11-28 
> 23:31:24-05:00, cbell@mysql_cab_desk. +869 -0
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     New source file for backup progress methods.
> > 
> >   sql/backup/backup_progress.cc@stripped, 2007-11-28 
> 23:31:24-05:00, cbell@mysql_cab_desk. +0 -0
> > 
> >   sql/backup/backup_progress.h@stripped, 2007-11-28 
> 23:31:24-05:00, cbell@mysql_cab_desk. +195 -0
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     New header file for backup progress methods.
> > 
> >   sql/backup/backup_progress.h@stripped, 2007-11-28 
> 23:31:24-05:00, cbell@mysql_cab_desk. +0 -0
> > 
> >   sql/backup/data_backup.cc@stripped, 2007-11-28 23:31:22-05:00, 
> cbell@mysql_cab_desk. +38 -0
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Adds method calls to report progress information for backup and
> >     restore.
> > 
> >   sql/backup/sql_backup.cc@stripped, 2007-11-28 23:31:23-05:00, 
> cbell@mysql_cab_desk. +68 -59
> >     WL#4116 : Online Backup: Record Online Backup Progress
> >     
> >     Adds method calls to report progress information for backup and
> >     restore. Also changes summary to print out resulting row from
> >     the online_backup table.
> >     
> >     Note: this allows one to use BACKUP... \G to display as a
> >     vertical query. cool.
> > 
> > diff -Nrup a/scripts/mysql_system_tables.sql 
> b/scripts/mysql_system_tables.sql
> > --- a/scripts/mysql_system_tables.sql	2007-10-30 
> 09:09:48 -04:00
> > +++ b/scripts/mysql_system_tables.sql	2007-11-28 
> 23:31:19 -05:00
> > @@ -83,5 +83,11 @@ DROP PREPARE stmt;
> >  CREATE TABLE IF NOT EXISTS event ( db char(64) CHARACTER 
> SET utf8 COLLATE utf8_bin NOT NULL default '', name char(64) 
> CHARACTER SET utf8 NOT NULL default '', body longblob NOT 
> NULL, definer char(77) CHARACTER SET utf8 COLLATE utf8_bin 
> NOT NULL default '', execute_at DATETIME default NULL, 
> interval_value int(11) default NULL, interval_field 
> ENUM('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SE
> COND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_
> SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICRO
> SECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROS
> ECOND') default NULL, created TIMESTAMP NOT NULL, modified 
> TIMESTAMP NOT NULL, last_executed DATETIME default NULL, 
> starts DATETIME default NULL, ends DATETIME default NULL, 
> status ENUM('ENABLED','DISABLED','SLAVESIDE_DISABLED') NOT 
> NULL default 'ENABLED', on_completion ENUM('DROP','PRESERVE') 
> NOT NULL default 'DROP', sql_mode  
> set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE'
> ,'!
> >  
> NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_D
> IR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_
> KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323',
> 'MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES
> ','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE',
> 'NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','T
> RADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') 
> DEFAULT '' NOT NULL, comment char(64) CHARACTER SET utf8 
> COLLATE utf8_bin NOT NULL default '', originator int(10) NOT 
> NULL, time_zone char(64) CHARACTER SET latin1 NOT NULL 
> DEFAULT 'SYSTEM', character_set_client char(32) collate 
> utf8_bin, collation_connection char(32) collate utf8_bin, 
> db_collation char(32) collate utf8_bin, body_utf8 longblob, 
> PRIMARY KEY (db, name) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 
> COMMENT 'Events';
> >  
> >  
> > +CREATE TABLE IF NOT EXISTS online_backup ( backup_id 
> BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT 'Surrogate 
> key for (near) duplicate entries', process_id INT UNSIGNED 
> NOT NULL COMMENT 'The process id that operation ran as', 
> binlog_pos INT UNSIGNED DEFAULT 0 COMMENT 'The recorded 
> binlog position of backup/restore', binlog_file CHAR(64) 
> COMMENT 'The recorded binlog filename at time of 
> backup/restore', backup_state ENUM('complete', 'starting', 
> 'validity point', 'running', 'error', 'cancel') NOT NULL 
> COMMENT 'Status of current operation', operation 
> ENUM('backup', 'restore') NOT NULL COMMENT 'Type of 
> operation', error_num INT NOT NULL DEFAULT 0 COMMENT 'The 
> error from this run 0 == none', num_objects INT UNSIGNED NOT 
> NULL DEFAULT 0 COMMENT 'The number of objects in the backup', 
> total_bytes BIGINT UNSIGNED COMMENT 'The size of the backup 
> repository in bytes', validity_point_time datetime COMMENT 
> 'The time of the validity point.', start_time datetime 
> COMMENT 'The date/tim
> e !
> >  of start of operation', stop_time datetime COMMENT 'The 
> date/time of end of operation', host_or_server_name CHAR (30) 
> COMMENT 'The server name where operation ran', username CHAR 
> (30) COMMENT 'The user name who ran the operation', 
> backup_file CHAR (100) COMMENT 'The name of the file', 
> user_comment VARCHAR (200) DEFAULT NULL COMMENT 'The comment 
> from user entered at command line', command VARCHAR (512) 
> COMMENT 'The command used to issue operation', engines 
> VARCHAR (100) COMMENT 'The name of the storage engines used 
> in the operation') ENGINE=MYISAM;
> > +
> > +
> > +CREATE TABLE IF NOT EXISTS online_backup_progress ( 
> backup_id BIGINT UNSIGNED NOT NULL COMMENT 'Key for 
> online_backup table entries', object CHAR (30) NOT NULL 
> COMMENT 'The object being operated on', start_time datetime 
> COMMENT 'The date/time of start of operation', stop_time 
> datetime COMMENT 'The date/time of end of operation', 
> total_bytes BIGINT COMMENT 'The size of the object in bytes', 
> progress BIGINT UNSIGNED COMMENT 'The number of bytes 
> processed', error_num INT NOT NULL DEFAULT 0 COMMENT 'The 
> error from this run 0 == none', notes CHAR(100) COMMENT 
> 'Commentary from the backup engine') ENGINE=MYISAM;
> > +
> > +
> >  CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position 
> BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch 
> BIGINT UNSIGNED NOT NULL, inserts INT UNSIGNED NOT NULL, 
> updates INT UNSIGNED NOT NULL, deletes INT UNSIGNED NOT NULL, 
> schemaops INT UNSIGNED NOT NULL, orig_server_id INT UNSIGNED 
> NOT NULL, orig_epoch BIGINT UNSIGNED NOT NULL, gci INT 
> UNSIGNED NOT NULL, PRIMARY KEY(epoch, orig_server_id, 
> orig_epoch)) ENGINE=MYISAM;
> >  
> > diff -Nrup a/sql/backup/CMakeLists.txt b/sql/backup/CMakeLists.txt
> > --- a/sql/backup/CMakeLists.txt	2007-11-16 05:05:55 -05:00
> > +++ b/sql/backup/CMakeLists.txt	2007-11-28 23:31:19 -05:00
> > @@ -25,7 +25,7 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
> >  SET(BACKUP_SOURCES stream.cc logger.cc string_pool.cc
> >                 archive.cc meta_backup.cc data_backup.cc
> >                 sql_backup.cc be_default.cc buffer_iterator.cc
> > -               be_snapshot.cc be_thread.cc)
> > +               be_snapshot.cc be_thread.cc backup_progress.cc)
> >  
> >  IF(NOT SOURCE_SUBLIBS)
> >    ADD_LIBRARY(backup ${BACKUP_SOURCES})
> > diff -Nrup a/sql/backup/Makefile.am b/sql/backup/Makefile.am
> > --- a/sql/backup/Makefile.am	2007-11-16 05:10:35 -05:00
> > +++ b/sql/backup/Makefile.am	2007-11-28 23:31:20 -05:00
> > @@ -36,7 +36,8 @@ libbackup_la_SOURCES = \
> >        be_default.cc \
> >        be_snapshot.cc \
> >        buffer_iterator.cc \
> > -      be_thread.cc
> > +      be_thread.cc \
> > +      backup_progress.cc
> >  
> >  libbackupstream_la_SOURCES= \
> >    stream_v1_transport.c \
> > @@ -59,6 +60,7 @@ noinst_HEADERS = \
> >        be_snapshot.h \
> >        buffer_iterator.h \
> >        be_thread.h \
> > +      backup_progress.h \
> >  	stream_v1.h \
> >  	stream_v1_services.h
> >  
> > diff -Nrup a/sql/backup/archive.h b/sql/backup/archive.h
> > --- a/sql/backup/archive.h	2007-11-09 16:19:38 -05:00
> > +++ b/sql/backup/archive.h	2007-11-28 23:31:21 -05:00
> > @@ -83,6 +83,7 @@ class Archive_info
> >     struct tm start_time;              ///< the start 
> datetime of the backup
> >     struct tm end_time;                ///< the end 
> datetime of the backup
> >     struct tm vp_time;                 ///< time of validation point
> > +   ulonglong backup_prog_id;          ///< the backup_id 
> for reporting progress
> >  
> >     // Classes representing various types of meta-data items.
> >  
> > diff -Nrup a/sql/backup/backup_engine.h b/sql/backup/backup_engine.h
> > --- a/sql/backup/backup_engine.h	2007-11-06 13:32:08 -05:00
> > +++ b/sql/backup/backup_engine.h	2007-11-28 23:31:22 -05:00
> > @@ -191,6 +191,8 @@ class Driver
> >    /// Unknown size constant used for backup image size estimates.
> >    static const size_t UNKNOWN_SIZE= static_cast<size_t>(-1);
> >  
> > +  ulonglong backup_prog_id;
> > +
> >   protected:
> >  
> >    /// Refers to the list of tables passed when the driver 
> was created.
> > diff -Nrup a/sql/backup/backup_progress.cc 
> b/sql/backup/backup_progress.cc
> > --- /dev/null	Wed Dec 31 16:00:00 196900
> > +++ b/sql/backup/backup_progress.cc	2007-11-28 23:31:24 -05:00
> > @@ -0,0 +1,869 @@
> > +/* Copyright (C) 2004-2007 MySQL AB
> > +
> > +   This program is free software; you can redistribute it 
> and/or modify
> > +   it under the terms of the GNU General Public License as 
> published by
> > +   the Free Software Foundation; version 2 of the License.
> > +
> > +   This program is distributed in the hope that it will be useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > +   GNU General Public License for more details.
> > +
> > +   You should have received a copy of the GNU General 
> Public License
> > +   along with this program; if not, write to the Free Software
> > +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
> MA  02111-1307 USA
> > +*/
> > +
> > +/**
> > +   @file backup_progress.cc
> > +
> > +   This file contains the methods to create and update rows in the 
> > +   online backup progress tables.
> > +
> > +   @todo Decide on what "size" means. Does it mean number 
> of rows or number
> > +         of byte?
> > +  */
> > +
> > +#include "backup_progress.h"
> > +#include "be_thread.h"
> > +
> > +extern bool check_if_table_exists(THD *thd, TABLE_LIST 
> *table, bool *exists);
> > +
> > +/**
> > +   Open backup progress table.
> > +
> > +   This method opens the online backup table specified. It 
> uses the locking
> > +   thread mechanism in be_thread.cc to open the table in a 
> separate thread.
> > +
> > +   @param char *         table_name  The name of the table to open.
> > +   @param thr_lock_type  lock        The lock type -- 
> TL_WRITE or TL_READ.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to open table
> > +
> > +   @todo : Replace poling loop with signal.
> > +  */
> > +Locking_thread_st *open_backup_progress_table(const char 
> *table_name,
> > +                                              enum 
> thr_lock_type lock)
> > +{
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +  bool exists;                          // See if table exists
> > +
> > +  DBUG_ENTER("open_backup_progress_table()");
> > +
> > +  tables.init_one_table("mysql", table_name, lock);
> > +
> > +  /*
> > +    First, check to see if table exists.
> > +  */
> > +  if (check_if_table_exists(current_thd, &tables, &exists))
> > +    DBUG_RETURN(locking_thd);
> > +
> > +  /*
> > +    Create a new thread to open and lock the tables.
> > +  */
> > +  locking_thd= new Locking_thread_st();
> > +  locking_thd->tables_in_backup= &tables;
> > +
> > +  /*
> > +    Start the locking thread and wait until it is ready.
> > +  */
> > +  locking_thd->start_locking_thread();
> > +
> > +  /*
> > +    Poll the locking thread until ready.
> > +  */
> > +  while (locking_thd && (locking_thd->lock_state != 
> LOCK_ACQUIRED) &&
> > +         (locking_thd->lock_state != LOCK_ERROR))
> > +    sleep(0);
> > +  if (locking_thd->lock_state == LOCK_ERROR)
> > +  {
> > +    delete locking_thd;
> > +    locking_thd= NULL;
> > +  }
> > +  DBUG_RETURN(locking_thd);
> > +}
> > +
> > +/**
> > +   Find the row in the table that matches the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed.
> > +
> > +   @param TABLE *    table      The table to search.
> > +   @param ulonglong  backup_id  The id of the row to locate.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +my_bool find_online_backup_row(TABLE *table, ulonglong backup_id)
> > +{
> > +  uchar key[MAX_KEY_LENGTH]; // key buffer for search
> > +
> > +  DBUG_ENTER("find_online_backup_row()");
> > +
> > +  /*
> > +    Create key to find row. We have to use field->store() 
> to be able to
> > +    handle VARCHAR and CHAR fields.
> > +    Assumption here is that the two first fields in the table are
> > +    'db' and 'name' and the first key is the primary key over the
> > +    same fields.
> > +  */
> > +  table->field[ET_FIELD_BACKUP_ID]->store(backup_id, TRUE);
> > +
> > +  key_copy(key, table->record[0], table->key_info, 
> table->key_info->key_length);
> > +
> > +  if (table->file->index_read_idx_map(table->record[0], 0, 
> key, HA_WHOLE_KEY,
> > +                                      HA_READ_KEY_EXACT))
> > +  {
> > +    DBUG_PRINT("info", ("Row not found"));
> > +    DBUG_RETURN(TRUE);
> > +  }
> > +
> > +  DBUG_PRINT("info", ("Row found!"));
> > +  DBUG_RETURN(FALSE);
> > +}
> > +
> > +/**
> > +   Update an integer field for the row in the table that 
> matches the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the field specified.
> > +
> > +   @param ulonglong            backup_id   The id of the 
> row to locate.
> > +   @param char *               table_name  The name of the 
> table to open.
> > +   @param enum_ob_table_field  fld         Field to update.
> > +   @param ulonglong            value       Value to set field to.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int update_online_backup_int_field(ulonglong backup_id, 
> char *table_name,
> > +                                   enum_ob_table_field 
> fld, ulonglong value)
> > +{
> > +  TABLE *table= NULL;                   // table to open
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  int ret= 0;                           // return value
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +
> > +  DBUG_ENTER("update_int_field()");
> > +
> > +  locking_thd= open_backup_progress_table(table_name, TL_WRITE);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  if (find_online_backup_row(table, backup_id))
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(1);
> > +  }
> > +
> > +  store_record(table, record[1]);
> > +
> > +  /*
> > +    Fill in the data.
> > +  */
> > +  table->field[fld]->store(value, TRUE);
> > +  table->field[fld]->set_notnull();
> > +
> > +  /*
> > +    Update the row.
> > +  */
> > +  if ((ret= table->file->ha_update_row(table->record[1], 
> table->record[0])))
> > +    table->file->print_error(ret, MYF(0));
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update a datetime field for the row in the table that 
> matches the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the field specified.
> > +
> > +   @param ulonglong            backup_id   The id of the 
> row to locate.
> > +   @param char *               table_name  The name of the 
> table to open.
> > +   @param enum_ob_table_field  fld         Field to update.
> > +   @param my_time_t            value       Value to set field to.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int update_online_backup_datetime_field(ulonglong 
> backup_id, char *table_name,
> > +                                        
> enum_ob_table_field fld, my_time_t value)
> > +{
> > +  TABLE *table= NULL;                   // table to open
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  int ret= 0;                           // return value
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +
> > +  DBUG_ENTER("update_int_field()");
> > +
> > +  locking_thd= open_backup_progress_table(table_name, TL_WRITE);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  if (find_online_backup_row(table, backup_id))
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(1);
> > +  }
> > +
> > +  store_record(table, record[1]);
> > +
> > +  /*
> > +    Fill in the data.
> > +  */
> > +  if (value)
> > +  {
> > +    MYSQL_TIME time;
> > +    my_tz_OFFSET0->gmt_sec_to_TIME(&time, value);
> > +
> > +    table->field[fld]->set_notnull();
> > +    table->field[fld]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
> > +  }
> > +
> > +  /*
> > +    Update the row.
> > +  */
> > +  if ((ret= table->file->ha_update_row(table->record[1], 
> table->record[0])))
> > +    table->file->print_error(ret, MYF(0));
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   report_ob_init()
> > +
> > +   This method inserts a new row in the online_backup 
> table populating it
> > +   with the initial values passed. It returns the 
> backup_id of the new row.
> > +
> > +   @param int                process_id   The process id 
> of the operation 
> > +   @param enum_backup_state  state        The current 
> state of the operation
> > +   @param enum_backup_op     operation    The current 
> state of the operation
> > +   @param int                error_num    The error number
> > +   @param char *             user_comment The user's 
> comment specified in the
> > +                                          command (not 
> implemented yet)
> > +   @param char *             backup_file  The name of the 
> target file
> > +   @param char *             command      The actual 
> command entered
> > +
> > +   @returns long backup_id  The autoincrement value for 
> the new row.
> > +  */
> > +ulonglong report_ob_init(int process_id,
> > +                    enum_backup_state state,
> > +                    enum_backup_op operation,
> > +                    int error_num,
> > +                    char *user_comment,
> > +                    char *backup_file,
> > +                    char *command)
> > +{
> > +  ulonglong backup_id= 0;
> > +  int ret= 0;                                  // return value
> > +  TABLE *table= NULL;                          // table to open
> > +  TABLE_LIST tables;                           // List of 
> tables (1 in this case)
> > +  char *host= current_thd->security_ctx->host; // host name
> > +  char *user= current_thd->security_ctx->user; // user name
> > +  Locking_thread_st *locking_thd= NULL;        // The 
> locking thread
> > +
> > +  DBUG_ENTER("report_ob_init()");
> > +
> > +  locking_thd= open_backup_progress_table("online_backup", 
> TL_WRITE);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  THD *t= table->in_use;
> > +  table->in_use= current_thd;
> > +
> > +  /*
> > +    Get defaults for new record.
> > +  */
> > +  restore_record(table, s->default_values); 
> > +
> > +  /*
> > +    Fill in the data.
> > +  */
> > +  table->field[ET_FIELD_PROCESS_ID]->store(process_id, TRUE);
> > +  table->field[ET_FIELD_PROCESS_ID]->set_notnull();
> > +  table->field[ET_FIELD_BACKUP_STATE]->store(state, TRUE);
> > +  table->field[ET_FIELD_BACKUP_STATE]->set_notnull();
> > +  table->field[ET_FIELD_OPER]->store(operation, TRUE);
> > +  table->field[ET_FIELD_OPER]->set_notnull();
> > +  table->field[ET_FIELD_ERROR_NUM]->store(error_num, TRUE);
> > +  table->field[ET_FIELD_ERROR_NUM]->set_notnull();
> > +
> > +  if (host)
> > +  {
> > +    if(table->field[ET_FIELD_HOST_OR_SERVER]->store(host, 
> > +       strlen(host), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_HOST_OR_SERVER]->set_notnull();
> > +  }
> > +
> > +  if (user)
> > +  {
> > +    if (table->field[ET_FIELD_USERNAME]->store(user,
> > +        strlen(user), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_USERNAME]->set_notnull();
> > +  }
> > +
> > +  if (user_comment)
> > +  {
> > +    if (table->field[ET_FIELD_COMMENT]->store(user_comment,
> > +        strlen(user_comment), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_COMMENT]->set_notnull();
> > +  }
> > +
> > +  if (backup_file)
> > +  {
> > +    if (table->field[ET_FIELD_BACKUP_FILE]->store(backup_file, 
> > +        strlen(backup_file), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_BACKUP_FILE]->set_notnull();
> > +  }
> > +
> > +  if (command)
> > +  {
> > +    if (table->field[ET_FIELD_COMMAND]->store(command,
> > +        strlen(command), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_COMMAND]->set_notnull();
> > +  }
> > +  table->in_use= t;
> > +
> > +  table->next_number_field=table->found_next_number_field;
> > +
> > +  /*
> > +    Write the row.
> > +  */
> > +  if ((ret= table->file->ha_write_row(table->record[0])))
> > +    table->file->print_error(ret, MYF(0));
> > +
> > +  /*
> > +    Get last insert id for row.
> > +  */
> > +  backup_id= table->file->insert_id_for_cur_row;
> > +  table->file->ha_release_auto_increment();
> > +
> > +end:
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(backup_id);
> > +}
> > +
> > +/**
> > +   Update the binlog information for the row that matches 
> the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the binlog values.
> > +
> > +   @param ulonglong            backup_id    The id of the 
> row to locate.
> > +   @param int                  backup_pos   The id of the 
> row to locate.
> > +   @param char *               binlog_file  The filename 
> of the binlog.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_binlog_info(ulonglong backup_id,
> > +                          int binlog_pos,
> > +                          char *binlog_file)
> > +{
> > +  TABLE *table= NULL;                   // table to open
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  int ret= 0;                           // return value
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +
> > +  DBUG_ENTER("report_ob_binlog_info()");
> > +
> > +  locking_thd= open_backup_progress_table("online_backup", 
> TL_WRITE);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  if (find_online_backup_row(table, backup_id))
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(1);
> > +  }
> > +
> > +  store_record(table, record[1]);
> > +
> > +  /*
> > +    Fill in the data.
> > +  */
> > +  table->field[ET_FIELD_BINLOG_POS]->store(binlog_pos, TRUE);
> > +  table->field[ET_FIELD_BINLOG_POS]->set_notnull();
> > +
> > +  THD *t= table->in_use;
> > +  table->in_use= current_thd;
> > +
> > +  if (binlog_file)
> > +  {
> > +    if(table->field[ET_FIELD_BINLOG_FILE]->store(binlog_file, 
> > +       strlen(binlog_file), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_BINLOG_FILE]->set_notnull();
> > +  }
> > +  table->in_use= t;
> > +
> > +  /*
> > +    Update the row.
> > +  */
> > +  if ((ret= table->file->ha_update_row(table->record[1], 
> table->record[0])))
> > +    table->file->print_error(ret, MYF(0));
> > +
> > +end:
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the error number for the row that matches the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the error number value.
> > +
> > +   @param ulonglong  backup_id  The id of the row to locate.
> > +   @param int        error_num  New error number.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_error(ulonglong backup_id,
> > +                    int error_num)
> > +{
> > +  int ret= 0;  // return value
> > +
> > +  DBUG_ENTER("report_ob_error()");
> > +  update_online_backup_int_field(backup_id, "online_backup", 
> > +                                 ET_FIELD_ERROR_NUM, error_num);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the number of objects for the row that matches 
> the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the number of objects value.
> > +
> > +   @param ulonglong  backup_id   The id of the row to locate.
> > +   @param int        num_objects  New error number.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_num_objects(ulonglong backup_id,
> > +                          int num_objects)
> > +{
> > +  int ret= 0;  // return value
> > +
> > +  DBUG_ENTER("report_ob_num_objects()");
> > +  update_online_backup_int_field(backup_id, "online_backup",
> > +                                 ET_FIELD_NUM_OBJ, num_objects);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the size for the row that matches the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the size value.
> > +
> > +   @param ulonglong  backup_id  The id of the row to locate.
> > +   @param int        size       New size value.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_size(ulonglong backup_id,
> > +                   longlong size)
> > +{
> > +  int ret= 0;  // return value
> > +
> > +  DBUG_ENTER("report_ob_size()");
> > +  update_online_backup_int_field(backup_id, "online_backup",
> > +                                 ET_FIELD_TOTAL_BYTES, size);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the start/stop time for the row that matches the 
> backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the start/stop values.
> > +
> > +   @param ulonglong  backup_id  The id of the row to locate.
> > +   @param my_time_t  start      Start datetime.
> > +   @param my_time_t  stop       Stop datetime.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_time(ulonglong backup_id,
> > +                   my_time_t start,
> > +                   my_time_t stop)
> > +{
> > +  int ret= 0;  // return value
> > +
> > +  DBUG_ENTER("report_ob_time()");
> > +  if (start)
> > +    update_online_backup_datetime_field(backup_id, "online_backup",
> > +                                        
> ET_FIELD_START_TIME, start);
> > +  if (stop)
> > +    update_online_backup_datetime_field(backup_id, "online_backup",
> > +                                        ET_FIELD_STOP_TIME, stop);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the validity point time for the row that matches 
> the backup_id.
> > +
> > +   This method updates the validity point time for the 
> backup operation
> > +   identified by backup_id.
> > +
> > +   @param ulonglong  backup_id  The id of the row to locate.
> > +   @param my_time_t  vp_time    Validity point datetime.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_vp_time(ulonglong backup_id,
> > +                      my_time_t vp_time)
> > +{
> > +  int ret= 0;  // return value
> > +
> > +  DBUG_ENTER("report_ob_vp_time()");
> > +  if (vp_time)
> > +    update_online_backup_datetime_field(backup_id, "online_backup",
> > +                                        ET_FIELD_VP, vp_time);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the engines string for the row that matches the 
> backup_id.
> > +
> > +   This method updates the engines information for the 
> backup operation
> > +   identified by backup_id. This method appends to the 
> those listed in the
> > +   table for the backup_id.
> > +
> > +   @param ulonglong  backup_id    The id of the row to locate.
> > +   @param char *     egnine_name  The name of the engine to add.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_engines(ulonglong backup_id,
> > +                      const char *engine_name)
> > +{
> > +  TABLE *table= NULL;                   // table to open
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  int ret= 0;                           // return value
> > +  String str;                           // engines string
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +
> > +  DBUG_ENTER("report_ob_engines()");
> > +
> > +  locking_thd= open_backup_progress_table("online_backup", 
> TL_WRITE);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  if (find_online_backup_row(table, backup_id))
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(1);
> > +  }
> > +
> > +  store_record(table, record[1]);
> > +
> > +  /*
> > +    Fill in the data.
> > +  */
> > +  THD *t= table->in_use;
> > +  table->in_use= current_thd;
> > +
> > +  str.length(0);
> > +  table->field[ET_FIELD_ENGINES]->val_str(&str);
> > +  if (str.length() > 0)
> > +    str.append(", ");
> > +  str.append(engine_name);
> > +  if (str.length() > 0)
> > +  {
> > +    if(table->field[ET_FIELD_ENGINES]->store(str.c_ptr(), 
> > +       str.length(), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_ENGINES]->set_notnull();
> > +  }
> > +  table->in_use= t;
> > +
> > +  /*
> > +    Update the row.
> > +  */
> > +  if ((ret= table->file->ha_update_row(table->record[1], 
> table->record[0])))
> > +    table->file->print_error(ret, MYF(0));
> > +
> > +end:
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Update the state for the row that matches the backup_id.
> > +
> > +   This method locates the row in the online backup table 
> that matches the
> > +   backup_id passed and updates the state value.
> > +
> > +   @param ulonglong          backup_id  The id of the row 
> to locate.
> > +   @param enum_backup_state  state      New state value.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int report_ob_state(ulonglong backup_id,
> > +                    enum_backup_state state)
> > +{
> > +  int ret= 0;  // return value
> > +
> > +  DBUG_ENTER("report_ob_state()");
> > +  update_online_backup_int_field(backup_id, "online_backup", 
> > +                                 ET_FIELD_BACKUP_STATE, state);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Creates a new progress row for the row that matches the 
> backup_id.
> > +
> > +   This method inserts a new row in the online backup 
> progress table using
> > +   the values passed. This method is used to insert 
> progress information during
> > +   the backup operation.
> > +
> > +   @param ulonglong  backup_id  The id of the master table row.
> > +   @param char *     object     The name of the object processed.
> > +   @param my_time_t  start      Start datetime.
> > +   @param my_time_t  stop       Stop datetime.
> > +   @param longlong   size       Size value.
> > +   @param longlong   progress   Progress (percent).
> > +   @param int        error_num  Error number (should be 0 
> is success).
> > +   @param char *     notes      Misc data from engine
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to write row
> > +  */
> > +int report_ob_progress(ulonglong backup_id,
> > +                       char *object,
> > +                       my_time_t start,
> > +                       my_time_t stop,
> > +                       longlong size,
> > +                       longlong progress,
> > +                       int error_num,
> > +                       char *notes)
> > +{
> > +  int ret= 0;                           // return value
> > +  TABLE *table= NULL;                   // table to open
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +
> > +  DBUG_ENTER("report_ob_progress()");
> > +
> > +  locking_thd= 
> open_backup_progress_table("online_backup_progress", TL_WRITE);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  THD *t= table->in_use;
> > +  table->in_use= current_thd;
> > +
> > +  /*
> > +    Get defaults for new record.
> > +  */
> > +  restore_record(table, s->default_values); 
> > +
> > +  /*
> > +    Fill in the data.
> > +  */
> > +  table->field[ET_FIELD_BACKUP_ID_FK]->store(backup_id, TRUE);
> > +  table->field[ET_FIELD_BACKUP_ID_FK]->set_notnull();
> > +
> > +  if (object)
> > +  {
> > +    if (table->field[ET_FIELD_PROG_OBJECT]->store(object,
> > +        strlen(object), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_PROG_OBJECT]->set_notnull();
> > +  }
> > +
> > +  if (notes)
> > +  {
> > +    if (table->field[ET_FIELD_PROG_NOTES]->store(notes,
> > +        strlen(notes), system_charset_info))
> > +      goto end;
> > +    table->field[ET_FIELD_PROG_NOTES]->set_notnull();
> > +  }
> > +  table->in_use= t;
> > +
> > +  if (start)
> > +  {
> > +    MYSQL_TIME time;
> > +    my_tz_OFFSET0->gmt_sec_to_TIME(&time, start);
> > +
> > +    table->field[ET_FIELD_PROG_START_TIME]->set_notnull();
> > +    
> table->field[ET_FIELD_PROG_START_TIME]->store_time(&time, 
> MYSQL_TIMESTAMP_DATETIME);
> > +  }
> > +
> > +  if (stop)
> > +  {
> > +    MYSQL_TIME time;
> > +    my_tz_OFFSET0->gmt_sec_to_TIME(&time, stop);
> > +
> > +    table->field[ET_FIELD_PROG_STOP_TIME]->set_notnull();
> > +    
> table->field[ET_FIELD_PROG_STOP_TIME]->store_time(&time, 
> MYSQL_TIMESTAMP_DATETIME);
> > +  }
> > +
> > +  table->field[ET_FIELD_PROG_SIZE]->store(size, TRUE);
> > +  table->field[ET_FIELD_PROG_SIZE]->set_notnull();
> > +  table->field[ET_FIELD_PROGRESS]->store(progress, TRUE);
> > +  table->field[ET_FIELD_PROGRESS]->set_notnull();
> > +  table->field[ET_FIELD_PROG_ERROR_NUM]->store(error_num, TRUE);
> > +  table->field[ET_FIELD_PROG_ERROR_NUM]->set_notnull();
> > +
> > +  /*
> > +    Write the row.
> > +  */
> > +  if ((ret= table->file->ha_write_row(table->record[0])))
> > +    table->file->print_error(ret, MYF(0));
> > +
> > +end:
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > +/**
> > +   Sums the sizes for the row that matches the backup_id.
> > +
> > +   This method sums the size entries from the online 
> backup progress rows
> > +   for the backup operation identified by backup_id.
> > +
> > +   @param ulonglong          backup_id  The id of the row 
> to locate.
> > +
> > +   @returns  ulonglong  Total size of all backup progress rows
> > +  */
> > +ulonglong sum_progress_rows(ulonglong backup_id)
> > +{
> > +  int last_read_res;                    // result of last read
> > +  TABLE *table= NULL;                   // table to open
> > +  TABLE_LIST tables;                    // List of tables 
> (1 in this case)
> > +  ulonglong size= 0;                    // total size
> > +  handler *hdl;                         // handler pointer
> > +  Locking_thread_st *locking_thd= NULL; // The locking thread
> > +
> > +  DBUG_ENTER("sum_progress_rows()");
> > +
> > +  locking_thd= 
> open_backup_progress_table("online_backup_progress", TL_READ);
> > +  if (!locking_thd)
> > +  {
> > +    locking_thd->kill_locking_thread();
> > +    DBUG_RETURN(0);
> > +  }
> > +
> > +  table= locking_thd->tables_in_backup->table;
> > +  table->use_all_columns();
> > +
> > +  hdl= table->file;
> > +  last_read_res= hdl->ha_rnd_init(1);
> > +  THD *t= table->in_use;
> > +  table->in_use= current_thd;
> > +  while (!hdl->rnd_next(table->record[0]))
> > +    if ((table->field[ET_FIELD_PROGRESS]->val_int() == 100) &&
> > +        (table->field[ET_FIELD_PROG_ERROR_NUM]->val_int() == 0)
> &&
> > +        (table->field[ET_FIELD_BACKUP_ID_FK]->val_int() == 
> backup_id))
> > +      size+= table->field[ET_FIELD_PROG_SIZE]->val_int();
> > +  table->in_use= t;
> > +
> > +  hdl->ha_rnd_end();
> > +
> > +  locking_thd->kill_locking_thread();
> > +  DBUG_RETURN(size);
> > +}
> > +
> > +/**
> > +   Print summary for the row that matches the backup_id.
> > +
> > +   This method prints the summary information for the 
> backup operation
> > +   identified by backup_id.
> > +
> > +   @param ulonglong  backup_id  The id of the row to locate.
> > +
> > +   @returns 0 = success
> > +   @returns 1 = failed to find row
> > +  */
> > +int print_backup_summary(THD *thd, ulonglong backup_id)
> > +{
> > +  Protocol *protocol= thd->protocol;    // client comms
> > +  List<Item> field_list;                // list of fields to send
> > +  String     op_str;                    // operations string
> > +  int ret= 0;                           // return value
> > +  char buf[255];                        // buffer for 
> summary information
> > +  String str;
> > +
> > +  DBUG_ENTER("print_backup_summary()");
> > +
> > +  /*
> > +    Send field list.
> > +  */
> > +  op_str.length(0);
> > +  op_str.append("backup_id");
> > +  field_list.push_back(new 
> Item_empty_string(op_str.c_ptr(), op_str.length()));
> > +  protocol->send_fields(&field_list, 
> Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
> > +
> > +  /*
> > +    Send field data.
> > +  */
> > +  protocol->prepare_for_resend();
> > +  my_snprintf(buf, sizeof(buf), "%d", backup_id);
> > +  protocol->store(buf, system_charset_info);
> > +  protocol->write();
> > +
> > +  send_eof(thd);
> > +  DBUG_RETURN(ret);
> > +}
> > +
> > diff -Nrup a/sql/backup/backup_progress.h 
> b/sql/backup/backup_progress.h
> > --- /dev/null	Wed Dec 31 16:00:00 196900
> > +++ b/sql/backup/backup_progress.h	2007-11-28 23:31:24 -05:00
> > @@ -0,0 +1,195 @@
> > +#ifndef _BACKUP_PROGRESS_H
> > +#define _BACKUP_PROGRESS_H
> > +
> > +/* Copyright (C) 2004-2007 MySQL AB
> > +
> > +   This program is free software; you can redistribute it 
> and/or modify
> > +   it under the terms of the GNU General Public License as 
> published by
> > +   the Free Software Foundation; version 2 of the License.
> > +
> > +   This program is distributed in the hope that it will be useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > +   GNU General Public License for more details.
> > +
> > +   You should have received a copy of the GNU General 
> Public License
> > +   along with this program; if not, write to the Free Software
> > +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
> MA  02111-1307  USA */
> > +
> > +/**
> > +   @file backup_progress.h
> > +
> > +   Data Dictionary related operations of Online Backup.
> > +*/
> > +
> > +#include "my_global.h"
> > +#include "my_time.h"
> > +#include "mysql_priv.h"
> > +
> > +/**
> > +   List of fields for online backup table.
> > +  */
> > +enum enum_ob_table_field
> > +{
> > +  ET_FIELD_BACKUP_ID = 0, /* start from 0 to correspond 
> with field array */
> > +  ET_FIELD_PROCESS_ID,
> > +  ET_FIELD_BINLOG_POS,
> > +  ET_FIELD_BINLOG_FILE,
> > +  ET_FIELD_BACKUP_STATE,
> > +  ET_FIELD_OPER,
> > +  ET_FIELD_ERROR_NUM,
> > +  ET_FIELD_NUM_OBJ,
> > +  ET_FIELD_TOTAL_BYTES,
> > +  ET_FIELD_VP,
> > +  ET_FIELD_START_TIME,
> > +  ET_FIELD_STOP_TIME,
> > +  ET_FIELD_HOST_OR_SERVER,
> > +  ET_FIELD_USERNAME,
> > +  ET_FIELD_BACKUP_FILE,
> > +  ET_FIELD_COMMENT,
> > +  ET_FIELD_COMMAND,
> > +  ET_FIELD_ENGINES,
> > +  ET_FIELD_COUNT /* a cool trick to count the number of 
> fields :) */
> > +};
> > +
> > +/**
> > +   List of fields for online backup progress table.
> > +  */
> > +enum enum_ob_progress_table_field
> > +{
> > +  ET_FIELD_BACKUP_ID_FK = 0, /* start from 0 to correspond 
> with field array */
> > +  ET_FIELD_PROG_OBJECT,
> > +  ET_FIELD_PROG_START_TIME,
> > +  ET_FIELD_PROG_STOP_TIME,
> > +  ET_FIELD_PROG_SIZE,
> > +  ET_FIELD_PROGRESS,
> > +  ET_FIELD_PROG_ERROR_NUM,
> > +  ET_FIELD_PROG_NOTES,
> > +  ET_FIELD_PROG_COUNT /* a cool trick to count the number 
> of fields :) */
> > +};
> > +
> > +/**
> > +   List of states for online backup table.
> > +  */
> > +enum enum_backup_state
> > +{
> > +  BUP_COMPLETE = 1,
> > +  BUP_STARTING,
> > +  BUP_VALIDITY_POINT,
> > +  BUP_RUNNING,
> > +  BUP_ERRORS,
> > +  BUP_CANCEL
> > +};
> > +
> > +/**
> > +   List of operations for online backup table.
> > +  */
> > +enum enum_backup_op
> > +{
> > +  OP_BACKUP = 1,
> > +  OP_RESTORE,
> > +  OP_SHOW,
> > +  OP_OTHER
> > +};
> > +
> > +/*
> > +  This method inserts a new row in the online_backup table 
> populating it with
> > +  the initial values passed. It returns the backup_id of 
> the new row.
> > +*/
> > +ulonglong report_ob_init(int process_id,
> > +                    enum_backup_state state,
> > +                    enum_backup_op operation,
> > +                    int error_num,
> > +                    char *user_comment,
> > +                    char *backup_file,
> > +                    char *command);
> > +
> > +/*
> > +  This method updates the binary log information for the 
> backup operation
> > +  identified by backup_id.
> > +*/
> > +int report_ob_binlog_info(ulonglong backup_id,
> > +                          int binlog_pos,
> > +                          char *binlog_file);
> > +
> > +/*
> > +  This method updates the error number for the backup 
> operation identified by
> > +  backup_id.
> > +*/
> > +int report_ob_error(ulonglong backup_id,
> > +                    int error_num);
> > +
> > +/*
> > +  This method updates the state for the backup operation 
> identified by
> > +  backup_id.
> > +*/
> > +int report_ob_state(ulonglong backup_id,
> > +                    enum_backup_state state);
> > +
> > +/*
> > +  This method updates the number of objects for the backup 
> operation identified by
> > +  backup_id.
> > +*/
> > +int report_ob_num_objects(ulonglong backup_id,
> > +                          int num_objects);
> > +
> > +/*
> > +  This method updates the size for the backup operation 
> identified by
> > +  backup_id.
> > +*/
> > +int report_ob_size(ulonglong backup_id,
> > +                   longlong size);
> > +
> > +/*
> > +  This method updates the start/stop time for the backup 
> operation identified by
> > +  backup_id.
> > +
> > +  Note: This method ignores values for start or stop that 
> are NULL (only saves 
> > +  values provided so that it can be called once for start 
> and once again later 
> > +  for stop).
> > +*/
> > +int report_ob_time(ulonglong backup_id,
> > +                   my_time_t start,
> > +                   my_time_t stop);
> > +
> > +/*
> > +  This method updates the validity point time for the 
> backup operation
> > +  identified by backup_id.
> > +*/
> > +int report_ob_vp_time(ulonglong backup_id,
> > +                      my_time_t vp_time);
> > +
> > +/*
> > +  This method updates the engines information for the 
> backup operation
> > +  identified by backup_id. This method appends to the 
> those listed in the
> > +  table for the backup_id.
> > +*/
> > +int report_ob_engines(ulonglong backup_id,
> > +                      const char *engine_name);
> > +
> > +/*
> > +  This method inserts a new row in the progress table.
> > +*/
> > +int report_ob_progress(ulonglong backup_id,
> > +                       char *object,
> > +                       my_time_t start,
> > +                       my_time_t stop,
> > +                       longlong size,
> > +                       longlong progress,
> > +                       int error_num,
> > +                       char *notes);
> > +
> > +/*
> > +  This method sums the size entries from the online backup 
> progress rows
> > +  for the backup operation identified by backup_id.
> > +*/
> > +ulonglong sum_progress_rows(ulonglong backup_id);
> > +
> > +/*
> > +  This method prints the summary information for the 
> backup operation
> > +  identified by backup_id.
> > +*/
> > +int print_backup_summary(THD *thd, ulonglong backup_id);
> > +
> > +#endif
> > +
> > diff -Nrup a/sql/backup/data_backup.cc b/sql/backup/data_backup.cc
> > --- a/sql/backup/data_backup.cc	2007-11-20 09:14:23 -05:00
> > +++ b/sql/backup/data_backup.cc	2007-11-28 23:31:22 -05:00
> > @@ -1,4 +1,5 @@
> >  #include "../mysql_priv.h"
> > +#include "backup_progress.h"
> >  
> >  /**
> >    @file
> > @@ -185,6 +186,19 @@ class Backup_pump
> >    void set_logger(Logger *log)
> >    { m_log= log; }
> >  
> > +  /*
> > +    Record the backup id for this driver.
> > +  */
> > +  void set_backup_prog_id(ulonglong backup_prog_id)
> > +  { m_drv->backup_prog_id= backup_prog_id; };
> > +
> > +  /*
> > +    Record the engine name this driver.
> > +    Note: must be called after set_backup_prog_id.
> > +  */
> > +  void set_backup_prog_engine_name(const char *engine_name)
> > +  { report_ob_engines(m_drv->backup_prog_id, engine_name); };
> 
> I'd not add progress reporting to the responsibilities of the 
> Pump class - it is 
> perfectly ok to report these things outside. Adding weakly 
> related tasks to a 
> class weakens modularity of the code...
> 
> > +
> >   private:
> >  
> >    static const uint m_buf_size= 2048; ///< Size of buffers 
> used for data transfers.
> > @@ -513,6 +527,12 @@ int write_table_data(THD* thd, Backup_in
> >        continue;
> >  
> >      Scheduler::Pump *p= new Scheduler::Pump(no,*i,s);
> > +    
> > +    /*
> > +      Record the backup id and name for this driver.
> > +    */
> > +    p->set_backup_prog_id(info.backup_prog_id);
> > +    p->set_backup_prog_engine_name(p->m_name);
> 
> It seems pointless to pass objects member value to this 
> objects method - if 
> method needs this value it can read it directly.
> 
> I opt for calling report_ob_engines() and such outside of the 
> Pump object.
> 
> >  
> >      if (!p || !p->is_valid())
> >      {
> > @@ -625,6 +645,7 @@ int write_table_data(THD* thd, Backup_in
> >      // VP creation
> >      DBUG_PRINT("backup/data",("-- SYNC PHASE --"));
> >  
> > +    report_ob_state(info.backup_prog_id, BUP_VALIDITY_POINT);
> 
> PROBLEM:
> I think it is not acceptable to have such complex thing 
> happen here between 
> lock()/unlock() calls. Complex because inside 
> report_ob_state() function we 
> spawn the locking thread, open progress table and potentially 
> write to disk.
> 
> >      /*
> >        Block commits.
> >  
> > @@ -651,6 +672,8 @@ int write_table_data(THD* thd, Backup_in
> >        info.binlog_information.position= li.pos;
> >        memcpy(info.binlog_information.binlog_file_name, 
> >               li.log_file_name, strlen(li.log_file_name));
> > +      if (strlen(li.log_file_name) > 0)
> > +        
> info.binlog_information.binlog_file_name[strlen(li.log_file_name)]= 0;
> >        DBUG_PRINT("SYNC PHASE - binlog position : ", ("%d", 
> li.pos));
> >        DBUG_PRINT("SYNC PHASE - binlog filename : ", ("%s", 
> li.log_file_name));
> >      }
> > @@ -674,6 +697,15 @@ int write_table_data(THD* thd, Backup_in
> >      if (error)
> >        goto error;
> >  
> > +    BACKUP_BREAKPOINT("bp_validity_point");
> > +    report_ob_vp_time(info.backup_prog_id, (my_time_t)skr);
> > +    report_ob_state(info.backup_prog_id, BUP_RUNNING);
> > +    BACKUP_BREAKPOINT("bp_running");
> > +
> 
> I think this is executed after VP has been created (after 
> unlock() calls) which 
> is correct. But then the "bp_validity_point" breakpoint seems 
> missplaced - it is 
>   already past the validity point.
> 
> > +    if (mysql_bin_log.is_open())
> > +      report_ob_binlog_info(info.backup_prog_id, 
> (int)info.binlog_information.position,
> > +                            
> info.binlog_information.binlog_file_name);
> > +
> 
> Minor thing: instead of examining mysql_bin_log again (it was 
> already done above 
> when binlog pos was saved in the info structure) examine the 
> info structure to 
> know if there is anything to report.
> 
> >      // get final data from drivers
> >      DBUG_PRINT("backup/data",("-- FINISH PHASE --"));
> >      BACKUP_BREAKPOINT("data_finish");
> > @@ -1431,6 +1463,12 @@ int restore_table_data(THD*, Restore_inf
> >          (img->type() == Image_info::SNAPSHOT_IMAGE))
> >        get_default_snapshot_tables(NULL, 
> (default_backup::Restore *)drv[no], 
> >                                    &table_list, &table_list_last);
> > +
> > +    /*
> > +      Record the backup id and name for this driver.
> > +    */
> > +    drv[no]->backup_prog_id= info.backup_prog_id;
> > +    report_ob_engines(info.backup_prog_id, img->name());
> >    }
> >  
> >    {
> > diff -Nrup a/sql/backup/sql_backup.cc b/sql/backup/sql_backup.cc
> > --- a/sql/backup/sql_backup.cc	2007-11-23 10:07:24 -05:00
> > +++ b/sql/backup/sql_backup.cc	2007-11-28 23:31:23 -05:00
> > @@ -31,6 +31,7 @@
> >  #include "be_default.h"
> >  #include "be_snapshot.h"
> >  #include "ddl_blocker.h"
> > +#include "backup_progress.h"
> >  
> >  namespace backup {
> >  
> > @@ -75,6 +76,7 @@ extern pthread_cond_t COND_DDL_blocker;
> >  int
> >  execute_backup_command(THD *thd, LEX *lex)
> >  {
> > +  ulonglong backup_prog_id= 0;
> >    time_t skr;
> >  
> >    DBUG_ENTER("execute_backup_command");
> > @@ -114,9 +116,21 @@ execute_backup_command(THD *thd, LEX *le
> >      {
> >        backup::Restore_info info(*stream);
> >  
> > +      info.backup_prog_id= report_ob_init(thd->id, 
> BUP_STARTING, OP_RESTORE, 
> > +                                          0, "",
> > +                                          
> lex->backup_dir.str, thd->query);
> > +      backup_prog_id= info.backup_prog_id;
> > +      BACKUP_BREAKPOINT("bp_starting");
> > +
> >        if (check_info(thd,info))
> >          goto restore_error;
> >  
> > +      /*
> > +        Save starting datetime of restore for progress.
> > +      */
> > +      skr= my_time(0);
> > +      report_ob_time(info.backup_prog_id, (my_time_t)skr, NULL);
> > +
> >        if (lex->sql_command == SQLCOM_SHOW_ARCHIVE)
> >        {
> >          my_error(ER_NOT_ALLOWED_COMMAND,MYF(0));
> > @@ -131,6 +145,9 @@ execute_backup_command(THD *thd, LEX *le
> >        {
> >          
> info.report_error(backup::log_level::INFO,ER_BACKUP_RESTORE_START);
> >  
> > +        report_ob_state(info.backup_prog_id, BUP_RUNNING);
> > +        BACKUP_BREAKPOINT("bp_running");
> > +
> >          /*
> >            Freeze all DDL operations by turning on DDL blocker.
> >          */
> > @@ -150,12 +167,22 @@ execute_backup_command(THD *thd, LEX *le
> >            report_errors(thd,info,ER_BACKUP_RESTORE);
> >            goto restore_error;
> >          }
> > -        else
> > -        {
> > -          
> info.report_error(backup::log_level::INFO,ER_BACKUP_RESTORE_DONE);
> > -          info.total_size += info.header_size;
> > -          send_summary(thd,info);
> > -        }
> > +
> > +        report_ob_num_objects(info.backup_prog_id, 
> info.table_count);
> > +        report_ob_size(info.backup_prog_id, info.data_size);
> > +
> > +        /*
> > +          Save ending datetime of restore for progress.
> > +        */
> > +        skr= my_time(0);
> > +        report_ob_time(info.backup_prog_id, NULL, (my_time_t)skr);
> > +        report_ob_state(info.backup_prog_id, BUP_COMPLETE);
> > +        BACKUP_BREAKPOINT("bp_complete");
> > +
> > +        
> info.report_error(backup::log_level::INFO,ER_BACKUP_RESTORE_DONE);
> > +        info.total_size += info.header_size;
> > +        report_ob_size(info.backup_prog_id, info.total_size);
> > +        send_summary(thd,info);
> >  
> >          /*
> >            Unfreeze all DDL operations by turning off DDL blocker.
> > @@ -177,6 +204,11 @@ execute_backup_command(THD *thd, LEX *le
> >      BACKUP_BREAKPOINT("DDL_unblocked");
> >  
> >      res= res ? res : backup::ERROR;
> > +    report_ob_error(backup_prog_id, res);
> > +    report_ob_state(backup_prog_id, BUP_ERRORS);
> > +    skr= my_time(0);
> > +    report_ob_time(backup_prog_id, NULL, (my_time_t)skr);
> > +    BACKUP_BREAKPOINT("bp_error");
> >      
> >     finish_restore:
> >  
> > @@ -210,9 +242,18 @@ execute_backup_command(THD *thd, LEX *le
> >  
> >        backup::Backup_info info(thd);
> >  
> > +      info.backup_prog_id= report_ob_init(thd->id, 
> BUP_STARTING, OP_BACKUP,
> > +                                          0, "",
> > +                                          
> lex->backup_dir.str, thd->query);
> > +      backup_prog_id= info.backup_prog_id;
> > +      BACKUP_BREAKPOINT("bp_starting");
> > +
> >        if (check_info(thd,info))
> >          goto backup_error;
> >  
> > +      report_ob_state(info.backup_prog_id, BUP_RUNNING);
> > +      BACKUP_BREAKPOINT("bp_running");
> > +
> >        
> info.report_error(backup::log_level::INFO,ER_BACKUP_BACKUP_START);
> >  
> >        /*
> > @@ -221,6 +262,8 @@ execute_backup_command(THD *thd, LEX *le
> >        skr= my_time(0);
> >        gmtime_r(&skr, &info.start_time);
> >  
> > +      report_ob_time(info.backup_prog_id, (my_time_t)skr, NULL);
> > +
> >        info.save_errors();
> >  
> >        if (lex->db_list.is_empty())
> > @@ -234,6 +277,8 @@ execute_backup_command(THD *thd, LEX *le
> >          info.add_dbs(lex->db_list); // backup databases 
> specified by user
> >        }
> >  
> > +      report_ob_num_objects(info.backup_prog_id, info.table_count);
> > +
> >        if (check_info(thd,info))
> >          goto backup_error;
> >  
> > @@ -249,11 +294,8 @@ execute_backup_command(THD *thd, LEX *le
> >          report_errors(thd,info,ER_BACKUP_BACKUP);
> >          goto backup_error;
> >        }
> > -      else
> > -      {
> > -        
> info.report_error(backup::log_level::INFO,ER_BACKUP_BACKUP_DONE);
> > -        send_summary(thd,info);
> > -      }
> > +
> > +      report_ob_size(info.backup_prog_id, info.data_size);
> >  
> >        /*
> >          Save ending datetime of backup.
> > @@ -261,6 +303,14 @@ execute_backup_command(THD *thd, LEX *le
> >        skr= my_time(0);
> >        gmtime_r(&skr, &info.end_time);
> >  
> > +      report_ob_time(info.backup_prog_id, NULL, (my_time_t)skr);
> > +      report_ob_state(info.backup_prog_id, BUP_COMPLETE);
> > +      BACKUP_BREAKPOINT("bp_complete");
> > +
> > +      
> info.report_error(backup::log_level::INFO,ER_BACKUP_BACKUP_DONE);
> > +      report_ob_size(info.backup_prog_id, info.total_size);
> > +      send_summary(thd,info);
> > +
> >        /*
> >          Unfreeze all DDL operations by turning off DDL blocker.
> >        */
> > @@ -278,7 +328,12 @@ execute_backup_command(THD *thd, LEX *le
> >      */
> >      unblock_DDL();
> >      res= res ? res : backup::ERROR;
> > -   
> > +    report_ob_error(backup_prog_id, res);
> > +    report_ob_state(backup_prog_id, BUP_ERRORS);
> > +    skr= my_time(0);
> > +    report_ob_time(backup_prog_id, NULL, (my_time_t)skr);
> > +    BACKUP_BREAKPOINT("bp_error");
> > +
> >     finish_backup:
> >  
> >      if (stream)
> > @@ -1319,54 +1374,8 @@ int check_info(THD *thd, Restore_info &i
> >  static
> >  bool send_summary(THD *thd, const Archive_info &info, bool backup)
> >  {
> > -  Protocol   *protocol= ::current_thd->protocol; // client comms
> > -  List<Item> field_list;                         // list 
> of fields to send
> > -  Item       *item;                              // field item
> > -  char       buf[255];                           // buffer for data
> > -  String     op_str;                             // 
> operations string
> > -  String     print_str;                          // string to print
> > -
> >    DBUG_ENTER("backup::send_summary");
> > -
> > -  DBUG_PRINT(backup?"backup":"restore", ("sending summary"));
> > -
> > -  op_str.length(0);
> > -  if (backup)
> > -    op_str.append("Backup Summary");
> > -  else
> > -    op_str.append("Restore Summary");
> > -
> > -
> > -  field_list.push_back(item= new 
> Item_empty_string(op_str.c_ptr(),255)); // TODO: use varchar field
> > -  item->maybe_null= TRUE;
> > -  protocol->send_fields(&field_list, 
> Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
> > -
> > -  my_snprintf(buf,sizeof(buf)," header     = %-8lu 
> bytes",(unsigned long)info.header_size);
> > -  protocol->prepare_for_resend();
> > -  protocol->store(buf,system_charset_info);
> > -  protocol->write();
> > -
> > -  my_snprintf(buf,sizeof(buf)," meta-data  = %-8lu 
> bytes",(unsigned long)info.meta_size);
> > -  protocol->prepare_for_resend();
> > -  protocol->store(buf,system_charset_info);
> > -  protocol->write();
> > -
> > -  my_snprintf(buf,sizeof(buf)," data       = %-8lu 
> bytes",(unsigned long)info.data_size);
> > -  protocol->prepare_for_resend();
> > -  protocol->store(buf,system_charset_info);
> > -  protocol->write();
> > -
> > -  my_snprintf(buf,sizeof(buf),"              --------------");
> > -  protocol->prepare_for_resend();
> > -  protocol->store(buf,system_charset_info);
> > -  protocol->write();
> > -
> > -  my_snprintf(buf,sizeof(buf)," total        %-8lu bytes", 
> (unsigned long)info.total_size);
> > -  protocol->prepare_for_resend();
> > -  protocol->store(buf,system_charset_info);
> > -  protocol->write();
> > -
> > -  send_eof(thd);
> > +  print_backup_summary(thd, info.backup_prog_id);
> >    DBUG_RETURN(0);
> >  }
> >  
> 
> Rafal
> 

Thread
bk commit into 6.0 tree (cbell:1.2691) WL#4116cbell29 Nov
  • Re: bk commit into 6.0 tree (cbell:1.2691) WL#4116Rafal Somla29 Nov
    • RE: bk commit into 6.0 tree (cbell:1.2691) WL#4116Chuck Bell29 Nov
      • Re: bk commit into 6.0 tree (cbell:1.2691) WL#4116Rafal Somla29 Nov
    • RE: bk commit into 6.0 tree (cbell:1.2691) WL#4116Chuck Bell29 Nov