forked from huawei/openGauss-server
probackup备机备份
This commit is contained in:
parent
28934bcdfa
commit
f4686aa3c9
|
|
@ -39,6 +39,8 @@ static uint32 stream_stop_timeout = 0;
|
|||
/* Time in which we started to wait for streaming end */
|
||||
static time_t stream_stop_begin = 0;
|
||||
|
||||
static const uint32 archive_timeout_deno = 5;
|
||||
|
||||
//const char *progname = "pg_probackup";
|
||||
|
||||
/* list of files contained in backup */
|
||||
|
|
@ -63,6 +65,7 @@ typedef struct
|
|||
|
||||
XLogRecPtr startpos;
|
||||
TimeLineID starttli;
|
||||
bool renamepartial;
|
||||
} StreamThreadArg;
|
||||
|
||||
static pthread_t stream_thread;
|
||||
|
|
@ -268,6 +271,12 @@ static void start_stream_wal(const char *database_path, PGconn *backup_conn)
|
|||
stream_thread_arg.starttli = current.tli;
|
||||
|
||||
thread_interrupted = false;
|
||||
|
||||
if (current.from_replica) {
|
||||
stream_thread_arg.renamepartial = true;
|
||||
} else {
|
||||
stream_thread_arg.renamepartial = false;
|
||||
}
|
||||
pthread_create(&stream_thread, NULL, StreamLog, &stream_thread_arg);
|
||||
}
|
||||
|
||||
|
|
@ -442,6 +451,27 @@ static void sync_files(parray *database_map, const char *database_path, parray *
|
|||
{
|
||||
time_t start_time, end_time;
|
||||
char pretty_time[20];
|
||||
|
||||
/* In case of backup from replica >= 9.6 we must fix minRecPoint,
|
||||
* First we must find pg_control in backup_files_list.
|
||||
*/
|
||||
if (current.from_replica && !exclusive_backup)
|
||||
{
|
||||
pgFile *pg_control = NULL;
|
||||
for (int i = 0; i < parray_num(backup_files_list); i++)
|
||||
{
|
||||
pgFile *tmp_file = (pgFile *)parray_get(backup_files_list, (size_t)i);
|
||||
if (tmp_file->external_dir_num == 0 &&
|
||||
(strcmp(tmp_file->rel_path, XLOG_CONTROL_FILE) == 0))
|
||||
{
|
||||
pg_control = tmp_file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!pg_control)
|
||||
elog(ERROR, "Failed to find file \"%s\" in backup filelist.", XLOG_CONTROL_FILE);
|
||||
set_min_recovery_point(pg_control, database_path, current.stop_lsn);
|
||||
}
|
||||
|
||||
/* close and sync page header map */
|
||||
if (current.hdr_map.fp)
|
||||
|
|
@ -735,7 +765,6 @@ PGconn *
|
|||
pgdata_basic_setup(const ConnectionOptions conn_opt, PGNodeInfo *nodeInfo)
|
||||
{
|
||||
PGconn *cur_conn;
|
||||
bool from_replica;
|
||||
errno_t rc = 0;
|
||||
|
||||
/* Create connection for PostgreSQL */
|
||||
|
|
@ -743,11 +772,6 @@ pgdata_basic_setup(const ConnectionOptions conn_opt, PGNodeInfo *nodeInfo)
|
|||
conn_opt.pgdatabase,
|
||||
conn_opt.pguser);
|
||||
|
||||
from_replica = pg_is_in_recovery(cur_conn);
|
||||
if (from_replica) {
|
||||
elog(ERROR, "gs_probackup is not supported on standby\n");
|
||||
}
|
||||
|
||||
/* Confirm data block size and xlog block size are compatible */
|
||||
confirm_block_size(cur_conn, "block_size", BLCKSZ);
|
||||
confirm_block_size(cur_conn, "wal_block_size", XLOG_BLCKSZ);
|
||||
|
|
@ -755,10 +779,12 @@ pgdata_basic_setup(const ConnectionOptions conn_opt, PGNodeInfo *nodeInfo)
|
|||
nodeInfo->wal_block_size = XLOG_BLCKSZ;
|
||||
nodeInfo->pgpro_support = pgpro_support(cur_conn);
|
||||
|
||||
|
||||
current.from_replica = pg_is_in_recovery(cur_conn);
|
||||
|
||||
nodeInfo->server_version = PQserverVersion(conn);
|
||||
exclusive_backup = true;
|
||||
if (!current.from_replica) {
|
||||
exclusive_backup = true;
|
||||
}
|
||||
|
||||
current.checksum_version = 0;
|
||||
|
||||
|
|
@ -868,6 +894,10 @@ do_backup(time_t start_time, pgSetBackupParams *set_backup_params,
|
|||
*/
|
||||
backup_conn = pgdata_basic_setup(instance_config.conn_opt, &nodeInfo);
|
||||
|
||||
if (current.from_replica) {
|
||||
elog(INFO, "Backup %s is going to be taken from standby", base36enc((unsigned long int)start_time));
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that backup directory was initialized for the same PostgreSQL
|
||||
* instance we opened connection to. And that target backup database PGDATA
|
||||
|
|
@ -1186,6 +1216,20 @@ bool inform_user_wal_seg_absent(bool is_start_lsn, uint32 *try_count, bool segme
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Try to find compressed WAL file */
|
||||
void tryToFindCompressedWALFile(bool *file_exists, char *gz_wal_segment_path, char *wal_segment_path)
|
||||
{
|
||||
if (!(*file_exists)) {
|
||||
#ifdef HAVE_LIBZ
|
||||
*file_exists = fileExists(gz_wal_segment_path, FIO_BACKUP_HOST);
|
||||
if (*file_exists)
|
||||
elog(LOG, "Found compressed WAL segment: %s", wal_segment_path);
|
||||
#endif
|
||||
} else {
|
||||
elog(LOG, "Found WAL segment: %s", wal_segment_path);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for target LSN or WAL segment, containing target LSN.
|
||||
*
|
||||
|
|
@ -1259,10 +1303,7 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
|
|||
}
|
||||
|
||||
/* TODO: remove this in 3.0 (it is a cludge against some old bug with archive_timeout) */
|
||||
if (instance_config.archive_timeout > 0)
|
||||
timeout = instance_config.archive_timeout;
|
||||
else
|
||||
timeout = ARCHIVE_TIMEOUT_DEFAULT;
|
||||
timeout = (instance_config.archive_timeout > 0) ? instance_config.archive_timeout : ARCHIVE_TIMEOUT_DEFAULT;
|
||||
|
||||
if (segment_only)
|
||||
elog(LOG, "Looking for segment: %s", wal_segment);
|
||||
|
|
@ -1282,20 +1323,9 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
|
|||
if (!file_exists)
|
||||
{
|
||||
file_exists = fileExists(wal_segment_path, FIO_BACKUP_HOST);
|
||||
|
||||
/* Try to find compressed WAL file */
|
||||
if (!file_exists)
|
||||
{
|
||||
#ifdef HAVE_LIBZ
|
||||
file_exists = fileExists(gz_wal_segment_path, FIO_BACKUP_HOST);
|
||||
if (file_exists)
|
||||
elog(LOG, "Found compressed WAL segment: %s", wal_segment_path);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
elog(LOG, "Found WAL segment: %s", wal_segment_path);
|
||||
}
|
||||
|
||||
tryToFindCompressedWALFile(&file_exists, gz_wal_segment_path, wal_segment_path);
|
||||
}
|
||||
|
||||
if (file_exists)
|
||||
{
|
||||
/* Do not check for target LSN */
|
||||
|
|
@ -1313,6 +1343,32 @@ wait_wal_lsn(XLogRecPtr target_lsn, bool is_start_lsn, TimeLineID tli,
|
|||
elog(LOG, "Found LSN: %X/%X", (uint32) (target_lsn >> 32), (uint32) target_lsn);
|
||||
return target_lsn;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we failed to get target LSN in a reasonable time, try
|
||||
* to get LSN of last valid record prior to the target LSN. But only
|
||||
* in case of a backup from a replica.
|
||||
* Note, that with NullXRecOff target_lsn we do not wait
|
||||
* for 'timeout / 5' seconds before going for previous record,
|
||||
* because such LSN cannot be delivered at all.
|
||||
*
|
||||
* There are two cases for this:
|
||||
* 1. Replica returned readpoint LSN which just do not exists. We want to look
|
||||
* for previous record in the same(!) WAL segment which endpoint points to this LSN.
|
||||
* 2. Replica returened endpoint LSN with NullXRecOff. We want to look
|
||||
* for previous record which endpoint points greater or equal LSN in previous WAL segment.
|
||||
*/
|
||||
if (current.from_replica &&
|
||||
(XRecOffIsNull(target_lsn) || try_count > timeout / archive_timeout_deno)) {
|
||||
XLogRecPtr res = get_prior_record_lsn(wal_segment_dir, current.start_lsn, target_lsn, tli,
|
||||
in_prev_segment, instance_config.xlog_seg_size);
|
||||
if (!XLogRecPtrIsInvalid(res)) {
|
||||
/* LSN of the prior record was found */
|
||||
elog(LOG, "Found prior LSN: %X/%X",
|
||||
(uint32) (res >> 32), (uint32) res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
|
@ -1392,9 +1448,11 @@ static void get_valid_stop_lsn(pgBackup *backup, bool *stop_lsn_exists, XLogRecP
|
|||
!XRecOffIsValid(lsn_tmp) ||
|
||||
lsn_tmp < stop_backup_lsn_tmp)
|
||||
{
|
||||
elog(ERROR, "Failed to get next WAL record after %X/%X",
|
||||
(uint32) (stop_backup_lsn_tmp >> 32),
|
||||
(uint32) (stop_backup_lsn_tmp));
|
||||
/* Backup from master should error out here */
|
||||
if (!backup->from_replica)
|
||||
elog(ERROR, "Failed to get next WAL record after %X/%X",
|
||||
(uint32)(stop_backup_lsn_tmp >> 32),
|
||||
(uint32)(stop_backup_lsn_tmp));
|
||||
|
||||
/* No luck, falling back to looking up for previous record */
|
||||
elog(WARNING, "Failed to get next WAL record after %X/%X, "
|
||||
|
|
@ -1666,8 +1724,10 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
|
|||
res = pgut_execute(conn, "SET datestyle = 'ISO, DMY';", 0, NULL);
|
||||
PQclear(res);
|
||||
|
||||
/* Create restore point */
|
||||
if (backup != NULL)
|
||||
/* Create restore point
|
||||
* Only if backup is from master.
|
||||
*/
|
||||
if (backup != nullptr && !backup->from_replica)
|
||||
{
|
||||
create_restore_point(backup, conn);
|
||||
}
|
||||
|
|
@ -1686,22 +1746,7 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
|
|||
* wait for pg_stop_backup() forever.
|
||||
*/
|
||||
PgStopBackupSent(conn, &stop_backup_query);
|
||||
|
||||
if (!pg_stop_backup_is_sent)
|
||||
{
|
||||
bool sent = false;
|
||||
|
||||
stop_backup_query = "SELECT"
|
||||
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
|
||||
" current_timestamp(0)::timestamptz,"
|
||||
" pg_catalog.pg_stop_backup() as lsn";
|
||||
|
||||
sent = pgut_send(conn, stop_backup_query, 0, NULL, WARNING);
|
||||
pg_stop_backup_is_sent = true;
|
||||
if (!sent)
|
||||
elog(ERROR, "Failed to send pg_stop_backup query");
|
||||
}
|
||||
|
||||
|
||||
/* After we have sent pg_stop_backup, we don't need this callback anymore */
|
||||
pgut_atexit_pop(backup_stopbackup_callback, pg_startbackup_conn);
|
||||
|
||||
|
|
@ -1769,9 +1814,13 @@ pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn,
|
|||
* If replica returned valid STOP_LSN of not actually existing record,
|
||||
* look for previous record with endpoint >= STOP_LSN.
|
||||
*/
|
||||
if (!stop_lsn_exists)
|
||||
if (!stop_lsn_exists) {
|
||||
if (backup->from_replica) {
|
||||
stop_backup_lsn = stop_backup_lsn_tmp;
|
||||
}
|
||||
stop_backup_lsn = wait_wal_lsn(stop_backup_lsn_tmp, false, backup->tli,
|
||||
false, false, ERROR, stream_wal);
|
||||
}
|
||||
|
||||
if (stream_wal)
|
||||
{
|
||||
|
|
@ -2068,16 +2117,14 @@ parse_filelist_filenames(parray *files, const char *root)
|
|||
|
||||
while (unlogged_file_num >= 0 &&
|
||||
(unlogged_file_reloid != 0) &&
|
||||
(unlogged_file->relOid == unlogged_file_reloid))
|
||||
{
|
||||
(unlogged_file->relOid == unlogged_file_reloid)) {
|
||||
pgFileFree(unlogged_file);
|
||||
parray_remove(files, unlogged_file_num);
|
||||
|
||||
unlogged_file_num--;
|
||||
i--;
|
||||
|
||||
unlogged_file = (pgFile *) parray_get(files,
|
||||
unlogged_file_num);
|
||||
unlogged_file = (pgFile *) parray_get(files, unlogged_file_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2220,8 +2267,7 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
|
|||
|
||||
if (!XLogRecPtrIsInvalid(stop_backup_lsn))
|
||||
{
|
||||
if (xlogpos >= stop_backup_lsn)
|
||||
{
|
||||
if (xlogpos >= stop_backup_lsn) {
|
||||
stop_stream_lsn = xlogpos;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2324,12 +2370,12 @@ StreamLog(void *arg)
|
|||
#else
|
||||
if(ReceiveXlogStream(stream_arg->conn, stream_arg->startpos, stream_arg->starttli,
|
||||
NULL, (const char *) stream_arg->basedir, stop_streaming,
|
||||
standby_message_timeout_local, false) == false)
|
||||
standby_message_timeout_local, stream_arg->renamepartial) == false)
|
||||
elog(ERROR, "Problem in receivexlog");
|
||||
#endif
|
||||
|
||||
elog(LOG, "finished streaming WAL at %X/%X (timeline %u)",
|
||||
(uint32) (stop_stream_lsn >> 32), (uint32) stop_stream_lsn, stream_arg->starttli);
|
||||
(uint32) (stop_stream_lsn >> 32), (uint32) stop_stream_lsn, stream_arg->starttli);
|
||||
stream_arg->ret = 0;
|
||||
|
||||
PQfinish(stream_arg->conn);
|
||||
|
|
|
|||
|
|
@ -1472,7 +1472,14 @@ void anchor_lsn_keep_segments_timelines(InstanceConfig *instance, parray *timeli
|
|||
interval->begin_segno = segno;
|
||||
GetXLogSegNo(backup->stop_lsn, segno, instance->xlog_seg_size);
|
||||
|
||||
interval->end_segno = segno;
|
||||
/*
|
||||
* On replica it is possible to get STOP_LSN pointing to contrecord,
|
||||
* so set end_segno to the next segment after STOP_LSN just to be safe.
|
||||
*/
|
||||
if (backup->from_replica)
|
||||
interval->end_segno = segno + 1;
|
||||
else
|
||||
interval->end_segno = segno;
|
||||
|
||||
GetXLogFileName(begin_segno_str, tlinfo->tli, interval->begin_segno, instance->xlog_seg_size);
|
||||
GetXLogFileName(end_segno_str, tlinfo->tli, interval->end_segno, instance->xlog_seg_size);
|
||||
|
|
@ -1808,6 +1815,7 @@ pgBackupWriteControl(FILE *out, pgBackup *backup)
|
|||
fio_fprintf(out, "compress-alg = %s\n",
|
||||
deparse_compress_alg(backup->compress_alg));
|
||||
fio_fprintf(out, "compress-level = %d\n", backup->compress_level);
|
||||
fio_fprintf(out, "from-replica = %s\n", backup->from_replica ? "true" : "false");
|
||||
|
||||
fio_fprintf(out, "\n#Compatibility\n");
|
||||
fio_fprintf(out, "block-size = %u\n", backup->block_size);
|
||||
|
|
@ -2055,7 +2063,6 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
|
|||
len += nRet;
|
||||
}
|
||||
|
||||
|
||||
if (file->linked)
|
||||
{
|
||||
nRet = snprintf_s(line+len, remainLen - len,remainLen - len - 1,",\"linked\":\"%s\"", file->linked);
|
||||
|
|
@ -2063,7 +2070,6 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
|
|||
len += nRet;
|
||||
}
|
||||
|
||||
|
||||
if (file->n_blocks > 0)
|
||||
{
|
||||
nRet = snprintf_s(line+len,remainLen - len,remainLen - len - 1, ",\"n_blocks\":\"%i\"", file->n_blocks);
|
||||
|
|
@ -2089,6 +2095,7 @@ write_backup_filelist(pgBackup *backup, parray *files, const char *root,
|
|||
|
||||
nRet = snprintf_s(line+len,remainLen - len,remainLen - len - 1, "}\n");
|
||||
securec_check_ss_c(nRet, "\0", "\0");
|
||||
len += nRet;
|
||||
|
||||
if (sync)
|
||||
COMP_FILE_CRC32(true, backup->content_crc, line, strlen(line));
|
||||
|
|
@ -2191,6 +2198,7 @@ readBackupControlFile(const char *path)
|
|||
{'s', 0, "merge-dest-id", &merge_dest_backup, SOURCE_FILE_STRICT},
|
||||
{'s', 0, "compress-alg", &compress_alg, SOURCE_FILE_STRICT},
|
||||
{'u', 0, "compress-level", &backup->compress_level, SOURCE_FILE_STRICT},
|
||||
{'b', 0, "from-replica", &backup->from_replica, SOURCE_FILE_STRICT},
|
||||
{'s', 0, "external-dirs", &backup->external_dir_str, SOURCE_FILE_STRICT},
|
||||
{'s', 0, "note", &backup->note, SOURCE_FILE_STRICT},
|
||||
{'s', 0, "recovery-name", &recovery_name, SOURCE_FILE_STRICT},
|
||||
|
|
@ -2424,6 +2432,7 @@ pgBackupInit(pgBackup *backup)
|
|||
backup->checksum_version = 0;
|
||||
|
||||
backup->stream = false;
|
||||
backup->from_replica = false;
|
||||
backup->parent_backup = INVALID_BACKUP_ID;
|
||||
backup->merge_dest_backup = INVALID_BACKUP_ID;
|
||||
backup->parent_backup_link = NULL;
|
||||
|
|
|
|||
|
|
@ -882,6 +882,7 @@ static void threads_handle(pgBackup *dest_backup,
|
|||
full_backup->recovery_time = dest_backup->recovery_time;
|
||||
full_backup->recovery_xid = dest_backup->recovery_xid;
|
||||
full_backup->tli = dest_backup->tli;
|
||||
full_backup->from_replica = dest_backup->from_replica;
|
||||
|
||||
pfree(full_backup->external_dir_str);
|
||||
full_backup->external_dir_str = pgut_strdup(dest_backup->external_dir_str);
|
||||
|
|
|
|||
|
|
@ -634,9 +634,10 @@ wal_contains_lsn(const char *archivedir, XLogRecPtr target_lsn,
|
|||
res = XLogReadRecord(xlogreader, target_lsn, &errormsg) != NULL;
|
||||
/* Didn't find 'target_lsn' and there is no error, return false */
|
||||
|
||||
if (errormsg)
|
||||
elog(WARNING, "Could not read WAL record at %X/%X: %s",
|
||||
(uint32) (target_lsn >> 32), (uint32) (target_lsn), errormsg);
|
||||
if (!current.from_replica)
|
||||
if (errormsg)
|
||||
elog(WARNING, "Could not read WAL record at %X/%X: %s",
|
||||
(uint32) (target_lsn >> 32), (uint32) (target_lsn), errormsg);
|
||||
|
||||
CleanupXLogPageRead(xlogreader);
|
||||
XLogReaderFree(xlogreader);
|
||||
|
|
@ -1459,7 +1460,7 @@ XLogThreadWorker(void *arg)
|
|||
* Usually SimpleXLogPageRead_local() does it by itself. But here we need
|
||||
* to do it manually to support threads.
|
||||
*/
|
||||
if (reader_data->need_switch && errormsg == NULL)
|
||||
if (reader_data->need_switch)
|
||||
{
|
||||
if (SwitchThreadToNextWal(xlogreader, thread_arg))
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@ struct pgBackup
|
|||
|
||||
bool stream; /* Was this backup taken in stream mode?
|
||||
* i.e. does it include all needed WAL files? */
|
||||
bool from_replica; /* Was this backup taken from replica */
|
||||
time_t parent_backup; /* Identifier of the previous backup.
|
||||
* Which is basic backup for this
|
||||
* incremental backup. */
|
||||
|
|
|
|||
|
|
@ -69,8 +69,10 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
|
|||
securec_check_ss_c(rc, "\0", "\0");
|
||||
params[0] = gs_pstrdup(start_lsn);
|
||||
|
||||
res = pgut_execute(backup_conn, "CHECKPOINT;", 0, NULL);
|
||||
PQclear(res);
|
||||
if (!current.from_replica) {
|
||||
res = pgut_execute(backup_conn, "CHECKPOINT;", 0, NULL);
|
||||
PQclear(res);
|
||||
}
|
||||
|
||||
res = pgut_execute(backup_conn, "SELECT pg_cbm_tracked_location()", 0, NULL);
|
||||
if (PQnfields(res) != 1) {
|
||||
|
|
@ -94,8 +96,7 @@ pg_ptrack_get_pagemapset(PGconn *backup_conn, XLogRecPtr lsn)
|
|||
pagemap.bitmapsize = 0;
|
||||
|
||||
/* Construct database map */
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
for (i = 0; i < PQntuples(res); i++) {
|
||||
page_map_entry *pm_entry = (page_map_entry *) pgut_malloc(sizeof(page_map_entry));
|
||||
|
||||
/* get path */
|
||||
|
|
|
|||
|
|
@ -373,6 +373,10 @@ print_backup_json_object(PQExpBuffer buf, pgBackup *backup)
|
|||
json_add_key(buf, "compress-level", json_level);
|
||||
appendPQExpBuffer(buf, "%d", backup->compress_level);
|
||||
|
||||
json_add_value(buf, "from-replica",
|
||||
backup->from_replica ? "true" : "false", json_level,
|
||||
true);
|
||||
|
||||
json_add_key(buf, "block-size", json_level);
|
||||
appendPQExpBuffer(buf, "%u", backup->block_size);
|
||||
|
||||
|
|
|
|||
|
|
@ -7127,8 +7127,9 @@
|
|||
AddBuiltinFunc(_0(2626), _1("pg_sleep"), _2(1), _3(true), _4(false), _5(pg_sleep), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1, 701), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("pg_sleep"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_start_backup", 1,
|
||||
AddBuiltinFunc(_0(2172), _1("pg_start_backup"), _2(2), _3(true), _4(false), _5(pg_start_backup), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(1), _20(2, 25, 16), _21(NULL), _22(NULL), _23(2, "label", "fast"), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("pg_start_backup"), _26(NULL), _27(NULL), _28(NULL), _29(1, 1), _30(false), _31(false), _32(false), _33(NULL), _34('f'))
|
||||
"pg_start_backup", 2,
|
||||
AddBuiltinFunc(_0(2172), _1("pg_start_backup"), _2(2), _3(true), _4(false), _5(pg_start_backup), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(1), _20(2, 25, 16), _21(NULL), _22(NULL), _23(2, "label", "fast"), _24("({CONST :consttype 16 :consttypmod -1 :constcollid 0 :constlen 1 :constbyval true :constisnull false :ismaxvalue false :location 72803 :constvalue 1 [ 0 0 0 0 0 0 0 0 ] :cursor_data :row_count 0 :cur_dno 0 :is_open false :found false :not_found false :null_open false :null_fetch false})"), _25("pg_start_backup"), _26(NULL), _27(NULL), _28(NULL), _29(1, 1), _30(false), _31(false), _32(false), _33(NULL), _34('f')),
|
||||
AddBuiltinFunc(_0(6203), _1("pg_start_backup"), _2(3), _3(true), _4(false), _5(pg_start_backup_v2), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 25, 16, 16), _21(NULL), _22(NULL), _23(3, "label", "fast", "exclusive"), _24(NULL), _25("pg_start_backup_v2"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_stat_bad_block", 1,
|
||||
|
|
@ -7693,8 +7694,9 @@
|
|||
AddBuiltinFunc(_0(5601), _1("pg_stat_set_last_data_changed_time"), _2(1), _3(true), _4(false), _5(pg_stat_set_last_data_changed_time), _6(2278), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 26), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("pg_stat_set_last_data_changed_time"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_stop_backup", 1,
|
||||
AddBuiltinFunc(_0(2173), _1("pg_stop_backup"), _2(0), _3(true), _4(false), _5(pg_stop_backup), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("pg_stop_backup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
"pg_stop_backup", 2,
|
||||
AddBuiltinFunc(_0(2173), _1("pg_stop_backup"), _2(0), _3(true), _4(false), _5(pg_stop_backup), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("pg_stop_backup"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f')),
|
||||
AddBuiltinFunc(_0(6204), _1("pg_stop_backup"), _2(1), _3(true), _4(true), _5(pg_stop_backup_v2), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(1), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(1,16), _21(4, 16, 25, 25, 25), _22(4, 'i', 'o', 'o', 'o'), _23(4, "exclusive", "lsn","labelfile", "spcmapfile"), _24(NULL), _25("pg_stop_backup_v2"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_switch_xlog", 1,
|
||||
|
|
|
|||
|
|
@ -500,6 +500,10 @@ static void knl_u_proc_init(knl_u_proc_context* proc_cxt)
|
|||
proc_cxt->clientIsGsroach = false;
|
||||
proc_cxt->IsBinaryUpgrade = false;
|
||||
proc_cxt->IsWLMWhiteList = false;
|
||||
proc_cxt->sessionBackupState = SESSION_BACKUP_NONE;
|
||||
proc_cxt->LabelFile = NULL;
|
||||
proc_cxt->TblspcMapFile = NULL;
|
||||
proc_cxt->registerAbortBackupHandlerdone = false;
|
||||
proc_cxt->gsRewindAddCount = false;
|
||||
proc_cxt->PassConnLimit = false;
|
||||
proc_cxt->sessionBackupState = SESSION_BACKUP_NONE;
|
||||
|
|
|
|||
|
|
@ -156,11 +156,13 @@ Datum pg_cbm_get_changed_block(PG_FUNCTION_ARGS)
|
|||
text *start_lsn_arg = PG_GETARG_TEXT_P(0);
|
||||
text *end_lsn_arg = PG_GETARG_TEXT_P(1);
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/* At present, we only allow merging CBM files on master */
|
||||
if (RecoveryInProgress())
|
||||
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is in progress"),
|
||||
errhint("pg_cbm_get_changed_block() cannot be executed"
|
||||
"during recovery.")));
|
||||
#endif
|
||||
|
||||
char *start_lsn_str = text_to_cstring(start_lsn_arg);
|
||||
char *end_lsn_str = text_to_cstring(end_lsn_arg);
|
||||
|
|
|
|||
|
|
@ -13334,6 +13334,17 @@ XLogRecPtr do_pg_stop_backup(char *labelfile, bool waitforarchive)
|
|||
}
|
||||
u_sess->proc_cxt.sessionBackupState = SESSION_BACKUP_NONE;
|
||||
StopSuspendWalInsert(lastlrc);
|
||||
|
||||
/*
|
||||
* Clean up session-level lock.
|
||||
*
|
||||
* You might think that WALInsertLockRelease() can be called before
|
||||
* cleaning up session-level lock because session-level lock doesn't need
|
||||
* to be protected with WAL insertion lock. But since
|
||||
* CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be
|
||||
* cleaned up before it.
|
||||
*/
|
||||
u_sess->proc_cxt.sessionBackupState = SESSION_BACKUP_NONE;
|
||||
|
||||
if (exclusive) {
|
||||
/*
|
||||
|
|
@ -13642,6 +13653,13 @@ void do_pg_abort_backup(void)
|
|||
int32 lastlrc = 0;
|
||||
|
||||
StartSuspendWalInsert(&lastlrc);
|
||||
/*
|
||||
* Quick exit if session is not keeping around a non-exclusive backup
|
||||
* already started.
|
||||
*/
|
||||
if (u_sess->proc_cxt.sessionBackupState != SESSION_BACKUP_NON_EXCLUSIVE)
|
||||
return;
|
||||
|
||||
Assert(t_thrd.shemem_ptr_cxt.XLogCtl->Insert.nonExclusiveBackups > 0);
|
||||
t_thrd.shemem_ptr_cxt.XLogCtl->Insert.nonExclusiveBackups--;
|
||||
|
||||
|
|
@ -13652,6 +13670,7 @@ void do_pg_abort_backup(void)
|
|||
u_sess->proc_cxt.sessionBackupState = SESSION_BACKUP_NONE;
|
||||
|
||||
StopSuspendWalInsert(lastlrc);
|
||||
u_sess->proc_cxt.sessionBackupState = SESSION_BACKUP_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -75,6 +75,13 @@ Datum pg_start_backup(PG_FUNCTION_ARGS)
|
|||
char startxlogstr[MAXFNAMELEN];
|
||||
errno_t errorno = EOK;
|
||||
|
||||
SessionBackupState status = u_sess->proc_cxt.sessionBackupState;
|
||||
|
||||
if (status == SESSION_BACKUP_NON_EXCLUSIVE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("a non-exclusive backup is already in progress in this session")));
|
||||
|
||||
backupidstr = text_to_cstring(backupid);
|
||||
dir = AllocateDir("pg_tblspc");
|
||||
if (!dir) {
|
||||
|
|
@ -114,6 +121,13 @@ Datum pg_stop_backup(PG_FUNCTION_ARGS)
|
|||
char stopxlogstr[MAXFNAMELEN];
|
||||
errno_t errorno = EOK;
|
||||
|
||||
SessionBackupState status = u_sess->proc_cxt.sessionBackupState;
|
||||
|
||||
if (status == SESSION_BACKUP_NON_EXCLUSIVE)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("a non-exclusive backup is already in progress in this session")));
|
||||
|
||||
/* when delay xlog recycle is true, we do not copy xlog from archive */
|
||||
stoppoint = do_pg_stop_backup(NULL, !GetDelayXlogRecycle());
|
||||
|
||||
|
|
@ -124,6 +138,156 @@ Datum pg_stop_backup(PG_FUNCTION_ARGS)
|
|||
PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr));
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_start_backup_v2: set up for taking an on-line backup dump
|
||||
*
|
||||
*/
|
||||
Datum pg_start_backup_v2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text* backupid = PG_GETARG_TEXT_P(0);
|
||||
bool fast = PG_GETARG_BOOL(1);
|
||||
bool exclusive = PG_GETARG_BOOL(2);
|
||||
char* backupidstr = NULL;
|
||||
char* labelfile = NULL;
|
||||
char* tblspcmapfile = NULL;
|
||||
XLogRecPtr startpoint;
|
||||
DIR *dir;
|
||||
char startxlogstr[MAXFNAMELEN];
|
||||
errno_t errorno = EOK;
|
||||
MemoryContext oldContext;
|
||||
|
||||
u_sess->probackup_context = AllocSetContextCreate(u_sess->top_mem_cxt, "probackup context",
|
||||
ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
oldContext = MemoryContextSwitchTo(u_sess->probackup_context);
|
||||
|
||||
SessionBackupState status = u_sess->proc_cxt.sessionBackupState;
|
||||
|
||||
if (status == SESSION_BACKUP_NON_EXCLUSIVE)
|
||||
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("a non-exclusive backup is already in progress in this session")));
|
||||
|
||||
backupidstr = text_to_cstring(backupid);
|
||||
dir = AllocateDir("pg_tblspc");
|
||||
if (!dir) {
|
||||
ereport(ERROR, (errmsg("could not open directory \"%s\": %m", "pg_tblspc")));
|
||||
}
|
||||
|
||||
if (exclusive) {
|
||||
startpoint = do_pg_start_backup(backupidstr, fast, NULL, dir, NULL, NULL, false, true);
|
||||
} else {
|
||||
if (status == SESSION_BACKUP_EXCLUSIVE)
|
||||
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("a backup is already in progress in this session")));
|
||||
|
||||
startpoint = do_pg_start_backup(backupidstr, fast, &labelfile,dir, &tblspcmapfile, NULL,false,true);
|
||||
u_sess->proc_cxt.LabelFile = MemoryContextStrdup(u_sess->probackup_context, labelfile);
|
||||
if (tblspcmapfile != NULL) {
|
||||
u_sess->proc_cxt.TblspcMapFile = MemoryContextStrdup(u_sess->probackup_context, tblspcmapfile);
|
||||
} else {
|
||||
u_sess->proc_cxt.TblspcMapFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
errorno = snprintf_s(startxlogstr, sizeof(startxlogstr), sizeof(startxlogstr) - 1, "%X/%X",
|
||||
(uint32)(startpoint >> 32), (uint32)startpoint);
|
||||
securec_check_ss(errorno, "", "");
|
||||
|
||||
PG_RETURN_TEXT_P(cstring_to_text(startxlogstr));
|
||||
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_stop_backup_v2: finish taking an on-line backup dump
|
||||
*
|
||||
*/
|
||||
Datum pg_stop_backup_v2(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *)fcinfo->resultinfo;
|
||||
TupleDesc tupdesc;
|
||||
Tuplestorestate *tupstore;
|
||||
MemoryContext perqueryctx, oldcontext, oldcontext2;
|
||||
Datum values[3];
|
||||
bool nulls[3];
|
||||
XLogRecPtr stoppoint;
|
||||
char stopxlogstr[MAXFNAMELEN];
|
||||
errno_t errorno = EOK;
|
||||
bool exclusive = PG_GETARG_BOOL(0);
|
||||
errno_t rc;
|
||||
|
||||
SessionBackupState status = u_sess->proc_cxt.sessionBackupState;
|
||||
|
||||
oldcontext2 = MemoryContextSwitchTo(u_sess->probackup_context);
|
||||
|
||||
/* check to see if caller supports us returning a tuplestore */
|
||||
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("set-valued function called in context that cannot accept a set")));
|
||||
if (!(rsinfo->allowedModes & SFRM_Materialize))
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("materialize mode required, but it is not allowed in this context")));
|
||||
|
||||
/* Build a tuple descriptor for our result type */
|
||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||
ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("return type must be a row type")));
|
||||
|
||||
perqueryctx = rsinfo->econtext->ecxt_per_query_memory;
|
||||
oldcontext = MemoryContextSwitchTo(perqueryctx);
|
||||
|
||||
tupstore = tuplestore_begin_heap(true, false, u_sess->attr.attr_memory.work_mem);
|
||||
rsinfo->returnMode = SFRM_Materialize;
|
||||
rsinfo->setResult = tupstore;
|
||||
rsinfo->setDesc = tupdesc;
|
||||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
rc = memset_s(values, sizeof(values), 0, sizeof(values));
|
||||
securec_check(rc, "\0", "\0");
|
||||
rc = memset_s(nulls, sizeof(nulls), false, sizeof(nulls));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
if (exclusive) {
|
||||
if (status == SESSION_BACKUP_NON_EXCLUSIVE)
|
||||
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("non-exclusive backup in progress"), errhint("Did you mean to use pg_stop_backup('f')?")));
|
||||
/* when delay xlog recycle is true, we do not copy xlog from archive */
|
||||
stoppoint = do_pg_stop_backup(NULL, !GetDelayXlogRecycle());
|
||||
nulls[1] = true;
|
||||
nulls[2] = true;
|
||||
} else {
|
||||
if (status != SESSION_BACKUP_NON_EXCLUSIVE)
|
||||
ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("non-exclusive backup is not in progress")));
|
||||
|
||||
stoppoint = do_pg_stop_backup(u_sess->proc_cxt.LabelFile, !GetDelayXlogRecycle());
|
||||
|
||||
values[1] = CStringGetTextDatum(u_sess->proc_cxt.LabelFile);
|
||||
pfree(u_sess->proc_cxt.LabelFile);
|
||||
u_sess->proc_cxt.LabelFile = NULL;
|
||||
|
||||
if (u_sess->proc_cxt.TblspcMapFile) {
|
||||
values[2] = CStringGetTextDatum(u_sess->proc_cxt.TblspcMapFile);
|
||||
pfree(u_sess->proc_cxt.TblspcMapFile);
|
||||
u_sess->proc_cxt.TblspcMapFile = NULL;
|
||||
} else {
|
||||
nulls[2] = true;
|
||||
}
|
||||
}
|
||||
|
||||
errorno = snprintf_s(stopxlogstr, sizeof(stopxlogstr), sizeof(stopxlogstr) - 1, "%X/%X",
|
||||
(uint32)(stoppoint >> 32), (uint32)stoppoint);
|
||||
securec_check_ss(errorno, "", "");
|
||||
values[0] = CStringGetTextDatum(stopxlogstr);
|
||||
|
||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||
tuplestore_donestoring(tupstore);
|
||||
|
||||
MemoryContextSwitchTo(oldcontext2);
|
||||
|
||||
return (Datum) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* gs_roach_stop_backup: stop roach backup with passed-in backup name
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
DROP FUNCTION IF EXISTS pg_catalog.pg_start_backup(IN backupid TEXT, IN fast BOOL, IN exclusive BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_stop_backup(IN exclusive BOOL) CASCADE;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
DROP FUNCTION IF EXISTS pg_catalog.pg_start_backup(IN BACKUPID TEXT, IN FAST BOOL, IN EXCLUSIVE BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_stop_backup(IN EXCLUSIVE BOOL) CASCADE;
|
||||
|
|
@ -2360,3 +2360,21 @@ out system_identifier pg_catalog.int8,
|
|||
out pg_control_last_modified pg_catalog.timestamptz)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_control_system';
|
||||
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_start_backup(IN backupid TEXT, IN fast BOOL, IN exclusive BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_stop_backup(IN exclusive BOOL) CASCADE;
|
||||
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6203;
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.pg_start_backup
|
||||
(IN backupid pg_catalog.text,
|
||||
IN fast pg_catalog.bool,
|
||||
IN exclusive pg_catalog.bool)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_start_backup_v2';
|
||||
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6204;
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.pg_stop_backup
|
||||
(IN exclusive pg_catalog.bool,
|
||||
out lsn pg_catalog.text,
|
||||
out labelfile pg_catalog.text,
|
||||
out spcmapfile pg_catalog.text)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_stop_backup_v2';
|
||||
|
||||
|
|
|
|||
|
|
@ -2393,3 +2393,21 @@ out catalog_version_no pg_catalog.int4,
|
|||
out system_identifier pg_catalog.int8,
|
||||
out pg_control_last_modified pg_catalog.timestamptz)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_control_system';
|
||||
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_start_backup(IN backupid TEXT, IN fast BOOL, IN exclusive BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_stop_backup(IN exclusive BOOL) CASCADE;
|
||||
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6203;
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.pg_start_backup
|
||||
(IN backupid pg_catalog.text,
|
||||
IN fast pg_catalog.bool,
|
||||
IN exclusive pg_catalog.bool)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_start_backup_v2';
|
||||
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6204;
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.pg_stop_backup
|
||||
(IN exclusive pg_catalog.bool,
|
||||
out lsn pg_catalog.text,
|
||||
out labelfile pg_catalog.text,
|
||||
out spcmapfile pg_catalog.text)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_stop_backup_v2';
|
||||
|
|
|
|||
|
|
@ -994,7 +994,12 @@ typedef struct knl_u_proc_context {
|
|||
* */
|
||||
enum SessionBackupState sessionBackupState;
|
||||
bool registerExclusiveHandlerdone;
|
||||
|
||||
/*
|
||||
* Store label file and tablespace map during non-exclusive backups.
|
||||
*/
|
||||
char* LabelFile;
|
||||
char* TblspcMapFile;
|
||||
bool registerAbortBackupHandlerdone; /* unterminated backups handler flag */
|
||||
} knl_u_proc_context;
|
||||
|
||||
/* maximum possible number of fields in a date string */
|
||||
|
|
@ -2278,6 +2283,7 @@ typedef struct knl_session_context {
|
|||
MemoryContext top_transaction_mem_cxt;
|
||||
MemoryContext self_mem_cxt;
|
||||
MemoryContext top_portal_cxt;
|
||||
MemoryContext probackup_context;
|
||||
MemoryContextGroup* mcxt_group;
|
||||
/* temp_mem_cxt is a context which will be reset when the session attach to a thread */
|
||||
MemoryContext temp_mem_cxt;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ extern void proc_exit(int code);
|
|||
extern void sess_exit(int code);
|
||||
extern void shmem_exit(int code);
|
||||
extern void on_proc_exit(pg_on_exit_callback function, Datum arg);
|
||||
extern void before_shmem_exit(pg_on_exit_callback function, Datum arg);
|
||||
extern void on_shmem_exit(pg_on_exit_callback function, Datum arg);
|
||||
extern void cancel_shmem_exit(pg_on_exit_callback function, Datum arg);
|
||||
extern void on_exit_reset(void);
|
||||
|
|
|
|||
|
|
@ -2686,6 +2686,8 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999 order by 1;
|
|||
6116 | int1smaller
|
||||
6117 | int1inc
|
||||
6118 | set_hashbucket_info
|
||||
6203 | pg_start_backup
|
||||
6204 | pg_stop_backup
|
||||
6224 | gs_get_next_xid_csn
|
||||
6321 | pg_stat_file_recursive
|
||||
7777 | sysdate
|
||||
|
|
|
|||
|
|
@ -2773,6 +2773,8 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999 order by 1;
|
|||
6200 | mot_session_memory_detail
|
||||
6201 | mot_global_memory_detail
|
||||
6202 | mot_local_memory_detail
|
||||
6203 | pg_start_backup
|
||||
6204 | pg_stop_backup
|
||||
6224 | gs_get_next_xid_csn
|
||||
6321 | pg_stat_file_recursive
|
||||
7777 | sysdate
|
||||
|
|
|
|||
Loading…
Reference in New Issue