~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to sql/backup/kernel.cc

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/**
2
2
  @file
3
3
 
4
 
  Implementation of the backup kernel API.
5
 
 
6
 
  @todo Do not overwrite existing backup locations.
7
 
  @todo Add more error messages.
 
4
  @brief Implementation of the backup kernel API.
 
5
 
 
6
  @section s1 How to use backup kernel API to perform backup and restore operations
 
7
  
 
8
  To perform backup or restore operation an appropriate context must be created.
 
9
  This involves creating required resources and correctly setting up the server.
 
10
  When operation is completed or interrupted, the context must be destroyed and
 
11
  all preparations reversed.
 
12
  
 
13
  All this is accomplished by creating an instance of Backup_create_ctx class and
 
14
  then using its methods to perform the operation. When the instance is 
 
15
  destroyed, the required clean-up is performed.
 
16
  
 
17
  This is how backup is performed using the context object:
 
18
  @code
 
19
  {
 
20
  
 
21
   Backup_restore_ctx context(thd); // create context instance
 
22
   Backup_info *info= context.prepare_for_backup(location); // prepare for backup
 
23
  
 
24
   // select objects to backup
 
25
   info->add_all_dbs();
 
26
   or
 
27
   info->add_dbs(<list of db names>);
 
28
  
 
29
   info->close(); // indicate that selection is done
 
30
  
 
31
   context.do_backup(); // perform backup
 
32
   
 
33
   context.close(); // explicit clean-up
 
34
  
 
35
  } // if code jumps here, context destructor will do the clean-up automatically
 
36
  @endcode
 
37
  
 
38
  Similar code will be used for restore (bit simpler as we don't support 
 
39
  selective restores yet):
 
40
  @code
 
41
  {
 
42
  
 
43
   Backup_restore_ctx context(thd); // create context instance
 
44
   Restore_info *info= context.prepare_for_restore(location); // prepare for restore
 
45
  
 
46
   context.do_restore(); // perform restore
 
47
   
 
48
   context.close(); // explicit clean-up
 
49
  
 
50
  } // if code jumps here, context destructor will do the clean-up automatically
 
51
  @endcode
 
52
 
8
53
  @todo Use internal table name representation when passing tables to
9
54
        backup/restore drivers.
10
 
  @todo Implement meta-data freeze during backup/restore.
11
55
  @todo Handle other types of meta-data in Backup_info methods.
12
56
  @todo Handle item dependencies when adding new items.
13
 
  @todo Lock I_S tables when reading table list and similar (is it needed?)
14
 
  @todo When reading table list from I_S tables, use select conditions to
15
 
        limit amount of data read. (check prepare_select_* functions in sql_help.cc)
16
57
  @todo Handle other kinds of backup locations (far future).
17
 
 */
 
58
 
 
59
  @note This comment was added to show Jorgen and Oystein how to push patches 
 
60
  into the team tree - please remove it if you see it. Second version of the 
 
61
  patch, to show how to collapse/re-edit csets.
 
62
*/
18
63
 
19
64
#include "../mysql_priv.h"
 
65
#include "../si_objects.h"
20
66
 
21
 
#include "backup_aux.h"
 
67
#include "backup_kernel.h"
 
68
#include "backup_info.h"
 
69
#include "restore_info.h"
 
70
#include "logger.h"
22
71
#include "stream.h"
23
 
#include "backup_kernel.h"
24
 
#include "catalog.h" 
25
 
#include "debug.h"
26
72
#include "be_native.h"
27
73
#include "be_default.h"
28
74
#include "be_snapshot.h"
 
75
#include "be_nodata.h"
29
76
#include "ddl_blocker.h"
30
77
#include "backup_progress.h"
31
 
#include "si_objects.h"
32
 
 
33
 
extern DDL_blocker_class *DDL_blocker;
34
 
 
35
 
namespace backup {
36
 
 
37
 
// Helper functions
38
 
 
39
 
static IStream* open_for_read(const Location&);
40
 
static OStream* open_for_write(const Location&);
41
 
 
42
 
static int start_backup_or_restore();
43
 
static void finish_backup_or_restore();
44
 
 
45
 
/*
46
 
  Report errors. The main error code and optional arguments for its description
47
 
  are given plus a logger object which can contain stored errors.
48
 
 */
49
 
static int report_errors(THD*, Logger&, int, ...);
50
 
 
51
 
/*
52
 
  Check if info object is valid. If not, report error to client.
53
 
 */
54
 
static int check_info(THD*,Backup_info&);
55
 
static int check_info(THD*,Restore_info&);
56
 
 
57
 
static bool send_summary(THD*,const Backup_info&);
58
 
static bool send_summary(THD*,const Restore_info&);
59
 
 
60
 
#ifdef DBUG_BACKUP
61
 
// Flag used for testing error reporting
62
 
bool test_error_flag= FALSE;
63
 
#endif
64
 
 
65
 
/*
66
 
  (De)initialize memory allocator for backup stream library.
67
 
 */
68
 
void prepare_stream_memory();
69
 
void free_stream_memory();
70
 
 
71
 
}
 
78
 
 
79
 
 
80
/** 
 
81
  Global Initialization for online backup system.
 
82
 
 
83
  @note This function is called in the server initialization sequence, just
 
84
  after it loads all its plugins.
 
85
 */
 
86
int backup_init()
 
87
{
 
88
  pthread_mutex_init(&Backup_restore_ctx::run_lock, MY_MUTEX_INIT_FAST);
 
89
  return 0;
 
90
}
 
91
 
 
92
/**
 
93
  Global clean-up for online backup system.
 
94
  
 
95
  @note This function is called in the server shut-down sequences, just before
 
96
  it shuts-down all its plugins.
 
97
 */
 
98
void backup_shutdown()
 
99
{
 
100
  pthread_mutex_destroy(&Backup_restore_ctx::run_lock);
 
101
}
 
102
 
 
103
/*
 
104
  Forward declarations of functions used for sending response from BACKUP/RESTORE
 
105
  statement.
 
106
 */ 
 
107
static int send_error(Backup_restore_ctx &context, int error_code, ...);
 
108
static int send_reply(Backup_restore_ctx &context);
 
109
 
72
110
 
73
111
/**
74
112
  Call backup kernel API to execute backup related SQL statement.
76
114
  @param lex  results of parsing the statement.
77
115
 
78
116
  @note This function sends response to the client (ok, result set or error).
 
117
 
 
118
  @returns 0 on success, error code otherwise.
79
119
 */
80
120
 
81
121
int
82
122
execute_backup_command(THD *thd, LEX *lex)
83
123
{
84
 
  ulonglong backup_prog_id= 0;
85
 
  time_t start=0, stop=0;
 
124
  int res= 0;
86
125
  
87
126
  DBUG_ENTER("execute_backup_command");
88
127
  DBUG_ASSERT(thd && lex);
89
 
 
90
 
  BACKUP_BREAKPOINT("backup_command");
 
128
  DEBUG_SYNC(thd, "before_backup_command");
91
129
 
92
130
  using namespace backup;
93
131
 
94
 
  mysql_reset_errors(thd, 0);
95
 
  thd->no_warnings_for_error= FALSE;
96
 
 
97
 
  /*
98
 
    Check access for SUPER rights. If user does not have SUPER, fail with error.
99
 
  */
100
 
  if (check_global_access(thd, SUPER_ACL))
101
 
  {
102
 
    my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
103
 
    DBUG_RETURN(ER_SPECIFIC_ACCESS_DENIED_ERROR);
104
 
  }
105
 
 
106
 
  /*
107
 
    Check for progress tables.
108
 
  */
109
 
  if (check_ob_progress_tables(thd))
110
 
  {
111
 
    my_error(ER_BACKUP_PROGRESS_TABLES, MYF(0));
112
 
    DBUG_RETURN(ER_BACKUP_PROGRESS_TABLES);
113
 
  }
114
 
 
115
 
  Location *loc= Location::find(lex->backup_dir);
116
 
 
117
 
  if (!loc || !loc->is_valid())
118
 
  {
119
 
    my_error(ER_BACKUP_INVALID_LOC,MYF(0),lex->backup_dir.str);
120
 
    DBUG_RETURN(ER_BACKUP_INVALID_LOC);
121
 
  }
122
 
 
123
 
  /*
124
 
    Start_backup_or_restore() will check if another BACKUP/RESTORE command is 
125
 
    running now and inform us about that. If this is the case we report error.
126
 
   */ 
127
 
  if ((lex->sql_command == SQLCOM_RESTORE) 
128
 
      || (lex->sql_command == SQLCOM_BACKUP))
129
 
    if(start_backup_or_restore())
130
 
    {
131
 
      my_error(ER_BACKUP_RUNNING,MYF(0));
132
 
      DBUG_RETURN(ER_BACKUP_RUNNING);
133
 
    }
134
 
 
135
 
  prepare_stream_memory();
136
 
  int res= 0;
137
 
 
138
 
  /*
139
 
    Important: above start_backup_or_restore() and prepare_stream_memory() 
140
 
    *must* be matched by finish_backup_or_restore() and free_stream_memory(),
141
 
    respectively. Therefore be careful with early return with DBUG_RETURN() - 
142
 
    use "goto backup/restore_error" instead.
143
 
   */ 
 
132
  Backup_restore_ctx context(thd); // reports errors
 
133
  
 
134
  if (!context.is_valid())
 
135
    DBUG_RETURN(send_error(context, ER_BACKUP_CONTEXT_CREATE));
144
136
 
145
137
  switch (lex->sql_command) {
146
138
 
147
 
  case SQLCOM_SHOW_ARCHIVE:
 
139
  case SQLCOM_BACKUP:
 
140
  {
 
141
    // prepare for backup operation
 
142
    
 
143
    Backup_info *info= context.prepare_for_backup(lex->backup_dir, thd->query,
 
144
                                                  lex->backup_compression);
 
145
                                                              // reports errors
 
146
 
 
147
    if (!info || !info->is_valid())
 
148
      DBUG_RETURN(send_error(context, ER_BACKUP_BACKUP_PREPARE));
 
149
 
 
150
    DEBUG_SYNC(thd, "after_backup_start_backup");
 
151
 
 
152
    // select objects to backup
 
153
 
 
154
    if (lex->db_list.is_empty())
 
155
    {
 
156
      context.write_message(log_level::INFO, "Backing up all databases");
 
157
      res= info->add_all_dbs(); // backup all databases
 
158
    }
 
159
    else
 
160
    {
 
161
      context.write_message(log_level::INFO, "Backing up selected databases");
 
162
      res= info->add_dbs(lex->db_list); // backup databases specified by user
 
163
    }
 
164
 
 
165
    info->close(); // close catalogue after filling it with objects to backup
 
166
 
 
167
    if (res || !info->is_valid())
 
168
      DBUG_RETURN(send_error(context, ER_BACKUP_BACKUP_PREPARE));
 
169
 
 
170
    if (info->db_count() == 0)
 
171
    {
 
172
      context.fatal_error(ER_BACKUP_NOTHING_TO_BACKUP);
 
173
      DBUG_RETURN(send_error(context, ER_BACKUP_NOTHING_TO_BACKUP));
 
174
    }
 
175
 
 
176
    // perform backup
 
177
 
 
178
    res= context.do_backup();
 
179
 
 
180
    if (res)
 
181
      DBUG_RETURN(send_error(context, ER_BACKUP_BACKUP));
 
182
 
 
183
    break;
 
184
  }
 
185
 
148
186
  case SQLCOM_RESTORE:
149
187
  {
150
 
    backup::IStream *stream= open_for_read(*loc);
151
 
 
152
 
    if (!stream)
153
 
    {
154
 
      my_error(ER_BACKUP_READ_LOC,MYF(0),loc->describe());
155
 
      goto restore_error;
156
 
    }
157
 
    else
158
 
    {
159
 
      if (lex->sql_command == SQLCOM_SHOW_ARCHIVE)
160
 
      {
161
 
        my_error(ER_NOT_ALLOWED_COMMAND,MYF(0));
162
 
        goto restore_error;
163
 
      }
164
 
 
165
 
      start= my_time(0);
166
 
      
167
 
      backup_prog_id= report_ob_init(thd->id, BUP_STARTING, OP_RESTORE, 
168
 
                                     0, "", lex->backup_dir.str, thd->query);
169
 
      report_ob_time(backup_prog_id, start, 0);
170
 
      BACKUP_BREAKPOINT("bp_starting_state");
171
 
 
172
 
      Restore_info info(thd,*stream);
173
 
 
174
 
      info.backup_prog_id= backup_prog_id;
175
 
 
176
 
      if (check_info(thd,info))
177
 
      {
178
 
        stop= my_time(0);
179
 
        goto restore_error;
180
 
      }
181
 
 
182
 
      info.report_error(log_level::INFO,ER_BACKUP_RESTORE_START);
183
 
      info.save_start_time(start);
184
 
 
185
 
      report_ob_state(backup_prog_id, BUP_RUNNING);
186
 
      BACKUP_BREAKPOINT("bp_running_state");
187
 
 
188
 
      /*
189
 
        Freeze all DDL operations by turning on DDL blocker.
190
 
      */
191
 
      if (!DDL_blocker->block_DDL(thd))
192
 
      {
193
 
        stop= my_time(0); 
194
 
        info.save_end_time(stop);
195
 
        goto restore_error;
196
 
      }
197
 
 
198
 
      info.save_errors();
199
 
      info.restore_all_dbs();
200
 
 
201
 
      if (check_info(thd,info))
202
 
      {
203
 
        stop= my_time(0);
204
 
        info.save_end_time(stop);
205
 
        goto restore_error;
206
 
      }
207
 
      
208
 
      info.clear_saved_errors();
209
 
 
210
 
      res= mysql_restore(thd,info,*stream);      
211
 
      stop= my_time(0);
212
 
      info.save_end_time(stop);
213
 
 
214
 
      if (res)
215
 
      {
216
 
        report_errors(thd,info,ER_BACKUP_RESTORE);
217
 
        goto restore_error;
218
 
      }
219
 
 
220
 
      report_ob_num_objects(backup_prog_id, info.table_count);
221
 
      report_ob_size(backup_prog_id, info.data_size);
222
 
      report_ob_time(backup_prog_id, 0, stop);
223
 
      report_ob_state(backup_prog_id, BUP_COMPLETE);
224
 
      BACKUP_BREAKPOINT("bp_complete_state");
225
 
 
226
 
      info.report_error(log_level::INFO,ER_BACKUP_RESTORE_DONE);
227
 
      send_summary(thd,info);
228
 
    } // if (!stream)
229
 
 
230
 
    goto finish_restore;
231
 
 
232
 
   restore_error:
233
 
 
234
 
    res= res ? res : ERROR;
235
 
 
236
 
    report_ob_error(backup_prog_id, res);
237
 
    
238
 
    if (stop)
239
 
      report_ob_time(backup_prog_id, 0, stop);
240
 
 
241
 
    report_ob_state(backup_prog_id, BUP_ERRORS);
242
 
    BACKUP_BREAKPOINT("bp_error_state");
243
 
   
244
 
   finish_restore:
245
 
 
246
 
    /*
247
 
      Unfreeze all DDL operations by turning off DDL blocker.
248
 
    */
249
 
    DDL_blocker->unblock_DDL();
250
 
    BACKUP_BREAKPOINT("DDL_unblocked");
251
 
    
252
 
    if (stream)
253
 
      stream->close();
254
 
 
255
 
    break;
256
 
  }
257
 
 
258
 
  case SQLCOM_BACKUP:
259
 
  {
260
 
    /* if set to true, backup location will be removed (e.g., upon failure) */
261
 
    bool remove_location= FALSE; 
262
 
    backup::OStream *stream= open_for_write(*loc);
263
 
 
264
 
    if (!stream)
265
 
    {
266
 
      my_error(ER_BACKUP_WRITE_LOC,MYF(0),loc->describe());
267
 
      goto backup_error;
268
 
    }
269
 
    else
270
 
    {
271
 
      start= my_time(0);
272
 
      
273
 
      /*
274
 
        Freeze all DDL operations by turning on DDL blocker.
275
 
 
276
 
        Note: The block_ddl() call must occur before the information_schema
277
 
              is read so that any new tables (e.g. CREATE in progress) can
278
 
              be counted. Waiting until after this step caused backup to
279
 
              skip new or dropped tables.
280
 
      */
281
 
      if (!DDL_blocker->block_DDL(thd))
282
 
        goto backup_error;
283
 
 
284
 
      Backup_info info(thd);
285
 
 
286
 
      backup_prog_id= report_ob_init(thd->id, BUP_STARTING, OP_BACKUP,
287
 
                                     0, "", lex->backup_dir.str, thd->query);
288
 
      report_ob_time(backup_prog_id, start, 0);
289
 
      BACKUP_BREAKPOINT("bp_starting_state");
290
 
 
291
 
      info.backup_prog_id= backup_prog_id;
292
 
 
293
 
      if (check_info(thd,info))
294
 
        goto backup_error;
295
 
 
296
 
      info.report_error(log_level::INFO,ER_BACKUP_BACKUP_START);
297
 
      info.save_start_time(start);
298
 
      report_ob_state(backup_prog_id, BUP_RUNNING);
299
 
      BACKUP_BREAKPOINT("bp_running_state");
300
 
 
301
 
      info.save_errors();
302
 
 
303
 
      if (lex->db_list.is_empty())
304
 
      {
305
 
        info.write_message(log_level::INFO,"Backing up all databases");
306
 
        info.add_all_dbs(); // backup all databases
307
 
      }
308
 
      else
309
 
      {
310
 
        info.write_message(log_level::INFO,"Backing up selected databases");
311
 
        res= info.add_dbs(lex->db_list); // backup databases specified by user
312
 
      }
313
 
      if ((info.db_count() == 0) && (res != ERROR))
314
 
      {
315
 
        res= ERROR;
316
 
        info.report_error(log_level::ERROR, ER_BACKUP_NOTHING_TO_BACKUP, MYF(0));
317
 
        stop= my_time(0); 
318
 
        info.save_end_time(stop);
319
 
        report_errors(thd, info, ER_BACKUP_BACKUP);
320
 
        goto backup_error;
321
 
      }
322
 
 
323
 
      report_ob_num_objects(backup_prog_id, info.table_count);
324
 
 
325
 
      if (check_info(thd,info))
326
 
      {
327
 
        stop= my_time(0); 
328
 
        info.save_end_time(stop);
329
 
        goto backup_error;
330
 
      }
331
 
 
332
 
      info.close();
333
 
 
334
 
      if (check_info(thd,info))
335
 
      {
336
 
        stop= my_time(0); 
337
 
        info.save_end_time(stop);
338
 
        goto backup_error;
339
 
      }
340
 
 
341
 
      info.clear_saved_errors();
342
 
 
343
 
      res= mysql_backup(thd,info,*stream);
344
 
      stop= my_time(0);
345
 
      info.save_end_time(stop);
346
 
 
347
 
      if (res)
348
 
      {
349
 
        report_errors(thd,info,ER_BACKUP_BACKUP);
350
 
        goto backup_error;
351
 
      }
352
 
 
353
 
      report_ob_size(info.backup_prog_id, info.data_size);
354
 
      report_ob_time(info.backup_prog_id, 0, stop);
355
 
      report_ob_state(info.backup_prog_id, BUP_COMPLETE);
356
 
      BACKUP_BREAKPOINT("bp_complete_state");
357
 
 
358
 
      info.report_error(log_level::INFO,ER_BACKUP_BACKUP_DONE);
359
 
      send_summary(thd,info);
360
 
 
361
 
    } // if (!stream)
362
 
 
363
 
    goto finish_backup;
364
 
 
365
 
   backup_error:
366
 
 
367
 
    res= res ? res : ERROR;
368
 
 
369
 
    report_ob_error(backup_prog_id, res);
370
 
    report_ob_state(backup_prog_id, BUP_ERRORS);
371
 
 
372
 
    if (stop)
373
 
      report_ob_time(backup_prog_id, 0, stop);
374
 
 
375
 
    /*
376
 
      If the output stream was opened, a file or other system resource
377
 
      (depending on the type of the backup location) could be created. Since
378
 
      we failed to write backup image, this resource should be removed.
379
 
      We set remove_location flag so that loc->remove() will be called after
380
 
      closing the output stream.
381
 
     */
382
 
    remove_location= TRUE;
383
 
 
384
 
    BACKUP_BREAKPOINT("bp_error_state");
385
 
 
386
 
   finish_backup:
387
 
 
388
 
    /*
389
 
      Unfreeze all DDL operations by turning off DDL blocker.
390
 
    */
391
 
    DDL_blocker->unblock_DDL();
392
 
    BACKUP_BREAKPOINT("DDL_unblocked");
393
 
 
394
 
    if (stream)
395
 
    {
396
 
      stream->close();
397
 
 
398
 
      if (remove_location)
399
 
        if (loc->remove() != OK)
400
 
          res= res ? res : ERROR;
401
 
    }
402
 
 
 
188
    Restore_info *info= context.prepare_for_restore(lex->backup_dir, thd->query);
 
189
    
 
190
    if (!info || !info->is_valid())
 
191
      DBUG_RETURN(send_error(context, ER_BACKUP_RESTORE_PREPARE));
 
192
    
 
193
    DEBUG_SYNC(thd, "after_backup_start_restore");
 
194
 
 
195
    res= context.do_restore();      
 
196
 
 
197
    DEBUG_SYNC(thd, "restore_before_end");
 
198
 
 
199
    if (res)
 
200
      DBUG_RETURN(send_error(context, ER_BACKUP_RESTORE));
 
201
    
403
202
    break;
404
203
  }
405
204
 
412
211
 
413
212
  } // switch(lex->sql_command)
414
213
 
415
 
  loc->free();
416
 
  free_stream_memory();
417
 
  finish_backup_or_restore();
418
 
 
419
 
  DBUG_RETURN(res);
420
 
}
 
