Skip to content

Commit

Permalink
[CBRD-24892] The restoredb with level 1 fails when some of the perman…
Browse files Browse the repository at this point in the history
…ent volume header is not included (#4553) (#4566)

http://jira.cubrid.org/browse/CBRD-24892

backport: #4553
  • Loading branch information
hornetmj authored Aug 9, 2023
1 parent d9c37ea commit cad9ca3
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 4 deletions.
40 changes: 38 additions & 2 deletions src/storage/file_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -10234,7 +10234,8 @@ fileio_decompress_restore_volume (THREAD_ENTRY * thread_p, FILEIO_BACKUP_SESSION
int
fileio_restore_volume (THREAD_ENTRY * thread_p, FILEIO_BACKUP_SESSION * session_p, char *to_vol_label_p,
char *verbose_to_vol_label_p, char *prev_vol_label_p, FILEIO_RESTORE_PAGE_BITMAP * page_bitmap,
bool is_remember_pages)
bool is_remember_pages, bool & is_prev_vol_header_restored,
FILEIO_UNLINKED_VOLINFO_MAP & unlinked_volinfo)
{
int next_page_id = 0;
INT64 total_nbytes = 0;
Expand Down Expand Up @@ -10420,7 +10421,7 @@ fileio_restore_volume (THREAD_ENTRY * thread_p, FILEIO_BACKUP_SESSION * session_
goto error;
}

if (volid != LOG_DBFIRST_VOLID)
if (volid != LOG_DBFIRST_VOLID && is_prev_vol_header_restored)
{
VOLID prev_volid;
int prev_vdes;
Expand All @@ -10441,7 +10442,42 @@ fileio_restore_volume (THREAD_ENTRY * thread_p, FILEIO_BACKUP_SESSION * session_
}

fileio_dismount (thread_p, prev_vdes);

if (unlinked_volinfo.count (volid))
{
// The volume headers of both previous and current volumes are in the full or big incremental backup volumes.
// Therefore, the link between the two volumes is naturally established during the restoration process.
// So, there is no need to explicitly set it.
unlinked_volinfo.erase (volid);

_er_log_debug (ARG_FILE_LINE, "RESTOREDB: [UNSAVE UNLINK] [lv%d] volid=%d, vol=%s, prev_vol=%s\n",
session_p->dbfile.level, volid, to_vol_label_p, prev_vol_label_p);
}
}

if (incremental_includes_volume_header == true)
{
if (volid != LOG_DBFIRST_VOLID && is_prev_vol_header_restored == false)
{
_er_log_debug (ARG_FILE_LINE, "RESTOREDB: [FOUND UNLINK] [lv%d] volid=%d, vol=%s, prev_vol=%s\n",
session_p->dbfile.level, volid, to_vol_label_p, prev_vol_label_p);

if (!unlinked_volinfo.count (volid))
{
unlinked_volinfo[volid] =
std::make_pair (std::string (to_vol_label_p), std::string (prev_vol_label_p));

_er_log_debug (ARG_FILE_LINE, "RESTOREDB: [SAVE UNLINK] [lv%d] volid=%d, vol=%s, prev_vol=%s\n",
session_p->dbfile.level, volid, to_vol_label_p, prev_vol_label_p);
}
}
}

is_prev_vol_header_restored = true;
}
else
{
is_prev_vol_header_restored = false;
}

/* save current volname */
Expand Down
8 changes: 7 additions & 1 deletion src/storage/file_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

#include <stdio.h>
#include <time.h>
#include <map>

#define NULL_VOLDES (-1) /* Value of a null (invalid) vol descriptor */

Expand Down Expand Up @@ -454,6 +455,10 @@ struct flush_stats
unsigned int num_tokens;
};

// *INDENT-OFF*
using FILEIO_UNLINKED_VOLINFO_MAP = std::map <int, std::pair<std::string, std::string>>;
// *INDENT-ON*

