Compare commits

..

1 Commits

Author SHA1 Message Date
林科旭 0c4cf14576 修复 undo recycler线程cpu占用100% 2022-03-31 18:00:26 +08:00
47 changed files with 263 additions and 1037 deletions

View File

@ -72,7 +72,7 @@ select_package_command
export PLAT_FORM_STR=$(sh "${ROOT_DIR}/src/get_PlatForm_str.sh")
if [ "${PLAT_FORM_STR}"x == "Failed"x -o "${PLAT_FORM_STR}"x == ""x ]
then
echo "We only support openEuler(aarch64), EulerOS(aarch64), CentOS, Kylin(aarch64), Asianux platform."
echo "We only support openEuler(aarch64), EulerOS(aarch64), CentOS, Kylin(aarch64) platform."
exit 1;
fi
@ -96,21 +96,16 @@ elif [[ "$PLAT_FORM_STR" =~ "kylin" ]]; then
if [ "$PLATFORM_ARCH"X == "aarch64"X ];then
GAUSSDB_EXTRA_FLAGS=" -D__USE_NUMA"
fi
elif [[ "$PLAT_FORM_STR" =~ "asianux" ]]; then
dist_version="Asianux"
if [ "$PLATFORM_ARCH"X == "aarch64"X ];then
GAUSSDB_EXTRA_FLAGS=" -D__USE_NUMA"
fi
else
echo "We only support openEuler(aarch64), EulerOS(aarch64), CentOS, Kylin(aarch64), Asianux platform."
echo "We only support openEuler(aarch64), EulerOS(aarch64), CentOS, Kylin(aarch64) platform."
echo "Kernel is $kernel"
exit 1
fi
##add platform architecture information
if [ "$PLATFORM_ARCH"X == "aarch64"X ] ; then
if [ "$dist_version" != "openEuler" ] && [ "$dist_version" != "EulerOS" ] && [ "$dist_version" != "Kylin" ] && [ "$dist_version" != "Asianux" ]; then
echo "We only support NUMA on openEuler(aarch64), EulerOS(aarch64), Kylin(aarch64), Asianux platform."
if [ "$dist_version" != "openEuler" ] && [ "$dist_version" != "EulerOS" ] && [ "$dist_version" != "Kylin" ] ; then
echo "We only support NUMA on openEuler(aarch64), EulerOS(aarch64), Kylin(aarch64) platform."
exit 1
fi
fi

View File

@ -1229,12 +1229,6 @@ parse_next_sync_groups(char **pgroup, char *result)
static int
transform_az_name(char *config_value, char *allAZString, int allAZStringBufLen, const char *data_dir)
{
if (strcmp(config_value, "''") == 0) {
errno_t rc = strncpy_s(allAZString, allAZStringBufLen, config_value, strlen(config_value));
securec_check_c(rc, "\0", "\0");
return SUCCESS;
}
char *azString = NULL;
char *buf = allAZString;
int buflen = allAZStringBufLen;

View File

@ -5923,7 +5923,7 @@ int main(int argc, char** argv)
&option_index)) != -1)
#endif
#else
while ((c = getopt_long(argc, argv, "b:cD:e:fi:G:l:m:M:N:o:O:p:P:r:R:v:x:sS:t:u:U:wWZ:C:dqL:T:Q:", long_options,
while ((c = getopt_long(argc, argv, "b:cD:e:fi:G:l:m:M:N:o:O:p:P:r:R:v:x:sS:t:u:U:wWZ:dqL:T:Q:", long_options,
&option_index)) != -1)
#endif
#endif

View File

@ -233,7 +233,7 @@ char* all_data_nodename_list = NULL;
const uint32 USTORE_UPGRADE_VERSION = 92368;
const uint32 PACKAGE_ENHANCEMENT = 92444;
const uint32 SUBSCRIPTION_VERSION = 92580;
const uint32 SUBSCRIPTION_BINARY_VERSION_NUM = 92606;
const uint32 SUBSCRIPTION_BINARY_VERSION_NUM = 92607;
#ifdef DUMPSYSLOG
char* syslogpath = NULL;

View File

@ -31,9 +31,6 @@
it will be backuped up in external dirs */
parray *pgdata_nobackup_dir = NULL;
/* list of logical replication slots */
parray *logical_replslot = NULL;
static int standby_message_timeout_local = 10 ; /* 10 sec = default */
static XLogRecPtr stop_backup_lsn = InvalidXLogRecPtr;
static XLogRecPtr stop_stream_lsn = InvalidXLogRecPtr;
@ -92,11 +89,10 @@ static void backup_cleanup(bool fatal, void *userdata);
static void *backup_files(void *arg);
static void do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool backup_logs,
bool backup_replslots);
static void do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool backup_logs);
static void pg_start_backup(const char *label, bool smooth, pgBackup *backup,
PGNodeInfo *nodeInfo, PGconn *conn, bool backup_replslots);
PGNodeInfo *nodeInfo, PGconn *conn);
static void pg_stop_backup(pgBackup *backup, PGconn *pg_startbackup_conn, PGNodeInfo *nodeInfo);
static int checkpoint_timeout(PGconn *backup_conn);
@ -562,7 +558,7 @@ static void sync_files(parray *database_map, const char *database_path, parray *
* Move files from 'pgdata' to a subdirectory in 'backup_path'.
*/
static void
do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool backup_logs, bool backup_replslots)
do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool backup_logs)
{
int i;
char database_path[MAXPGPATH];
@ -595,7 +591,7 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
securec_check_c(rc, "\0", "\0");
/* Call pg_start_backup function in openGauss connect */
pg_start_backup(label, smooth_checkpoint, &current, nodeInfo, backup_conn, backup_replslots);
pg_start_backup(label, smooth_checkpoint, &current, nodeInfo, backup_conn);
/* Obtain current timeline */
#if PG_VERSION_NUM >= 90600
@ -628,10 +624,10 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
/* list files with the logical path. omit $PGDATA */
if (fio_is_remote(FIO_DB_HOST))
fio_list_dir(backup_files_list, instance_config.pgdata,
true, true, false, backup_logs, true, 0, backup_replslots);
true, true, false, backup_logs, true, 0);
else
dir_list_file(backup_files_list, instance_config.pgdata,
true, true, false, backup_logs, true, 0, FIO_LOCAL_HOST, backup_replslots);
true, true, false, backup_logs, true, 0, FIO_LOCAL_HOST);
/*
* Get database_map (name to oid) for use in partial restore feature.
@ -753,11 +749,6 @@ do_backup_instance(PGconn *backup_conn, PGNodeInfo *nodeInfo, bool no_sync, bool
}
pgdata_nobackup_dir = NULL;
if (logical_replslot) {
free_dir_list(logical_replslot);
}
logical_replslot = NULL;
/* Cleanup */
if (backup_list)
{
@ -858,7 +849,7 @@ static void do_after_backup()
*/
int
do_backup(time_t start_time, pgSetBackupParams *set_backup_params,
bool no_validate, bool no_sync, bool backup_logs, bool backup_replslots)
bool no_validate, bool no_sync, bool backup_logs)
{
PGconn *backup_conn = NULL;
PGNodeInfo nodeInfo;
@ -934,7 +925,7 @@ do_backup(time_t start_time, pgSetBackupParams *set_backup_params,
add_note(&current, set_backup_params->note);
/* backup data */
do_backup_instance(backup_conn, &nodeInfo, no_sync, backup_logs, backup_replslots);
do_backup_instance(backup_conn, &nodeInfo, no_sync, backup_logs);
pgut_atexit_pop(backup_cleanup, NULL);
/* compute size of wal files of this backup stored in the archive */
@ -1043,15 +1034,13 @@ confirm_block_size(PGconn *conn, const char *name, int blcksz)
*/
static void
pg_start_backup(const char *label, bool smooth, pgBackup *backup,
PGNodeInfo *nodeInfo, PGconn *conn, bool backup_replslots)
PGNodeInfo *nodeInfo, PGconn *conn)
{
PGresult *res;
const char *params[2];
uint32 lsn_hi;
uint32 lsn_lo;
int ret;
int i;
XLogRecPtr startLsn;
params[0] = label;
@ -1079,33 +1068,7 @@ pg_start_backup(const char *label, bool smooth, pgBackup *backup,
XLogDataFromLSN(ret, PQgetvalue(res, 0, 0), &lsn_hi, &lsn_lo);
securec_check_for_sscanf_s(ret, 2, "\0", "\0");
/* Calculate LSN */
startLsn = ((uint64) lsn_hi )<< 32 | lsn_lo;
if (backup_replslots) {
logical_replslot = parray_new();
/* query for logical replication slots of subscriptions */
res = pgut_execute(conn,
"SELECT slot_name, restart_lsn FROM pg_catalog.pg_get_replication_slots()"
"WHERE slot_type = 'logical' AND plugin = 'pgoutput'", 0, NULL);
if (PQntuples(res) == 0) {
elog(LOG, "logical replication slots for subscriptions not found");
} else {
XLogRecPtr repslotLsn;
for (i = 0; i < PQntuples(res); i++) {
XLogDataFromLSN(ret, PQgetvalue(res, i, 1), &lsn_hi, &lsn_lo);
securec_check_for_sscanf_s(ret, 2, "\0", "\0");
repslotLsn = ((uint64) lsn_hi )<< 32 | lsn_lo;
startLsn = Min(startLsn, repslotLsn);
char* slotname = pg_strdup(PQgetvalue(res, i, 0));
parray_append(logical_replslot, slotname);
}
elog(WARNING, "logical replication slots for subscriptions will be backed up. "
"If don't use them after restoring, please drop them to avoid affecting xlog recycling.");
}
}
backup->start_lsn = startLsn;
backup->start_lsn = ((uint64) lsn_hi )<< 32 | lsn_lo;
PQclear(res);
}

View File

@ -42,6 +42,13 @@ const char *pgdata_exclude_dir[] =
(const char *)"pg_stat_tmp",
(const char *)"pgsql_tmp",
/*
* It is generally not useful to backup the contents of this directory even
* if the intention is to restore to another master. See backup.sgml for a
* more detailed description.
*/
(const char *)"pg_replslot",
/* Contents removed on startup, see dsm_cleanup_for_mmap(). */
(const char *)"pg_dynshmem",
@ -61,7 +68,7 @@ const char *pgdata_exclude_dir[] =
(const char *)"pg_subtrans",
/* end of list */
NULL, /* pg_log and pg_replslot will be set later */
NULL, /* pg_log will be set later */
NULL
};
@ -121,20 +128,17 @@ may be removed int the future */
static int pgCompareString(const void *str1, const void *str2);
static char dir_check_file(pgFile *file, bool backup_logs, bool backup_replslots);
static char dir_check_file(pgFile *file, bool backup_logs);
static char check_in_tablespace(pgFile *file, bool in_tablespace);
static char check_db_dir(pgFile *file);
static char check_digit_file(pgFile *file);
static char check_nobackup_dir(pgFile *file);
static void dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
bool exclude, bool follow_symlink, bool backup_logs,
bool skip_hidden, int external_dir_num, fio_location location,
bool backup_replslots);
bool skip_hidden, int external_dir_num, fio_location location);
static void opt_path_map(ConfigOption *opt, const char *arg,
TablespaceList *list, const char *type);
char check_logical_replslot_dir(const char *rel_path);
/* Tablespace mapping */
static TablespaceList tablespace_dirs = {NULL, NULL};
/* Extra directories mapping */
@ -534,7 +538,7 @@ db_map_entry_free(void *entry)
void
dir_list_file(parray *files, const char *root, bool exclude, bool follow_symlink,
bool add_root, bool backup_logs, bool skip_hidden, int external_dir_num,
fio_location location, bool backup_replslots)
fio_location location)
{
pgFile *file;
@ -561,7 +565,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool follow_symlink
parray_append(files, file);
dir_list_file_internal(files, file, root, exclude, follow_symlink,
backup_logs, skip_hidden, external_dir_num, location, backup_replslots);
backup_logs, skip_hidden, external_dir_num, location);
if (!add_root)
pgFileFree(file);
@ -585,7 +589,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool follow_symlink
* - datafiles
*/
static char
dir_check_file(pgFile *file, bool backup_logs, bool backup_replslots)
dir_check_file(pgFile *file, bool backup_logs)
{
int i;
int sscanf_res;
@ -648,29 +652,6 @@ dir_check_file(pgFile *file, bool backup_logs, bool backup_replslots)
}
}
/*
* Backup pg_replslot if it is specified.
* It is generally not useful to backup the contents of this directory even
* if the intention is to restore to another master. See backup.sgml for a
* more detailed description.
*/
if (!backup_replslots) {
if (strcmp(file->rel_path, PG_REPLSLOT_DIR) == 0) {
/* Skip */
elog(VERBOSE, "Excluding directory content: %s", file->rel_path);
return CHECK_EXCLUDE_FALSE;
}
} else {
/*
* Check file that under pg_replslot and judge whether it
* belonged to logical replication slots for subscriptions.
*/
if (strcmp(file->rel_path, PG_REPLSLOT_DIR) != 0 &&
path_is_prefix_of_path(PG_REPLSLOT_DIR, file->rel_path)) {
return check_logical_replslot_dir(file->rel_path);
}
}
ret = check_nobackup_dir(file);
if (ret != -1) { /* -1 means need backup */
return ret;
@ -768,35 +749,6 @@ static char check_nobackup_dir(pgFile *file)
return ret;
}
char check_logical_replslot_dir(const char *rel_path)
{
char ret = CHECK_FALSE;
int i = 0;
char *tmp = pg_strdup(rel_path);
char *p;
#define DIRECTORY_DELIMITER "/"
if (logical_replslot) {
/* extract slot name from rel_path, such as sub1 from pg_replslot/sub1/snap */
p = strtok(tmp, DIRECTORY_DELIMITER);
if (p != NULL) {
p = strtok(NULL, DIRECTORY_DELIMITER);
}
for (i = 0; p != NULL && i < (int)parray_num(logical_replslot); i++) {
char *slotName = (char *)parray_get(logical_replslot, i);
if (strcmp(p, slotName) == 0) {
pfree(tmp);
return CHECK_TRUE;
}
}
} else {
ret = CHECK_TRUE;
}
pfree(tmp);
return ret;
}
static char check_db_dir(pgFile *file)
{
char ret = -1;
@ -937,8 +889,7 @@ bool SkipSomeDirFile(pgFile *file, struct dirent *dent, bool skipHidden)
static void
dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
bool exclude, bool follow_symlink, bool backup_logs,
bool skip_hidden, int external_dir_num, fio_location location,
bool backup_replslots)
bool skip_hidden, int external_dir_num, fio_location location)
{
DIR *dir;
struct dirent *dent;
@ -986,7 +937,7 @@ dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
if (exclude)
{
check_res = dir_check_file(file, backup_logs, backup_replslots);
check_res = dir_check_file(file, backup_logs);
if (check_res == CHECK_FALSE)
{
/* Skip */
@ -1012,7 +963,7 @@ dir_list_file_internal(parray *files, pgFile *parent, const char *parent_dir,
*/
if (S_ISDIR(file->mode))
dir_list_file_internal(files, file, child, exclude, follow_symlink,
backup_logs, skip_hidden, external_dir_num, location, backup_replslots);
backup_logs, skip_hidden, external_dir_num, location);
}
if (errno && errno != ENOENT)

View File

@ -51,7 +51,6 @@ typedef struct
bool exclusive_backup;
bool skip_hidden;
int external_dir_num;
bool backup_replslots;
} fio_list_dir_request;
typedef struct
@ -1795,7 +1794,7 @@ cleanup:
/* Compile the array of files located on remote machine in directory root */
void fio_list_dir(parray *files, const char *root, bool exclude,
bool follow_symlink, bool add_root, bool backup_logs,
bool skip_hidden, int external_dir_num, bool backup_replslots)
bool skip_hidden, int external_dir_num)
{
fio_header hdr;
fio_list_dir_request req;
@ -1812,7 +1811,6 @@ void fio_list_dir(parray *files, const char *root, bool exclude,
req.exclusive_backup = exclusive_backup;
req.skip_hidden = skip_hidden;
req.external_dir_num = external_dir_num;
req.backup_replslots = backup_replslots;
hdr.cop = FIO_LIST_DIR;
hdr.size = sizeof(req);
@ -1872,14 +1870,7 @@ void fio_list_dir(parray *files, const char *root, bool exclude,
securec_check_ss_c(nRet, "\0", "\0");
}
/*
* Check file that under pg_replslot and judge whether it
* belonged to logical replication slots for subscriptions.
*/
if (backup_replslots && strcmp(buf, PG_REPLSLOT_DIR) != 0 &&
path_is_prefix_of_path(PG_REPLSLOT_DIR, buf) && check_logical_replslot_dir(file->rel_path) != 1) {
continue;
}
parray_append(files, file);
}
@ -1923,7 +1914,7 @@ static void fio_list_dir_impl(int out, char* buf)
dir_list_file(file_files, req->path, req->exclude, req->follow_symlink,
req->add_root, req->backup_logs, req->skip_hidden,
req->external_dir_num, FIO_LOCAL_HOST, req->backup_replslots);
req->external_dir_num, FIO_LOCAL_HOST);
/* send information about files to the main process */
for (i = 0; i < (int)parray_num(file_files); i++)