214
  if (context.close())
 
215
    DBUG_RETURN(send_error(context, ER_BACKUP_CONTEXT_REMOVE));
 
216
 
 
217
  // All seems OK - send positive reply to client
 
218
 
 
219
  DBUG_RETURN(send_reply(context));
 
220
}
 
221
 
 
222
/**
 
223
  Report errors.
 
224
 
 
225
  Current implementation reports the last error saved in the logger if it exist.
 
226
  Otherwise it reports error given by @c error_code.
 
227
 
 
228
  @returns 0 on success, error code otherwise.
 
229
 */
 
230
int send_error(Backup_restore_ctx &log, int error_code, ...)
 
231
{
 
232
  MYSQL_ERROR *error= log.last_saved_error();
 
233
 
 
234
  if (error && !util::report_mysql_error(log.thd(), error, error_code))
 
235
  {
 
236
    if (error->code)
 
237
      error_code= error->code;
 
238
  }
 
239
  else // there are no error information in the logger - report error_code
 
240
  {
 
241
    char buf[ERRMSGSIZE + 20];
 
242
    va_list args;
 
243
    va_start(args, error_code);
 
244
 
 
245
    my_vsnprintf(buf, sizeof(buf), ER_SAFE(error_code), args);
 
246
    my_printf_error(error_code, buf, MYF(0));
 
247
 
 
248
    va_end(args);
 
249
  }
 
250
 
 
251
  if (log.backup::Logger::m_state == backup::Logger::RUNNING)
 
252
    log.report_stop(my_time(0), FALSE); // FASLE = no success
 
253
  return error_code;
 
254
}
 
255
 
 
256
 
 
257
/**
 
258
  Send positive reply after a backup/restore operation.
 
259
 
 
260
  Currently the id of the operation is returned. It can be used to select
 
261
  correct entries form the backup progress tables.
 
262
*/
 
263
int send_reply(Backup_restore_ctx &context)
 
264
{
 
265
  Protocol *protocol= context.thd()->protocol;    // client comms
 
266
  List<Item> field_list;                // list of fields to send
 
267
  char buf[255];                        // buffer for llstr
 
268
 
 
269
  DBUG_ENTER("send_reply");
 
270
 
 
271
  /*
 
272
    Send field list.
 
273
  */
 
274
  field_list.push_back(new Item_empty_string(STRING_WITH_LEN("backup_id")));
 
275
  protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
 
276
 
 
277
  /*
 
278
    Send field data.
 
279
  */
 
280
  protocol->prepare_for_resend();
 
281
  llstr(context.op_id(), buf);
 
282
  protocol->store(buf, system_charset_info);
 
283
  protocol->write();
 
284
 
 
285
  my_eof(context.thd());
 
286
  DBUG_RETURN(0);
 
287
}
 
288
 
 
289
 
 
290
namespace backup {
 
291
 
 
292
/**
 
293
  This class provides memory allocation services for backup stream library.
 
294
 
 
295
  An instance of this class is created during preparations for backup/restore
 
296
  operation. When it is deleted, all allocated memory is freed.
 
297
*/
 
298
class Mem_allocator
 
299
{
 
300
 public:
 
301
 
 
302
  Mem_allocator();
 
303
  ~Mem_allocator();
 
304
 
 
305
  void* alloc(size_t);
 
306
  void  free(void*);
 
307
 
 
308
 private:
 
309
 
 
310
  struct node;
 
311
  node *first;  ///< Pointer to the first segment in the list.
 
312
};
 
313
 
 
314
 
 
315
} // backup namespace
421
316
 
422
317
 
423
318
/*************************************************
424
319
 
425
 
                   BACKUP
 
320
   Implementation of Backup_restore_ctx class
426
321
 
427
322
 *************************************************/
428
323
 
429
 
// Declarations for functions used in backup operation
430
 
 
431
 
namespace backup {
432
 
 
433
 
// defined in data_backup.cc
434
 
int write_table_data(THD*, Backup_info&, OStream&);
435
 
 
436
 
} // backup namespace
437
 
 
 
324
// static members
 
325
 
 
326
bool Backup_restore_ctx::is_running= FALSE;
 
327
pthread_mutex_t Backup_restore_ctx::run_lock;
 
328
backup::Mem_allocator *Backup_restore_ctx::mem_alloc= NULL;
 
329
 
 
330
 
 
331
Backup_restore_ctx::Backup_restore_ctx(THD *thd)
 
332
 :Logger(thd), m_state(CREATED), m_thd_options(thd->options),
 
333
  m_error(0), m_path(NULL), m_remove_loc(FALSE), m_stream(NULL),
 
334
  m_catalog(NULL), m_tables_locked(FALSE)
 
335
{
 
336
  /*
 
337
    Check for progress tables.
 
338
  */
 
339
  if (check_ob_progress_tables(thd))
 
340
    m_error= ER_BACKUP_PROGRESS_TABLES;
 
341
}
 
342
 
 
343
Backup_restore_ctx::~Backup_restore_ctx()
 
344
{
 
345
  close();
 
346
  
 
347
  delete m_catalog;  
 
348
  delete m_stream;
 
349
}
 
350
 
 
351
/**
 
352
  Do preparations common to backup and restore operations.
 
353
  
 
354
  It is checked if another operation is in progress and if yes then
 
355
  error is reported. Otherwise the current operation is registered so that
 
356
  no other can be started. All preparations common to backup and restore 
 
357
  operations are done. In particular, all changes to meta data are blocked
 
358
  with DDL blocker.
 
359
 
 
360
  @returns 0 on success, error code otherwise.
 
361
 */ 
 
362
int Backup_restore_ctx::prepare(LEX_STRING location)
 
363
{
 
364
  if (m_error)
 
365
    return m_error;
 
366
  
 
367
  // Prepare error reporting context.
 
368
  
 
369
  mysql_reset_errors(m_thd, 0);
 
370
  m_thd->no_warnings_for_error= FALSE;
 
371
  save_errors();  
 
372
 
 
373
 
 
374
  /*
 
375
    Check access for SUPER rights. If user does not have SUPER, fail with error.
 
376
  */
 
377
  if (check_global_access(m_thd, SUPER_ACL))
 
378
  {
 
379
    fatal_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, "SUPER");
 
380
    return m_error;
 
381
  }
 
382
 
 
383
  /*
 
384
    Check if another BACKUP/RESTORE is running and if not, register 
 
385
    this operation.
 
386
   */
 
387
 
 
388
  pthread_mutex_lock(&run_lock);
 
389
 
 
390
  if (!is_running)
 
391
    is_running= TRUE;
 
392
  else
 
393
    fatal_error(ER_BACKUP_RUNNING);
 
394
 
 
395
  pthread_mutex_unlock(&run_lock);
 
396
 
 
397
  if (m_error)
 
398
    return m_error;
 
399
 
 
400
  // check if location is valid (we assume it is a file path)
 
401
 
 
402
  bool bad_filename= (location.length == 0);
 
403
  
 
404
  /*
 
405
    On some systems certain file names are invalid. We use 
 
406
    check_if_legal_filename() function from mysys to detect this.
 
407
   */ 
 
408
#if defined(__WIN__) || defined(__EMX__)  
 
409
 
 
410
  bad_filename = bad_filename || check_if_legal_filename(location.str);
 
411
  
 
412
#endif
 
413
 
 
414
  if (bad_filename)
 
415
  {
 
416
    fatal_error(ER_BAD_PATH, location.str);
 
417
    return m_error;
 
418
  }
 
419
 
 
420
  m_path= location.str;
 
421
 
 
422
  // create new instance of memory allocator for backup stream library
 
423
 
 
424
  using namespace backup;
 
425
 
 
426
  delete mem_alloc;
 
427
  mem_alloc= new Mem_allocator();
 
428
 
 
429
  if (!mem_alloc)
 
430
  {
 
431
    fatal_error(ER_OUT_OF_RESOURCES);
 
432
    return m_error;
 
433
  }
 
434
 
 
435
  // Freeze all meta-data. 
 
436
 
 
437
  if (obs::ddl_blocker_enable(m_thd))
 
438
  {
 
439
    fatal_error(ER_DDL_BLOCK);
 
440
    return m_error;
 
441
  }
 
442
 
 
443
  return 0;
 
444
}
 
445
 
 
446
/**
 
447
  Prepare for backup operation.
 
448
  
 
449
  @param[in] location   path to the file where backup image should be stored
 
450
  @param[in] query      BACKUP query starting the operation
 
451
  @param[in] with_compression  backup image compression switch
 
452
  
 
453
  @returns Pointer to a @c Backup_info instance which can be used for selecting
 
454
  which objects to backup. NULL if an error was detected.
 
455
  
 
456
  @note This function reports errors.
 
457
 
 
458
  @note It is important that changes of meta-data are blocked as part of the
 
459
  preparations. The set of server objects and their definitions should not
 
460
  change after the backup context has been prepared and before the actual backup
 
461
  is performed using @c do_backup() method.
 
462
 */ 
 
463
Backup_info* 
 
464
Backup_restore_ctx::prepare_for_backup(LEX_STRING location, const char *query,
 
465
                                       bool with_compression)
 
466
{
 
467
  using namespace backup;
 
468
  
 
469
  if (m_error)
 
470
    return NULL;
 
471
  
 
472
  if (Logger::init(BACKUP, location, query))
 
473
  {
 
474
    fatal_error(ER_BACKUP_LOGGER_INIT);
 
475
    return NULL;
 
476
  }
 
477
 
 
478
  time_t when= my_time(0);
 
479
  report_start(when);
 
480
  
 
481
  /*
 
482
    Do preparations common to backup and restore operations. After call
 
483
    to prepare() all meta-data changes are blocked.
 
484
   */ 
 
485
  if (prepare(location))
 
486
    return NULL;
 
487
 
 
488
  backup::String path(location);
 
489
  
 
490
  /*
 
491
    Open output stream.
 
492
   */
 
493
 
 
494
  Output_stream *s= new Output_stream(*this, path, with_compression);
 
495
  m_stream= s;
 
496
  
 
497
  if (!s)
 
498
  {
 
499
    fatal_error(ER_OUT_OF_RESOURCES);
 
500
    return NULL;
 
501
  }
 
502
  
 
503
  if (!s->open())
 
504
  {
 
505
    fatal_error(ER_BACKUP_WRITE_LOC, path.ptr());
 
506
    return NULL;
 
507
  }
 
508
 
 
509
  /*
 
510
    Create backup catalogue.
 
511
   */
 
512
 
 
513
  Backup_info *info= new Backup_info(*this); // reports errors
 
514
 
 
515
  if (!info)
 
516
  {
 
517
    fatal_error(ER_OUT_OF_RESOURCES);
 
518
    return NULL;
 
519
  }
 
520
 
 
521
  if (!info->is_valid())
 
522
    return NULL;
 
523
 
 
524
  info->save_start_time(when);
 
525
  m_catalog= info;
 
526
  m_state= PREPARED_FOR_BACKUP;
 
527
  
 
528
  return info;
 
529
}
 
530
 
 
531
/**
 
532
  Prepare for restore operation.
 
533
  
 
534
  @param[in] location   path to the file where backup image is stored
 
535
  @param[in] query      RESTORE query starting the operation
 
536
  
 
537
  @returns Pointer to a @c Restore_info instance containing catalogue of the
 
538
  backup image (read from the image). NULL if errors were detected.
 
539
  
 
540
  @note This function reports errors.
 
541
 */ 
 
