1
0
mirror of https://github.com/postgrespro/pg_probackup.git synced 2024-11-25 09:01:48 +02:00

Clean up the snapshot related stuff

This is not really part of the core of pg_rman, rather better to
focus on incremental backup or stuff like that.
This commit is contained in:
Michael Paquier 2013-12-13 00:20:20 +09:00
parent ebe2166379
commit b92d722bdb
2 changed files with 0 additions and 536 deletions

230
backup.c
View File

@ -57,14 +57,6 @@ static void delete_online_wal_backup(void);
static bool dirExists(const char *path);
static void execute_freeze(void);
static void execute_unfreeze(void);
static void execute_split(parray *tblspc_list);
static void execute_resync(void);
static void execute_mount(parray *tblspcmp_list);
static void execute_umount(void);
static void execute_script(const char *mode, bool is_cleanup, parray *output);
static void snapshot_cleanup(bool fatal, void *userdata);
static void add_files(parray *files, const char *root, bool add_root, bool is_pgdata);
static int strCompare(const void *str1, const void *str2);
static void create_file_list(parray *files, const char *root, const char *prefix, bool is_append);
@ -241,20 +233,6 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
for (i = 0; pgdata_exclude[i]; i++); /* find first empty slot */
pgdata_exclude[i] = PG_TBLSPC_DIR;
/* set the error processing for the snapshot */
pgut_atexit_push(snapshot_cleanup, cleanup_list);
/* create snapshot volume */
if (!check)
{
/* freeze I/O of the file-system */
execute_freeze();
/* create the snapshot, and obtain the name of TABLESPACE backup from snapshot */
execute_split(tblspc_list);
/* unfreeze I/O of the file-system */
execute_unfreeze();
}
/*
* when DB cluster is not contained in the backup from the snapshot,
* DB cluster is added to the backup file list from non-snapshot.
@ -315,10 +293,6 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
/* create file list of non-snapshot objects */
create_file_list(files, pgdata, NULL, false);
/* mount snapshot volume to file-system, and obtain that mounted directory */
if (!check)
execute_mount(tblspcmp_list);
/* backup files from snapshot volume */
for (i = 0; i < parray_num(tblspcmp_list); i++)
{
@ -414,17 +388,7 @@ do_backup_database(parray *backup_list, pgBackupOption bkupopt)
parray_walk(tblspcmp_list, free);
parray_free(tblspcmp_list);
/* snapshot became unnecessary, annul the snapshot */
if (!check)
{
/* unmount directory of mounted snapshot volume */
execute_umount();
/* annul the snapshot */
execute_resync();
}
/* unset the error processing for the snapshot */
pgut_atexit_pop(snapshot_cleanup, cleanup_list);
/* don't use 'parray_walk'. element of parray not allocate memory by malloc */
parray_free(cleanup_list);
PQclear(tblspc_res);
@ -1557,200 +1521,6 @@ delete_arclog_link(void)
parray_free(files);
}
/*
* Execute the command 'freeze' of snapshot-script.
* When the command ends normally, 'unfreeze' is added to the cleanup list.
*/
static void
execute_freeze(void)
{
/* append 'unfreeze' command to cleanup list */
parray_append(cleanup_list, SNAPSHOT_UNFREEZE);
/* execute 'freeze' command */
execute_script(SNAPSHOT_FREEZE, false, NULL);
}
/*
* Execute the command 'unfreeze' of snapshot-script.
* Remove 'unfreeze' from the cleanup list before executing the command
* when 'unfreeze' is included in the cleanup list.
*/
static void
execute_unfreeze(void)
{
int i;
/* remove 'unfreeze' command from cleanup list */
for (i = 0; i < parray_num(cleanup_list); i++)
{
char *mode;
mode = (char *) parray_get(cleanup_list, i);
if (strcmp(mode,SNAPSHOT_UNFREEZE) == 0)
{
parray_remove(cleanup_list, i);
break;
}
}
/* execute 'unfreeze' command */
execute_script(SNAPSHOT_UNFREEZE, false, NULL);
}
/*
* Execute the command 'split' of snapshot-script.
* When the command ends normally, 'resync' is added to the cleanup list.
*/
static void
execute_split(parray *tblspc_list)
{
/* append 'resync' command to cleanup list */
parray_append(cleanup_list, SNAPSHOT_RESYNC);
/* execute 'split' command */
execute_script(SNAPSHOT_SPLIT, false, tblspc_list);
}
/*
* Execute the command 'resync' of snapshot-script.
* Remove 'resync' from the cleanup list before executing the command
* when 'resync' is included in the cleanup list.
*/
static void
execute_resync(void)
{
int i;
/* remove 'resync' command from cleanup list */
for (i = 0; i < parray_num(cleanup_list); i++)
{
char *mode;
mode = (char *) parray_get(cleanup_list, i);
if (strcmp(mode, SNAPSHOT_RESYNC) == 0)
{
parray_remove(cleanup_list, i);
break;
}
}
/* execute 'resync' command */
execute_script(SNAPSHOT_RESYNC, false, NULL);
}
/*
* Execute the command 'mount' of snapshot-script.
* When the command ends normally, 'umount' is added to the cleanup list.
*/
static void
execute_mount(parray *tblspcmp_list)
{
/* append 'umount' command to cleanup list */
parray_append(cleanup_list, SNAPSHOT_UMOUNT);
/* execute 'mount' command */
execute_script(SNAPSHOT_MOUNT, false, tblspcmp_list);
}
/*
* Execute the command 'umount' of snapshot-script.
* Remove 'umount' from the cleanup list before executing the command
* when 'umount' is included in the cleanup list.
*/
static void
execute_umount(void)
{
int i;
/* remove 'umount' command from cleanup list */
for (i = 0; i < parray_num(cleanup_list); i++)
{
char *mode = (char *) parray_get(cleanup_list, i);
if (strcmp(mode, SNAPSHOT_UMOUNT) == 0)
{
parray_remove(cleanup_list, i);
break;
}
}
/* execute 'umount' command */
execute_script(SNAPSHOT_UMOUNT, false, NULL);
}
/*
* Execute the snapshot-script in the specified mode.
* A standard output of snapshot-script is stored in the array given to the parameter.
* If is_cleanup is TRUE, processing is continued.
*/
static void
execute_script(const char *mode, bool is_cleanup, parray *output)
{
char ss_script[MAXPGPATH];
char command[1024];
char fline[2048];
int num;
FILE *out;
parray *lines;
/* obtain the path of snapshot-script. */
join_path_components(ss_script, backup_path, SNAPSHOT_SCRIPT_FILE);
snprintf(command, sizeof(command),
"%s %s %s", ss_script, mode, is_cleanup ? "cleanup" : "");
/* execute snapshot-script */
out = popen(command, "r");
if (out == NULL)
elog(ERROR_SYSTEM, _("could not execute snapshot-script: %s\n"), strerror(errno));
/* read STDOUT and store into the array each line */
lines = parray_new();
while (fgets(fline, sizeof(fline), out) != NULL)
{
/* remove line separator */
if (fline[strlen(fline) - 1] == '\n')
fline[strlen(fline) - 1] = '\0';
parray_append(lines, pgut_strdup(fline));
}
pclose(out);
/*
* status of the command is obtained from the last element of the array
* if last element is not 'SUCCESS', that means ERROR.
*/
num = parray_num(lines);
if (num <= 0 || strcmp((char *) parray_get(lines, num - 1), "SUCCESS") != 0)
elog(is_cleanup ? WARNING : ERROR_SYSTEM, _("snapshot-script failed: %s"), mode);
/* if output is not NULL, concat array. */
if (output)
{
parray_remove(lines, num -1); /* remove last element, that is command status */
parray_concat(output, lines);
}
/* if output is NULL, clear directory list */
else
{
parray_walk(lines, free);
parray_free(lines);
}
}
/*
* Delete the unnecessary object created by snapshot-script.
* The command necessary for the deletion is given from the parameter.
* When the error occurs, this function is called.
*/
static void
snapshot_cleanup(bool fatal, void *userdata)
{
parray *cleanup_list;
int i;
/* Execute snapshot-script for cleanup */
cleanup_list = (parray *) userdata;
for (i = parray_num(cleanup_list) - 1; i >= 0; i--)
execute_script((char *) parray_get(cleanup_list, i), true, NULL);
}
/*
* Append files to the backup list array.
*/