View File

@ -163,7 +163,5 @@ extern z_off_t fio_gzseek(gzFile f, z_off_t offset, int whence);
extern const char* fio_gzerror(gzFile file, int *errnum);
#endif
extern char check_logical_replslot_dir(const char *rel_path);
#endif

View File

@ -154,7 +154,6 @@ void help_pg_probackup(void)
printf(_(" [--remote-port=port] [--ssh-options=ssh_options]\n"));
printf(_(" [--remote-libpath=libpath]\n"));
printf(_(" [--ttl=interval] [--expire-time=time]\n"));
printf(_(" [--backup-pg-replslot]\n"));
printf(_(" [--help]\n"));
printf(_("\n %s restore -B backup-path --instance=instance_name\n"), PROGRAM_NAME);
@ -421,7 +420,6 @@ static void help_backup(void)
printf(_(" [--remote-port=port] [--ssh-options=ssh_options]\n"));
printf(_(" [--remote-libpath=libpath]\n"));
printf(_(" [--ttl=interval] [--expire-time=time]\n\n"));
printf(_(" [--backup-pg-replslot]\n"));
printf(_(" -B, --backup-path=backup-path location of the backup storage area\n"));
printf(_(" --instance=instance_name name of the instance\n"));
@ -443,7 +441,6 @@ static void help_backup(void)
printf(_(" --note=text add note to backup\n"));
printf(_(" (example: --note='backup before app update to v13.1')\n"));
printf(_(" --archive-timeout=timeout wait timeout for WAL segment archiving (default: 5min)\n"));
printf(_(" --backup-pg-replslot] backup of '%s' directory\n"), PG_REPLSLOT_DIR);
printf(_("\n Logging options:\n"));
printf(_(" --log-level-console=log-level-console\n"));

View File

@ -77,7 +77,6 @@ int rw_timeout = 0;
/* backup options */
bool backup_logs = false;
bool backup_replslots = false;
bool smooth_checkpoint;
char *remote_agent;
static char *backup_note = NULL;
@ -187,7 +186,6 @@ static ConfigOption cmd_options[] =
{ 'b', 145, "wal", &delete_wal, SOURCE_CMD_STRICT },
{ 'b', 146, "expired", &delete_expired, SOURCE_CMD_STRICT },
{ 's', 172, "status", &delete_status, SOURCE_CMD_STRICT },
{ 'b', 186, "backup-pg-replslot", &backup_replslots, SOURCE_CMD_STRICT},
{ 'b', 147, "force", &force, SOURCE_CMD_STRICT },
{ 'b', 148, "compress", &compress_shortcut, SOURCE_CMD_STRICT },
@ -552,7 +550,7 @@ static int do_actual_operate()
elog(ERROR, "required parameter not specified: BACKUP_MODE "
"(-b, --backup-mode)");
return do_backup(start_time, set_backup_params, no_validate, no_sync, backup_logs, backup_replslots);
return do_backup(start_time, set_backup_params, no_validate, no_sync, backup_logs);
}
case RESTORE_CMD:
return do_restore_or_validate(current.backup_id,

View File

@ -69,7 +69,6 @@ extern const char *PROGRAM_FULL_PATH;
#define HEADER_MAP "page_header_map"
#define HEADER_MAP_TMP "page_header_map_tmp"
#define PG_RELATIVE_TBLSPC_DIR "pg_location"
#define PG_REPLSLOT_DIR "pg_replslot"
/* Timeout defaults */
#define ARCHIVE_TIMEOUT_DEFAULT 300

View File

@ -54,9 +54,6 @@ extern bool smooth_checkpoint;
it will be backuped up in external dirs */
extern parray *pgdata_nobackup_dir;
/* list of logical replication slots */
extern parray *logical_replslot;
/* remote probackup options */
extern char* remote_agent;
@ -92,7 +89,7 @@ extern const char *pgdata_exclude_dir[];
/* in backup.c */
extern int do_backup(time_t start_time, pgSetBackupParams *set_backup_params,
bool no_validate, bool no_sync, bool backup_logs, bool backup_replslots);
bool no_validate, bool no_sync, bool backup_logs);
extern BackupMode parse_backup_mode(const char *value);
extern const char *deparse_backup_mode(BackupMode mode);
extern void process_block_change(ForkNumber forknum, const RelFileNode rnode,
@ -242,8 +239,7 @@ extern const char* deparse_compress_alg(int alg);
/* in dir.c */
extern void dir_list_file(parray *files, const char *root, bool exclude,
bool follow_symlink, bool add_root, bool backup_logs,
bool skip_hidden, int external_dir_num, fio_location location,
bool backup_replslots = false);
bool skip_hidden, int external_dir_num, fio_location location);
extern void create_data_directories(parray *dest_files,
const char *data_dir,
@ -436,8 +432,7 @@ extern int fio_send_file(const char *from_fullpath, const char *to_fullpath, FIL
pgFile *file, char **errormsg);
extern void fio_list_dir(parray *files, const char *root, bool exclude, bool follow_symlink,
bool add_root, bool backup_logs, bool skip_hidden, int external_dir_num,
bool backup_replslots = false);
bool add_root, bool backup_logs, bool skip_hidden, int external_dir_num);
extern bool pgut_rmtree(const char *path, bool rmtopdir, bool strict);