542
Restore_info* 
 
543
Backup_restore_ctx::prepare_for_restore(LEX_STRING location, const char *query)
 
544
{
 
545
  using namespace backup;  
 
546
 
 
547
  if (m_error)
 
548
    return NULL;
 
549
  
 
550
  if (Logger::init(RESTORE, location, query))
 
551
  {
 
552
    fatal_error(ER_BACKUP_LOGGER_INIT);
 
553
    return NULL;
 
554
  }
 
555
 
 
556
  time_t when= my_time(0);  
 
557
  report_start(when);
 
558
 
 
559
  /*
 
560
    Do preparations common to backup and restore operations. After this call
 
561
    changes of meta-data are blocked.
 
562
   */ 
 
563
  if (prepare(location))
 
564
    return NULL;
 
565
  
 
566
  /*
 
567
    Open input stream.
 
568
   */
 
569
 
 
570
  backup::String path(location);
 
571
  Input_stream *s= new Input_stream(*this, path);
 
572
  m_stream= s;
 
573
  
 
574
  if (!s)
 
575
  {
 
576
    fatal_error(ER_OUT_OF_RESOURCES);
 
577
    return NULL;
 
578
  }
 
579
  
 
580
  if (!s->open())
 
581
  {
 
582
    fatal_error(ER_BACKUP_READ_LOC, path.ptr());
 
583
    return NULL;
 
584
  }
 
585
 
 
586
  /*
 
587
    Create restore catalogue.
 
588
   */
 
589
 
 
590
  Restore_info *info= new Restore_info(*this);  // reports errors
 
591
 
 
592
  if (!info)
 
593
  {
 
594
    fatal_error(ER_OUT_OF_RESOURCES);
 
595
    return NULL;
 
596
  }
 
597
 
 
598
  if (!info->is_valid())
 
599
    return NULL;
 
600
 
 
601
  info->save_start_time(when);
 
602
  m_catalog= info;
 
603
 
 
604
  /*
 
605
    Read catalogue from the input stream.
 
606
   */
 
607
 
 
608
  if (read_header(*info, *s))
 
609
  {
 
610
    fatal_error(ER_BACKUP_READ_HEADER);
 
611
    return NULL;
 
612
  }
 
613
 
 
614
  if (s->next_chunk() != BSTREAM_OK)
 
615
  {
 
616
    fatal_error(ER_BACKUP_NEXT_CHUNK);
 
617
    return NULL;
 
618
  }
 
619
 
 
620
  if (read_catalog(*info, *s))
 
621
  {
 
622
    fatal_error(ER_BACKUP_READ_HEADER);
 
623
    return NULL;
 
624
  }
 
625
 
 
626
  if (s->next_chunk() != BSTREAM_OK)
 
627
  {
 
628
    fatal_error(ER_BACKUP_NEXT_CHUNK);
 
629
    return NULL;
 
630
  }
 
631
 
 
632
  m_state= PREPARED_FOR_RESTORE;
 
633
 
 
634
  return info;
 
635
}
 
636
 
 
637
/*
 
638
  Lock tables being restored.
 
639
 
 
640
  Backup kernel ensures that all tables being restored are exclusively locked.
 
641
 
 
642
  We use open_and_lock_tables() for locking. This is a temporary solution until
 
643
  a better mechanism is devised - open_and_lock_tables() is not good if there
 
644
  are many tables to be processed.
 
645
 
 
646
  The built-in restore drivers need to open tables to write rows to them. Since
 
647
  we have opened tables here, we store pointers to opened TABLE_LIST structures
 
648
  in the restore catalogue so that the built-in drivers can access them later.
 
649
 
 
650
  @todo Replace open_and_lock_tables() by a lighter solution.
 
651
  @todo Hide table locking behind the server API.
 
652
*/ 
 
653
int Backup_restore_ctx::lock_tables_for_restore()
 
654
{
 
655
  TABLE_LIST *tables= NULL;
 
656
 
 
657
  /*
 
658
    Iterate over all tables in all snapshots and create a linked TABLE_LIST
 
659
    for call to open_and_lock_tables(). Store pointers to TABLE_LIST structures
 
660
    in the restore catalogue for later access to opened tables.
 
661
  */ 
 
662
 
 
663
  for (uint s= 0; s < m_catalog->snap_count(); ++s)
 
664
  {
 
665
    backup::Snapshot_info *snap= m_catalog->m_snap[s];
 
666
 
 
667
    for (ulong t=0; t < snap->table_count(); ++t)
 
668
    {
 
669
      backup::Image_info::Table *tbl= snap->get_table(t);
 
670
      DBUG_ASSERT(tbl); // All tables should be present in the catalogue.
 
671
 
 
672
      TABLE_LIST *ptr= backup::mk_table_list(*tbl, TL_WRITE, m_thd->mem_root);
 
673
      DBUG_ASSERT(ptr);  // FIXME: report error instead
 
674
 
 
675
      tables= backup::link_table_list(*ptr, tables);      
 
676
      tbl->m_table= ptr;
 
677
    }
 
678
  }
 
679
 
 
680
  /*
 
681
    Open and lock the tables.
 
682
    
 
683
    Note: simple_open_n_lock_tables() must be used here since we don't want
 
684
    to do derived tables processing. Processing derived tables even leads 
 
685
    to crashes as those reported in BUG#34758.
 
686
  */ 
 
687
  if (simple_open_n_lock_tables(m_thd,tables))
 
688
  {
 
689
    fatal_error(ER_BACKUP_OPEN_TABLES,"RESTORE");
 
690
    return m_error;
 
691
  }
 
692
 
 
693
  m_tables_locked= TRUE;
 
694
  return 0;
 
695
}
 
696
 
 
697
/**
 
698
  Unlock tables which were locked by @c lock_tables_for_restore.
 
699
 */ 
 
700
int Backup_restore_ctx::unlock_tables()
 
701
{
 
702
  // Do nothing if tables are not locked.
 
703
  if (!m_tables_locked)
 
704
    return 0;
 
705
 
 
706
  DBUG_PRINT("restore",("unlocking tables"));
 
707
 
 
708
  close_thread_tables(m_thd);
 
709
  m_tables_locked= FALSE;
 
710
 
 
711
  return 0;
 
712
}
 
713
 
 
714
/**
 
715
  Destroy a backup/restore context.
 
716
  
 
717
  This should reverse all settings made when context was created and prepared.
 
718
  If it was requested, the backup/restore location is removed. Also, the backup
 
719
  stream memory allocator is shut down. Any other allocated resources are 
 
720
  deleted in the destructor. Changes to meta-data are unblocked.
 
721
  
 
722
  @returns 0 or error code if error was detected.
 
723
  
 
724
  @note This function reports errors.
 
725
 */ 
 
726
int Backup_restore_ctx::close()
 