extern int fileio_open (const char *vlabel, int flags, int mode);
extern void fileio_close (int vdes);
extern int fileio_format (THREAD_ENTRY * thread_p, const char *db_fullname, const char *vlabel, VOLID volid,
Expand Down Expand Up @@ -577,7 +582,8 @@ extern int fileio_get_next_restore_file (THREAD_ENTRY * thread_p, FILEIO_BACKUP_
VOLID * volid);
extern int fileio_restore_volume (THREAD_ENTRY * thread_p, FILEIO_BACKUP_SESSION * session, char *to_vlabel,
char *verbose_to_vlabel, char *prev_vlabel, FILEIO_RESTORE_PAGE_BITMAP * page_bitmap,
bool remember_pages);
bool remember_pages, bool & is_prev_vheader_restored,
FILEIO_UNLINKED_VOLINFO_MAP & unlinked_vol_info);
extern int fileio_skip_restore_volume (THREAD_ENTRY * thread_p, FILEIO_BACKUP_SESSION * session);
extern const char *fileio_get_zip_method_string (FILEIO_ZIP_METHOD zip_method);
extern const char *fileio_get_zip_level_string (FILEIO_ZIP_LEVEL zip_level);
Expand Down
41 changes: 40 additions & 1 deletion src/transaction/log_page_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8350,6 +8350,8 @@ logpb_check_stop_at_time (FILEIO_BACKUP_SESSION * session, time_t stop_at, time_
return NO_ERROR;
}

using namespace std;

/*
* logpb_restore - Restore volume from its backup
*
Expand Down Expand Up @@ -8424,6 +8426,9 @@ logpb_restore (THREAD_ENTRY * thread_p, const char *db_fullname, const char *log
REL_COMPATIBILITY compat;
int dummy;

bool is_prev_volheader_restored = false;
FILEIO_UNLINKED_VOLINFO_MAP unlinked_volinfo;

try_level = (FILEIO_BACKUP_LEVEL) r_args->level;
start_level = try_level;

Expand Down Expand Up @@ -8725,6 +8730,8 @@ logpb_restore (THREAD_ENTRY * thread_p, const char *db_fullname, const char *log
case LOG_DBLOG_ARCHIVE_VOLID:
case LOG_DBTDE_KEYS_VOLID:

is_prev_volheader_restored = false;

/* We can only take the most recent information, and we do not want to overwrite it with out of data
* information from earlier backups. This is because we are applying the restoration in reverse time
* order. */
Expand Down Expand Up @@ -8778,7 +8785,7 @@ logpb_restore (THREAD_ENTRY * thread_p, const char *db_fullname, const char *log

success =
fileio_restore_volume (thread_p, session, volume_name_p, verbose_to_volname, prev_volname, page_bitmap,
remember_pages);
remember_pages, is_prev_volheader_restored, unlinked_volinfo);

if (success != NO_ERROR)
{
Expand Down Expand Up @@ -8865,6 +8872,38 @@ logpb_restore (THREAD_ENTRY * thread_p, const char *db_fullname, const char *log
try_level = (FILEIO_BACKUP_LEVEL) (try_level - 1);
}

// Incremental backup volumes often do not include volume header pages.
// Accordingly, it is necessary to set unlinked volumes after all volume header pages are restored.
// *INDENT-OFF*
for (const auto &[volid, volnames] : unlinked_volinfo)
{
VOLID prev_volid;
int prev_vdes;
const char *prev_volname, *volname;

volname = volnames.first.c_str();
prev_volname = volnames.second.c_str();

prev_volid = fileio_find_previous_perm_volume (thread_p, volid);
prev_vdes = fileio_mount (thread_p, NULL, prev_volname, prev_volid, false, false);
if (prev_vdes == NULL_VOLDES)
{
goto error;
}

if (disk_set_link (thread_p, prev_volid, volid, volname, false, DISK_FLUSH_AND_INVALIDATE) != NO_ERROR)
{
fileio_dismount (thread_p, prev_vdes);
goto error;
}

fileio_dismount (thread_p, prev_vdes);

_er_log_debug (ARG_FILE_LINE, "RESTOREDB: [FIXED UNLINK] volid=%d, vol=%s, prev_vol=%s", volid, volname,
prev_volname);
}
// *INDENT-ON*

/* make bkvinf file */
fileio_make_backup_volume_info_name (from_volbackup, logpath, nopath_name);
backup_volinfo_fp = fopen (from_volbackup, "w");
Expand Down

0 comments on commit cad9ca3

Please sign in to comment.