View File

@ -8641,7 +8641,7 @@
),
AddFuncGroup(
"pg_stat_get_wal_senders", 1,
AddBuiltinFunc(_0(3099), _1("pg_stat_get_wal_senders"), _2(0), _3(false), _4(true), _5(pg_stat_get_wal_senders), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(10), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(21, 20, 23, 25, 25, 25, 25, 1184, 1184, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 23, 25, 25), _22(21, 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'), _23(21, "pid", "sender_pid", "local_role", "peer_role", "peer_state", "state", "catchup_start", "catchup_end", "sender_sent_location", "sender_write_location", "sender_flush_location", "sender_replay_location", "receiver_received_location", "receiver_write_location", "receiver_flush_location", "receiver_replay_location", "sync_percent", "sync_state", "sync_priority", "sync_most_available", "channel"), _24(NULL), _25("pg_stat_get_wal_senders"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("statistics: information about currently active replication"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
AddBuiltinFunc(_0(3099), _1("pg_stat_get_wal_senders"), _2(0), _3(false), _4(true), _5(pg_stat_get_wal_senders), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(10), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(22, 20, 23, 25, 25, 25, 25, 1184, 1184, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 23, 23, 25, 25), _22(22, 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'), _23(22, "pid", "sender_pid", "local_role", "peer_role", "peer_state", "state", "catchup_start", "catchup_end", "sender_sent_location", "sender_write_location", "sender_flush_location", "sender_replay_location", "receiver_received_location", "receiver_write_location", "receiver_flush_location", "receiver_replay_location", "sync_percent", "sync_state", "sync_group", "sync_priority", "sync_most_available", "channel"), _24(NULL), _25("pg_stat_get_wal_senders"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("statistics: information about currently active replication"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
),
AddFuncGroup(
"pg_stat_get_wlm_ec_operator_info", 1,

View File

@ -6230,7 +6230,7 @@ Datum GetPartBoundaryByTuple(Relation rel, HeapTuple tuple)
return Timestamp2Boundarys(rel, Align2UpBoundary(value, partMap->intervalValue, boundaryTs));
}
Oid AddNewIntervalPartition(Relation rel, void* insertTuple, bool isDDL)
Oid AddNewIntervalPartition(Relation rel, void* insertTuple)
{
Relation pgPartRel = NULL;
Oid newPartOid = InvalidOid;
@ -6327,13 +6327,7 @@ Oid AddNewIntervalPartition(Relation rel, void* insertTuple, bool isDDL)
*/
CommandCounterIncrement();
/*
* If add interval partition in the DDL, do not need to change the csn
* because the scn has been changed in the DDL.
*/
if (!isDDL) {
UpdatePgObjectChangecsn(RelationGetRelid(rel), rel->rd_rel->relkind);
}
UpdatePgObjectChangecsn(RelationGetRelid(rel), rel->rd_rel->relkind);
return newPartOid;
}
@ -7119,7 +7113,7 @@ int lookupHBucketid(oidvector *buckets, int low, int2 bktId)
* Description :
* Notes :
*/
Oid heapTupleGetPartitionId(Relation rel, void *tuple, bool isDDL)
Oid heapTupleGetPartitionId(Relation rel, void *tuple)
{
Oid partitionid = InvalidOid;
@ -7146,7 +7140,7 @@ Oid heapTupleGetPartitionId(Relation rel, void *tuple, bool isDDL)
(errcode(ERRCODE_NO_DATA_FOUND), errmsg("inserted partition key does not map to any table partition")));
} break;
case PART_AREA_INTERVAL: {
return AddNewIntervalPartition(rel, tuple, isDDL);
return AddNewIntervalPartition(rel, tuple);
} break;
case PART_AREA_LIST: {
ereport(ERROR,

View File

@ -68,7 +68,7 @@ Subscription *GetSubscription(Oid subid, bool missing_ok)
/* Get slotname */
datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup, Anum_pg_subscription_subslotname, &isnull);
if (!isnull) {
if (unlikely(isnull)) {
sub->slotname = pstrdup(NameStr(*DatumGetName(datum)));
} else {
sub->slotname = NULL;
@ -92,10 +92,10 @@ Subscription *GetSubscription(Oid subid, bool missing_ok)
datum = SysCacheGetAttr(SUBSCRIPTIONOID, tup, Anum_pg_subscription_subbinary, &isnull);
if (unlikely(isnull)) {
sub->binary = false;
} else {
sub->binary = DatumGetBool(datum);
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE),
errmsg("null binary for subscription %u", subid)));
}
sub->binary = DatumGetBool(datum);
ReleaseSysCache(tup);

View File

@ -1454,14 +1454,7 @@ FuncCandidateList sort_candidate_func_list(FuncCandidateList oldCandidates)
}
candidates[smallestIndex] = NULL;
}
for (int i = 0; i < size; i++) {
if (candidates[i] != NULL) {
lastCandidate->next = candidates[i];
lastCandidate = lastCandidate->next;
}
}
lastCandidate->next = NULL;
pfree(candidates);
return sortedCandidates;
}

View File

@ -59,7 +59,7 @@ bool open_join_children = true;
bool will_shutdown = false;
/* hard-wired binary version number */
const uint32 GRAND_VERSION_NUM = 92606;
const uint32 GRAND_VERSION_NUM = 92607;
const uint32 PREDPUSH_SAME_LEVEL_VERSION_NUM = 92522;
const uint32 UPSERT_WHERE_VERSION_NUM = 92514;
@ -101,7 +101,7 @@ const uint32 PRIVS_DIRECTORY_VERSION_NUM = 92460;
const uint32 COMMENT_RECORD_PARAM_VERSION_NUM = 92484;
const uint32 SCAN_BATCH_MODE_VERSION_NUM = 92568;
const uint32 PUBLICATION_VERSION_NUM = 92580;
const uint32 SUBSCRIPTION_BINARY_VERSION_NUM = 92606;
const uint32 SUBSCRIPTION_BINARY_VERSION_NUM = 92607;
/* Version number of the guc parameter backend_version added in V500R001C20 */
const uint32 V5R1C20_BACKEND_VERSION_NUM = 92305;

View File

@ -10340,16 +10340,7 @@ check_sql_expr(const char *stmt, int location, int leaderlen)
oldCxt = MemoryContextSwitchTo(u_sess->plsql_cxt.curr_compile_context->compile_tmp_cxt);
u_sess->plsql_cxt.plpgsql_yylloc = plpgsql_yylloc;
RawParserHook parser_hook= raw_parser;
#ifndef ENABLE_MULTIPLE_NODES
if (u_sess->attr.attr_sql.b_sql_plugin) {
int id = GetCustomParserId();
if (id >= 0 && g_instance.raw_parser_hook[id] != NULL) {
parser_hook = (RawParserHook)g_instance.raw_parser_hook[id];
}
}
#endif
(void)parser_hook(stmt, NULL);
(void) raw_parser(stmt);
MemoryContextSwitchTo(oldCxt);
/* Restore former ereport callback */

View File