727
{
 
728
  if (m_state == CLOSED)
 
729
    return 0;
 
730
 
 
731
  using namespace backup;
 
732
 
 
733
  time_t when= my_time(0);
 
734
 
 
735
  // If auto commit is turned off, be sure to commit the transaction
 
736
  // TODO: move it to the big switch, case: MYSQLCOM_BACKUP?
 
737
 
 
738
  if (m_thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
 
739
  {
 
740
    ha_autocommit_or_rollback(m_thd, 0);
 
741
    end_active_trans(m_thd);
 
742
  }
 
743
 
 
744
  // unlock tables if they are still locked
 
745
 
 
746
  unlock_tables();
 
747
 
 
748
  // unfreeze meta-data
 
749
 
 
750
  obs::ddl_blocker_disable();
 
751
 
 
752
  // restore thread options
 
753
 
 
754
  m_thd->options= m_thd_options;
 
755
 
 
756
  // close stream
 
757
 
 
758
  if (m_stream)
 
759
    m_stream->close();
 
760
 
 
761
  if (m_catalog)
 
762
    m_catalog->save_end_time(when);
 
763
 
 
764
  // destroy backup stream's memory allocator (this frees memory)
 
765
 
 
766
  delete mem_alloc;
 
767
  mem_alloc= NULL;
 
768
  
 
769
  // deregister this operation
 
770
 
 
771
  pthread_mutex_lock(&run_lock);
 
772
  is_running= FALSE;
 
773
  pthread_mutex_unlock(&run_lock);
 
774
 
 
775
  /* 
 
776
    Remove the location, if asked for.
 
777
    
 
778
    Important: This is done only for backup operation - RESTORE should never
 
779
    remove the specified backup image!
 
780
   */
 
781
  if (m_remove_loc && m_state == PREPARED_FOR_BACKUP)
 
782
  {
 
783
    int res= my_delete(m_path, MYF(0));
 
784
 
 
785
    /*
 
786
      Ignore ENOENT error since it is ok if the file doesn't exist.
 
787
     */
 
788
    if (res && my_errno != ENOENT)
 
789
    {
 
790
      report_error(ER_CANT_DELETE_FILE, m_path, my_errno);
 
791
      if (!m_error)
 
792
        m_error= ER_CANT_DELETE_FILE;
 
793
    }
 
794
  }
 
795
 
 
796
  // We report completion of the operation only if no errors were detected.
 
797
 
 
798
  if (!m_error)
 
799
    report_stop(when, TRUE);
 
800
 
 
801
  m_state= CLOSED;
 
802
  return m_error;
 
803
}
438
804
 
439
805
/**
440
806
  Create backup archive.
 
807
  
 
808
  @pre @c prepare_for_backup() method was called.
 
809
 
 
810
  @returns 0 on success, error code otherwise.
441
811
*/
442
 
 
443
 
int mysql_backup(THD *thd,
444
 
                 backup::Backup_info &info,
445
 
                 backup::OStream &s)
 
812
int Backup_restore_ctx::do_backup()
446
813
{
447
 
  DBUG_ENTER("mysql_backup");
 
814
  DBUG_ENTER("do_backup");
448
815
 
 
816
  // This function should not be called when context is not valid
 
817
  DBUG_ASSERT(is_valid());
 
818
  DBUG_ASSERT(m_state == PREPARED_FOR_BACKUP);
 
819
  DBUG_ASSERT(m_thd);
 
820
  DBUG_ASSERT(m_stream);
 
821
  DBUG_ASSERT(m_catalog);
 
822
  
449
823
  using namespace backup;
450
824
 
451
 
  // This function should not be called with invalid backup info.
452
 
  DBUG_ASSERT(info.is_valid());
453
 
 
454
 
  BACKUP_BREAKPOINT("backup_meta");
 
825
  Output_stream &s= *static_cast<Output_stream*>(m_stream);
 
826
  Backup_info   &info= *static_cast<Backup_info*>(m_catalog);
 
827
 
 
828
  DEBUG_SYNC(m_thd, "before_backup_meta");
 
829
 
 
830
  report_stats_pre(info);
455
831
 
456
832
  DBUG_PRINT("backup",("Writing preamble"));
457
833
 
458
 
  if (write_preamble(info,s))
459
 
    goto error;
 
834
  if (write_preamble(info, s))
 
835
  {
 
836
    fatal_error(ER_BACKUP_WRITE_HEADER);
 
837
    DBUG_RETURN(m_error);
 
838
  }
460
839
 
461
840
  DBUG_PRINT("backup",("Writing table data"));
462
841
 
463
 
  BACKUP_BREAKPOINT("backup_data");
 
842
  DEBUG_SYNC(m_thd, "before_backup_data");
464
843
 
465
 
  if (write_table_data(thd,info,s))
466
 
    goto error;
 
844
  if (write_table_data(m_thd, info, s)) // reports errors
 
845
    DBUG_RETURN(send_error(*this, ER_BACKUP_BACKUP));
467
846
 
468
847
  DBUG_PRINT("backup",("Writing summary"));
469
848
 
470
 
  if (write_summary(info,s))
471
 
    goto error;
 
849
  if (write_summary(info, s))
 
850
  {
 
851
    fatal_error(ER_BACKUP_WRITE_SUMMARY);
 
852
    DBUG_RETURN(m_error);
 
853
  }
 
854
 
 
855
  report_stats_post(info);
472
856
 
473
857
  DBUG_PRINT("backup",("Backup done."));
474
 
  BACKUP_BREAKPOINT("backup_done");
 
858
  DEBUG_SYNC(m_thd, "before_backup_done");
475
859
 
476
860
  DBUG_RETURN(0);
477
 
 
478
 
 error:
479
 
 
480
 
  DDL_blocker->unblock_DDL();
481
 
  DBUG_RETURN(ERROR);
482
 
}
483
 
 
484
 
namespace backup {
485
 
 
486
 
 
487
 
/**
488
 
  Find backup engine which can backup data of a given table.
489
 
 
490
 
  When necessary, a @c Snapshot_info object is created and added to the
491
 
  @c m_snap[] table.
492
 
 
493
 
  @param t    pointer to table's opened TABLE structure
494
 
  @param tbl  Table_ref describing the table
495
 
 
496
 
  @return position in @c m_snap[] of the @c Snapshot_info object to which the
497
 
  table has been added or -1 on error.
498
 
 
499
 
  @todo Add error messages.
500
 
 */
501
 
int Backup_info::find_backup_engine(const ::TABLE *const t,
502
 
                                    const Table_ref &tbl)
503
 
{
504
 
   handlerton *hton= t->s->db_type();
505
 
   Table_ref::describe_buf buf;
506
 
   int no;
507
 
 
508
 
   DBUG_ENTER("Backup_info::find_backup_engine");
509
 
   DBUG_ASSERT(t);
510
 
 
511
 
   DBUG_PRINT("backup",("Locating backup engine for table %s which uses"
512
 
                        " storage engine %s%s",
513
 
                        tbl.describe(buf),
514
 
                        hton ? ::ha_resolve_storage_engine_name(hton) : "(unknown engine)",
515
 
                        hton->get_backup_engine ? " (has native backup)." : "."));
516
 
 
517
 
   /*
518
 
     Note: at backup time the native and CS snapshot info objects are always
519
 
     located at m_snap[0] and m_snap[1], respectively. They are created in
520
 
     the Backup_info constructor.
521
 
   */
522
 
 
523
 
  // try native driver if table has native backup engine
524
 
 
525
 
  if (hton->get_backup_engine)
526
 
  {
527
 
    // see if the snapshot exists already (skip default ones)
528
 
    for (no=2; no < 256 && m_snap[no] ; ++no)
529
 
     if (m_snap[no]->accept(tbl,hton))
530
 
       DBUG_RETURN(no);
531
 
 
532
 
    if (no == 256)
533
 
    {
534
 
      // TODO: report error
535
 
      DBUG_RETURN(-1);
536
 
    }
537
 
 
538
 
    // We need to create native snapshot for this table
539
 
 
540
 
    m_snap[no]= new Native_snapshot(t->s->db_plugin);
541
 
 
542
 
    if (!m_snap[no])
543
 
    {
544
 
      // TODO: report error
545
 
      DBUG_RETURN(-1);
546
 
    }
547
 
 
548
 
    if (!m_snap[no]->accept(tbl,hton))
549
 
    {
550
 
      // TODO: report error
551
 
      DBUG_RETURN(-1);
552
 
    }
553
 
 
554
 
    DBUG_RETURN(no);
555
 
  }
556
 
 
557
 
  /*
558
 
    Try default drivers in decreasing order of preferrence
559
 
    (first snapshot, then default)
560
 
  */
561
 
  for (no=1; no >=0; --no)
562
 
  {
563
 
    if (!m_snap[no]->accept(tbl,hton))
564
 
     continue;
565
 
 
566
 
    DBUG_RETURN(no);
567
 
  }
568
 
 
569
 
  report_error(ER_BACKUP_NO_BACKUP_DRIVER,tbl.describe(buf,sizeof(buf)));
570
 
  DBUG_RETURN(-1);
571
 
}
572
 
 
573
 
} // backup namespace
574
 
 
575
 
 
576
 
/****************************
577
 
 
578
 
  Backup_info implementation
579
 
 
580
 
 ****************************/
581
 
 
582
 
namespace backup {
583
 
 
584
 
//  Returns tmp table containing records from a given I_S table
585
 
TABLE* get_schema_table(THD *thd, ST_SCHEMA_TABLE *st);
586
 
 
587
 
 
588
 
/**
589
 
  Create @c Backup_info structure and prepare it for populating with meta-data
590
 
  items.
591
 
 
592
 
  When adding a complete database to the archive, all its tables are added.
593
 
  These are found by reading INFORMATION_SCHEMA.TABLES table. The table is
594
 
  opened here so that it is ready for use in @c add_db_items() method. It is
595
 
  closed when the structure is closed with the @c close() method.
596
 
 
597
 
  @todo Report errors.
598
 
 */
599
 
Backup_info::Backup_info(THD *thd):
600
 
  Logger(Logger::BACKUP),
601
 
  m_state(INIT),
602
 
  m_thd(thd), i_s_tables(NULL)
603
 
{
604
 
  i_s_tables= get_schema_table(m_thd, ::get_schema_table(SCH_TABLES));
605
 
  if (!i_s_tables)
606
 
  {
607
 
    report_error(ER_BACKUP_LIST_TABLES);
608
 
    m_state= ERROR;
609
 
  }
610
 
 
611
 
  // create default and CS snapshot objects
612
 
 
613
 
  m_snap[0]= new Default_snapshot();
614
 
  if (!m_snap[0])
615
 
  {
616
 
    // TODO: report error
617
 
    close();
618
 
    m_state= ERROR;
619
 
  }
620
 
 
621
 
  m_snap[1]= new CS_snapshot();
622
 
  if (!m_snap[1])
623
 
  {
624
 
    // TODO: report error
625
 
    close();
626
 
    m_state= ERROR;
627
 
  }
628
 
}
629
 
 
630
 
Backup_info::~Backup_info()
631
 
{
632
 
  close();
633
 
  m_state= DONE;
634
 
  name_strings.delete_elements();
635
 
  // Note: snapshot objects are deleted in ~Image_info()
636
 
}
637
 
 
638
 
/**
639
 
  Store information about table data snapshot inside @c st_bstream_snapshot_info
640
 
  structure.
641
 
*/
642
 
void save_snapshot_info(const Snapshot_info &snap, st_bstream_snapshot_info &info)
643
 
{
644
 
  bzero(&info,sizeof(st_bstream_snapshot_info));
645
 
  info.type= enum_bstream_snapshot_type(snap.type());
646
 
  info.version= snap.version;
647
 
  info.table_count= snap.table_count();
648
 
 
649
 
  if (snap.type() == Snapshot_info::NATIVE_SNAPSHOT)
650
 
  {
651
 
    const Native_snapshot &nsnap= static_cast<const Native_snapshot&>(snap);
652
 
 
653
 
    info.engine.major= nsnap.se_ver >> 8;
654
 
    info.engine.minor= nsnap.se_ver & 0xFF;
655
 
    info.engine.name.begin= (byte*)nsnap.m_name;
656
 
    info.engine.name.end= info.engine.name.begin + strlen(nsnap.m_name);
657
 
  }
658
 
}
659
 
 
660
 
/**
661
 
  Close @c Backup_info object after populating it with items.
662
 
 
663
 
  After this call the @c Backup_info object is ready for use as a catalogue
664
 
  for backup stream functions such as @c bstream_wr_preamble().
665
 
 */
666
 
bool Backup_info::close()
667
 
{
668
 
  bool ok= is_valid();
669
 
 
670
 
  if(i_s_tables)
671
 
    ::free_tmp_table(m_thd,i_s_tables);
672
 
  i_s_tables= NULL;
673
 
 
674
 
  /*
675
 
    Go through snapshots and save their descriptions inside snapshots[] table.
676
 
  */
677
 
  for (uint no=0; no < 256; ++no)
678
 
  {
679
 
    Snapshot_info *snap= m_snap[no];
680
 
 
681
 
    if (!snap)
682
 
      continue;
683
 
 
684
 
    if (snap->m_no == 0 || snap->table_count() == 0)
685
 
    {
686
 
      DBUG_ASSERT(snap->m_no == 0);
687
 
      DBUG_ASSERT(snap->table_count() == 0);
688
 
      delete snap;
689
 
      m_snap[no]= NULL;
690
 
      continue;
691
 
    }
692
 
 
693
 
    save_snapshot_info(*snap,snapshot[snap->m_no-1]);
694
 
  }
695
 
 
696
 
  if (m_state == INIT)
697
 
    m_state= READY;
698
 
 
699
 
  return ok;
700
 
}
701
 
 
702
 
 
703
 
/**
704
 
  Add to backup image all databases in the list.
705
 
 
706
 
  For each database, all objects stored in that database are also added to
707
 
  the image.
708
 
 
709
 
  @todo Report errors.
710
 
 */
711
 
int Backup_info::add_dbs(List< ::LEX_STRING > &dbs)
712
 
{
713
 
  using namespace obs;
714
 
 
715
 
  List_iterator< ::LEX_STRING > it(dbs);
716
 
  ::LEX_STRING *s;
717
 
  String unknown_dbs; // comma separated list of databases which don't exist
718
 
 
719
 
  while ((s= it++))
720
 
  {
721
 
    String db_name(*s);
722
 
 
723
 
    if (is_internal_db_name(&db_name))
724
 
    {
725
 
      report_error(log_level::ERROR, ER_BACKUP_CANNOT_INCLUDE_DB,
726
 
                   db_name.c_ptr());
727
 
      goto error;
728
 
    }
729
 
    
730
 
    Obj *db= get_database(&db_name);
731
 
 
732
 
    if (db && !check_db_existence(db->get_name()))
733
 
    {    
734
 
      if (!unknown_dbs.is_empty()) // we just compose unknown_dbs list
735
 
      {
736
 
        delete db;
737
 
        continue;
738
 
      }
739
 
      
740
 
      Db_item *it= add_db(db);
741
 
 
742
 
      if (!it)
743
 
      {
744
 
        delete db;
745
 
        // TODO: report error
746
 
        goto error;
747
 
      }
748
 
 
749
 
      if (add_db_items(*it))
750
 
        goto error;
751
 
    }
752
 
    else
753
 
    {
754
 
      if (!unknown_dbs.is_empty())
755
 
        unknown_dbs.append(",");
756
 
      unknown_dbs.append(*db->get_name());
757
 
      delete db;
758
 
    }
759
 
  }
760
 
 
761
 
  if (!unknown_dbs.is_empty())
762
 
  {
763
 
    report_error(ER_BAD_DB_ERROR,unknown_dbs.c_ptr());
764
 
    goto error;
765
 
  }
766
 
 
767
 
  return 0;
768
 
 
769
 
 error:
770
 
 
771
 
  m_state= ERROR;
772
 
  return backup::ERROR;
773
 
}
774
 
 
775
 
/**
776
 
  Add all databases to backup image (except the internal ones).
777
 
 
778
 
  For each database, all objects stored in that database are also added to
779
 
  the image.
780
 
 
781
 
  @todo Report errors.
782
 
*/
783
 
int Backup_info::add_all_dbs()
784
 
{
785
 
  using namespace obs;
786
 
 
787
 
  int res= 0;
788
 
  ObjIterator *dbit= get_databases(m_thd);
789
 
  
790
 
  if (!dbit)
791
 
  {
792
 
    report_error(ER_BACKUP_LIST_DBS);
793
 
    return ERROR;
794
 
  }
795
 
  
796
 
  Obj *db;
797
 
  
798
 
  while ((db= dbit->next()))
799
 
  {
800
 
    // skip internal databases
801
 
    if (is_internal_db_name(db->get_name()))
802
 
    {
803
 
      DBUG_PRINT("backup",(" Skipping internal database %s",db->get_name()->ptr()));
804
 
      delete db;
805
 
      continue;
806
 
    }
807
 
 
808
 
    DBUG_PRINT("backup", (" Found database %s", db->get_name()->ptr()));
809
 
 
810
 
    Db_item *it= add_db(db);
811
 
 
812
 
    if (!it)
813
 
    {
814
 
      res= -3;
815
 
      delete db;
816
 
      goto finish;
817
 
    }
818
 
 
819
 
    /* 
820
 
      Note: the db instance is now owned by *this and will be deleted at 
821
 
      destruction time.
822
 
     */
823
 
    
824
 
    if (add_db_items(*it))
825
 
    {
826
 
      res= -4;
827
 
      goto finish;
828
 
    }
829
 
  }
830
 
 
831
 
  DBUG_PRINT("backup", ("No more databases in I_S"));
832
 
 
833
 
 finish:
 
861
}
 
862
 
 
863
/**
 
864
  Create all triggers and events from restore catalogue.
 
865
 
 
866
  This helper method iterates over all triggers and events stored in the 
 
867
  restore catalogue and creates them. When metadata section of the backup image 
 
868
  is read, trigger and event objects are materialized and stored in the 
 
869
  catalogue but they are not executed then (see @c bcat_create_item()). 
 
870
  This method can be used to re-create the corresponding server objects after 
 
871
  all other objects and table data have been restored.
 
872
 
 
873
  Note that we first restore all triggers and then the events.
 
874
 
 
875
  @returns 0 on success, error code otherwise.
 
876
*/ 
 
877
int Backup_restore_ctx::restore_triggers_and_events()
 
878
{
 
879
  using namespace backup;
 
880
 
 
881
  DBUG_ASSERT(m_catalog);
 
882
 
 
883
  Image_info::Iterator *dbit= m_catalog->get_dbs();
 
884
  Image_info::Obj *obj;
 
885
  List<Image_info::Obj> events;
 
886
  Image_info::Obj::describe_buf buf;
 
887
 
 
888
  DBUG_ENTER("restore_triggers_and_events");
 
889
 
 
890
  // create all trigers and collect events in the events list
 
891
  
 
892
  while ((obj= (*dbit)++)) 
 
893
  {
 
894
    Image_info::Iterator *it= 
 
895
                    m_catalog->get_db_objects(*static_cast<Image_info::Db*>(obj));
 
896
 
 
897
    while ((obj= (*it)++))
 
898
      switch (obj->type()) {
 
899
      
 
900
      case BSTREAM_IT_EVENT:
 
901
        DBUG_ASSERT(obj->m_obj_ptr);
 
902
        events.push_back(obj);
 
903
        break;
 
904
      
 
905
      case BSTREAM_IT_TRIGGER:
 
906
        DBUG_ASSERT(obj->m_obj_ptr);
 
907
        if (obj->m_obj_ptr->execute(m_thd))
 
908
        {
 
909
          delete it;
 
910
          delete dbit;
 
911
          fatal_error(ER_BACKUP_CANT_RESTORE_TRIGGER,obj->describe(buf));
 
912
          DBUG_RETURN(m_error);
 
913
        }
 
914
        break;
 
915
 
 
916
      default: break;      
 
917
      }
 
918
 
 
919
    delete it;
 
920
  }
834
921
 
835
922
  delete dbit;
836
923
 
837
 
  if (res)
838
 
    m_state= ERROR;
839
 
 
840
 
  return res;
841
 
}
842
 
 
843
 
 
844
 
/**
845
 
  Add to archive all objects belonging to a given database.
846
 
 
847
 
  @todo Handle other types of objects - not only tables.
848
 
  @todo Use WHERE clauses when reading I_S.TABLES
849
 
 */
850
 
int Backup_info::add_db_items(Db_item &dbi)
851
 
{
852
 
  using namespace obs;
853
 
 
854
 
  ObjIterator *it= get_db_tables(m_thd,&dbi.name()); 
855
 
 
856
 
  /*
857
 
    If error debugging is switched on (see debug.h) then I_S.TABLES access
858
 
    error will be triggered when backing up database whose name starts with 'a'.
859
 
   */
860
 
  TEST_ERROR_IF(dbi.name().ptr()[0]=='a');
861
 
 
862
 
  if (!it || TEST_ERROR)
863
 
  {
864
 
    report_error(ER_BACKUP_LIST_DB_TABLES,dbi.name().ptr());
865
 
    return ERROR;
866
 
  }
867
 
  
868
 
  int res= 0;
869
 
  Obj *t= NULL;
870
 
 
871
 
  while ((t= it->next()))
872
 
  {
873
 
    DBUG_PRINT("backup", ("Found table %s for database %s",
874
 
                           t->get_name()->ptr(), dbi.name().ptr()));
875
 
 
876
 
    /*
877
 
      add_table() method selects/creates a snapshot to which this table is added.
878
 
      The backup engine is chooden in Backup_info::find_backup_engine() method.
879
 
    */
880
 
    Table_item *ti= add_table(dbi,Table_ref(dbi,t));
881
 
 
882
 
    if (!ti)
 
924
  // now create all events
 
925
 
 
926
  List_iterator<Image_info::Obj> it(events);
 
927
  Image_info::Obj *ev;
 
928
 
 
929
  while ((ev= it++)) 
 
930
    if (ev->m_obj_ptr->execute(m_thd))
883
931
    {
884
 
      delete t;
885
 
      goto error;
886
 
    }
887
 
 
888
 
    if (add_table_items(*ti))
889
 
      goto error;
890
 
  }
891
 
 
892
 
  delete it;  
893
 
  it= get_db_stored_procedures(m_thd, &dbi.name());
894
 
  
895
 
  if (!it)
896
 
  {
897
 
    // TODO: report error
898
 
    goto error;
899
 
  }
900
 
  
901
 
  add_objects(dbi, BSTREAM_IT_SPROC, *it);
902
 
 
903
 
  delete it;
904
 
  it= get_db_stored_functions(m_thd, &dbi.name());
905
 
 
906
 
  if (!it)
907
 
  {
908
 
    // TODO: report error
909
 
    goto error;
910
 
  }
911
 
  
912
 
  add_objects(dbi, BSTREAM_IT_SFUNC, *it);
913
 
 
914
 
  delete it;
915
 
  it= get_db_views(m_thd, &dbi.name());
916
 
 
917
 
  if (!it)
918
 
  {
919
 
    // TODO: report error
920
 
    goto error;
921
 
  }
922
 
  
923
 
  add_objects(dbi, BSTREAM_IT_VIEW, *it);
924
 
 
925
 
  delete it;
926
 
  it= get_db_events(m_thd, &dbi.name());
927
 
 
928
 
  if (!it)
929
 
  {
930
 
    // TODO: report error
931
 
    goto error;
932
 
  }
933
 
  
934
 
  add_objects(dbi, BSTREAM_IT_EVENT, *it);
935
 
  
936
 
  delete it;
937
 
  it= get_db_triggers(m_thd, &dbi.name());
938
 
 
939
 
  if (!it)
940
 
  {
941
 
    // TODO: report error
942
 
    goto error;
943
 
  }
944
 
  
945
 
  add_objects(dbi, BSTREAM_IT_TRIGGER, *it);
946
 
  
947
 
  goto finish;
948
 
 
949
 
 error:
950
 
 
951
 
  res= res ? res : ERROR;
952
 
  m_state= ERROR;
953
 
  
954
 
 finish:
955
 
 
956
 
  delete it;
957
 
  return res;
958
 
}
959
 
 
960
 
/**
961
 
  Add table to archive's list of meta-data items.
962
 
 
963
 
  @todo Correctly handle temporary tables.
964
 
  @todo Avoid opening tables here - open them only in bcat_get_create_stmt().
965
 
*/
966
 
Image_info::Table_item*
967
 
Backup_info::add_table(Db_item &dbi, const Table_ref &t)
968
 
{
969
 
  Table_ref::describe_buf buf;
970
 
  // TODO: skip table if it is a tmp one
971
 
 
972
 
  Table_item *ti= NULL;
973
 
 
974
 
  /*
975
 
    open table temporarily to:
976
 
     - get its handlerton
977
 
     - get a CREATE statement for it
978
 
  */
979
 
 
980
 
  TABLE_LIST entry, *tl= &entry;
981
 
  bzero(&entry,sizeof(entry));
982
 
 
983
 
  // FIXME: table/db name mangling
984
 
  entry.db= const_cast<char*>(t.db().name().ptr());
985
 
  entry.alias= entry.table_name= const_cast<char*>(t.name().ptr());
986
 
 
987
 
  uint cnt;
988
 
  int res= ::open_tables(m_thd,&tl,&cnt,0);
989
 
 
990
 
  if (res || !tl->table)
991
 
  {
992
 
    report_error(ER_BACKUP_TABLE_OPEN,t.describe(buf));
993
 
    return NULL;
994
 
  }
995
 
 
996
 
  /*
997
 
    alternative way of opening a single tmp table - but it
998
 
    doesn't initialize TABLE_LIST structure which we need for getting
999
 
    CREATE statement.
1000
 
 
1001
 
    char path[FN_REFLEN];
1002
 
    const char *db= t.db().name().ptr();
1003
 
    const char *name= t.name().ptr();
1004
 
 
1005
 
    ::build_table_filename(path, sizeof(path), db, name, "", 0);
1006
 
 
1007
 
    ::TABLE *table= ::open_temporary_table(m_thd, path, db, name,
1008
 
                      FALSE /=* don't link to thd->temporary_tables *=/);
1009
 
 
1010
 
    ...
1011
 
 
1012
 
    ::intern_close_table(table);
1013
 
    my_free(table, MYF(0));
1014
 
  */
1015
 
 
1016
 
  int no= find_backup_engine(tl->table,t); // Note: reports errors
1017
 
 
1018
 
  DBUG_PRINT("backup",(" table %s backed-up with %s engine",
1019
 
                       t.describe(buf),
1020
 
                       m_snap[no]->name()));
1021
 
 
1022
 
  /*
1023
 
    If error debugging is switched on (see debug.h) then any table whose
1024
 
    name starts with 'a' will trigger "no backup driver" error.
1025
 
   */
1026
 
  TEST_ERROR_IF(t.name().ptr()[0]=='a');
1027
 
 
1028
 
  if (no < 0 || TEST_ERROR)
1029
 
    goto end;
1030
 
 
1031
 
  // add table to the catalogue
1032
 
 
1033
 
  ti= Image_info::add_table(dbi,t,no);
1034
 
 
1035
 
  /*
1036
 
    If error debugging is switched on (see debug.h) then any table whose
1037
 
    name starts with 'b' will trigger error when added to backup image.
1038
 
   */
1039
 
  TEST_ERROR_IF(t.name().ptr()[0]=='b');
1040
 
 
1041
 
  if (!ti || TEST_ERROR)
1042
 
  {
1043
 
    report_error(ER_OUT_OF_RESOURCES);
1044
 
    goto end;
1045
 
  }
1046
 
 
1047
 
 end:
1048
 
 
1049
 
  ::close_thread_tables(m_thd);
1050
 
 
1051
 
  return ti;
1052
 
}
1053
 
 
1054
 
/**
1055
 
  Add to archive all items belonging to a given table.
1056
 
 
1057
 
  @todo Implement this.
1058
 
*/
1059
 
int Backup_info::add_table_items(Table_item&)
1060
 
{
1061
 
  // TODO: Implement when we handle per-table meta-data.
1062
 
  return 0;
1063
 
}
1064
 
 
1065
 
} // backup namespace
1066
 
 
1067
 
 
1068
 
/*************************************************
1069
 
 
1070
 
                   RESTORE
1071
 
 
1072
 
 *************************************************/
1073
 
 
1074
 
// Declarations of functions used in restore operation
1075
 
 
1076
 
namespace backup {
1077
 
 
1078
 
// defined in data_backup.cc
1079
 
int restore_table_data(THD*, Restore_info&, IStream&);
1080
 
 
1081
 
} // backup namespace
1082
 
 
1083
 
/**
1084
 
   Toggle foreign key constraints on and off.
1085
 
 
1086
 
   @param THD thd          Current thread structure.
1087
 
   @param my_bool turn_on  TRUE = turn on, FALSE = turn off.
1088
 
 
1089
 
   @returns TRUE if foreign key contraints are turned on already
1090
 
   @returns FALSE if foreign key contraints are turned off
1091
 
  */
1092
 
my_bool fkey_constr(THD *thd, my_bool turn_on)
1093
 
{
1094
 
  my_bool fk_status= FALSE;
1095
 
 
1096
 
  DBUG_ENTER("mysql_restore");
1097
 
  if (turn_on)
1098
 
    thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
1099
 
  else
1100
 
  {
1101
 
    fk_status= (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)? FALSE : TRUE;
1102
 
    thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
1103
 
  }
1104
 
  DBUG_RETURN(fk_status);
 
932
      fatal_error(ER_BACKUP_CANT_RESTORE_EVENT,ev->describe(buf));
 
933
      DBUG_RETURN(m_error);
 
934
    };
 
935
 
 
936
  DBUG_RETURN(0);
1105
937
}
1106
938
 