View File

@ -1,306 +0,0 @@
#!/bin/sh
#############################################################################
# Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
#############################################################################
CMD_SUDO="/usr/bin/sudo"
CMD_LVCREATE="${CMD_SUDO} /usr/sbin/lvcreate"
CMD_LVREMOVE="${CMD_SUDO} /usr/sbin/lvremove"
CMD_MOUNT="${CMD_SUDO} /bin/mount"
CMD_UMOUNT="${CMD_SUDO} /bin/umount"
INFO=-2
WARNING=-1
ERROR=0
#
# Please set the information necessary for the snapshot acquisition
# to each array.
#
# The following arrays are one sets.
#
# SNAPSHOT_NAME .... name for snapshot volume
# SNAPSHOT_SIZE .... size to allocate for snapshot volume
# SNAPSHOT_VG ...... volume group to which logical volume to create snapshot belongs
# SNAPSHOT_LV ...... logical volume to create snapshot
# SNAPSHOT_MOUNT ... mount point to file-system of snapshot volume
#
# increase and decrease the slot in proportion to the number of acquisition
# of snapshots.
#
# example:
#
# SNAPSHOT_NAME[0]="snap00"
# SNAPSHOT_SIZE[0]="2G"
# SNAPSHOT_VG[0]="/dev/VolumeGroup00"
# SNAPSHOT_LV[0]="/dev/VolumeGroup00/LogicalVolume00"
# SNAPSHOT_MOUNT[0]="/mnt/pgdata"
#
# SNAPSHOT_NAME[1]="snap01"
# SNAPSHOT_SIZE[1]="2G"
# SNAPSHOT_VG[1]="/dev/VolumeGroup00"
# SNAPSHOT_LV[1]="/dev/VolumeGroup00/LogicalVolume01"
# SNAPSHOT_MOUNT[1]="/mnt/tblspc/account"
#
#SNAPSHOT_NAME[0]=""
#SNAPSHOT_SIZE[0]=""
#SNAPSHOT_VG[0]=""
#SNAPSHOT_LV[0]=""
#SNAPSHOT_MOUNT[0]=""
#
# Please set the tablespace name and tablespace storage path in snapshot
# to each array.
#
# The following arrays are one sets.
#
# SNAPSHOT_TBLSPC ........ name of tablespace in snapshot volume
# SNAPSHOT_TBLSPC_DIR .... stored directory of tablespace in snapshot volume
#
# Note: set 'PG-DATA' to SNAPSHOT_TBLSPC when PGDATA in snapshot volume.
#
# increase and decrease the slot in proportion to the number of acquisition
# of tablespace.
#
# example:
#
# SNAPSHOT_TBLSPC[0]="PG-DATA"
# SNAPSHOT_TBLSPC_DIR[0]="/mnt/pgdata/pgdata"
# SNAPSHOT_TBLSPC[1]="custom"
# SNAPSHOT_TBLSPC_DIR[1]="/mnt/tblspc_custom/tblspc/custom"
# SNAPSHOT_TBLSPC[2]="account"
# SNAPSHOT_TBLSPC_DIR[2]="/mnt/tblspc_account/tblspc/account"
#
#SNAPSHOT_TBLSPC[0]=""
#SNAPSHOT_TBLSPC_DIR[0]=""
#
# argument of the command.
# this variables are set by set_args().
#
ARGS_SS_NAME="" # SNAPSHOT_NAME[N]
ARGS_SS_SIZE="" # SNAPSHOT_SIZE[N]
ARGS_SS_VG="" # SNAPSHOT_VG[N]
ARGS_SS_LV="" # SNAPSHOT_LV[N]
ARGS_SS_MOUNT="" # SNAPSHOT_MOUNT[N]
#
# implement of interface 'freeze'.
# don't remove this function even if there is no necessity.
#
function freeze()
{
# nothing to do
return
}
#
# implement of interface 'unfreeze'.
# don't remove this function even if there is no necessity.
#
function unfreeze()
{
# nothing to do
return
}
#
# implement of interface 'split'.
# create a snapshot volume from the setting of the specified slot.
# don't remove this function even if there is no necessity.
#
function split()
{
local i=0
for ss_name in "${SNAPSHOT_NAME[@]}"
do
set_args "${ss_name}" "${SNAPSHOT_SIZE[${i}]}" "" "${SNAPSHOT_LV[${i}]}" ""
execute_split
i=$(expr ${i} + 1)
done
# print tablespace name
i=0
for tblspc in "${SNAPSHOT_TBLSPC[@]}"
do
local tblspc="${SNAPSHOT_TBLSPC[${i}]}"
echo "${tblspc}"
i=$(expr ${i} + 1)
done
return
}
#
# implement of interface 'resync'.
# remove a snapshot volume from the setting of the specified slot.
# don't remove this function even if there is no necessity.
#
function resync()
{
local i=0
for ss_name in "${SNAPSHOT_NAME[@]}"
do
set_args "${ss_name}" "" "${SNAPSHOT_VG[${i}]}" "" ""
execute_resync
i=$(expr ${i} + 1)
done
return
}
#
# implement of interface 'mount'.
# create mount point of the snapshot volume to the file-system.
# don't remove this function even if there is no necessity.
#
function mount()
{
local i=0
for ss_name in "${SNAPSHOT_NAME[@]}"
do
set_args "${ss_name}" "" "${SNAPSHOT_VG[${i}]}" "" "${SNAPSHOT_MOUNT[${i}]}"
execute_mount
i=$(expr ${i} + 1)
done
# print tablespace name and stored directory
i=0
for tblspc in "${SNAPSHOT_TBLSPC[@]}"
do
local tblspc_mp="${SNAPSHOT_TBLSPC_DIR[${i}]}"
echo "${tblspc}=${tblspc_mp}"
i=$(expr ${i} + 1)
done
return
}
#
# implement of interface 'umount'.
# remove mount point of the snapshot volume from the file-system.
# don't remove this function even if there is no necessity.
#
function umount()
{
for ss_mp in "${SNAPSHOT_MOUNT[@]}"
do
set_args "" "" "" "" "${ss_mp}"
execute_umount
done
return
}
#
# create the snapshot volume.
#
function execute_split()
{
${CMD_LVCREATE} --snapshot --size=${ARGS_SS_SIZE} --name="${ARGS_SS_NAME}" "${ARGS_SS_LV}" > /dev/null
[ ${?} -ne 0 ] && \
print_log ${ERROR} "${CMD_LVCREATE} command failed: ${ARGS_SS_LV}"
}
#
# remove the snapshot volume.
#
function execute_resync()
{
${CMD_LVREMOVE} -f "${ARGS_SS_VG}/${ARGS_SS_NAME}" > /dev/null
[ ${?} -ne 0 ] && \
print_log ${ERROR} "${CMD_LVREMOVE} command failed: ${ARGS_SS_VG}/${ARGS_SS_NAME}"
}
#
# mount the snapshot volume to file-system.
#
function execute_mount()
{
${CMD_MOUNT} "${ARGS_SS_VG}/${ARGS_SS_NAME}" "${ARGS_SS_MOUNT}" > /dev/null
[ ${?} -ne 0 ] && \
print_log ${ERROR} "${CMD_MOUNT} command failed: ${ARGS_SS_MOUNT}"
}
#
# unmount the directory from file-system in snapshot volume.
#
function execute_umount()
{
${CMD_UMOUNT} "${ARGS_SS_MOUNT}" > /dev/null
[ ${?} -ne 0 ] && \
print_log ${ERROR} "${CMD_UMOUNT} command failed: ${ARGS_SS_MOUNT}"
}
#
# set argument of command to execute.
#
set_args()
{
ARGS_SS_NAME="${1}"
ARGS_SS_SIZE="${2}"
ARGS_SS_VG="${3}"
ARGS_SS_LV="${4}"
ARGS_SS_MOUNT="${5}"
}
#
# output the log message and abort the script when level <= ERROR
#
function print_log()
{
local level="${1}"
local message="${2}"
# if cleanup enable change ERROR to WARNING
[ -n "${cleanup}" -a ${level} -ge 0 ] && \
level=${WARNING}
case "${level}" in
${INFO} ) # INFO
echo "INFO: ${message}" 1>&2
;;
${WARNING} ) # WARNING
echo "WARNING: ${message}" 1>&2
;;
${ERROR} ) # ERROR
echo "ERROR: ${message}" 1>&2
;;
esac
[ ${level} -ge 0 ] && exit
}
#
# main
#
command="${1}"
cleanup="${2}"
case "${command}" in
"freeze" )
freeze
;;
"unfreeze" )
unfreeze
;;
"split" )
split
;;
"resync" )
resync
;;
"mount" )
mount
;;
"umount" )
umount
;;
* )
print_log ${ERROR} "specified invalid command: ${command} (internal error)"
;;
esac
echo "SUCCESS"
exit