@ -26,11 +26,9 @@ import logging
try:
from .dao.gsql_execute import GSqlExecute
from .dao.execute_factory import ExecuteFactory
from .mcts import MCTS
except ImportError:
from dao.gsql_execute import GSqlExecute
from dao.execute_factory import ExecuteFactory
from mcts import MCTS
ENABLE_MULTI_NODE = False
SAMPLE_NUM = 5
@ -194,12 +192,9 @@ class IndexAdvisor:
self.workload_used_index))
if DRIVER:
self.db.close_conn()
if MAX_INDEX_STORAGE:
opt_config = MCTS(self.workload_info[0], atomic_config_total, candidate_indexes,
MAX_INDEX_STORAGE, MAX_INDEX_NUM)
else:
opt_config = greedy_determine_opt_config(self.workload_info[0], atomic_config_total,
candidate_indexes, self.index_cost_total[0])
opt_config = greedy_determine_opt_config(self.workload_info[0], atomic_config_total,
candidate_indexes, self.index_cost_total[0])
self.retain_lower_cost_index(candidate_indexes)
if len(opt_config) == 0:
print("No optimal indexes generated!")
@ -948,7 +943,7 @@ def check_parameter(args):
raise argparse.ArgumentTypeError("%s is an invalid positive int value" %
args.max_index_num)
if args.max_index_storage is not None and args.max_index_storage <= 0:
raise argparse.ArgumentTypeError("%s is an invalid positive float value" %
raise argparse.ArgumentTypeError("%s is an invalid positive int value" %
args.max_index_storage)
JSON_TYPE = args.json
MAX_INDEX_NUM = args.max_index_num
@ -976,7 +971,7 @@ def main(argv):
arg_parser.add_argument(
"--max_index_num", help="Maximum number of suggested indexes", type=int)
arg_parser.add_argument("--max_index_storage",
help="Maximum storage of suggested indexes/MB", type=float)
help="Maximum storage of suggested indexes/MB", type=int)
arg_parser.add_argument("--multi_iter_mode", action='store_true',
help="Whether to use multi-iteration algorithm", default=False)
arg_parser.add_argument("--multi_node", action='store_true',

View File

@ -1,397 +0,0 @@
import sys
import math
import random
import copy
STORAGE_THRESHOLD = 0
AVAILABLE_CHOICES = None
ATOMIC_CHOICES = None
WORKLOAD_INFO = None
MAX_INDEX_NUM = 0
def is_same_index(index, compared_index):
return index.table == compared_index.table and \
index.columns == compared_index.columns and \
index.index_type == compared_index.index_type
def atomic_config_is_valid(atomic_config, config):
# if candidate indexes contains all atomic index of current config1, then record it
for atomic_index in atomic_config:
is_exist = False
for index in config:
if is_same_index(index, atomic_index):
index.storage = atomic_index.storage
is_exist = True
break
if not is_exist:
return False
return True
def find_subsets_num(choice):
atomic_subsets_num = []
for pos, atomic in enumerate(ATOMIC_CHOICES):
if not atomic or len(atomic) > len(choice):
continue
# find valid atomic index
if atomic_config_is_valid(atomic, choice):
atomic_subsets_num.append(pos)
# find the same atomic index as the candidate index
if len(atomic) == 1 and (is_same_index(choice[-1], atomic[0])):
choice[-1].atomic_pos = pos
return atomic_subsets_num
def find_best_benefit(choice):
atomic_subsets_num = find_subsets_num(choice)
total_benefit = 0
for ind, obj in enumerate(WORKLOAD_INFO):
# calculate the best benefit for the current sql
max_benefit = 0
for pos in atomic_subsets_num:
if (obj.cost_list[0] - obj.cost_list[pos]) > max_benefit:
max_benefit = obj.cost_list[0] - obj.cost_list[pos]
total_benefit += max_benefit
return total_benefit
def get_diff(available_choices, choices):
except_choices = copy.copy(available_choices)
for i in available_choices:
for j in choices:
if is_same_index(i, j):
except_choices.remove(i)
return except_choices
class State(object):
"""
The game state of the Monte Carlo tree search,
the state data recorded under a certain Node node,
including the current game score, the current number of game rounds,
and the execution record from the beginning to the current.
It is necessary to realize whether the current state has reached the end of the game state,
and support the operation of randomly fetching from the Action collection.
"""
def __init__(self):
self.current_storage = 0.0
self.current_benefit = 0.0
# record the sum of choices up to the current state
self.accumulation_choices = []
# record available choices of current state
self.available_choices = []
self.displayable_choices = []
def get_available_choices(self):
return self.available_choices
def set_available_choices(self, choices):
self.available_choices = choices
def get_current_storage(self):
return self.current_storage
def set_current_storage(self, value):
self.current_storage = value
def get_current_benefit(self):
return self.current_benefit
def set_current_benefit(self, value):
self.current_benefit = value
def get_accumulation_choices(self):
return self.accumulation_choices
def set_accumulation_choices(self, choices):
self.accumulation_choices = choices
def is_terminal(self):
# the current node is a leaf node
return len(self.accumulation_choices) == MAX_INDEX_NUM
def compute_benefit(self):
return self.current_benefit
def get_next_state_with_random_choice(self):
# ensure that the choices taken are not repeated
if not self.available_choices:
return None
random_choice = random.choice([choice for choice in self.available_choices])
self.available_choices.remove(random_choice)
choice = copy.copy(self.accumulation_choices)
choice.append(random_choice)
benefit = find_best_benefit(choice)
# if current choice not satisfy restrictions, then continue get next choice
if benefit <= self.current_benefit or \
self.current_storage + random_choice.storage > STORAGE_THRESHOLD:
return self.get_next_state_with_random_choice()
next_state = State()
# initialize the properties of the new state
next_state.set_accumulation_choices(choice)
next_state.set_current_benefit(benefit)
next_state.set_current_storage(self.current_storage + random_choice.storage)
next_state.set_available_choices(get_diff(AVAILABLE_CHOICES, choice))
return next_state
def __repr__(self):
self.displayable_choices = ['{}: {}'.format(choice.table, choice.columns)
for choice in self.accumulation_choices]
return "reward: {}, storage :{}, choices: {}".format(
self.current_benefit, self.current_storage, self.displayable_choices)
class Node(object):
"""
The Node of the Monte Carlo tree search tree contains the parent node and
current point information,
which is used to calculate the traversal times and quality value of the UCB,
and the State of the Node selected by the game.
"""
def __init__(self):
self.visit_number = 0
self.quality = 0.0
self.parent = None
self.children = []
self.state = None
def get_parent(self):
return self.parent
def set_parent(self, parent):
self.parent = parent
def get_children(self):
return self.children
def expand_child(self, node):
node.set_parent(self)
self.children.append(node)
def set_state(self, state):
self.state = state
def get_state(self):
return self.state
def get_visit_number(self):
return self.visit_number
def set_visit_number(self, number):
self.visit_number = number
def update_visit_number(self):
self.visit_number += 1
def get_quality_value(self):
return self.quality
def set_quality_value(self, value):
self.quality = value
def update_quality_value(self, reward):
self.quality += reward
def is_all_expand(self):
return len(self.children) == \
len(AVAILABLE_CHOICES) - len(self.get_state().get_accumulation_choices())
def __repr__(self):
return "Node: {}, Q/N: {}/{}, State: {}".format(
hash(self), self.quality, self.visit_number, self.state)
def tree_policy(node):
"""
In the Selection and Expansion stages of Monte Carlo tree search,
the node that needs to be searched (such as the root node) is passed in,
and the best node that needs to be expanded is returned
according to the exploration/exploitation algorithm.
Note that if the node is a leaf node, it will be returned directly.
The basic strategy is to first find the child nodes that have not been selected at present,
and select them randomly if there are more than one. If both are selected,
find the one with the largest UCB value that has weighed exploration/exploitation,
and randomly select if the UCB values are equal.
"""
# check if the current node is leaf node
while node and not node.get_state().is_terminal():
if node.is_all_expand():
node = best_child(node, True)
else:
# return the new sub node
sub_node = expand(node)
# when there is no node that satisfies the condition in the remaining nodes,
# this state is empty
if sub_node.get_state():
return sub_node
# return the leaf node
return node
def default_policy(node):
"""
In the Simulation stage of Monte Carlo tree search, input a node that needs to be expanded,
create a new node after random operation, and return the reward of the new node.
Note that the input node should not be a child node,
and there are unexecuted Actions that can be expendable.
The basic strategy is to choose the Action at random.
"""
# get the state of the game
current_state = copy.deepcopy(node.get_state())
# run until the game over
while not current_state.is_terminal():
# pick one random action to play and get next state
next_state = current_state.get_next_state_with_random_choice()
if not next_state:
break
current_state = next_state
final_state_reward = current_state.compute_benefit()
return final_state_reward
def expand(node):
"""
Enter a node, expand a new node on the node, use the random method to execute the Action,
and return the new node. Note that it is necessary to ensure that the newly
added nodes are different from other node Action
"""
new_state = node.get_state().get_next_state_with_random_choice()
sub_node = Node()
sub_node.set_state(new_state)
node.expand_child(sub_node)
return sub_node
def best_child(node, is_exploration):
"""
Using the UCB algorithm,
select the child node with the highest score after weighing the exploration and exploitation.
Note that if it is the prediction stage,
the current Q-value score with the highest score is directly selected.
"""
best_score = -sys.maxsize
best_sub_node = None
# travel all sub nodes to find the best one
for sub_node in node.get_children():
# The children nodes of the node contains the children node whose state is empty,
# this kind of node comes from the node that does not meet the conditions.
if not sub_node.get_state():
continue
# ignore exploration for inference
if is_exploration:
C = 1 / math.sqrt(2.0)
else:
C = 0.0
# UCB = quality / times + C * sqrt(2 * ln(total_times) / times)
left = sub_node.get_quality_value() / sub_node.get_visit_number()
right = 2.0 * math.log(node.get_visit_number()) / sub_node.get_visit_number()
score = left + C * math.sqrt(right)
# get the maximum score, while filtering nodes that do not meet the space constraints and
# nodes that have no revenue
if score > best_score \
and sub_node.get_state().get_current_storage() <= STORAGE_THRESHOLD \
and sub_node.get_state().get_current_benefit() > 0:
best_sub_node = sub_node
best_score = score
return best_sub_node
def backpropagate(node, reward):
"""
In the Backpropagation stage of Monte Carlo tree search,
input the node that needs to be expended and the reward of the newly executed Action,
feed it back to the expend node and all upstream nodes,
and update the corresponding data.
"""
# update util the root node
while node is not None:
# update the visit number
node.update_visit_number()
# update the quality value
node.update_quality_value(reward)
# change the node to the parent node
node = node.parent
def monte_carlo_tree_search(node):
"""
Implement the Monte Carlo tree search algorithm, pass in a root node,
expand new nodes and update data according to the
tree structure that has been explored before in a limited time,
and then return as long as the child node with the highest exploitation.
When making predictions,
you only need to select the node with the largest exploitation according to the Q value,
and find the next optimal node.
"""
computation_budget = len(AVAILABLE_CHOICES) * 3
# run as much as possible under the computation budget
for i in range(computation_budget):
# 1. find the best node to expand
expand_node = tree_policy(node)
if not expand_node:
# when it is None, it means that all nodes are added but no nodes meet the space limit
break
# 2. random get next action and get reward
reward = default_policy(expand_node)
# 3. update all passing nodes with reward
backpropagate(expand_node, reward)
# get the best next node
best_next_node = best_child(node, False)
return best_next_node
def MCTS(workload_info, atomic_choices, available_choices, storage_threshold, max_index_num):
global ATOMIC_CHOICES, STORAGE_THRESHOLD, WORKLOAD_INFO, AVAILABLE_CHOICES, MAX_INDEX_NUM
WORKLOAD_INFO = workload_info
AVAILABLE_CHOICES = available_choices
ATOMIC_CHOICES = atomic_choices
STORAGE_THRESHOLD = storage_threshold
MAX_INDEX_NUM = max_index_num if max_index_num else len(available_choices)
# create the initialized state and initialized node
init_state = State()
choices = copy.copy(available_choices)
init_state.set_available_choices(choices)
init_node = Node()
init_node.set_state(init_state)
current_node = init_node
opt_config = []
# set the rounds to play
for i in range(len(AVAILABLE_CHOICES)):
if current_node:
current_node = monte_carlo_tree_search(current_node)
if current_node:
opt_config = current_node.state.accumulation_choices
else:
break
return opt_config

View File

@ -27,7 +27,6 @@ from collections.abc import Iterable
from collections import defaultdict
import index_advisor_workload as iaw
import mcts
def hash_any(obj):
@ -228,32 +227,6 @@ select * from student_range_part1 where credit=1;
class IndexAdvisorTester(unittest.TestCase):
def test_mcts(self):
storage_threshold = 12
index1 = iaw.IndexItem('public.a', 'col1', index_type='global')
index2 = iaw.IndexItem('public.b', 'col1', index_type='global')
index3 = iaw.IndexItem('public.c', 'col1', index_type='global')
index4 = iaw.IndexItem('public.d', 'col1', index_type='global')
atomic_index1 = iaw.IndexItem('public.a', 'col1', index_type='global')
atomic_index2 = iaw.IndexItem('public.b', 'col1', index_type='global')
atomic_index3 = iaw.IndexItem('public.c', 'col1', index_type='global')
atomic_index4 = iaw.IndexItem('public.d', 'col1', index_type='global')
atomic_index1.storage = 10
atomic_index2.storage = 4
atomic_index3.storage = 7
available_choices = [index1, index2, index3, index4]
atomic_choices = [[], [atomic_index2], [atomic_index1], [atomic_index3],
[atomic_index2, atomic_index3], [atomic_index4]]
query = iaw.QueryItem('select * from gia_01', 1)
query.cost_list = [10, 7, 5, 9, 4, 11]
workload_info = [query]
results = mcts.MCTS(workload_info, atomic_choices, available_choices, storage_threshold, 2)
self.assertLessEqual([index1.atomic_pos, index2.atomic_pos, index3.atomic_pos], [2, 1, 3])
self.assertSetEqual({results[0].table, results[1].table}, {'public.b', 'public.c'})
def test_get_indexable_columns(self):
tables = 'table1 table2 table2 table3 table3 table3'.split()
columns = 'col1,col2 col2 col3 col1,col2 col2,col3 col2,col5'.split()

View File

@ -23175,7 +23175,7 @@ static void checkValidationForExchangeTable(Relation partTableRel, Relation ordT
int2 bucketId = InvalidBktId;
// get right partition oid for the tuple
targetPartOid = heapTupleGetPartitionId(partTableRel, (HeapTuple)tuple, true);
targetPartOid = heapTupleGetPartitionId(partTableRel, (HeapTuple) tuple);
searchFakeReationForPartitionOid(
partRelHTAB, CurrentMemoryContext, partTableRel, targetPartOid, partRel, part, RowExclusiveLock);
@ -24797,8 +24797,7 @@ static Oid AddTemporaryPartitionForAlterPartitions(const AlterTableCmd* cmd, Rel
destPartOid = AddTemporaryHashPartitionForAlterPartitions(cmd, partTableRel, partSeq, renameTargetPart);
break;
}
case PART_TYPE_RANGE:
case PART_TYPE_INTERVAL: {
case PART_TYPE_RANGE: {
destPartOid = AddTemporaryRangePartitionForAlterPartitions(cmd, partTableRel, partSeq, renameTargetPart);
break;
}
@ -25099,11 +25098,11 @@ static void readTuplesAndInsertInternal(Relation tempTableRel, Relation partTabl
/* tableam_tops_copy_tuple is not ready so we add UStore hack path */
copyTuple = tableam_tops_copy_tuple(tuple);
targetPartOid = heapTupleGetPartitionId(partTableRel, (void *)tuple, true);
targetPartOid = heapTupleGetPartitionId(partTableRel, (void *)tuple);
searchFakeReationForPartitionOid(
partRelHTAB, CurrentMemoryContext, partTableRel, targetPartOid, partRel, part, RowExclusiveLock);
if (RelationIsSubPartitioned(partTableRel)) {
targetPartOid = heapTupleGetPartitionId(partRel, (void *)tuple, true);
targetPartOid = heapTupleGetPartitionId(partRel, (void *)tuple);
searchFakeReationForPartitionOid(partRelHTAB, CurrentMemoryContext, partRel, targetPartOid, subPartRel,
subPart, RowExclusiveLock);
partRel = subPartRel;

View File

@ -827,6 +827,9 @@ void InitBSqlPluginHookIfNeeded()
{
const char* b_sql_plugin = "b_sql_plugin";
CFunInfo tmpCF;
if (!CheckIfExtensionExists(b_sql_plugin)) {
return;
}
tmpCF = load_external_function(b_sql_plugin, INIT_PLUGIN_OBJECT, false, false);
if (tmpCF.user_fn != NULL) {
@ -862,11 +865,9 @@ List* pg_parse_query(const char* query_string, List** query_string_locationlist)
List* (*parser_hook)(const char*, List**) = raw_parser;
#ifndef ENABLE_MULTIPLE_NODES
if (u_sess->attr.attr_sql.b_sql_plugin) {
int id = GetCustomParserId();
if (id >= 0 && g_instance.raw_parser_hook[id] != NULL) {
parser_hook = (List* (*)(const char*, List**))g_instance.raw_parser_hook[id];
}
int id = GetCustomParserId();
if (id >= 0 && g_instance.raw_parser_hook[id] != NULL) {
parser_hook = (List* (*)(const char*, List**))g_instance.raw_parser_hook[id];
}
#endif
raw_parsetree_list = parser_hook(query_string, query_string_locationlist);
@ -6114,9 +6115,6 @@ void ProcessInterrupts(void)
/* The logical replication launcher can be stopped at any time. */
proc_exit(0);
} else if (IsLogicalWorker()) {
ereport(FATAL, (errcode(ERRCODE_ADMIN_SHUTDOWN),
errmsg("terminating logical replication worker due to administrator command")));
#endif
} else if (IsTxnSnapCapturerProcess()) {
ereport(FATAL,
@ -7574,7 +7572,7 @@ int PostgresMain(int argc, char* argv[], const char* dbname, const char* usernam
init_set_params_htab();
#ifndef ENABLE_MULTIPLE_NODES
if (u_sess->proc_cxt.MyDatabaseId != InvalidOid && DB_IS_CMPT(B_FORMAT) && u_sess->attr.attr_sql.b_sql_plugin) {
if (u_sess->proc_cxt.MyDatabaseId != InvalidOid && DB_IS_CMPT(B_FORMAT)) {
InitBSqlPluginHookIfNeeded();
}
#endif

View File

@ -848,7 +848,7 @@ static bool InitSession(knl_session_context* session)
t_thrd.proc_cxt.PostInit->InitSession();
#ifndef ENABLE_MULTIPLE_NODES
if (u_sess->proc_cxt.MyDatabaseId != InvalidOid && DB_IS_CMPT(B_FORMAT) && u_sess->attr.attr_sql.b_sql_plugin) {
if (u_sess->proc_cxt.MyDatabaseId != InvalidOid && DB_IS_CMPT(B_FORMAT)) {
InitBSqlPluginHookIfNeeded();
}
#endif

View File

@ -322,6 +322,7 @@ static bool RelationFindReplTupleByIndex(EState *estate, Relation rel, Relation
}
if (found) {
/* Found tuple, try to lock it in the lockmode. */
outslot->tts_tuple = ExecMaterializeSlot(outslot);
xwait = TransactionIdIsValid(snap.xmin) ? snap.xmin : snap.xmax;
/*
* If the tuple is locked, wait for locking transaction to finish
@ -345,16 +346,12 @@ static bool RelationFindReplTupleByIndex(EState *estate, Relation rel, Relation
ItemPointer tid = tableam_tops_get_t_self(targetRel, outslot->tts_tuple);
if (RelationIsUstoreFormat(targetRel)) {
/* materialize the slot, so we can visit it after the scan is end */
outslot->tts_tuple = UHeapMaterialize(outslot);
ItemPointerCopy(tid, &UHeaplocktup.ctid);
rc = memset_s(&tbuf, sizeof(tbuf), 0, sizeof(tbuf));
securec_check(rc, "\0", "\0");
UHeaplocktup.disk_tuple = &tbuf.hdr;
locktup = &UHeaplocktup;
} else {
/* materialize the slot, so we can visit it after the scan is end */
outslot->tts_tuple = ExecMaterializeSlot(outslot);
ItemPointerCopy(tid, &heaplocktup.t_self);
locktup = &heaplocktup;
}
@ -404,10 +401,6 @@ static bool tuple_equals_slot(TupleDesc desc, const Tuple tup, TupleTableSlot *s
/* Check equality of the attributes. */
for (attrnum = 0; attrnum < desc->natts; attrnum++) {
TypeCacheEntry *typentry;
/* skip generate column */
if (GetGeneratedCol(desc, attrnum)) {
continue;
}
/*
* If one value is NULL and other is not, then they are certainly not
* equal
@ -485,6 +478,7 @@ static bool RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, Tuple
found = true;
ExecStoreTuple(scantuple, outslot, InvalidBuffer, false);
outslot->tts_tuple = ExecMaterializeSlot(outslot);
xwait = TransactionIdIsValid(snap.xmin) ? snap.xmin : snap.xmax;
/*
@ -517,16 +511,12 @@ static bool RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, Tuple
ItemPointer tid = tableam_tops_get_t_self(rel, outslot->tts_tuple);
if (RelationIsUstoreFormat(targetRel)) {
/* materialize the slot, so we can visit it after the scan is end */
outslot->tts_tuple = UHeapMaterialize(outslot);
ItemPointerCopy(tid, &UHeaplocktup.ctid);
rc = memset_s(&tbuf, sizeof(tbuf), 0, sizeof(tbuf));
securec_check(rc, "\0", "\0");
UHeaplocktup.disk_tuple = &tbuf.hdr;
locktup = &UHeaplocktup;
} else {
/* materialize the slot, so we can visit it after the scan is end */
outslot->tts_tuple = ExecMaterializeSlot(outslot);
ItemPointerCopy(tid, &heaplocktup.t_self);
locktup = &heaplocktup;
}
@ -663,6 +653,7 @@ void ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, TupleTableSlot
/* Compute stored generated columns */
if (rel->rd_att->constr && rel->rd_att->constr->has_generated_stored) {
ExecComputeStoredGenerated(resultRelInfo, estate, slot, tuple, CMD_UPDATE);
tuple = slot->tts_tuple;
}
/* Check the constraints of the tuple */
@ -681,11 +672,10 @@ void ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, TupleTableSlot
rowMovement = true;
}
tuple = slot->tts_tuple;
CommandId cid = GetCurrentCommandId(true);
/* OK, update the tuple and index entries for it */
if (!rowMovement) {
res = tableam_tuple_update(targetRelation, parentRelation, searchSlotTid, tuple, cid,
res = tableam_tuple_update(targetRelation, parentRelation, searchSlotTid, slot->tts_tuple, cid,
InvalidSnapshot, estate->es_snapshot, true, &oldslot, &tmfd, &updateIndexes, &modifiedIdxAttrs,
false, allowInplaceUpdate);
CheckTupleModifyRes(res);

View File

@ -1278,10 +1278,13 @@ static const char *MXStatusToString(MultiXactStatus status)
static char *mxid_to_string(MultiXactId multi, int nmembers, MultiXactMember *members)
{
char *str = NULL;
static char *str = NULL;
StringInfoData buf;
int i;
if (str != NULL)
pfree(str);
initStringInfo(&buf);
appendStringInfo(&buf, XID_FMT " %d[" XID_FMT " (%s)", multi, nmembers,
@ -1292,7 +1295,7 @@ static char *mxid_to_string(MultiXactId multi, int nmembers, MultiXactMember *me
}
appendStringInfoChar(&buf, ']');
str = MemoryContextStrdup(SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_STORAGE), buf.data);
str = MemoryContextStrdup(TopMemoryContext, buf.data);
pfree(buf.data);
return str;
}

View File

@ -1818,47 +1818,3 @@ void UHeapSlotStoreUHeapTuple(UHeapTuple utuple, TupleTableSlot *slot, bool shou
/* Mark extracted state invalid */
slot->tts_nvalid = 0;
}
/*
* Make the contents of the uheap table's slot contents solely depend on the slot(make them a local copy),
* and not on underlying external resources like another memory context, buffers etc.
*
* @pram slot: slot to be materialized.
*/
Tuple UHeapMaterialize(TupleTableSlot *slot)
{
Assert(!slot->tts_isempty);
Assert(slot->tts_tupslotTableAm == TAM_USTORE);
Assert(slot->tts_tupleDescriptor != NULL);
/*
* If we have a regular physical tuple, and it's locally palloc'd, we have
* nothing to do.
*/
if (slot->tts_tuple && slot->tts_shouldFree) {
return slot->tts_tuple;
}
/*
* Otherwise, copy or build a physical tuple, and store it into the slot.
*
* We may be called in a context that is shorter-lived than the tuple
* slot, but we have to ensure that the materialized tuple will survive
* anyway.
*/
MemoryContext old_context = MemoryContextSwitchTo(slot->tts_mcxt);
if (slot->tts_tuple != NULL) {
slot->tts_tuple = UHeapCopyTuple((UHeapTuple)slot->tts_tuple);
} else {
slot->tts_tuple = UHeapFormTuple(slot->tts_tupleDescriptor, slot->tts_values, slot->tts_isnull);
}
slot->tts_shouldFree = true;
MemoryContextSwitchTo(old_context);
/*
* Have to deform from scratch, otherwise tts_values[] entries could point
* into the non-materialized tuple (which might be gone when accessed).
*/
slot->tts_nvalid = 0;
return slot->tts_tuple;
}

View File

@ -448,7 +448,9 @@ static void RecycleWaitIfNotUsed()
#endif
) {
uint64 nonRecycled = 0;
while (true) {
while (g_instance.attr.attr_storage.undo_zone_count == 0) {
/* Clear any already-pending wakeups */
ResetLatch(&t_thrd.proc->procLatch);
if (t_thrd.undorecycler_cxt.shutdown_requested) {
ereport(LOG, (errmodule(MOD_UNDO), errmsg(UNDOFORMAT("UndoRecycler: shutting down"))));
ResourceOwnerRelease(t_thrd.utils_cxt.CurrentResourceOwner, RESOURCE_RELEASE_BEFORE_LOCKS, false, true);

View File

@ -223,7 +223,6 @@ void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, XLogReaderState *
return;
}
ResourceOwner tmpOwner = t_thrd.utils_cxt.CurrentResourceOwner;
/* cast so we get a warning when new rmgrs are added */
switch ((RmgrIds)XLogRecGetRmid(record)) {
/*
@ -258,7 +257,6 @@ void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, XLogReaderState *
default:
break;
}
t_thrd.utils_cxt.CurrentResourceOwner = tmpOwner;
}
/*

View File

@ -406,7 +406,7 @@ static void logicalrep_write_tuple(StringInfo out, Relation rel, HeapTuple tuple
pfree(outputbytes);
}
} else {
char* outputstr = NULL;
char *outputstr;
pq_sendbyte(out, LOGICALREP_COLUMN_TEXT);
if (!typclass->typbyval && typclass->typlen == -1) {
/* definitely detoasted Datum */
@ -464,8 +464,10 @@ static void logicalrep_read_tuple(StringInfo in, LogicalRepTupleData *tuple)
len = pq_getmsgint(in, sizeof(uint32)); /* read length */
/* and data */
value->data = (char *)palloc0((len + 1) * sizeof(char));
value->data = (char *) palloc((len + 1) * sizeof(char));
pq_copymsgbytes(in, value->data, len);
/* not strictly necessary but per StringInfo practice */
value->data[len] = '\0';
/* make StringInfo fully valid */
value->len = len;
value->cursor = 0;

View File

@ -94,7 +94,7 @@
#include "utils/relcache.h"
static const int NAPTIME_PER_CYCLE = 10; /* max sleep time between cycles (10ms) */
static const double HALF = 0.5;
static const float HALF = 0.5;
typedef struct FlushPosition {
dlist_node node;
@ -121,6 +121,18 @@ static void LogicalrepWorkerSighub(SIGNAL_ARGS)
t_thrd.applyworker_cxt.got_SIGHUP = true;
}
/* SIGTERM: time to die */
static void LogicalrepWorkerSigterm(SIGNAL_ARGS)
{
int saveErrno = errno;
t_thrd.applyworker_cxt.got_SIGTERM = true;
if (t_thrd.proc)
SetLatch(&t_thrd.proc->procLatch);
errno = saveErrno;
}
/*
* Make sure that we started local transaction.
*
@ -1056,15 +1068,13 @@ static void ApplyLoop(void)
/* mark as idle, before starting to loop */
pgstat_report_activity(STATE_IDLE, NULL);
for (;;) {
while (!t_thrd.applyworker_cxt.got_SIGTERM) {
MemoryContextSwitchTo(t_thrd.applyworker_cxt.messageContext);
int len;
char *buf = NULL;
unsigned char type;
CHECK_FOR_INTERRUPTS();
/* Wait a while for data to arrive */
if ((WalReceiverFuncTable[GET_FUNC_IDX]).walrcv_receive(NAPTIME_PER_CYCLE, &type, &buf, &len)) {
StringInfoData s;
@ -1361,7 +1371,7 @@ void ApplyWorkerMain()
*/
gspqsignal(SIGHUP, LogicalrepWorkerSighub);
gspqsignal(SIGINT, StatementCancelHandler);
gspqsignal(SIGTERM, die);
gspqsignal(SIGTERM, LogicalrepWorkerSigterm);
gspqsignal(SIGQUIT, quickdie);
gspqsignal(SIGALRM, handle_sig_alarm);
@ -1717,11 +1727,3 @@ static void UpdateConninfo(char* standbysInfo)
ereport(LOG, (errmsg("Update conninfo successfully, new conninfo %s.", standbysInfo)));
}
/*
* Is current process a logical replication worker?
*/
bool IsLogicalWorker(void)
{
return t_thrd.applyworker_cxt.curWorker != NULL;
}

View File

@ -78,7 +78,7 @@ void _PG_output_plugin_init(OutputPluginCallbacks *cb)
cb->shutdown_cb = pgoutput_shutdown;
}
static void parse_output_parameters(List *options, PGOutputData *data)
static void parse_output_parameters(List* options, PGOutputData* data)
{
ListCell *lc;
bool protocol_version_given = false;

View File

@ -1934,18 +1934,14 @@ ArchiveConfig* formArchiveConfigFromStr(char *content, bool encrypted)
ArchiveConnConfig* conn_config = NULL;
char* media_type = NULL;
errno_t rc = EOK;
char *content_copy = NULL;
/* SplitIdentifierString will change origin string */
char *content_copy = pstrdup(content);
char *tmp = NULL;
List* elemlist = NIL;
int param_num = 0;
size_t elem_index = 0;
archive_config = (ArchiveConfig *)palloc0(sizeof(ArchiveConfig));
char decryptSecretAccessKeyStr[DEST_CIPHER_LENGTH] = {'\0'};
if (content == NULL || strlen(content) == 0) {
goto FAILURE;
}
/* SplitIdentifierString will change origin string */
content_copy = pstrdup(content);
/* Parse string into list of identifiers */
if (!SplitIdentifierString(content_copy, ';', &elemlist, false, false)) {
goto FAILURE;

View File

@ -401,7 +401,6 @@ int WalSenderMain(void)
t_thrd.walsender_cxt.server_run_mode = t_thrd.postmaster_cxt.HaShmData->current_mode;
SetHaWalSenderChannel();
Assert(t_thrd.utils_cxt.CurrentResourceOwner != NULL);
/* Handle handshake messages before streaming */
WalSndHandshake();
@ -497,7 +496,6 @@ static void WalSndHandshake(void)
while (!repCxt.replicationStarted) {
int firstchar;
Assert(t_thrd.utils_cxt.CurrentResourceOwner != NULL);
WalSndSetState(WALSNDSTATE_STARTUP);
set_ps_display("idle", false);
@ -2035,8 +2033,6 @@ bool isLogicalSlotExist(char* slotName)
}
static void IdentifyCommand(Node* cmd_node, ReplicationCxt* repCxt, const char *cmd_string){
ResourceOwner tmpOwner = t_thrd.utils_cxt.CurrentResourceOwner;
Assert(tmpOwner != NULL);
switch (cmd_node->type) {
case T_IdentifySystemCmd:
IdentifySystem();
@ -2144,7 +2140,7 @@ static void IdentifyCommand(Node* cmd_node, ReplicationCxt* repCxt, const char *
ereport(FATAL,
(errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("invalid standby query string: %s", cmd_string)));
}
t_thrd.utils_cxt.CurrentResourceOwner = tmpOwner;
}
/*
@ -3600,12 +3596,8 @@ static int WalSndLoop(WalSndSendDataCallback send_data)
t_thrd.walsender_cxt.last_logical_xlog_advanced_timestamp = GetCurrentTimestamp();
t_thrd.walsender_cxt.waiting_for_ping_response = false;
ResourceOwner tmpOwner = t_thrd.utils_cxt.CurrentResourceOwner;
Assert(!IsTransactionOrTransactionBlock() &&
strcmp(ResourceOwnerGetName(tmpOwner), "walsender top-level resource owner") == 0);
/* Loop forever, unless we get an error */
for (;;) {
t_thrd.utils_cxt.CurrentResourceOwner = tmpOwner;
TimestampTz now;
/* Clear any already-pending wakeups */
@ -4014,7 +4006,6 @@ static int WalSndLoop(WalSndSendDataCallback send_data)
}
}
t_thrd.utils_cxt.CurrentResourceOwner = tmpOwner;
WalSndShutdown();
return 1; /* keep the compiler quiet */
}
@ -5823,7 +5814,7 @@ Datum gs_paxos_stat_replication(PG_FUNCTION_ARGS)
*/
Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
{
#define PG_STAT_GET_WAL_SENDERS_COLS 21
#define PG_STAT_GET_WAL_SENDERS_COLS 22
TupleDesc tupdesc;
int *sync_priority = NULL;
@ -6060,9 +6051,11 @@ Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
/* sync_state and sync_prority */
if (!SyncRepRequested()) {
values[j++] = CStringGetTextDatum("Async");
nulls[j++] = true;
values[j++] = Int32GetDatum(0);
} else {
values[j++] = CStringGetTextDatum("Sync");
nulls[j++] = true;
values[j++] = Int32GetDatum(sync_priority[i]);
}
} else {
@ -6084,12 +6077,15 @@ Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
*/
if (priority == 0) {
values[j++] = CStringGetTextDatum("Async");
nulls[j++] = true;
} else if (list_member_int((List*)list_nth(sync_standbys, group), i)) {
values[j++] = GetWalsndSyncRepConfig(walsnd)->syncrep_method == SYNC_REP_PRIORITY
? CStringGetTextDatum("Sync")
: CStringGetTextDatum("Quorum");
values[j++] = Int32GetDatum(group);
} else {
values[j++] = CStringGetTextDatum("Potential");
values[j++] = Int32GetDatum(group);
}
values[j++] = Int32GetDatum(priority);
}

View File

@ -145,29 +145,6 @@ then
plat_form_str=ubuntu18.04_"$cpu_bit"
fi
##################################################################################
# the modification here will also lead to the synchronous modification of the 3rd-party compilation library path
# PR link : https://gitee.com/opengauss/openGauss-third_party/pulls/130
# redflag platform
# the result form like this: asianux_x86_64
##################################################################################
if [ "$kernel"x = "redflag"x ]
then
plat_form_str=asianux7.6_"$cpu_bit"
fi
##################################################################################
# the modification here will also lead to the synchronous modification of the 3rd-party compilation library path
# PR link : https://gitee.com/opengauss/openGauss-third_party/pulls/130
# asianux platform
# the result form like this: asianux_aarch64
##################################################################################
if [ "$kernel"x = "asianux"x ]
then
plat_form_str=asianux7.5_"$cpu_bit"
fi
##################################################################################
#
# other platform

View File

@ -314,5 +314,4 @@ template<bool hasnull>
void UHeapFillDiskTuple(TupleDesc tupleDesc, Datum *values, const bool *isnull, UHeapDiskTupleData *diskTuple,
uint32 dataSize, bool enableReverseBitmap, bool enableReserve);
void CheckTupleValidity(Relation rel, UHeapTuple utuple);
Tuple UHeapMaterialize(TupleTableSlot *slot);
#endif

View File

@ -165,7 +165,7 @@ extern void addNewPartitionTuple(Relation pg_part_desc, Partition new_part_desc,
Datum interval, Datum maxValues, Datum transitionPoint, Datum reloptions);
extern void heap_truncate_one_part(Relation rel , Oid partOid);
extern Oid heapTupleGetPartitionId(Relation rel, void *tuple, bool isDDL = false);
extern Oid heapTupleGetPartitionId(Relation rel, void *tuple);
extern Oid heapTupleGetSubPartitionId(Relation rel, void *tuple);
extern void heap_truncate(List *relids);
extern void heap_truncate_one_rel(Relation rel);
@ -240,7 +240,7 @@ extern char* make_column_map(TupleDesc tuple_desc);
*/
extern bool* CheckPartkeyHasTimestampwithzone(Relation partTableRel, bool isForSubPartition = false);
extern Oid AddNewIntervalPartition(Relation rel, void* insertTuple, bool isDDL = false);
extern Oid AddNewIntervalPartition(Relation rel, void* insertTuple);
extern int GetIndexKeyAttsByTuple(Relation relation, HeapTuple indexTuple);

View File

@ -0,0 +1,37 @@
-- for any x group
DO $$
DECLARE
ans boolean;
BEGIN
select case when working_version_num()=92301 then true else false end as ans into ans;
if ans = false then
DROP FUNCTION IF EXISTS pg_catalog.pg_stat_get_wal_senders() CASCADE;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3099;
CREATE FUNCTION pg_catalog.pg_stat_get_wal_senders(
OUT pid bigint,
OUT sender_pid integer,
OUT local_role text,
OUT peer_role text,
OUT peer_state text,
OUT state text,
OUT catchup_start timestamp with time zone,
OUT catchup_end timestamp with time zone,
OUT sender_sent_location text,
OUT sender_write_location text,
OUT sender_flush_location text,
OUT sender_replay_location text,
OUT receiver_received_location text,
OUT receiver_write_location text,
OUT receiver_flush_location text,
OUT receiver_replay_location text,
OUT sync_percent text,
OUT sync_state text,
OUT sync_priority integer,
OUT sync_most_available text,
OUT channel text
) RETURNS SETOF record
STABLE NOT FENCED NOT SHIPPABLE ROWS 10
LANGUAGE internal AS 'pg_stat_get_wal_senders';
end if;
END$$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 0;

View File

@ -0,0 +1,37 @@
-- for any x group
DO $$
DECLARE
ans boolean;
BEGIN
select case when working_version_num()=92301 then true else false end as ans into ans;
if ans = false then
DROP FUNCTION IF EXISTS pg_catalog.pg_stat_get_wal_senders() CASCADE;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3099;
CREATE FUNCTION pg_catalog.pg_stat_get_wal_senders(
OUT pid bigint,
OUT sender_pid integer,
OUT local_role text,
OUT peer_role text,
OUT peer_state text,
OUT state text,
OUT catchup_start timestamp with time zone,
OUT catchup_end timestamp with time zone,
OUT sender_sent_location text,
OUT sender_write_location text,
OUT sender_flush_location text,
OUT sender_replay_location text,
OUT receiver_received_location text,
OUT receiver_write_location text,
OUT receiver_flush_location text,
OUT receiver_replay_location text,
OUT sync_percent text,
OUT sync_state text,
OUT sync_priority integer,
OUT sync_most_available text,
OUT channel text
) RETURNS SETOF record
STABLE NOT FENCED NOT SHIPPABLE ROWS 10
LANGUAGE internal AS 'pg_stat_get_wal_senders';
end if;
END$$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 0;

View File

@ -0,0 +1,38 @@
-- for any x group
DO $$
DECLARE
ans boolean;
BEGIN
select case when working_version_num()=92301 then true else false end as ans into ans;
if ans = false then
DROP FUNCTION IF EXISTS pg_catalog.pg_stat_get_wal_senders() CASCADE;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3099;
CREATE FUNCTION pg_catalog.pg_stat_get_wal_senders(
OUT pid bigint,
OUT sender_pid integer,
OUT local_role text,
OUT peer_role text,
OUT peer_state text,
OUT state text,
OUT catchup_start timestamp with time zone,
OUT catchup_end timestamp with time zone,
OUT sender_sent_location text,
OUT sender_write_location text,
OUT sender_flush_location text,
OUT sender_replay_location text,
OUT receiver_received_location text,
OUT receiver_write_location text,
OUT receiver_flush_location text,
OUT receiver_replay_location text,
OUT sync_percent text,
OUT sync_state text,
OUT sync_group integer,
OUT sync_priority integer,
OUT sync_most_available text,
OUT channel text
) RETURNS SETOF record
STABLE NOT FENCED NOT SHIPPABLE ROWS 10
LANGUAGE internal AS 'pg_stat_get_wal_senders';
end if;
END$$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 0;

View File

@ -0,0 +1,38 @@
-- for any x group
DO $$
DECLARE
ans boolean;
BEGIN
select case when working_version_num()=92301 then true else false end as ans into ans;
if ans = false then
DROP FUNCTION IF EXISTS pg_catalog.pg_stat_get_wal_senders() CASCADE;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3099;
CREATE FUNCTION pg_catalog.pg_stat_get_wal_senders(
OUT pid bigint,
OUT sender_pid integer,
OUT local_role text,
OUT peer_role text,
OUT peer_state text,
OUT state text,
OUT catchup_start timestamp with time zone,
OUT catchup_end timestamp with time zone,
OUT sender_sent_location text,
OUT sender_write_location text,
OUT sender_flush_location text,
OUT sender_replay_location text,
OUT receiver_received_location text,
OUT receiver_write_location text,
OUT receiver_flush_location text,
OUT receiver_replay_location text,
OUT sync_percent text,
OUT sync_state text,
OUT sync_group integer,
OUT sync_priority integer,
OUT sync_most_available text,
OUT channel text
) RETURNS SETOF record
STABLE NOT FENCED NOT SHIPPABLE ROWS 10
LANGUAGE internal AS 'pg_stat_get_wal_senders';
end if;
END$$;
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 0;

View File

@ -13,6 +13,5 @@
#define LOGICALWORKER_H
extern void ApplyWorkerMain();
extern bool IsLogicalWorker(void);
#endif /* LOGICALWORKER_H */

View File

@ -1385,8 +1385,6 @@ typedef struct PlDebugEntry {
PLpgSQL_function* func;
} PlDebugEntry;
typedef List* (*RawParserHook)(const char*, List**);
const int MAXINT8LEN = 25;
const int DEFAULT_DEBUG_BUF_SIZE = 1024;
const long NANOSECOND_PER_SECOND = 1000000000L; /* 1s */

View File

@ -215,107 +215,3 @@ select * from interval_normal_exchange where logdate > '2020-06-01' order by log
(0 rows)
drop table interval_normal_exchange;
drop table table_001;
ERROR: table "table_001" does not exist
create table table_001(
COL_1 smallint,
COL_2 char(5),
COL_3 int,
COL_4 date,
COL_5 boolean,
COL_6 nchar(5),
COL_7 float
);
drop table partition_table_001;
ERROR: table "partition_table_001" does not exist
create table partition_table_001(
COL_1 smallint,
COL_2 char(5),
COL_3 int,
COL_4 date,
COL_5 boolean,
COL_6 nchar(5),
COL_7 float
)
PARTITION BY RANGE (COL_4)
INTERVAL ('1 month')
(
PARTITION partition_table_001_p1 VALUES LESS THAN ('2020-03-01'),
PARTITION partition_table_001_p2 VALUES LESS THAN ('2020-04-01'),
PARTITION partition_table_001_p3 VALUES LESS THAN ('2020-05-01')
);
insert into partition_table_001 values (1,'aaa',1,'2020-02-23',true,'aaa',1.1);
insert into partition_table_001 values (2,'bbb',2,'2020-03-23',false,'bbb',2.2);
insert into partition_table_001 values (3,'ccc',3,'2020-04-23',true,'ccc',3.3);
insert into partition_table_001 values (4,'ddd',4,'2020-05-23',false,'ddd',4.4);
insert into partition_table_001 values (5,'eee',5,'2020-06-23',true,'eee',5.5);
insert into partition_table_001 values (6,'fff',6,'2020-07-23',false,'fff',6.6);
ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001;
select * from table_001 order by 1;
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7
-------+-------+-------+--------------------------+-------+-------+-------
4 | ddd | 4 | Sat May 23 00:00:00 2020 | f | ddd | 4.4
(1 row)
select * from partition_table_001 order by 1;
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7
-------+-------+-------+--------------------------+-------+-------+-------
1 | aaa | 1 | Sun Feb 23 00:00:00 2020 | t | aaa | 1.1
2 | bbb | 2 | Mon Mar 23 00:00:00 2020 | f | bbb | 2.2
3 | ccc | 3 | Thu Apr 23 00:00:00 2020 | t | ccc | 3.3
5 | eee | 5 | Tue Jun 23 00:00:00 2020 | t | eee | 5.5
6 | fff | 6 | Thu Jul 23 00:00:00 2020 | f | fff | 6.6
(5 rows)
select relname, parttype, partstrategy, boundaries from pg_partition
where parentid = (select oid from pg_class where relname = 'partition_table_001')
order by relname;
relname | parttype | partstrategy | boundaries
------------------------+----------+--------------+------------------------------
partition_table_001 | r | i |
partition_table_001_p1 | p | r | {2020-03-01}
partition_table_001_p2 | p | r | {2020-04-01}
partition_table_001_p3 | p | r | {2020-05-01}
sys_p1 | p | i | {"Mon Jun 01 00:00:00 2020"}
sys_p2 | p | i | {"Wed Jul 01 00:00:00 2020"}
sys_p3 | p | i | {"Sat Aug 01 00:00:00 2020"}
(7 rows)
ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001;
select * from table_001 order by 1;
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7
-------+-------+-------+-------+-------+-------+-------
(0 rows)
select * from partition_table_001 order by 1;
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7
-------+-------+-------+--------------------------+-------+-------+-------
1 | aaa | 1 | Sun Feb 23 00:00:00 2020 | t | aaa | 1.1
2 | bbb | 2 | Mon Mar 23 00:00:00 2020 | f | bbb | 2.2
3 | ccc | 3 | Thu Apr 23 00:00:00 2020 | t | ccc | 3.3
4 | ddd | 4 | Sat May 23 00:00:00 2020 | f | ddd | 4.4
5 | eee | 5 | Tue Jun 23 00:00:00 2020 | t | eee | 5.5
6 | fff | 6 | Thu Jul 23 00:00:00 2020 | f | fff | 6.6
(6 rows)
insert into table_001 values (7,'eee',7,'2020-08-23',true,'eee',7.7);
ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001 with validation verbose;
select * from table_001 order by 1;
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7
-------+-------+-------+--------------------------+-------+-------+-------
4 | ddd | 4 | Sat May 23 00:00:00 2020 | f | ddd | 4.4
(1 row)
select * from partition_table_001 order by 1;
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | col_7
-------+-------+-------+--------------------------+-------+-------+-------
1 | aaa | 1 | Sun Feb 23 00:00:00 2020 | t | aaa | 1.1
2 | bbb | 2 | Mon Mar 23 00:00:00 2020 | f | bbb | 2.2
3 | ccc | 3 | Thu Apr 23 00:00:00 2020 | t | ccc | 3.3
5 | eee | 5 | Tue Jun 23 00:00:00 2020 | t | eee | 5.5
6 | fff | 6 | Thu Jul 23 00:00:00 2020 | f | fff | 6.6
7 | eee | 7 | Sun Aug 23 00:00:00 2020 | t | eee | 7.7
(6 rows)
drop table table_001;
drop table partition_table_001;

View File

@ -1062,73 +1062,6 @@ select /*+ indexscan(tg_hash i_tg_hash_local_a) */ * from tg_hash where a < 9;
(81 rows)
drop table tg_hash;
drop table if exists test_ugi_045;
NOTICE: table "test_ugi_045" does not exist, skipping
create table test_ugi_045
(
c_id integer not null,
c_date DATE,
c_info varchar(20) not null
)
partition by range(c_date)
interval('2 day')
(
partition p1 values less than ('2021-06-01 00:00:00'),
partition p2 values less than ('2021-06-03 00:00:00'),
partition p3 values less than ('2021-06-05 00:00:00'),
partition p4 values less than ('2021-06-07 00:00:00'),
partition p5 values less than ('2021-06-09 00:00:00')
);
insert into test_ugi_045(c_id, c_date, c_info) values(1, '2021-05-30 00:00:00', '1-1');
insert into test_ugi_045(c_id, c_date, c_info) values(2, '2021-05-31 00:00:00', '1-1');
insert into test_ugi_045(c_id, c_date, c_info) values(3, '2021-06-01 00:00:00', '1-1');
insert into test_ugi_045(c_id, c_date, c_info) values(4, '2021-06-02 00:00:00', '1-2');
insert into test_ugi_045(c_id, c_date, c_info) values(5, '2021-06-03 00:00:00', '1-2');
insert into test_ugi_045(c_id, c_date, c_info) values(6, '2021-06-04 00:00:00', '1-3');
insert into test_ugi_045(c_id, c_date, c_info) values(7, '2021-06-05 00:00:00', '1-3');
insert into test_ugi_045(c_id, c_date, c_info) values(8, '2021-06-06 00:00:00', '1-4');
insert into test_ugi_045(c_id, c_date, c_info) values(9, '2021-06-07 00:00:00', '1-4');
insert into test_ugi_045(c_id, c_date, c_info) values(10, '2021-06-08 00:00:00', '1-5');
create index global_index_id_045 on test_ugi_045(c_date) global;
create index global_index_info_045 on test_ugi_045(c_info) global;
select *from test_ugi_045;
c_id | c_date | c_info
------+---------------------+--------
1 | 2021-05-30 00:00:00 | 1-1
2 | 2021-05-31 00:00:00 | 1-1
3 | 2021-06-01 00:00:00 | 1-1
4 | 2021-06-02 00:00:00 | 1-2
5 | 2021-06-03 00:00:00 | 1-2
6 | 2021-06-04 00:00:00 | 1-3
7 | 2021-06-05 00:00:00 | 1-3
8 | 2021-06-06 00:00:00 | 1-4
9 | 2021-06-07 00:00:00 | 1-4
10 | 2021-06-08 00:00:00 | 1-5
(10 rows)
alter table test_ugi_045 truncate partition p3 update global index;
set enable_seqscan = off;
set enable_bitmapscan = off;
select *from test_ugi_045;
c_id | c_date | c_info
------+---------------------+--------
1 | 2021-05-30 00:00:00 | 1-1
2 | 2021-05-31 00:00:00 | 1-1
3 | 2021-06-01 00:00:00 | 1-1
4 | 2021-06-02 00:00:00 | 1-2
7 | 2021-06-05 00:00:00 | 1-3
8 | 2021-06-06 00:00:00 | 1-4
9 | 2021-06-07 00:00:00 | 1-4
10 | 2021-06-08 00:00:00 | 1-5
(8 rows)
select *from test_ugi_045 where c_info = '1-2';
c_id | c_date | c_info
------+---------------------+--------
4 | 2021-06-02 00:00:00 | 1-2
(1 row)
drop table if exists test_ugi_045;
-- 清理过程
drop view check_truncate_results;
drop materialized view pg_partition_before_truncate;

View File

@ -97,61 +97,3 @@ select * from interval_exchange_test order by logdate;
select * from interval_normal_exchange order by logdate;
select * from interval_normal_exchange where logdate > '2020-06-01' order by logdate;
drop table interval_normal_exchange;
drop table table_001;
create table table_001(
COL_1 smallint,
COL_2 char(5),
COL_3 int,
COL_4 date,
COL_5 boolean,
COL_6 nchar(5),
COL_7 float
);
drop table partition_table_001;
create table partition_table_001(
COL_1 smallint,
COL_2 char(5),
COL_3 int,
COL_4 date,
COL_5 boolean,
COL_6 nchar(5),
COL_7 float
)
PARTITION BY RANGE (COL_4)
INTERVAL ('1 month')
(
PARTITION partition_table_001_p1 VALUES LESS THAN ('2020-03-01'),
PARTITION partition_table_001_p2 VALUES LESS THAN ('2020-04-01'),
PARTITION partition_table_001_p3 VALUES LESS THAN ('2020-05-01')
);
insert into partition_table_001 values (1,'aaa',1,'2020-02-23',true,'aaa',1.1);
insert into partition_table_001 values (2,'bbb',2,'2020-03-23',false,'bbb',2.2);
insert into partition_table_001 values (3,'ccc',3,'2020-04-23',true,'ccc',3.3);
insert into partition_table_001 values (4,'ddd',4,'2020-05-23',false,'ddd',4.4);
insert into partition_table_001 values (5,'eee',5,'2020-06-23',true,'eee',5.5);
insert into partition_table_001 values (6,'fff',6,'2020-07-23',false,'fff',6.6);
ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001;
select * from table_001 order by 1;
select * from partition_table_001 order by 1;
select relname, parttype, partstrategy, boundaries from pg_partition
where parentid = (select oid from pg_class where relname = 'partition_table_001')
order by relname;
ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001;
select * from table_001 order by 1;
select * from partition_table_001 order by 1;
insert into table_001 values (7,'eee',7,'2020-08-23',true,'eee',7.7);
ALTER TABLE partition_table_001 EXCHANGE PARTITION (sys_p1) WITH TABLE table_001 with validation verbose;
select * from table_001 order by 1;
select * from partition_table_001 order by 1;
drop table table_001;
drop table partition_table_001;

View File

@ -192,46 +192,6 @@ explain(costs off) select /*+ indexscan(tg_hash i_tg_hash_local_a) */ * from tg_
select /*+ indexscan(tg_hash i_tg_hash_local_a) */ * from tg_hash where a < 9;
drop table tg_hash;
drop table if exists test_ugi_045;
create table test_ugi_045
(
c_id integer not null,
c_date DATE,
c_info varchar(20) not null
)
partition by range(c_date)
interval('2 day')
(
partition p1 values less than ('2021-06-01 00:00:00'),
partition p2 values less than ('2021-06-03 00:00:00'),
partition p3 values less than ('2021-06-05 00:00:00'),
partition p4 values less than ('2021-06-07 00:00:00'),
partition p5 values less than ('2021-06-09 00:00:00')
);
insert into test_ugi_045(c_id, c_date, c_info) values(1, '2021-05-30 00:00:00', '1-1');
insert into test_ugi_045(c_id, c_date, c_info) values(2, '2021-05-31 00:00:00', '1-1');
insert into test_ugi_045(c_id, c_date, c_info) values(3, '2021-06-01 00:00:00', '1-1');
insert into test_ugi_045(c_id, c_date, c_info) values(4, '2021-06-02 00:00:00', '1-2');
insert into test_ugi_045(c_id, c_date, c_info) values(5, '2021-06-03 00:00:00', '1-2');
insert into test_ugi_045(c_id, c_date, c_info) values(6, '2021-06-04 00:00:00', '1-3');
insert into test_ugi_045(c_id, c_date, c_info) values(7, '2021-06-05 00:00:00', '1-3');
insert into test_ugi_045(c_id, c_date, c_info) values(8, '2021-06-06 00:00:00', '1-4');
insert into test_ugi_045(c_id, c_date, c_info) values(9, '2021-06-07 00:00:00', '1-4');
insert into test_ugi_045(c_id, c_date, c_info) values(10, '2021-06-08 00:00:00', '1-5');
create index global_index_id_045 on test_ugi_045(c_date) global;
create index global_index_info_045 on test_ugi_045(c_info) global;
select *from test_ugi_045;
alter table test_ugi_045 truncate partition p3 update global index;
set enable_seqscan = off;
set enable_bitmapscan = off;
select *from test_ugi_045;
select *from test_ugi_045 where c_info = '1-2';
drop table if exists test_ugi_045;
-- 清理过程
drop view check_truncate_results;
drop materialized view pg_partition_before_truncate;
drop materialized view pg_partition_before_truncate;