1107
939
/**
1108
940
  Restore objects saved in backup image.
1109
941
 
1110
 
  @pre The header and catalogue of backup image has been already read with
1111
 
  @c bstream_rd_header() function and stored inside the @c info object.
 
942
  @pre @c prepare_for_restore() method was called.
 
943
 
 
944
  @returns 0 on success, error code otherwise.
 
945
 
 
946
  @todo Remove the @c reset_diagnostic_area() hack.
1112
947
*/
1113
 
int mysql_restore(THD *thd, backup::Restore_info &info, backup::IStream &s)
 
948
int Backup_restore_ctx::do_restore()
1114
949
{
1115
 
  my_bool using_fkey_constr= FALSE;
 
950
  DBUG_ENTER("do_restore");
1116
951
 
1117
 
  DBUG_ENTER("mysql_restore");
 
952
  DBUG_ASSERT(is_valid());
 
953
  DBUG_ASSERT(m_state == PREPARED_FOR_RESTORE);
 
954
  DBUG_ASSERT(m_thd);
 
955
  DBUG_ASSERT(m_stream);
 
956
  DBUG_ASSERT(m_catalog);
1118
957
 
1119
958
  using namespace backup;
1120
959
 
1121
 
  s.next_chunk();
1122
 
 
1123
 
  DBUG_PRINT("restore",("Restoring meta-data"));
1124
 
 
1125
 
  /*
1126
 
    Turn off foreign key constraints (if turned on)
1127
 
  */
1128
 
  using_fkey_constr= fkey_constr(thd, FALSE);
1129
 
 
1130
 
  if (read_meta_data(info, s) == ERROR)
 
960
  int err;
 
961
  Input_stream &s= *static_cast<Input_stream*>(m_stream);
 
962
  Restore_info &info= *static_cast<Restore_info*>(m_catalog);
 
963
 
 
964
  report_stats_pre(info);
 
965
 
 
966
  DBUG_PRINT("restore", ("Restoring meta-data"));
 
967
 
 
968
  disable_fkey_constraints();
 
969
 
 
970
  if (read_meta_data(info, s))
1131
971
  {
1132
 
    fkey_constr(thd, using_fkey_constr);  
1133
 
    DBUG_RETURN(ERROR);
 
972
    fatal_error(ER_BACKUP_READ_META);
 
973
    DBUG_RETURN(m_error);
1134
974
  }
1135
975
 
1136
976
  s.next_chunk();
1137
977
 
1138
 
  thd->main_da.reset_diagnostics_area();
1139
 
 
1140
978
  DBUG_PRINT("restore",("Restoring table data"));
1141
979
 
 
980
  /* 
 
981
    FIXME: this call is here because object services doesn't clean the
 
982
    statement execution context properly, which leads to assertion failure.
 
983
    It should be fixed inside object services implementation and then the
 
984
    following line should be removed.
 
985
   */
 
986
  close_thread_tables(m_thd);
 
987
  m_thd->main_da.reset_diagnostics_area();
 
988
 
 
989
  if (lock_tables_for_restore()) // reports errors
 
990
    DBUG_RETURN(m_error);
 
991
 
1142
992
  // Here restore drivers are created to restore table data
1143
 
  if (restore_table_data(thd,info,s) == ERROR)
1144
 
  {
1145
 
    fkey_constr(thd, using_fkey_constr);
1146
 
    DBUG_RETURN(ERROR);
1147
 
  }
1148
 
 
1149
 
  /*
1150
 
    Turn on foreign key constraints (if previously turned on)
 
993
  err= restore_table_data(m_thd, info, s); // reports errors
 
994
 
 
995
  unlock_tables();
 
996
 
 
997
  if (err)
 
998
    DBUG_RETURN(ER_BACKUP_RESTORE);
 
999
 
 
1000
  /* 
 
1001
   Re-create all triggers and events (it was not done in @c bcat_create_item()).
 
1002
 
 
1003
   Note: it is important to do that after tables are unlocked, otherwise 
 
1004
   creation of these objects will fail.
1151
1005
  */
1152
 
  fkey_constr(thd, using_fkey_constr);
 
1006
 
 
1007
  if (restore_triggers_and_events())
 
1008
     DBUG_RETURN(ER_BACKUP_RESTORE);
1153
1009
 
1154
1010
  DBUG_PRINT("restore",("Done."));
1155
1011
 
1156
 
  if (read_summary(info,s) == ERROR)
1157
 
    DBUG_RETURN(ERROR);
 
1012
  if (read_summary(info, s))
 
1013
  {
 
1014
    fatal_error(ER_BACKUP_READ_SUMMARY);
 
1015
    DBUG_RETURN(m_error);
 
1016
  }
 
1017
 
 
1018
  /* 
 
1019
    FIXME: this call is here because object services doesn't clean the
 
1020
    statement execution context properly, which leads to assertion failure.
 
1021
    It should be fixed inside object services implementation and then the
 
1022
    following line should be removed.
 
1023
   */
 
1024
  close_thread_tables(m_thd);
 
1025
  m_thd->main_da.reset_diagnostics_area();
 
1026
 
 
1027
  report_stats_post(info);
1158
1028
 
1159
1029
  DBUG_RETURN(0);
1160
1030
}
1161
1031
 
1162
 
/****************************
1163
 
 
1164
 
  Restore_info implementation
1165
 
 
1166
 
 ****************************/
1167
1032
 
1168
1033
namespace backup {
1169
1034
 
1170
 
/**
1171
 
  Initialize @c Restore_info instance and load the catalogue from
1172
 
  the given backup stream.
1173
 
*/
1174
 
Restore_info::Restore_info(THD *thd, IStream &s):
1175
 
  Logger(Logger::RESTORE), m_valid(TRUE), m_thd(thd), curr_db(NULL),
1176
 
  system_charset(NULL), same_sys_charset(TRUE)
 
1035
/*************************************************
 
1036
 
 
1037
    Implementation of Mem_allocator class.
 
1038
 
 
1039
 *************************************************/
 
1040
 
 
1041
/// All allocated memory segments are linked into a list using this structure.
 
1042
struct Mem_allocator::node
1177
1043
{
1178
 
  int ret= BSTREAM_OK;
1179
 
 
1180
 
  ret= read_header(*this,s);
1181
 
 
1182
 
  if (!(m_valid= (ret != BSTREAM_ERROR)))
1183
 
    return;
1184
 
 
1185
 
  ret= s.next_chunk();
1186
 
 
1187
 
  if (!(m_valid= (ret == BSTREAM_OK)))
1188
 
    return;
1189
 
 
1190
 
  ret= read_catalog(*this,s);
1191
 
  m_valid= (ret != BSTREAM_ERROR);
1192
 
}
1193
 
 
1194
 
Restore_info::~Restore_info()
 
1044
  node *prev;
 
1045
  node *next;
 
1046
};
 
1047
 
 
1048
Mem_allocator::Mem_allocator() :first(NULL)
1195
1049
{}
1196
1050
 
1197
 
/**
1198
 
  Restore an object given its meta data.
1199
 
  
1200
 
  @param[in] it     Item instance identifying the object to restore
1201
 
  @param[in] sdata  the serialization read from backup image
1202
 
  @param[in] extra  other meta data stored in the image (not used now)
1203
 
 */ 
1204
 
result_t Restore_info::restore_item(Item &it, String &sdata, String &extra)
1205
 
{
1206
 
  using namespace obs;
1207
 
  
1208
 
  Obj *obj= it.obj_ptr(0, sdata);
1209
 
  
1210
 
  if (!obj)
1211
 
    return ERROR;
1212
 
  
1213
 
  return obj->execute(m_thd) ? ERROR : OK;
 
1051
/// Deletes all allocated segments which have not been freed explicitly.
 
1052
Mem_allocator::~Mem_allocator()
 
1053
{
 
1054
  node *n= first;
 
1055
 
 
1056
  while (n)
 
1057
  {
 
1058
    first= n->next;
 
1059
    my_free(n, MYF(0));
 
1060
    n= first;
 
1061
  }
 
1062
}
 
1063
 
 
1064
/**
 
1065
  Allocate memory segment of given size.
 
1066
 
 
1067
  Extra memory is allocated for @c node structure which holds pointers
 
1068
  to previous and next segment in the segments list. This is used when
 
1069
  deallocating allocated memory in the destructor.
 
1070
*/
 
1071
void* Mem_allocator::alloc(size_t howmuch)
 
1072
{
 
1073
  void *ptr= my_malloc(sizeof(node) + howmuch, MYF(0));
 
1074
 
 
1075
  if (!ptr)
 
1076
    return NULL;
 
1077
 
 
1078
  node *n= (node*)ptr;
 
1079
  ptr= n + 1;
 
1080
 
 
1081
  n->prev= NULL;
 
1082
  n->next= first;
 
1083
  if (first)
 
1084
    first->prev= n;
 
1085
  first= n;
 
1086
 
 
1087
  return ptr;
 
1088
}
 
1089
 
 
1090
/**
 
1091
  Explicit deallocation of previously allocated segment.
 
1092
 
 
1093
  The @c ptr should contain an address which was obtained from
 
1094
  @c Mem_allocator::alloc().
 
1095
 
 
1096
  The deallocated fragment is removed from the allocated fragments list.
 
1097
*/
 
1098
void Mem_allocator::free(void *ptr)
 
1099
{
 
1100
  if (!ptr)
 
1101
    return;
 
1102
 
 
1103
  node *n= ((node*)ptr) - 1;
 
1104
 
 
1105
  if (first == n)
 
1106
    first= n->next;
 
1107
 
 
1108
  if (n->prev)
 
1109
    n->prev->next= n->next;
 
1110
 
 
1111
  if (n->next)
 
1112
    n->next->prev= n->prev;
 
1113
 
 
1114
  my_free(n, MYF(0));
1214
1115
}
1215
1116
 
1216
1117
} // backup namespace
1217
1118
 
 
1119
 
1218
1120
/*************************************************
1219
1121
 
1220
1122
               CATALOGUE SERVICES
1222
1124
 *************************************************/
1223
1125
 
1224
1126
/**
1225
 
  Prepare @c Restore_info object for populating the catalogue with items to
1226
 
  restore.
 
1127
  Memory allocator for backup stream library.
 
1128
 
 
1129
  @pre A backup/restore context has been created and prepared for the 
 
1130
  operation (one of @c Backup_restore_ctx::prepare_for_backup() or 
 
1131
  @c Backup_restore_ctx::prepare_for_restore() have been called).
 
1132
 */
 
1133
extern "C"
 
1134
bstream_byte* bstream_alloc(unsigned long int size)
 
1135
{
 
1136
  using namespace backup;
 
1137
 
 
1138
  DBUG_ASSERT(Backup_restore_ctx::mem_alloc);
 
1139
 
 
1140
  return (bstream_byte*)Backup_restore_ctx::mem_alloc->alloc(size);
 
1141
}
 
1142
 
 
1143
/**
 
1144
  Memory deallocator for backup stream library.
 
1145
*/
 
1146
extern "C"
 
1147
void bstream_free(bstream_byte *ptr)
 
1148
{
 
1149
  using namespace backup;
 
1150
  if (Backup_restore_ctx::mem_alloc)
 
1151
    Backup_restore_ctx::mem_alloc->free(ptr);
 
1152
}
 
