Skip to content

Commit ce7fba6

Browse files
committed
squash! 43946ba
log_t::backup_start(): If we were running with innodb_log_archive=ON, ensure that the latest file is a valid recovery starting point. That is, wait for the latest log checkpoint to be within the file.
1 parent 5c0f619 commit ce7fba6

1 file changed

Lines changed: 31 additions & 11 deletions

File tree

storage/innobase/handler/backup_innodb.cc

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,19 @@ class InnoDB_backup
152152
struct context
153153
{
154154
/** Start LSN of the first backed up log file */
155-
lsn_t first_lsn;
155+
const lsn_t first_lsn;
156156
/** Start LSN of the last log file, or LSN_MAX if not determined yet */
157157
lsn_t max_first_lsn;
158158
/** Final LSN of the backup, or LSN_MAX if not determined yet */
159159
lsn_t last_lsn;
160160
/** size of the first log file */
161-
uint64_t first_size;
161+
const uint64_t first_size;
162162
/** Checkpoint at the start of the backup */
163-
lsn_t checkpoint;
163+
const lsn_t checkpoint;
164164
/** Log record pointing to the checkpoint */
165-
lsn_t checkpoint_end_lsn;
165+
const lsn_t checkpoint_end_lsn;
166166
/** the original state of innodb_log_archive before/after backup */
167-
bool archived;
167+
const bool archived;
168168
/** whether end() was invoked */
169169
bool cleaned_up;
170170
/** the start LSN of the last hard-linked file, or 0 */
@@ -361,19 +361,29 @@ class InnoDB_backup
361361
delete_logs();
362362
mutex.wr_unlock();
363363

364-
const bool fail{log_sys.backup_start(&old_size, thd)};
364+
if (log_sys.backup_start(&old_size, thd))
365+
{
366+
log_sys.latch.wr_unlock();
367+
fail:
368+
my_error(ER_OUT_OF_RESOURCES, MYF(ME_ERROR_LOG));
369+
return reinterpret_cast<void*>(-1);
370+
}
371+
365372
mutex.wr_lock();
366373

367-
if (!fail) try
374+
try
368375
{
369376
lsn_t start_end;
370377
const lsn_t start=
371378
#if 1 /* TODO: for incremental backup, allow the start to be specified */
372379
log_sys.get_latest_checkpoint(start_end);
373380
#else
374-
log_sys.archived_checkpoint;
381+
log_sys.archived_checkpoint;
375382
start_end= log_sys.archived_lsn;
376383
#endif
384+
ut_ad(start_end >= start);
385+
ut_ad(start >= log_sys.get_first_lsn());
386+
377387
ctx= new context{
378388
log_sys.get_first_lsn(), LSN_MAX, LSN_MAX, log_sys.file_size,
379389
start, start_end, !old_size, false, 0
@@ -420,14 +430,13 @@ class InnoDB_backup
420430
delete ctx;
421431
ctx= nullptr;
422432
log_sys.backup_stop(old_size, thd);
423-
my_error(ER_OUT_OF_RESOURCES, MYF(ME_ERROR_LOG));
424-
return reinterpret_cast<void*>(-1);
433+
goto fail;
425434
}
426435

427436
mutex.wr_unlock();
428437
log_sys.latch.wr_unlock();
429438
DEBUG_SYNC(thd, "innodb_backup_start");
430-
return fail ? reinterpret_cast<void*>(-1) : ctx;
439+
return ctx;
431440
}
432441

433442
/**
@@ -1433,10 +1442,21 @@ bool log_t::backup_start(uint64_t *old_size, THD *thd) noexcept
14331442
{
14341443
ut_ad(latch_have_wr());
14351444
ut_ad(!backup);
1445+
ut_ad(end_lsn >= last_checkpoint_lsn);
14361446
backup= true;
14371447
*old_size= 0;
14381448
if (archive)
1449+
{
1450+
if (first_lsn > last_checkpoint_lsn)
1451+
{
1452+
/* Wait for recovery to be independent from the previous log. */
1453+
mysql_mutex_lock(&buf_pool.flush_list_mutex);
1454+
buf_flush_wait(end_lsn, false);
1455+
ut_ad(first_lsn <= last_checkpoint_lsn);
1456+
mysql_mutex_unlock(&buf_pool.flush_list_mutex);
1457+
}
14391458
return false;
1459+
}
14401460
const uint64_t old_file_size{file_size};
14411461
latch.wr_unlock();
14421462
const bool fail{set_archive(true, thd, true)};

0 commit comments

Comments
 (0)