1153
 
 
1154
/**
 
1155
  Prepare restore catalogue for populating it with items read from
 
1156
  backup image.
1227
1157
 
1228
1158
  At this point we know the list of table data snapshots present in the image
1229
1159
  (it was read from image's header). Here we create @c Snapshot_info object
1230
1160
  for each of them.
1231
1161
 
1232
 
  @todo Report errors.
 
1162
  @rerturns 0 on success, error code otherwise.
1233
1163
*/
1234
1164
extern "C"
1235
1165
int bcat_reset(st_bstream_image_header *catalogue)
1236
1166
{
1237
1167
  using namespace backup;
1238
 
  uint no;
1239
 
 
 
1168
 
 
1169
  uint n;
 
1170
 
 
1171
  DBUG_ASSERT(catalogue);
1240
1172
  Restore_info *info= static_cast<Restore_info*>(catalogue);
1241
1173
 
1242
 
  for (no=0; no < info->snap_count; ++no)
 
1174
  /*
 
1175
    Iterate over the list of snapshots read from the backup image (and stored
 
1176
    in snapshot[] array in the catalogue) and for each snapshot create a 
 
1177
    corresponding Snapshot_info instance. A pointer to this instance is stored
 
1178
    in m_snap[] array.
 
1179
   */ 
 
1180
 
 
1181
  for (n=0; n < info->snap_count(); ++n)
1243
1182
  {
1244
 
    st_bstream_snapshot_info *snap= &info->snapshot[no];
 
1183
    st_bstream_snapshot_info *snap= &info->snapshot[n];
1245
1184
 
1246
 
    DBUG_PRINT("restore",("Creating info for snapshot no %d",no));
 
1185
    DBUG_PRINT("restore",("Creating info for snapshot no. %d", n));
1247
1186
 
1248
1187
    switch (snap->type) {
1249
1188
 
1250
1189
    case BI_NATIVE:
1251
1190
    {
1252
1191
      backup::LEX_STRING name_lex(snap->engine.name.begin, snap->engine.name.end);
1253
 
      plugin_ref se= ::ha_resolve_by_name(::current_thd,&name_lex);
1254
 
      handlerton *hton= plugin_data(se,handlerton*);
 
1192
      storage_engine_ref se= get_se_by_name(name_lex);
 
1193
      handlerton *hton= se_hton(se);
1255
1194
 
1256
 
      if (!hton)
 
1195
      if (!se || !hton)
1257
1196
      {
1258
 
        // TODO: report error
 
1197
        info->m_ctx.fatal_error(ER_BACKUP_CANT_FIND_SE, name_lex.str);
1259
1198
        return BSTREAM_ERROR;
1260
1199
      }
1261
1200
 
1262
1201
      if (!hton->get_backup_engine)
1263
1202
      {
1264
 
        // TODO: report error
 
1203
        info->m_ctx.fatal_error(ER_BACKUP_NO_NATIVE_BE, name_lex.str);
1265
1204
        return BSTREAM_ERROR;
1266
1205
      }
1267
1206
 
1268
 
      info->m_snap[no]= new Native_snapshot(se);
1269
 
 
 
1207
      info->m_snap[n]= new Native_snapshot(info->m_ctx, snap->version, se);
 
1208
                                                              // reports errors
1270
1209
      break;
1271
1210
    }
1272
1211
 
 
1212
    case BI_NODATA:
 
1213
      info->m_snap[n]= new Nodata_snapshot(info->m_ctx, snap->version);
 
1214
                                                              // reports errors
 
1215
      break;
 
1216
 
1273
1217
    case BI_CS:
1274
 
      info->m_snap[no]= new CS_snapshot();
 
1218
      info->m_snap[n]= new CS_snapshot(info->m_ctx, snap->version);
 
1219
                                                              // reports errors
1275
1220
      break;
1276
1221
 
1277
1222
    case BI_DEFAULT:
1278
 
      info->m_snap[no]= new Default_snapshot();
 
1223
      info->m_snap[n]= new Default_snapshot(info->m_ctx, snap->version);
 
1224
                                                              // reports errors
1279
1225
      break;
1280
1226
 
1281
1227
    default:
1282
 
      DBUG_PRINT("restore",("Unknown snapshot type %d",
1283
 
                            info->snapshot[no].type));
1284
 
      return BSTREAM_ERROR;
1285
 
    }
1286
 
 
1287
 
    if (!info->m_snap[no])
1288
 
    {
1289
 
      // TODO: report error
1290
 
      return BSTREAM_ERROR;
1291
 
    }
1292
 
 
1293
 
    if (info->m_snap[no]->set_version(snap->version) != OK)
1294
 
    {
1295
 
      // TODO: report error
1296
 
      return BSTREAM_ERROR;
1297
 
    }
1298
 
 
1299
 
    info->m_snap[no]->m_no= no+1;
1300
 
 
1301
 
    DBUG_PRINT("restore",(" snapshot uses %s engine",info->m_snap[no]->name()));
 
1228
      // note: we use convention that snapshots are counted starting from 1.
 
1229
      info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_BE, n + 1);
 
1230
      return BSTREAM_ERROR;
 
1231
    }
 
1232
 
 
1233
    if (!info->m_snap[n])
 
1234
    {
 
1235
      info->m_ctx.fatal_error(ER_OUT_OF_RESOURCES);
 
1236
      return BSTREAM_ERROR;
 
1237
    }
 
1238
 
 
1239
    info->m_snap[n]->m_num= n + 1;
 
1240
    info->m_ctx.report_driver(info->m_snap[n]->name());
1302
1241
  }
1303
1242
 
1304
1243
  return BSTREAM_OK;
1312
1251
*/
1313
1252
extern "C"
1314
1253
int bcat_close(st_bstream_image_header *catalogue)
1315
 
{ return BSTREAM_OK; }
 
1254
{
 
1255
  return BSTREAM_OK;
 
1256
}
1316
1257
 
1317
1258
/**
1318
1259
  Add item to restore catalogue.
1320
1261
  @todo Report errors.
1321
1262
*/
1322
1263
extern "C"
1323
 
int bcat_add_item(st_bstream_image_header *catalogue, struct st_bstream_item_info *item)
 
1264
int bcat_add_item(st_bstream_image_header *catalogue, 
 
1265
                  struct st_bstream_item_info *item)
1324
1266
{
1325
1267
  using namespace backup;
1326
1268
 
1335
1277
 
1336
1278
  switch (item->type) {
1337
1279
 
 
1280
  case BSTREAM_IT_TABLESPACE:
 
1281
  {
 
1282
    Image_info::Ts *ts= info->add_ts(name_str, item->pos); // reports errors
 
1283
 
 
1284
    return ts ? BSTREAM_OK : BSTREAM_ERROR;
 
1285
  }
 
1286
 
1338
1287
  case BSTREAM_IT_DB:
1339
1288
  {
1340
 
    Image_info::Db_ref db(name_str);
1341
 
 
1342
 
    Image_info::Db_item *dbi= info->add_db(db,item->pos);
1343
 
 
1344
 
    if (!dbi)
1345
 
    {
1346
 
      // TODO: report error
1347
 
      return BSTREAM_ERROR;
1348
 
    }
1349
 
 
1350
 
    return BSTREAM_OK;
 
1289
    Image_info::Db *db= info->add_db(name_str, item->pos); // reports errors
 
1290
 
 
1291
    return db ? BSTREAM_OK : BSTREAM_ERROR;
1351
1292
  }
1352
1293
 
1353
1294
  case BSTREAM_IT_TABLE:
1354
1295
  {
1355
1296
    st_bstream_table_info *it= (st_bstream_table_info*)item;
1356
1297
 
1357
 
    DBUG_PRINT("restore",(" table's snapshot no is %d",it->snap_no));
1358
 
 
1359
 
    Image_info::Db_item *db= info->get_db(it->base.db->base.pos);
 
1298
    DBUG_PRINT("restore",(" table's snapshot no. is %d", it->snap_num));
 
1299
 
 
1300
    Snapshot_info *snap= info->m_snap[it->snap_num];
 
1301
 
 
1302
    if (!snap)
 
1303
    {
 
1304
      /* 
 
1305
        This can happen only if the snapshot number is too big - if we failed
 
1306
        to create one of the snapshots listed in image's header we would stop
 
1307
        with error earlier.
 
1308
       */
 
1309
      DBUG_ASSERT(it->snap_num >= info->snap_count());
 
1310
      info->m_ctx.fatal_error(ER_BACKUP_WRONG_TABLE_BE, it->snap_num + 1);
 
1311
      return BSTREAM_ERROR;
 
1312
    }
 
1313
 
 
1314
    Image_info::Db *db= info->get_db(it->base.db->base.pos); // reports errors
1360
1315
 
1361
1316
    if (!db)
1362
 
    {
1363
 
      // TODO: report error
1364
 
      return BSTREAM_ERROR;
1365
 
    }
1366
 
 
1367
 
    DBUG_PRINT("restore",(" table's database is %s",db->name().ptr()));
1368
 
 
1369
 
    Image_info::Table_ref t(*db,name_str);
1370
 
 
1371
 
    Image_info::Table_item *ti= info->add_table(*db,t,it->snap_no,
1372
 
                                                      item->pos);
1373
 
    if (!ti)
1374
 
    {
1375
 
      // TODO: report error
1376
 
      return BSTREAM_ERROR;
1377
 
    }
1378
 
 
1379
 
    return BSTREAM_OK;
 
1317
      return BSTREAM_ERROR;
 
1318
 
 
1319
    DBUG_PRINT("restore",(" table's database is %s", db->name().ptr()));
 
1320
 
 
1321
    Image_info::Table *tbl= info->add_table(*db, name_str, *snap, item->pos); 
 
1322
                                                             // reports errors
 
1323
    
 
1324
    return tbl ? BSTREAM_OK : BSTREAM_ERROR;
1380
1325
  }
1381
1326
 
1382
1327
  case BSTREAM_IT_VIEW:
1389
1334
    
1390
1335
    DBUG_ASSERT(it->db);
1391
1336
    
1392
 
    Image_info::Db_item *db= (Image_info::Db_item*)
1393
 
                               info->locate_item((st_bstream_item_info*)it->db);
 
1337
    Image_info::Db *db= (Image_info::Db*) info->get_db(it->db->base.pos);
1394
1338
  
1395
1339
    DBUG_ASSERT(db);
1396
1340
    
1397
 
    Image_info::PerDb_item *it1= info->add_db_object(*db, item->type, name_str);
 
1341
    Image_info::Dbobj *it1= info->add_db_object(*db, item->type, name_str,
 
1342
                                                item->pos);
1398
1343
  
1399
1344
    if (!it1)
1400
1345
      return BSTREAM_ERROR;
1410
1355
 
1411
1356
/*****************************************************************
1412
1357
 
 
1358
   Iterators
 
1359
 
 
1360
 *****************************************************************/
 
1361
 
 
1362
static uint cset_iter;  ///< Used to implement trivial charset iterator.
 
1363
static uint null_iter;  ///< Used to implement trivial empty iterator.
 
1364
 
 
1365
/// Return pointer to an instance of iterator of a given type.
 
1366
extern "C"
 
1367
void* bcat_iterator_get(st_bstream_image_header *catalogue, unsigned int type)
 
1368
{
 
1369
  typedef backup::Image_info::Iterator Iterator; // to save some typing
 
1370
 
 
1371
  DBUG_ASSERT(catalogue);
 
1372
 
 
1373
  Backup_info *info= static_cast<Backup_info*>(catalogue);
 
1374
 
 
1375
  switch (type) {
 
1376
 
 
1377
  case BSTREAM_IT_PERTABLE: // per-table objects
 
1378
    return &null_iter;
 
1379
 
 
1380
  case BSTREAM_IT_CHARSET:  // character sets
 
1381
    cset_iter= 0;
 
1382
    return &cset_iter;
 
1383
 
 
1384
  case BSTREAM_IT_USER:     // users
 
1385
    return &null_iter;
 
1386
 
 
1387
  case BSTREAM_IT_TABLESPACE:     // table spaces
 
1388
  {
 
1389
    Iterator *it= info->get_tablespaces();
 
1390
  
 
1391
    if (!it)
 
1392
    {
 
1393
      info->m_ctx.fatal_error(ER_BACKUP_CAT_ENUM);
 
1394
      return NULL;
 
1395
    }
 
1396
 
 
1397
    return it;
 
1398
  }
 
1399
 
 
1400
  case BSTREAM_IT_DB:       // all databases
 
1401
  {
 
1402
    Iterator *it= info->get_dbs();
 
1403
  
 
1404
    if (!it)
 
1405
    {
 
1406
      info->m_ctx.fatal_error(ER_BACKUP_CAT_ENUM);
 
1407
      return NULL;
 
1408
    }
 
1409
 
 
1410
    return it;
 
1411
  }
 
1412
  
 
1413
  case BSTREAM_IT_PERDB:    // per-db objects, except tables
 
1414
  {
 
1415
    Iterator *it= info->get_perdb();
 
1416
  
 
1417
    if (!it)
 
1418
    {
 
1419
      info->m_ctx.fatal_error(ER_BACKUP_CAT_ENUM);
 
1420
      return NULL;
 
1421
    }
 
1422
 
 
1423
    return it;
 
1424
  }
 
1425
 
 
1426
  case BSTREAM_IT_GLOBAL:   // all global objects
 
1427
  {
 
1428
    Iterator *it= info->get_global();
 
1429
  
 
1430
    if (!it)
 
1431
    {
 
1432
      info->m_ctx.fatal_error(ER_BACKUP_CAT_ENUM);
 
1433
      return NULL;
 
1434
    }
 
1435
 
 
1436
    return it;
 
1437
  }
 
1438
 
 
1439
  default:
 
1440
    return NULL;
 
1441
 
 
1442
  }
 
1443
}
 
1444
 
 
1445
/// Return next item pointed by a given iterator and advance it to the next positon.
 
1446
extern "C"
 
1447
struct st_bstream_item_info*
 
1448
bcat_iterator_next(st_bstream_image_header *catalogue, void *iter)
 
1449
{
 
1450
  using namespace backup;
 
1451
 
 
1452
  /* If this is the null iterator, return NULL immediately */
 
1453
  if (iter == &null_iter)
 
1454
    return NULL;
 
1455
 
 
1456
  static bstream_blob name= {NULL, NULL};
 
1457
 
 
1458
  /*
 
1459
    If it is cset iterator then cset_iter variable contains iterator position.
 
1460
    We return only 2 charsets: the utf8 charset used to encode all strings and
 
1461
    the default server charset.
 
1462
  */
 
1463
  if (iter == &cset_iter)
 
1464
  {
 
1465
    switch (cset_iter) {
 
1466
      case 0: name.begin= (backup::byte*)my_charset_utf8_bin.csname; break;
 
1467
      case 1: name.begin= (backup::byte*)system_charset_info->csname; break;
 
1468
      default: name.begin= NULL; break;
 
1469
    }
 
1470
 
 
1471
    name.end= name.begin ? name.begin + strlen((char*)name.begin) : NULL;
 
1472
    cset_iter++;
 
1473
 
 
1474
    return name.begin ? (st_bstream_item_info*)&name : NULL;
 
1475
  }
 
1476
 
 
1477
  /*
 
1478
    In all other cases assume that iter points at instance of
 
1479
    @c Image_info::Iterator and use this instance to get next item.
 
1480
   */
 
1481
  const Image_info::Obj *ptr= (*(Image_info::Iterator*)iter)++;
 
1482
 
 
1483
  return ptr ? (st_bstream_item_info*)(ptr->info()) : NULL;
 
1484
}
 
1485
 
 
1486
extern "C"
 
1487
void  bcat_iterator_free(st_bstream_image_header *catalogue, void *iter)
 
1488
{
 
1489
  /*
 
1490
    Do nothing for the null and cset iterators, but delete the
 
1491
    @c Image_info::Iterator object otherwise.
 
1492
  */
 
1493
  if (iter == &null_iter)
 
1494
    return;
 
1495
 
 
1496
  if (iter == &cset_iter)
 
1497
    return;
 
1498
 
 
1499
  delete (backup::Image_info::Iterator*)iter;
 
1500
}
 
1501
 
 
1502
/* db-items iterator */
 
1503
 
 
1504
/** 
 
1505
  Return pointer to an iterator for iterating over objects inside a given 
 
1506
  database.
 
1507
 */
 
1508
extern "C"
 
1509
void* bcat_db_iterator_get(st_bstream_image_header *catalogue,
 
1510
                           st_bstream_db_info *dbi)
 
1511
{
 
1512
  DBUG_ASSERT(catalogue);
 
1513
  DBUG_ASSERT(dbi);
 
1514
  
 
1515
  Backup_info *info= static_cast<Backup_info*>(catalogue);
 
1516
  Backup_info::Db *db = info->get_db(dbi->base.pos);
 
1517
 
 
1518
  if (!db)
 
1519
  {
 
1520
    info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_OBJECT);
 
1521
    return NULL;
 
1522
  }
 
1523
 
 
1524
  backup::Image_info::Iterator *it= info->get_db_objects(*db);
 
1525
 
 
1526
  if (!it)
 
1527
  {
 
1528
    info->m_ctx.fatal_error(ER_BACKUP_LIST_DB_TABLES);
 
1529
    return NULL;
 
1530
  }
 
1531
 
 
1532
  return it;
 
1533
}
 
1534
 
 
1535
extern "C"
 
1536
struct st_bstream_dbitem_info*
 
1537
bcat_db_iterator_next(st_bstream_image_header *catalogue,
 
1538
                      st_bstream_db_info *db,
 
1539
                      void *iter)
 
1540
{
 
1541
  const backup::Image_info::Obj *ptr= (*(backup::Image_info::Iterator*)iter)++;
 
1542
 
 
1543
  return ptr ? (st_bstream_dbitem_info*)ptr->info() : NULL;
 
1544
}
 
1545
 
 
1546
extern "C"
 
1547
void  bcat_db_iterator_free(st_bstream_image_header *catalogue,
 
1548
                            st_bstream_db_info *db,
 
1549
                            void *iter)
 
1550
{
 
1551
  delete (backup::Image_info::Iterator*)iter;
 
1552
}
 
1553
 
 
1554
 
 
1555
/*****************************************************************
 
1556
 
1413
1557
   Services for backup stream library related to meta-data
1414
1558
   manipulation.
1415
1559
 
1416
1560
 *****************************************************************/
1417
1561
 
 
1562
/**
 
1563
  Create given item using serialization data read from backup image.
 
1564
 
 
1565
  @todo Decide what to do if unknown item type is found. Right now we
 
1566
  bail out.
 
1567
 */ 
1418
1568
extern "C"
1419
1569
int bcat_create_item(st_bstream_image_header *catalogue,
1420
1570
                     struct st_bstream_item_info *item,
1428
1578
  DBUG_ASSERT(item);
1429
1579
 
1430
1580
  Restore_info *info= static_cast<Restore_info*>(catalogue);
1431
 
 
1432
 
  Image_info::Item *it= info->locate_item(item);
1433
 
 
 
1581
  THD *thd= info->m_ctx.thd();
 
1582
  int create_err= 0;
 
1583
 
 
1584
  switch (item->type) {
 
1585
  
 
1586
  case BSTREAM_IT_DB:     create_err= ER_BACKUP_CANT_RESTORE_DB; break;
 
1587
  case BSTREAM_IT_TABLE:  create_err= ER_BACKUP_CANT_RESTORE_TABLE; break;
 
1588
  case BSTREAM_IT_VIEW:   create_err= ER_BACKUP_CANT_RESTORE_VIEW; break;
 
1589
  case BSTREAM_IT_SPROC:  create_err= ER_BACKUP_CANT_RESTORE_SROUT; break;
 
1590
  case BSTREAM_IT_SFUNC:  create_err= ER_BACKUP_CANT_RESTORE_SROUT; break;
 
1591
  case BSTREAM_IT_EVENT:  create_err= ER_BACKUP_CANT_RESTORE_EVENT; break;
 
1592
  case BSTREAM_IT_TRIGGER: create_err= ER_BACKUP_CANT_RESTORE_TRIGGER; break;
 
1593
  case BSTREAM_IT_TABLESPACE: create_err= ER_BACKUP_CANT_RESTORE_TS; break;
 
1594
  
1434
1595
  /*
1435
 
    TODO: Decide what to do when we come across unknown item (locate_item()
1436
 
    returns NULL): break the restore process as it is done now or continue
 
1596
    TODO: Decide what to do when we come across unknown item:
 
1597
    break the restore process as it is done now or continue
1437
1598
    with a warning?
1438
1599
  */
1439
1600
 
1440
 
  if (!it)
1441
 
    return BSTREAM_ERROR; // locate_item should report errors
 
1601
  default:
 
1602
    info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_OBJECT_TYPE);
 
1603
    return BSTREAM_ERROR;    
 
1604
  }
 
1605
 
 
1606
  Image_info::Obj *obj= find_obj(*info, *item);
 
1607
 
 
1608
  if (!obj)
 
1609
  {
 
1610
    info->m_ctx.fatal_error(ER_BACKUP_UNKNOWN_OBJECT);
 
1611
    return BSTREAM_ERROR;
 
1612
  }
1442
1613
 
1443
1614
  backup::String sdata(create_stmt.begin, create_stmt.end);
1444
 
  backup::String other_data(other_meta_data.begin, other_meta_data.end);
1445
1615
 
1446
1616
  DBUG_PRINT("restore",("Creating item of type %d pos %ld: %s",
1447
1617
                         item->type, item->pos, sdata.ptr()));
1448
 
 
1449
 
  result_t ret= info->restore_item(*it, sdata, other_data);
1450
 
 
1451
 
  return ret == OK ? BSTREAM_OK : BSTREAM_ERROR;
 
1618
  /*
 
1619
    Note: The instance created by Image_info::Obj::materialize() is deleted
 
1620
    when *info is destroyed.
 
1621
   */ 
 
1622
  obs::Obj *sobj= obj->materialize(0, sdata);
 
1623
 
 
1624
  Image_info::Obj::describe_buf buf;
 
1625
  const char *desc= obj->describe(buf);
 
1626
 
 
1627
  if (!sobj)
 
1628
  {
 
1629
    info->m_ctx.fatal_error(create_err, desc);
 
1630
    return BSTREAM_ERROR;
 
1631
  }
 
1632
 
 
1633
  /*
 
1634
    If the item we are creating is an event or trigger, we don't execute it
 
1635
    yet. It will be done in @c Backup_restore_ctx::do_restore() after table
 
1636
    data has been restored.
 
1637
   */ 
 
1638
  
 
1639
  switch (item->type) {
 
1640
 
 
1641
  case BSTREAM_IT_EVENT:
 
1642
  case BSTREAM_IT_TRIGGER:
 
1643
    return BSTREAM_OK;
 
1644
 
 
1645
  default: break;
 
1646
  
 
1647
  }
 
1648
 
 
1649
  // If we are to create a tablespace, first check if it already exists.
 
1650
 
 
1651
  if (item->type == BSTREAM_IT_TABLESPACE)
 
1652
  {
 
1653
    // if the tablespace exists, there is nothing more to do
 
1654
    if (obs::tablespace_exists(thd, sobj))
 
1655
    {
 
1656
      DBUG_PRINT("restore",(" skipping tablespace which exists"));
 
1657
      return BSTREAM_OK;
 
1658
    }
 
1659
 
 
1660
    /* 
 
1661
      If there is a different tablespace with the same name then we can't 
 
1662
      re-create the original tablespace used by tables being restored. We report 
 
1663
      this and cancel restore process.
 
1664
    */ 
 
1665
 
 
1666
    Obj *ts= obs::is_tablespace(thd, sobj->get_name()); 
 
1667
 
 
1668
    if (ts)
 
1669
    {
 
1670
      DBUG_PRINT("restore",(" tablespace has changed on the server - aborting"));
 
1671
      info->m_ctx.fatal_error(ER_BACKUP_TS_CHANGE, desc,
 
1672
                              obs::describe_tablespace(sobj)->ptr(),
 
1673
                              obs::describe_tablespace(ts)->ptr());
 
1674
      return BSTREAM_ERROR;
 
1675
    }
 
1676
  }
 
1677
 
 
1678
  // Create the object.
 
1679
 
 
1680
  if (sobj->execute(thd))
 
1681
  {
 
1682
    info->m_ctx.fatal_error(create_err, desc);
 
1683
    return BSTREAM_ERROR;
 
1684
  }
 
1685
  
 
1686
  return BSTREAM_OK;
1452
1687
}
1453
1688
 
 
1689
/**
 
1690
  Get serialization string for a given object.
 
1691
  
 
1692
  The catalogue should contain @c Image_info::Obj instance corresponding to the
 
1693
  object described by @c item. This instance should contain pointer to 
 
1694
  @c obs::Obj instance which can be used for getting the serialization string.
 
1695
 
 
1696
  @todo Decide what to do with the serialization string buffer - is it 
 
1697
  acceptable to re-use a single buffer as it is done now?
 
1698
 */ 
1454
1699
extern "C"
1455
1700
int bcat_get_item_create_query(st_bstream_image_header *catalogue,
1456
1701
                               struct st_bstream_item_info *item,
1463
1708
  DBUG_ASSERT(item);
1464
1709
  DBUG_ASSERT(stmt);
1465
1710
 
1466
 
  Image_info *info= static_cast<Image_info*>(catalogue);
1467
 
 
1468
 
  Image_info::Item *it= info->locate_item(item);
1469
 
 
1470
 
  if (!it)
 
1711
  Backup_info *info= static_cast<Backup_info*>(catalogue);
 
1712
 
 
1713
  int meta_err= 0;
 
1714
 
 
1715
  switch (item->type) {
 
1716
  
 
1717
  case BSTREAM_IT_DB:     meta_err= ER_BACKUP_GET_META_DB; break;
 
1718
  case BSTREAM_IT_TABLE:  meta_err= ER_BACKUP_GET_META_TABLE; break;
 
1719
  case BSTREAM_IT_VIEW:   meta_err= ER_BACKUP_GET_META_VIEW; break;
 
1720
  case BSTREAM_IT_SPROC:  meta_err= ER_BACKUP_GET_META_SROUT; break;
 
1721
  case BSTREAM_IT_SFUNC:  meta_err= ER_BACKUP_GET_META_SROUT; break;
 
1722
  case BSTREAM_IT_EVENT:  meta_err= ER_BACKUP_GET_META_EVENT; break;
 
1723
  case BSTREAM_IT_TRIGGER: meta_err= ER_BACKUP_GET_META_TRIGGER; break;
 
1724
  case BSTREAM_IT_TABLESPACE: meta_err= ER_BACKUP_GET_META_TS; break;
 
1725
  
 
1726
  /*
 
1727
    This can't happen - the item was obtained from the backup kernel.
 
1728
  */
 
1729
  default: DBUG_ASSERT(FALSE);
 
1730
  }
 
1731
 
 
1732
  Image_info::Obj *obj= find_obj(*info, *item);
 
1733
 
 
1734
  /*
 
1735
    The catalogue should contain the specified object and it should have 
 
1736
    a corresponding server object instance.
 
1737
   */ 
 
1738
  DBUG_ASSERT(obj);
 
1739
  DBUG_ASSERT(obj->m_obj_ptr);
 
1740
  
 
1741
  /*
 
1742
    Note: Using single buffer here means that the string returned by
 
1743
    this function will live only until the next call. This should be fine
 
1744
    given the current ussage of the function inside the backup stream library.
 
1745
    
 
1746
    TODO: document this or find better solution for string storage.
 
1747
   */ 
 
1748
  
 
1749
  ::String *buf= &(info->serialization_buf);
 
1750
  buf->length(0);
 
1751
 
 
1752
  if (obj->m_obj_ptr->serialize(info->m_ctx.thd(), buf))
1471
1753
  {
1472
 
    // TODO: warn that object was not found (?)
1473
 
    return BSTREAM_ERROR;
 
1754
    Image_info::Obj::describe_buf dbuf;
 
1755
 
 
1756
    info->m_ctx.fatal_error(meta_err, obj->describe(dbuf));
 
1757
    return BSTREAM_ERROR;    
1474
1758
  }
1475
1759
 
1476
 
  info->create_stmt_buf.length(0);
1477
 
  result_t res= it->get_serialization(::current_thd, info->create_stmt_buf);
1478
 
 
1479
 
  if (res != OK)
1480
 
    return BSTREAM_ERROR;
1481
 
 
1482
 
  stmt->begin= (backup::byte*)info->create_stmt_buf.ptr();
1483
 
  stmt->end= stmt->begin + info->create_stmt_buf.length();
 
1760
  stmt->begin= (backup::byte*)buf->ptr();
 
1761
  stmt->end= stmt->begin + buf->length();
1484
1762
 
1485
1763
  return BSTREAM_OK;
1486
1764
}
1487
1765
 
1488
 
 
 
1766
/**
 
1767
  Get extra meta-data (if any) for a given object.
 
1768
 
 
1769
  @note Extra meta-data is not used currently.
 
1770
 */ 
1489
1771
extern "C"
1490
1772
int bcat_get_item_create_data(st_bstream_image_header *catalogue,
1491
1773
                            struct st_bstream_item_info *item,
1498
1780
 
1499
1781
/*************************************************
1500
1782
 
1501
 
    MEMORY ALLOCATOR FOR BACKUP STREAM LIBRARY
1502
 
 
1503
 
 *************************************************/
1504
 
 
1505
 
namespace backup {
1506
 
 
1507
 
/**
1508
 
  This calss provides memory allocation services for backup stream library.
1509
 
 
1510
 
  An instance of this class must be created and pointer to it stored in the
1511
 
  static @c instance variable during BACKUP/RESTORE operation. This assumes
1512
 
  only one BACKUP/RESTORE operation is running at a time.
1513
 
*/
1514
 
class Mem_allocator
1515
 
{
1516
 
 public:
1517
 
 
1518
 
  Mem_allocator();
1519
 
  ~Mem_allocator();
1520
 
 
1521
 
  void* alloc(size_t);
1522
 
  void  free(void*);
1523
 
 
1524
 
  static Mem_allocator *instance;
1525
 
 
1526
 
 private:
1527
 
 
1528
 
  /// All allocated memory segments are linked into a list using this structure.
1529
 
  struct node
1530
 
  {
1531
 
    node *prev;
1532
 
    node *next;
1533
 
  };
1534
 
 
1535
 
  node *first;  ///< Pointer to the first segment in the list.
1536
 
};
1537
 
 
1538
 
 
1539
 
Mem_allocator::Mem_allocator(): first(NULL)
1540
 
{}
1541
 
 
1542
 
/// Deletes all allocated segments which have not been freed.
1543
 
Mem_allocator::~Mem_allocator()
1544
 
{
1545
 
  node *n= first;
1546
 
 
1547
 
  while (n)
1548
 
  {
1549
 
    first= n->next;
1550
 
    my_free(n,MYF(0));
1551
 
    n= first;
1552
 
  }
1553
 
}
1554
 
 
1555
 
/**
1556
 
  Allocate memory segment of given size.
1557
 
 
1558
 
  Extra memory is allocated for a @c node structure which holds pointers
1559
 
  to previous and next segment in the segments list. This is used when
1560
 
  deallocating allocated memory in the destructor.
1561
 
*/
1562
 
void* Mem_allocator::alloc(size_t howmuch)
1563
 
{
1564
 
  void *ptr= my_malloc(sizeof(node)+howmuch, MYF(0));
1565
 
 
1566
 
  if (!ptr)
1567
 
    return NULL;
1568
 
 
1569
 
  node *n= (node*)ptr;
1570
 
  ptr= n + 1;
1571
 
 
1572
 
  n->prev= NULL;
1573
 
  n->next= first;
1574
 
  if (first)
1575
 
    first->prev= n;
1576
 
  first= n;
1577
 
 
1578
 
  return ptr;
1579
 
}
1580
 
 
1581
 
/**
1582
 
  Explicit deallocation of previously allocated segment.
1583
 
 
1584
 
  The @c ptr should contain an address which was obtained from
1585
 
  @c Mem_allocator::alloc().
1586
 
 
1587
 
  The deallocated fragment is removed from the allocated fragments list.
1588
 
*/
1589
 
void Mem_allocator::free(void *ptr)
1590
 
{
1591
 
  if (!ptr)
1592
 
    return;
1593
 
 
1594
 
  node *n= ((node*)ptr) - 1;
1595
 
 
1596
 
  if (first == n)
1597
 
    first= n->next;
1598
 
 
1599
 
  if (n->prev)
1600
 
    n->prev->next= n->next;
1601
 
 
1602
 
  if (n->next)
1603
 
    n->next->prev= n->prev;
1604
 
 
1605
 
  my_free(n,MYF(0));
1606
 
}
1607
 
 
1608
 
Mem_allocator *Mem_allocator::instance= NULL;
1609
 
 
1610
 
/**
1611
 
  This function must be called before @c bstream_alloc() can be used.
1612
 
*/
1613
 
void prepare_stream_memory()
1614
 
{
1615
 
  if (Mem_allocator::instance)
1616
 
    delete Mem_allocator::instance;
1617
 
 
1618
 
  Mem_allocator::instance= new Mem_allocator();
1619
 
}
1620
 
 
1621
 
/**
1622
 
  This function should be called when @c bstream_alloc()/ @c bstream_free()
1623
 
  are no longer to be used.
1624
 
 
1625
 
  It destroys the Mem_allocator instance which frees all memory which was
1626
 
  allocated but not explicitly freed.
1627
 
*/
1628
 
void free_stream_memory()
1629
 
{
1630
 
  delete Mem_allocator::instance;
1631
 
  Mem_allocator::instance= NULL;
1632
 
}
1633
 
 
1634
 
}
1635
 
 
1636
 
extern "C" {
1637
 
 
1638
 
/**
1639
 
  Memory allocator for backup stream library.
1640
 
 
1641
 
  @pre @c prepare_stream_memory() has been called (i.e., the Mem_allocator
1642
 
  instance is created.
1643
 
 */
1644
 
bstream_byte* bstream_alloc(unsigned long int size)
1645
 
{
1646
 
  using namespace backup;
1647
 
 
1648
 
  DBUG_ASSERT(Mem_allocator::instance);
1649
 
 
1650
 
  return (bstream_byte*)Mem_allocator::instance->alloc(size);
1651
 
}
1652
 
 
1653
 
/**
1654
 
  Memory deallocator for backup stream library.
1655
 
*/
1656
 
void bstream_free(bstream_byte *ptr)
1657
 
{
1658
 
  using namespace backup;
1659
 
 
1660
 
  if (Mem_allocator::instance)
1661
 
    Mem_allocator::instance->free(ptr);
1662
 
}
1663
 
 
1664
 
}
1665
 
 
1666
 
/*************************************************
1667
 
 
1668
 
               BACKUP LOCATIONS
1669
 
 
1670
 
 *************************************************/
1671
 
 
1672
 
namespace backup {
1673
 
 
1674
 
/**
1675
 
  Specialization of @c Location class representing a file in the local
1676
 
  filesystem.
1677
 
*/
1678
 
struct File_loc: public Location
1679
 
{
1680
 
  ::String path;
1681
 
 
1682
 
  enum_type type() const
1683
 
  { return SERVER_FILE; }
1684
 
 
1685
 
  File_loc(const char *p)
1686
 
  { path.append(p); }
1687
 
 
1688
 
  bool is_valid()
1689
 
  {
1690
 
   /*
1691
 
     On some systems certain file names are invalid. We use 
1692
 
     check_if_legal_filename() function from mysys to detect this.
1693
 
    */ 
1694
 
#if defined(__WIN__) || defined(__EMX__)  
1695
 
  
1696
 
   if (check_if_legal_filename(path.c_ptr()))
1697
 
    return FALSE;
1698
 
  
1699
 
#endif
1700
 
    return TRUE;
1701
 
  }
1702
 
  
1703
 
  const char* describe()
1704
 
  { return path.c_ptr(); }
1705
 
 
1706
 
  result_t remove()
1707
 
  {
1708
 
    int res= my_delete(path.c_ptr(),MYF(0));
1709
 
 
1710
 
    /*
1711
 
      Ignore ENOENT error since it is ok if the file doesn't exist.
1712
 
     */
1713
 
    if (my_errno == ENOENT)
1714
 
      res= 0;
1715
 
 
1716
 
    if (res)
1717
 
      sql_print_error(ER(ER_CANT_DELETE_FILE),path.c_ptr(),my_errno);
1718
 
 
1719
 
    return res ? ERROR : OK;
1720
 
  }
1721
 
};
1722
 
 
1723
 
 
1724
 
template<class S>
1725
 
S* open_stream(const Location &loc)
1726
 
{
1727
 
  switch (loc.type()) {
1728
 
 
1729
 
  case Location::SERVER_FILE:
1730
 
  {
1731
 
    const File_loc &f= static_cast<const File_loc&>(loc);
1732
 
    S *s= new S(f.path);
1733
 
 
1734
 
    if (s && s->open())
1735
 
      return s;
1736
 
 
1737
 
    delete s;
1738
 
    return NULL;
1739
 
  }
1740
 
 
1741
 
  default:
1742
 
    return NULL;
1743
 
 
1744
 
  }
1745
 
}
1746
 
 
1747
 
template IStream* open_stream<IStream>(const Location&);
1748
 
template OStream* open_stream<OStream>(const Location&);
1749
 
 
1750
 
IStream* open_for_read(const Location &loc)
1751
 
{
1752
 
  return open_stream<IStream>(loc);
1753
 
}
1754
 
 
1755
 
OStream* open_for_write(const Location &loc)
1756
 
{
1757
 
  return open_stream<OStream>(loc);
1758
 
}
1759
 
 
1760
 
/**
1761
 
  Find location described by a string.
1762
 
 
1763
 
  The string is taken from the "TO ..." clause of BACKUP/RESTORE commands.
1764
 
  This function parses the string and creates instance of @c Location class
1765
 
  describing the location or NULL if string doesn't describe any valid location.
1766
 
 
1767
 
  Currently the only supported type of location is a file on the server host.
1768
 
  The string is supposed to contain a path to such file.
1769
 
 
1770
 
  @note No checks on the location are made at this stage. In particular the
1771
 
  location might not physically exist. In the future methods performing such
1772
 
  checks can be added to @Location class.
1773
 
 */
1774
 
Location*
1775
 
Location::find(const LEX_STRING &where)
1776
 
{
1777
 
  return where.str && where.length ? new File_loc(where.str) : NULL;
1778
 
}
1779
 
 
1780
 
} // backup namespace
1781
 
 
1782
 
 
1783
 
/*************************************************
1784
 
 
1785
 
                 Helper functions
1786
 
 
1787
 
 *************************************************/
1788
 
 
1789
 
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list); // defined in sql_show.cc
1790
 
 
1791
 
namespace backup {
1792
 
 
1793
 
/**
1794
 
  Report errors.
1795
 
 
1796
 
  Current implementation reports the last error saved in the logger if it exist.
1797
 
  Otherwise it reports error given by @c error_code.
1798
 
 */
1799
 
int report_errors(THD *thd, Logger &log, int error_code, ...)
1800
 
{
1801
 
  MYSQL_ERROR *error= log.last_saved_error();
1802
 
 
1803
 
  if (error && !util::report_mysql_error(thd,error,error_code))
1804
 
  {
1805
 
    if (error->code)
1806
 
      error_code= error->code;
1807
 
  }
1808
 
  else // there are no error information in the logger - report error_code
1809
 
  {
1810
 
    char buf[ERRMSGSIZE + 20];
1811
 
    va_list args;
1812
 
    va_start(args,error_code);
1813
 
 
1814
 
    my_vsnprintf(buf,sizeof(buf),ER_SAFE(error_code),args);
1815
 
    my_printf_error(error_code,buf,MYF(0));
1816
 
 
1817
 
    va_end(args);
1818
 
  }
1819
 
 
1820
 
  return error_code;
1821
 
}
1822
 
 
1823
 
inline
1824
 
int check_info(THD *thd, Backup_info &info)
1825
 
{
1826
 
  return info.is_valid() ? OK : report_errors(thd,info,ER_BACKUP_BACKUP_PREPARE);
1827
 
}
1828
 
 
1829
 
inline
1830
 
int check_info(THD *thd, Restore_info &info)
1831
 
{
1832
 
  return info.is_valid() ? OK : report_errors(thd,info,ER_BACKUP_RESTORE_PREPARE);
1833
 
}
1834
 
 
1835
 
/**
1836
 
  Send a summary of the backup/restore operation to the client.
1837
 
 
1838
 
  The data about the operation is taken from filled @c Archive_info
1839
 
  structure. Parameter @c backup determines if this was backup or
1840
 
  restore operation.
1841
 
*/
1842
 
static
1843
 
bool send_summary(THD *thd, const Image_info &info, bool backup)
1844
 
{
1845
 
  Protocol *protocol= thd->protocol;    // client comms
1846
 
  List<Item> field_list;                // list of fields to send
1847
 
  String     op_str("backup_id");       // operations string
1848
 
  int ret= 0;                           // return value
1849
 
  char buf[255];                        // buffer for summary information
1850
 
  String str;
1851
 
 
1852
 
  DBUG_ENTER("backup::send_summary");
1853
 
 
1854
 
  DBUG_PRINT(backup?"backup":"restore", ("sending summary"));
1855
 
 
1856
 
  /*
1857
 
    Send field list.
1858
 
  */
1859
 
  field_list.push_back(new Item_empty_string(op_str.c_ptr(), op_str.length()));
1860
 
  protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
1861
 
 
1862
 
  /*
1863
 
    Send field data.
1864
 
  */
1865
 
  protocol->prepare_for_resend();
1866
 
  llstr(info.backup_prog_id,buf);
1867
 
  protocol->store(buf, system_charset_info);
1868
 
  protocol->write();
1869
 
 
1870
 
  my_eof(thd);
1871
 
  DBUG_RETURN(ret);
1872
 
}
1873
 
 
1874
 
inline
1875
 
bool send_summary(THD *thd, const Backup_info &info)
1876
 
{ return send_summary(thd,info,TRUE); }
1877
 
 
1878
 
inline
1879
 
bool send_summary(THD *thd, const Restore_info &info)
1880
 
{ return send_summary(thd,info,FALSE); }
1881
 
 
1882
 
 
1883
 
/// Open given table in @c INFORMATION_SCHEMA database.
1884
 
TABLE* get_schema_table(THD *thd, ST_SCHEMA_TABLE *st)
1885
 
{
1886
 
  TABLE *t;
1887
 
  TABLE_LIST arg;
1888
 
  my_bitmap_map *old_map;
1889
 
 
1890
 
  bzero( &arg, sizeof(TABLE_LIST) );
1891
 
 
1892
 
  // set context for create_schema_table call
1893
 
  arg.schema_table= st;
1894
 
  arg.alias=        NULL;
1895
 
  arg.select_lex=   NULL;
1896
 
 
1897
 
  t= ::create_schema_table(thd,&arg); // Note: callers must free t.
1898
 
 
1899
 
  if( !t ) return NULL; // error!
1900
 
 
1901
 
  /*
1902
 
   Temporarily set thd->lex->wild to NULL to keep st->fill_table
1903
 
   happy.
1904
 
  */
1905
 
  ::String *wild= thd->lex->wild;
1906
 
  ::enum_sql_command command= thd->lex->sql_command;
1907
 
 
1908
 
  thd->lex->wild = NULL;
1909
 
  thd->lex->sql_command = enum_sql_command(0);
1910
 
 
1911
 
  // context for fill_table
1912
 
  arg.table= t;
1913
 
 
1914
 
  old_map= tmp_use_all_columns(t, t->read_set);
1915
 
 
1916
 
  st->fill_table(thd, &arg, 
1917
 
    obs::create_db_select_condition(thd, t, &thd->lex->db_list));
1918
 
 
1919
 
  tmp_restore_column_map(t->read_set, old_map);
1920
 
 
1921
 
  // undo changes to thd->lex
1922
 
  thd->lex->wild= wild;
1923
 
  thd->lex->sql_command= command;
1924
 
 
1925
 
  return t;
1926
 
}
1927
 
 
1928
 
/// Build linked @c TABLE_LIST list from a list stored in @c Table_list object.
 
1783
           Implementation of Table_ref class
 
1784
 
 
1785
 *************************************************/
 
1786
 
 
1787
namespace backup {
 
1788
 
 
1789
/** 
 
1790
  Produce string identifying the table in internal format (as used by 
 
1791
  storage engines).
 
1792
*/
 
1793
const char* Table_ref::internal_name(char *buf, size_t len) const
 
1794
{
 
1795
  uint plen= build_table_filename(buf, len, 
 
1796
                                  db().name().ptr(), name().ptr(), 
 
1797
                                  "", /* no extension */ 
 
1798
                                  0 /* not a temporary table - do conversions */);
 
1799
  buf[plen]='\0';
 
1800
  return buf;    
 
1801
}
 
1802
 
 
1803
/** 
 
1804
    Produce human readable string identifying the table 
 
1805
    (e.g. for error reporting)
 
1806
*/
 
1807
const char* Table_ref::describe(char *buf, size_t len) const
 
1808
{
 
1809
  my_snprintf(buf, len, "`%s`.`%s`", db().name().ptr(), name().ptr());
 
1810
  return buf;
 
1811
}
1929
1812
 
1930
1813
/*
1931
 
  FIXME: build list with the same order as in input
1932
 
  Actually, should work fine with reversed list as long as we use the reversed
1933
 
  list both in table writing and reading.
1934
 
 */
 
1814
  TODO: remove these functions. Currently they are only used by the myisam 
 
1815
  native backup engine.
 
1816
*/
1935
1817
TABLE_LIST *build_table_list(const Table_list &tables, thr_lock_type lock)
1936
1818
{
1937
1819
  TABLE_LIST *tl= NULL;
1938
1820
 
1939
1821
  for( uint tno=0; tno < tables.count() ; tno++ )
1940
1822
  {
1941
 
    TABLE_LIST *ptr= (TABLE_LIST*)my_malloc(sizeof(TABLE_LIST), MYF(MY_WME));
1942
 
    DBUG_ASSERT(ptr);  // FIXME: report error instead
1943
 
    bzero(ptr,sizeof(TABLE_LIST));
1944
 
 
1945
 
    Table_ref tbl= tables[tno];
1946
 
 
1947
 
    ptr->alias= ptr->table_name= const_cast<char*>(tbl.name().ptr());
1948
 
    ptr->db= const_cast<char*>(tbl.db().name().ptr());
1949
 
    ptr->lock_type= lock;
1950
 
 
1951
 
    // and add it to the list
1952
 
 
1953
 
    ptr->next_global= ptr->next_local=
1954
 
      ptr->next_name_resolution_table= tl;
1955
 
    tl= ptr;
1956
 
    tl->table= ptr->table;
 
1823
    TABLE_LIST *ptr = mk_table_list(tables[tno], lock, ::current_thd->mem_root);
 
1824
    DBUG_ASSERT(ptr);
 
1825
    tl= link_table_list(*ptr,tl);
1957
1826
  }
1958
1827
 
1959
1828
  return tl;
1960
1829
}
1961
1830
 
1962
 
 
1963
 
/// Execute SQL query without sending anything to client.
1964
 
 
1965
 
int silent_exec_query(THD *thd, ::String &query)
1966
 
{
1967
 
  Vio *save_vio= thd->net.vio;
1968
 
 
1969
 
  DBUG_PRINT("restore",("executing query %s",query.c_ptr()));
1970
 
 
1971
 
  /*
1972
 
    Note: the change net.vio idea taken from execute_init_command in
1973
 
    sql_parse.cc
1974
 
   */
1975
 
  thd->net.vio= 0;
1976
 
 
1977
 
  thd->query=         query.c_ptr();
1978
 
  thd->query_length=  query.length();
1979
 
 
1980
 
  thd->set_time(time(NULL));
1981
 
  pthread_mutex_lock(&::LOCK_thread_count);
1982
 
  thd->query_id= ::next_query_id();
1983
 
  pthread_mutex_unlock(&::LOCK_thread_count);
1984
 
 
1985
 
  /*
1986
 
    @todo The following is a work around for online backup and the DDL blocker.
1987
 
          It should be removed when the generalized solution is in place.
1988
 
          This is needed to ensure the restore (which uses DDL) is not blocked
1989
 
          when the DDL blocker is engaged.
1990
 
  */
1991
 
  thd->DDL_exception= TRUE;
1992
 
 
1993
 
  const char *ptr;
1994
 
  ::mysql_parse(thd,thd->query,thd->query_length,&ptr);
1995
 
 
1996
 
  thd->net.vio= save_vio;
1997
 
 
1998
 
  if (thd->is_error())
1999
 
  {
2000
 
    DBUG_PRINT("restore",
2001
 
              ("error executing query %s!", thd->query));
2002
 
    DBUG_PRINT("restore",("last error (%d): %s",thd->net.last_errno
2003
 
                                               ,thd->net.last_error));
2004
 
    return thd->net.last_errno ? (int)thd->net.last_errno : -1;
2005
 
  }
2006
 
 
2007
 
  return 0;
2008
 
}
 
1831
void free_table_list(TABLE_LIST*)
 
1832
{}
2009
1833
 
2010
1834
} // backup namespace
2011
1835
 
2012
 
extern pthread_mutex_t LOCK_backup;
 
1836
 
 
1837
/*************************************************
 
1838
 
 
1839
                 Helper functions
 
1840
 
 
1841
 *************************************************/
2013
1842
 
2014
1843
namespace backup {
2015
 
  
2016
 
static bool backup_or_restore_is_running= FALSE;
2017
 
 
2018
 
/**
2019
 
  Indicate that BACKUP/RESTORE operation has started.
2020
 
  
2021
 
  @returns 0 if it is OK to continue or non-zero if another BACKUP/RESTORE
2022
 
  command is running and it is not possible to execute enather one now.
2023
 
 */ 
2024
 
int start_backup_or_restore()
2025
 
{
2026
 
  bool running;
2027
 
  
2028
 
  pthread_mutex_lock(&::LOCK_backup);
2029
 
  running= backup_or_restore_is_running;
2030
 
  if (!running)
2031
 
    backup_or_restore_is_running= TRUE;
2032
 
  pthread_mutex_unlock(&::LOCK_backup);
2033
 
 
2034
 
  return running;
2035
 
}
2036
 
 
2037
 
/**
2038
 
  Indicate that BACKUP/RESTORE operation has finished.
2039
 
  
2040
 
  This function should be called only if an earlier call to 
2041
 
  start_backup_or_restore() was successful.
2042
 
 */ 
2043
 
void finish_backup_or_restore()
2044
 
{
2045
 
  pthread_mutex_lock(&::LOCK_backup);
2046
 
  backup_or_restore_is_running= FALSE;
2047
 
  pthread_mutex_unlock(&::LOCK_backup);
2048
 
}
 
1844
 
 
1845
/** 
 
1846
  Build linked @c TABLE_LIST list from a list stored in @c Table_list object.
 
1847
 
 
1848
  @note The order of tables in the returned list is different than in the 
 
1849
  input list (reversed).
 
1850
 
 
1851
  @todo Decide what to do if errors are detected. For example, how to react
 
1852
  if memory for TABLE_LIST structure could not be allocated?
 
1853
 */
 
1854
 
2049
1855
 
2050
1856
} // backup namespace