forked from huawei/openGauss-server
commit
97bd39fcfa
|
|
@ -1151,7 +1151,6 @@ static void deparseRelation(StringInfo buf, Relation rel)
|
|||
const char *nspname = NULL;
|
||||
const char *relname = NULL;
|
||||
ListCell *lc;
|
||||
char parttype = PARTTYPE_NON_PARTITIONED_RELATION;
|
||||
|
||||
/* obtain additional catalog information. */
|
||||
ForeignTable* table = GetForeignTable(RelationGetRelid(rel));
|
||||
|
|
@ -1180,31 +1179,34 @@ static void deparseRelation(StringInfo buf, Relation rel)
|
|||
relname = RelationGetRelationName(rel);
|
||||
}
|
||||
|
||||
/* foreign table could not be built from a partitioned table */
|
||||
UserMapping* user = GetUserMapping(rel->rd_rel->relowner, table->serverid);
|
||||
ForeignServer *server = GetForeignServer(table->serverid);
|
||||
PGconn* conn = GetConnection(server, user, false);
|
||||
/* In current version, there are some unpredictable operations (delete/update, etc.) of foreign table built on
|
||||
* partitioned table. We forbid all operations in this condition by default. */
|
||||
if (!ENABLE_SQL_BETA_FEATURE(PARTITION_FDW_ON)) {
|
||||
char parttype = PARTTYPE_NON_PARTITIONED_RELATION;
|
||||
UserMapping* user = GetUserMapping(GetUserId(), table->serverid);
|
||||
ForeignServer *server = GetForeignServer(table->serverid);
|
||||
PGconn* conn = GetConnection(server, user, false);
|
||||
|
||||
PQExpBuffer query = createPQExpBuffer();
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT c.parttype FROM pg_class c, pg_namespace n "
|
||||
"WHERE c.relname = '%s' and c.relnamespace = n.oid and n.nspname = '%s'",
|
||||
quote_identifier(relname), quote_identifier(nspname));
|
||||
PQExpBuffer query = createPQExpBuffer();
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT c.parttype FROM pg_class c, pg_namespace n "
|
||||
"WHERE c.relname = '%s' and c.relnamespace = n.oid and n.nspname = '%s'",
|
||||
quote_identifier(relname), quote_identifier(nspname));
|
||||
|
||||
PGresult* res = pgfdw_exec_query(conn, query->data);
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
|
||||
pgfdw_report_error(ERROR, res, conn, true, query->data);
|
||||
}
|
||||
/* res may be empty as the relname/nspname validation is not checked */
|
||||
if (PQntuples(res) > 0) {
|
||||
parttype = *PQgetvalue(res, 0, 0);
|
||||
}
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
PGresult* res = pgfdw_exec_query(conn, query->data);
|
||||
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
|
||||
pgfdw_report_error(ERROR, res, conn, true, query->data);
|
||||
}
|
||||
/* res may be empty as the relname/nspname validation is not checked */
|
||||
if (PQntuples(res) > 0) {
|
||||
parttype = *PQgetvalue(res, 0, 0);
|
||||
}
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
|
||||
if (!ENABLE_SQL_BETA_FEATURE(PARTITION_FDW_ON) &&
|
||||
(parttype == PARTTYPE_PARTITIONED_RELATION || parttype == PARTTYPE_SUBPARTITIONED_RELATION)) {
|
||||
ereport(ERROR, (errmsg("could not operate foreign table on partitioned table")));
|
||||
if ((parttype == PARTTYPE_PARTITIONED_RELATION || parttype == PARTTYPE_SUBPARTITIONED_RELATION)) {
|
||||
ereport(ERROR, (errmsg("could not operate foreign table on partitioned table")));
|
||||
}
|
||||
}
|
||||
|
||||
appendStringInfo(buf, "%s.%s", quote_identifier(nspname), quote_identifier(relname));
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ For example:
|
|||
* verbose: 0 (no output), 1 (less output), or 2 (full output)
|
||||
|
||||
# Hyperparameter list for 'xgboost_regression_logistic', 'xgboost_binary_logistic', 'xgboost_regression_gamma' and 'xgboost_regression_squarederror':
|
||||
* n_iter: Maximum iterations until convergence
|
||||
* batch_size: Number of tuples in each processing batch
|
||||
* booster: Which booster to use, e.g., gbtree, gblinear or dart (default: gbtree)
|
||||
* tree_method: The tree construction algorithm used in XGBoost. Choices: auto, exact, approx, hist, gpu_hist (gpu_hist only supported with GPU)
|
||||
|
|
|
|||
|
|
@ -2547,10 +2547,6 @@ int main(int argc, char** argv)
|
|||
hba_param = ((char**)pg_malloc_zero(arraysize * sizeof(char *)));
|
||||
config_value = ((char**)pg_malloc_zero(arraysize * sizeof(char*)));
|
||||
}
|
||||
if (false == allocate_memory_list()) {
|
||||
write_stderr(_("ERROR: Failed to allocate memory to list.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
key_mode = SERVER_MODE;
|
||||
/*
|
||||
|
|
@ -2769,8 +2765,54 @@ int main(int argc, char** argv)
|
|||
do_advice();
|
||||
exit(1);
|
||||
}
|
||||
char arguments[MAX_BUF_SIZE] = {0x00};
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if ((strlen(arguments) + strlen(argv[i])) >= (MAX_BUF_SIZE - 2)) {
|
||||
if (*arguments) {
|
||||
(void)write_log("The gs_guc run with the following arguments: [%s].\n", arguments);
|
||||
}
|
||||
(void)write_log("The gs_guc run with the following arguments: [%s].\n", argv[i]);
|
||||
rc = memset_s(arguments, MAX_BUF_SIZE, 0, MAX_BUF_SIZE - 1);
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
continue;
|
||||
}
|
||||
errno_t rc = strcat_s(arguments, MAX_BUF_SIZE, argv[i]);
|
||||
size_t len = strlen(arguments);
|
||||
if (rc != EOK) {
|
||||
break;
|
||||
}
|
||||
arguments[len] = ' ';
|
||||
arguments[len + 1] = '\0';
|
||||
}
|
||||
if (*arguments) {
|
||||
(void)write_log("The gs_guc run with the following arguments: [%s].\n", arguments);
|
||||
}
|
||||
|
||||
check_encrypt_options();
|
||||
|
||||
if (ctl_command == ENCRYPT_KEY_COMMAND) {
|
||||
process_encrypt_cmd(pgdata_D, pgdata_C, pgdata_R);
|
||||
(void)write_log("gs_guc encrypt %s\n", loginfo);
|
||||
} else if (ctl_command == GENERATE_KEY_COMMAND) {
|
||||
doGenerateOperation(pgdata_D, loginfo);
|
||||
}
|
||||
|
||||
if (ctl_command == ENCRYPT_KEY_COMMAND || ctl_command == GENERATE_KEY_COMMAND) {
|
||||
GS_FREE(g_prefix);
|
||||
GS_FREE(g_plainkey);
|
||||
GS_FREE(g_cipherkey);
|
||||
GS_FREE(key_username);
|
||||
GS_FREE(pgdata_D);
|
||||
GS_FREE(pgdata_R);
|
||||
GS_FREE(pgdata_C);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (false == allocate_memory_list()) {
|
||||
write_stderr(_("ERROR: Failed to allocate memory to list.\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ctl_command != ENCRYPT_KEY_COMMAND && ctl_command != GENERATE_KEY_COMMAND && (!bhave_param && !is_hba_conf)) {
|
||||
write_stderr(_("%s: the form of this command is incorrect\n"), progname);
|
||||
do_advice();
|
||||
|
|
@ -2832,30 +2874,6 @@ int main(int argc, char** argv)
|
|||
// log output redirect
|
||||
init_log(PROG_NAME);
|
||||
|
||||
/* print the log about arguments of gs_guc */
|
||||
char arguments[MAX_BUF_SIZE] = {0x00};
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if ((strlen(arguments) + strlen(argv[i])) >= (MAX_BUF_SIZE - 2)) {
|
||||
if (*arguments) {
|
||||
(void)write_log("The gs_guc run with the following arguments: [%s].\n", arguments);
|
||||
}
|
||||
(void)write_log("The gs_guc run with the following arguments: [%s].\n", argv[i]);
|
||||
rc = memset_s(arguments, MAX_BUF_SIZE, 0, MAX_BUF_SIZE - 1);
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
continue;
|
||||
}
|
||||
errno_t rc = strcat_s(arguments, MAX_BUF_SIZE, argv[i]);
|
||||
size_t len = strlen(arguments);
|
||||
if (rc != EOK) {
|
||||
break;
|
||||
}
|
||||
arguments[len] = ' ';
|
||||
arguments[len + 1] = '\0';
|
||||
}
|
||||
if (*arguments) {
|
||||
(void)write_log("The gs_guc run with the following arguments: [%s].\n", arguments);
|
||||
}
|
||||
|
||||
if ((true == is_hba_conf) &&
|
||||
((nodetype != INSTANCE_COORDINATOR) && (nodetype != INSTANCE_DATANODE))) {
|
||||
write_stderr(_("%s: authentication operation (-h) is not supported for \"gtm\" or \"gtm_proxy\"\n"), progname);
|
||||
|
|
@ -2863,54 +2881,38 @@ int main(int argc, char** argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (ctl_command == ENCRYPT_KEY_COMMAND) {
|
||||
process_encrypt_cmd(pgdata_D, pgdata_C, pgdata_R);
|
||||
(void)write_log("gs_guc encrypt %s\n", loginfo);
|
||||
} else if (ctl_command == GENERATE_KEY_COMMAND) {
|
||||
doGenerateOperation(pgdata_D, loginfo);
|
||||
} else {
|
||||
// the number of -Z is equal to 2
|
||||
if (node_type_number == LARGE_INSTANCE_NUM) {
|
||||
if (node_type_value[0] == node_type_value[1]) {
|
||||
(void)write_stderr("When the number of -Z is equal to 2, the value must be different.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int index = 0; index < LARGE_INSTANCE_NUM; index++) {
|
||||
if (node_type_value[index] != INSTANCE_COORDINATOR && node_type_value[index] != INSTANCE_DATANODE) {
|
||||
(void)write_stderr("ERROR: When the number of -Z is equal to 2, the parameter value of -Z must be "
|
||||
"coordinator or datanode.\n");
|
||||
exit(1);
|
||||
}
|
||||
checkLcName(node_type_value[index]);
|
||||
}
|
||||
nodetype = INSTANCE_COORDINATOR;
|
||||
|
||||
if (0 != validate_cluster_guc_options(nodename, nodetype, instance_name, pgdata_D)) {
|
||||
exit(1);
|
||||
}
|
||||
process_cluster_guc_option(nodename, nodetype, instance_name, pgdata_D);
|
||||
} else {
|
||||
checkLcName(nodetype);
|
||||
if (0 != validate_cluster_guc_options(nodename, nodetype, instance_name, pgdata_D)) {
|
||||
exit(1);
|
||||
}
|
||||
process_cluster_guc_option(nodename, nodetype, instance_name, pgdata_D);
|
||||
// the number of -Z is equal to 2
|
||||
if (node_type_number == LARGE_INSTANCE_NUM) {
|
||||
if (node_type_value[0] == node_type_value[1]) {
|
||||
(void)write_stderr("When the number of -Z is equal to 2, the value must be different.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int index = 0; index < LARGE_INSTANCE_NUM; index++) {
|
||||
if (node_type_value[index] != INSTANCE_COORDINATOR && node_type_value[index] != INSTANCE_DATANODE) {
|
||||
(void)write_stderr("ERROR: When the number of -Z is equal to 2, the parameter value of -Z must be "
|
||||
"coordinator or datanode.\n");
|
||||
exit(1);
|
||||
}
|
||||
checkLcName(node_type_value[index]);
|
||||
}
|
||||
nodetype = INSTANCE_COORDINATOR;
|
||||
|
||||
if (0 != validate_cluster_guc_options(nodename, nodetype, instance_name, pgdata_D)) {
|
||||
exit(1);
|
||||
}
|
||||
process_cluster_guc_option(nodename, nodetype, instance_name, pgdata_D);
|
||||
} else {
|
||||
checkLcName(nodetype);
|
||||
if (0 != validate_cluster_guc_options(nodename, nodetype, instance_name, pgdata_D)) {
|
||||
exit(1);
|
||||
}
|
||||
process_cluster_guc_option(nodename, nodetype, instance_name, pgdata_D);
|
||||
}
|
||||
|
||||
GS_FREE(g_prefix);
|
||||
GS_FREE(g_plainkey);
|
||||
GS_FREE(g_cipherkey);
|
||||
GS_FREE(key_username);
|
||||
GS_FREE(pgdata_D);
|
||||
GS_FREE(pgdata_R);
|
||||
GS_FREE(pgdata_C);
|
||||
GS_FREE(instance_name);
|
||||
|
||||
if (ctl_command == ENCRYPT_KEY_COMMAND || ctl_command == GENERATE_KEY_COMMAND)
|
||||
return 0;
|
||||
|
||||
nRet = print_guc_result((const char*)nodename);
|
||||
GS_FREE(nodename);
|
||||
clear_g_incorrect_nodeInfo();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "bin/elog.h"
|
||||
#include "nodes/pg_list.h"
|
||||
#include "replication/replicainternal.h"
|
||||
#include "storage/smgr/fd.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/datetime.h"
|
||||
|
|
@ -64,6 +65,7 @@ char g_buildprimary_slotname[MAX_VALUE_LEN] = {0};
|
|||
char g_str_replication_type[MAX_VALUE_LEN] = {0};
|
||||
int g_replconn_idx = -1;
|
||||
int g_replication_type = -1;
|
||||
bool is_cross_region_build = false;
|
||||
#define RT_WITH_DUMMY_STANDBY 0
|
||||
#define RT_WITH_MULTI_STANDBY 1
|
||||
|
||||
|
|
@ -576,7 +578,9 @@ void get_conninfo(const char* filename)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
if (IS_CROSS_CLUSTER_BUILD) {
|
||||
if (build_mode == CROSS_CLUSTER_FULL_BUILD || build_mode == CROSS_CLUSTER_INC_BUILD ||
|
||||
build_mode == CROSS_CLUSTER_STANDBY_FULL_BUILD) {
|
||||
/* For shared storage cluster */
|
||||
conninfo_para = config_para_cross_cluster_build;
|
||||
} else {
|
||||
conninfo_para = config_para_build;
|
||||
|
|
@ -864,10 +868,11 @@ PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term)
|
|||
|
||||
tnRet = memset_s(repl_conninfo_str, MAXPGPATH, 0, MAXPGPATH);
|
||||
securec_check_ss_c(tnRet, "", "");
|
||||
is_cross_region_build = false;
|
||||
if (register_username != NULL && register_password != NULL) {
|
||||
if (*register_username == '.') {
|
||||
register_username += 2;
|
||||
}
|
||||
}
|
||||
tnRet = snprintf_s(repl_conninfo_str,
|
||||
sizeof(repl_conninfo_str),
|
||||
sizeof(repl_conninfo_str) - 1,
|
||||
|
|
@ -882,6 +887,7 @@ PGconn* check_and_conn(int conn_timeout, int recv_timeout, uint32 term)
|
|||
repl_conn_info.remoteport,
|
||||
conn_timeout,
|
||||
recv_timeout, register_username, register_password);
|
||||
is_cross_region_build = true;
|
||||
} else {
|
||||
tnRet = snprintf_s(repl_conninfo_str,
|
||||
sizeof(repl_conninfo_str),
|
||||
|
|
|
|||
|
|
@ -244,7 +244,9 @@ bool SensitiveStrCheck(const char* target)
|
|||
|
||||
if (strstr(target_copy, "PASSWORD") != NULL || strstr(target_copy, "IDENTIFIED") != NULL ||
|
||||
strstr(target_copy, "GS_ENCRYPT_AES128") != NULL || strstr(target_copy, "GS_DECRYPT_AES128") != NULL ||
|
||||
strstr(target_copy, "GS_ENCRYPT") != NULL || strstr(target_copy, "GS_DECRYPT") != NULL) {
|
||||
strstr(target_copy, "GS_ENCRYPT") != NULL || strstr(target_copy, "GS_DECRYPT") != NULL ||
|
||||
strstr(target_copy, "PG_CREATE_PHYSICAL_REPLICATION_SLOT_EXTERN") != NULL ||
|
||||
strstr(target_copy, "SECRETKEY") != NULL || strstr(target_copy, "CREATE_CREDENTIAL") != NULL) {
|
||||
free(target_copy);
|
||||
return TRUE;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,6 @@ PsqlSettings pset;
|
|||
/* Used for change child process name in gsql parallel execute mode. */
|
||||
char* argv_para;
|
||||
int argv_num;
|
||||
static int PASSWORD_STR_LEN = 9;
|
||||
static bool dbname_alloced = false;
|
||||
static bool is_pipeline = false;
|
||||
static bool is_interactive = true;
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
|
|
@ -630,6 +628,10 @@ int main(int argc, char* argv[])
|
|||
|
||||
/* Stored connection and guc info for new connections in gsql parallel mode. */
|
||||
values_free[3] = true;
|
||||
if (options.dbname != NULL) {
|
||||
/* When we use a new dbname or exit the program, we need to free the value. */
|
||||
values_free[4] = true; /* The dbname index is 4 */
|
||||
}
|
||||
|
||||
pset.connInfo.keywords = keywords;
|
||||
pset.connInfo.values = values;
|
||||
|
|
@ -828,6 +830,12 @@ int main(int argc, char* argv[])
|
|||
for (int i = 0; i < PARAMS_ARRAY_SIZE; i++) {
|
||||
if (pset.connInfo.values_free[i] && NULL != pset.connInfo.values[i]) {
|
||||
if (strlen(pset.connInfo.values[i]) != 0) {
|
||||
/* Erase the connection information in the memory. */
|
||||
rc = memset_s(pset.connInfo.values[i],
|
||||
strlen(pset.connInfo.values[i]),
|
||||
0,
|
||||
strlen(pset.connInfo.values[i]));
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
free(pset.connInfo.values[i]);
|
||||
pset.connInfo.values[i] = NULL;
|
||||
}
|
||||
|
|
@ -859,13 +867,6 @@ int main(int argc, char* argv[])
|
|||
ResetQueryRetryController();
|
||||
EmptyRetryErrcodesList(pset.errcodes_list);
|
||||
|
||||
if (dbname_alloced) {
|
||||
rc = memset_s(options.dbname, strlen(options.dbname), 0, strlen(options.dbname));
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
free(options.dbname);
|
||||
options.dbname = NULL;
|
||||
}
|
||||
|
||||
return successResult;
|
||||
}
|
||||
|
||||
|
|
@ -1014,7 +1015,7 @@ static void parse_psql_options(int argc, char* const argv[], struct adhoc_opts*
|
|||
bool is_action_file = false;
|
||||
/* Database Security: Data importing/dumping support AES128. */
|
||||
char* dencrypt_key = NULL;
|
||||
char* needmask = NULL;
|
||||
char* dbname = NULL;
|
||||
errno_t rc = EOK;
|
||||
#ifdef USE_READLINE
|
||||
useReadline = false;
|
||||
|
|
@ -1054,9 +1055,7 @@ static void parse_psql_options(int argc, char* const argv[], struct adhoc_opts*
|
|||
}
|
||||
break;
|
||||
case 'd':
|
||||
options->dbname = pg_strdup(optarg);
|
||||
dbname_alloced = true;
|
||||
needmask = optarg;
|
||||
dbname = optarg;
|
||||
break;
|
||||
case 'e':
|
||||
if (!SetVariable(pset.vars, "ECHO", "queries")) {
|
||||
|
|
@ -1263,10 +1262,8 @@ static void parse_psql_options(int argc, char* const argv[], struct adhoc_opts*
|
|||
* if we still have arguments, use it as the database name and username
|
||||
*/
|
||||
while (argc - optind >= 1) {
|
||||
if (options->dbname == NULL) {
|
||||
options->dbname = pg_strdup(argv[optind]);
|
||||
dbname_alloced = true;
|
||||
needmask = argv[optind];
|
||||
if (dbname == NULL) {
|
||||
dbname = argv[optind];
|
||||
} else if (options->username == NULL) {
|
||||
options->username = argv[optind];
|
||||
} else if (!pset.quiet) {
|
||||
|
|
@ -1276,21 +1273,25 @@ static void parse_psql_options(int argc, char* const argv[], struct adhoc_opts*
|
|||
optind++;
|
||||
}
|
||||
|
||||
if (needmask != NULL) {
|
||||
/* mask Password information stored in dbname */
|
||||
if (dbname != NULL) {
|
||||
/* Save a copy for connection before masking the password. */
|
||||
options->dbname = pg_strdup(dbname);
|
||||
|
||||
/* mask informations in URI string. */
|
||||
if (strncmp(options->dbname, "postgresql://", strlen("postgresql://")) == 0) {
|
||||
char *off_argv = needmask + strlen("postgresql://");
|
||||
if (strncmp(dbname, "postgresql://", strlen("postgresql://")) == 0) {
|
||||
char *off_argv = dbname + strlen("postgresql://");
|
||||
rc = memset_s(off_argv, strlen(off_argv), '*', strlen(off_argv));
|
||||
check_memset_s(rc);
|
||||
} else if (strncmp(options->dbname, "postgres://", strlen("postgres://")) == 0) {
|
||||
char *off_argv = needmask + strlen("postgres://");
|
||||
} else if (strncmp(dbname, "postgres://", strlen("postgres://")) == 0) {
|
||||
char *off_argv = dbname + strlen("postgres://");
|
||||
rc = memset_s(off_argv, strlen(off_argv), '*', strlen(off_argv));
|
||||
check_memset_s(rc);
|
||||
}
|
||||
/* mask password */
|
||||
/* mask password in key/value string. */
|
||||
char *temp = NULL;
|
||||
if ((temp = strstr(needmask, "password")) != NULL) {
|
||||
char *off_argv = temp + PASSWORD_STR_LEN;
|
||||
if ((temp = strstr(dbname, "password")) != NULL) {
|
||||
char *off_argv = temp + strlen("password");
|
||||
rc = memset_s(off_argv, strlen(off_argv), '*', strlen(off_argv));
|
||||
check_memset_s(rc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3031,6 +3031,10 @@
|
|||
"get_byte", 1,
|
||||
AddBuiltinFunc(_0(721), _1("get_byte"), _2(2), _3(true), _4(false), _5(byteaGetByte), _6(23), _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('i'), _19(0), _20(2, 17, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("byteaGetByte"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("get byte"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"get_client_info", 1,
|
||||
AddBuiltinFunc(_0(7732), _1("get_client_info"), _2(0), _3(false), _4(true), _5(get_client_info), _6(2249), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(100), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(0), _21(2, 20, 25), _22(2, 'o', 'o'), _23(2, "sid", "client_info"), _24(NULL), _25("get_client_info"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(true), _32(false), _33("read current client"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"get_current_ts_config", 1,
|
||||
AddBuiltinFunc(_0(3759), _1("get_current_ts_config"), _2(0), _3(true), _4(false), _5(get_current_ts_config), _6(3734), _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(0), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("get_current_ts_config"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("get current tsearch configuration"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
|
|
@ -8173,14 +8177,14 @@
|
|||
"pg_rotate_logfile", 1,
|
||||
AddBuiltinFunc(_0(2622), _1("pg_rotate_logfile"), _2(0), _3(true), _4(false), _5(pg_rotate_logfile), _6(16), _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_rotate_logfile"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("rotate log file - old version for adminpack 1.0"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_sequence_parameters", 1,
|
||||
AddBuiltinFunc(_0(3078), _1("pg_sequence_parameters"), _2(1), _3(true), _4(false), _5(pg_sequence_parameters), _6(2249), _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(6, 26, 34, 34, 34, 34, 16), _22(6, 'i', 'o', 'o', 'o', 'o', 'o'), _23(6, "sequence_oid", "start_value", "minimum_value", "maximum_value", "increment", "cycle_option"), _24(NULL), _25("pg_sequence_parameters"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("sequence parameters, for use by information schema"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_sequence_last_value", 1,
|
||||
AddBuiltinFunc(_0(3080), _1("pg_sequence_last_value"), _2(1), _3(true), _4(false), _5(pg_sequence_last_value), _6(2249), _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(3, 26, 34, 34), _22(3, 'i', 'o', 'o'), _23(3, "sequence_oid", "cache_value", "last_value"), _24(NULL), _25("pg_sequence_last_value"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_sequence_parameters", 1,
|
||||
AddBuiltinFunc(_0(3078), _1("pg_sequence_parameters"), _2(1), _3(true), _4(false), _5(pg_sequence_parameters), _6(2249), _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(6, 26, 34, 34, 34, 34, 16), _22(6, 'i', 'o', 'o', 'o', 'o', 'o'), _23(6, "sequence_oid", "start_value", "minimum_value", "maximum_value", "increment", "cycle_option"), _24(NULL), _25("pg_sequence_parameters"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("sequence parameters, for use by information schema"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"pg_shared_memctx_detail", 1,
|
||||
AddBuiltinFunc(_0(3987), _1("pg_shared_memctx_detail"), _2(1), _3(false), _4(true), _5(pg_shared_memctx_detail), _6(16), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(100), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('s'), _19(0), _20(1, 2275), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("pg_shared_memctx_detail"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0))
|
||||
|
|
|
|||
|
|
@ -2509,6 +2509,8 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
|
||||
initStringInfo(&buffer);
|
||||
|
||||
char* signature = NULL;
|
||||
|
||||
switch (getObjectClass(object)) {
|
||||
case OCLASS_CLASS:
|
||||
getRelationDescription(&buffer, object->objectId);
|
||||
|
|
@ -2518,11 +2520,15 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
break;
|
||||
|
||||
case OCLASS_PROC:
|
||||
appendStringInfo(&buffer, _("function %s"), format_procedure(object->objectId));
|
||||
signature = format_procedure(object->objectId);
|
||||
appendStringInfo(&buffer, _("function %s"), signature);
|
||||
pfree_ext(signature);
|
||||
break;
|
||||
|
||||
case OCLASS_PACKAGE:
|
||||
appendStringInfo(&buffer, _("package %s"), format_procedure(object->objectId));
|
||||
signature = format_procedure(object->objectId);
|
||||
appendStringInfo(&buffer, _("package %s"), signature);
|
||||
pfree_ext(signature);
|
||||
break;
|
||||
|
||||
case OCLASS_TYPE:
|
||||
|
|
@ -2776,7 +2782,7 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
|
||||
initStringInfo(&opfam);
|
||||
getOpFamilyDescription(&opfam, amprocForm->amprocfamily);
|
||||
|
||||
signature = format_procedure(amprocForm->amproc);
|
||||
/* ------
|
||||
translator: %d is the function number, the first two %s's
|
||||
are data type names, the third %s is the description of the
|
||||
|
|
@ -2788,8 +2794,9 @@ char* getObjectDescription(const ObjectAddress* object)
|
|||
format_type_be(amprocForm->amproclefttype),
|
||||
format_type_be(amprocForm->amprocrighttype),
|
||||
opfam.data,
|
||||
format_procedure(amprocForm->amproc));
|
||||
signature);
|
||||
|
||||
pfree_ext(signature);
|
||||
pfree_ext(opfam.data);
|
||||
|
||||
systable_endscan(amscan);
|
||||
|
|
|
|||
|
|
@ -1105,8 +1105,29 @@ static List* BuildFuncInfoList(PLpgSQL_execstate* estate)
|
|||
void BuildSessionPackageRuntimeForAutoSession(uint64 sessionId, uint64 parentSessionId,
|
||||
PLpgSQL_execstate* estate, PLpgSQL_function* func)
|
||||
{
|
||||
SessionPackageRuntime* parentSessionPkgs = NULL;
|
||||
MemoryContext pkgRuntimeCtx = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"SessionPackageRuntime",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
MemoryContext oldCtx = MemoryContextSwitchTo(pkgRuntimeCtx);
|
||||
SessionPackageRuntime* resultSessionPkgs = (SessionPackageRuntime*)palloc0(sizeof(SessionPackageRuntime));
|
||||
resultSessionPkgs->context = pkgRuntimeCtx;
|
||||
|
||||
/* doing insert gs_source, no need to restore package value */
|
||||
if (func->is_insert_gs_source) {
|
||||
resultSessionPkgs->is_insert_gs_source = true;
|
||||
g_instance.global_session_pkg->Add(sessionId, resultSessionPkgs);
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
MemoryContextDelete(resultSessionPkgs->context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (u_sess->plsql_cxt.plpgsqlpkg_dlist_objects != NULL) {
|
||||
CopyCurrentSessionPkgs(resultSessionPkgs, u_sess->plsql_cxt.plpgsqlpkg_dlist_objects);
|
||||
}
|
||||
|
||||
SessionPackageRuntime* parentSessionPkgs = NULL;
|
||||
/* get parent session pkgs, build current session pkgs need include them */
|
||||
if (parentSessionId != 0) {
|
||||
if (!u_sess->plsql_cxt.not_found_parent_session_pkgs) {
|
||||
|
|
@ -1120,17 +1141,6 @@ void BuildSessionPackageRuntimeForAutoSession(uint64 sessionId, uint64 parentSes
|
|||
}
|
||||
}
|
||||
}
|
||||
MemoryContext pkgRuntimeCtx = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"SessionPackageRuntime",
|
||||
ALLOCSET_SMALL_MINSIZE,
|
||||
ALLOCSET_SMALL_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
MemoryContext oldCtx = MemoryContextSwitchTo(pkgRuntimeCtx);
|
||||
SessionPackageRuntime* resultSessionPkgs = (SessionPackageRuntime*)palloc0(sizeof(SessionPackageRuntime));
|
||||
resultSessionPkgs->context = pkgRuntimeCtx;
|
||||
if (u_sess->plsql_cxt.plpgsqlpkg_dlist_objects != NULL) {
|
||||
CopyCurrentSessionPkgs(resultSessionPkgs, u_sess->plsql_cxt.plpgsqlpkg_dlist_objects);
|
||||
}
|
||||
|
||||
if (parentSessionPkgs) {
|
||||
List* parentPkgList = parentSessionPkgs->runtimes;
|
||||
|
|
@ -1387,6 +1397,9 @@ void initAutoSessionPkgsValue(uint64 sessionId)
|
|||
if (sessionPkgs->runtimes == NULL) {
|
||||
return;
|
||||
}
|
||||
if (sessionPkgs->is_insert_gs_source) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(cell, sessionPkgs->runtimes) {
|
||||
pkgState = (PackageRuntimeState*)lfirst(cell);
|
||||
|
|
@ -1510,11 +1523,7 @@ void initAutonomousPkgValue(PLpgSQL_package* targetPkg, uint64 sessionId)
|
|||
|
||||
List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate, bool isAutonm)
|
||||
{
|
||||
List *autonmsList = NULL;
|
||||
/* ignore inline_code_block function */
|
||||
if (!OidIsValid(func->fn_oid)) {
|
||||
return NULL;
|
||||
}
|
||||
List *autonmsList = NIL;
|
||||
|
||||
uint64 currentSessionId = IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid;
|
||||
|
||||
|
|
@ -1525,6 +1534,13 @@ List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate
|
|||
* sessionpkgs from g_instance.global_session_pkg
|
||||
*/
|
||||
uint64 automnSessionId = u_sess->SPI_cxt.autonomous_session->current_attach_sessionid;
|
||||
if (func->is_insert_gs_source) {
|
||||
/* doing insert gs_source, need do noting */
|
||||
g_instance.global_session_pkg->Remove(automnSessionId);
|
||||
g_instance.global_session_pkg->Remove(currentSessionId);
|
||||
return NIL;
|
||||
}
|
||||
|
||||
SessionPackageRuntime* sessionpkgs = g_instance.global_session_pkg->Fetch(automnSessionId);
|
||||
RestoreAutonmSessionPkgs(sessionpkgs);
|
||||
if (sessionpkgs != NULL) {
|
||||
|
|
@ -1546,7 +1562,11 @@ List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate
|
|||
* and restore package values by it.
|
||||
*/
|
||||
if (u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, estate);
|
||||
/* doing insert gs_source, need do noting */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs == NULL
|
||||
|| !u_sess->plsql_cxt.auto_parent_session_pkgs->is_insert_gs_source) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, estate);
|
||||
}
|
||||
/* autonomous session will be reused by next autonomous procedure, need clean it */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs != NULL) {
|
||||
MemoryContextDelete(u_sess->plsql_cxt.auto_parent_session_pkgs->context);
|
||||
|
|
@ -1560,11 +1580,6 @@ List *processAutonmSessionPkgs(PLpgSQL_function* func, PLpgSQL_execstate* estate
|
|||
|
||||
void processAutonmSessionPkgsInException(PLpgSQL_function* func)
|
||||
{
|
||||
/* ignore inline_code_block function */
|
||||
if (!OidIsValid(func->fn_oid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 currentSessionId = IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid;
|
||||
|
||||
if (IsAutonomousTransaction(func->action->isAutonomous)) {
|
||||
|
|
@ -1578,6 +1593,13 @@ void processAutonmSessionPkgsInException(PLpgSQL_function* func)
|
|||
return;
|
||||
}
|
||||
uint64 automnSessionId = u_sess->SPI_cxt.autonomous_session->current_attach_sessionid;
|
||||
if (func->is_insert_gs_source) {
|
||||
/* doing insert gs_source, need do noting */
|
||||
g_instance.global_session_pkg->Remove(automnSessionId);
|
||||
g_instance.global_session_pkg->Remove(currentSessionId);
|
||||
return;
|
||||
}
|
||||
|
||||
SessionPackageRuntime* sessionpkgs = g_instance.global_session_pkg->Fetch(automnSessionId);
|
||||
RestoreAutonmSessionPkgs(sessionpkgs);
|
||||
if (sessionpkgs != NULL) {
|
||||
|
|
@ -1596,7 +1618,11 @@ void processAutonmSessionPkgsInException(PLpgSQL_function* func)
|
|||
* and restore package values by it.
|
||||
*/
|
||||
if (u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, NULL);
|
||||
/* doing insert gs_source, need do noting */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs == NULL
|
||||
|| !u_sess->plsql_cxt.auto_parent_session_pkgs->is_insert_gs_source) {
|
||||
BuildSessionPackageRuntimeForParentSession(currentSessionId, NULL);
|
||||
}
|
||||
/* autonomous session will be reused by next autonomous procedure, need clean it */
|
||||
if (u_sess->plsql_cxt.auto_parent_session_pkgs != NULL) {
|
||||
MemoryContextDelete(u_sess->plsql_cxt.auto_parent_session_pkgs->context);
|
||||
|
|
|
|||
|
|
@ -6245,14 +6245,21 @@ Oid AddNewIntervalPartition(Relation rel, void* insertTuple)
|
|||
CacheInvalidateRelcache(rel);
|
||||
}
|
||||
|
||||
/*
|
||||
* to avoid dead lock, we should release AccessShareLock on ADD_PARTITION_ACTION
|
||||
* locked by the transaction before aquire AccessExclusiveLock.
|
||||
*/
|
||||
UnlockRelationForAccessIntervalPartTabIfHeld(rel);
|
||||
/* it will accept invalidation messages generated by other sessions in lockRelationForAddIntervalPartition. */
|
||||
lockRelationForAddIntervalPartition(rel);
|
||||
LockRelationForAddIntervalPartition(rel);
|
||||
partitionRoutingForTuple(rel, insertTuple, u_sess->catalog_cxt.route);
|
||||
|
||||
/* if the partition exists, return partition's oid */
|
||||
if (u_sess->catalog_cxt.route->fileExist) {
|
||||
Assert(OidIsValid(u_sess->catalog_cxt.route->partitionId));
|
||||
unLockRelationForAddIntervalPartition(rel);
|
||||
/* we should take AccessShareLock again before release AccessExclusiveLock for consistency. */
|
||||
LockRelationForAccessIntervalPartitionTab(rel);
|
||||
UnlockRelationForAddIntervalPartition(rel);
|
||||
return u_sess->catalog_cxt.route->partitionId;
|
||||
}
|
||||
|
||||
|
|
@ -6320,6 +6327,8 @@ Oid AddNewIntervalPartition(Relation rel, void* insertTuple)
|
|||
*/
|
||||
CommandCounterIncrement();
|
||||
|
||||
UpdatePgObjectChangecsn(RelationGetRelid(rel), rel->rd_rel->relkind);
|
||||
|
||||
return newPartOid;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5862,7 +5862,7 @@ void AddGPIForSubPartition(Oid partTableOid, Oid partOid, Oid subPartOid)
|
|||
* @@GaussDB@@
|
||||
* Target : This routine is used to scan partition tuples and delete them from all global partition indexes.
|
||||
*/
|
||||
void ScanPartitionDeleteGPITuples(Relation partTableRel, Relation partRel, const List* indexRelList,
|
||||
void ScanPartitionDeleteGPITuples(Relation partTableRel, Relation partRel, const List* indexRelList,
|
||||
const List* indexInfoList)
|
||||
{
|
||||
TableScanDesc scan = NULL;
|
||||
|
|
@ -5893,9 +5893,8 @@ void ScanPartitionDeleteGPITuples(Relation partTableRel, Relation partRel, const
|
|||
Relation indexRel = (Relation)lfirst(cell);
|
||||
IndexInfo* indexInfo = static_cast<IndexInfo*>(lfirst(cell1));
|
||||
|
||||
if (!RelationIsUstoreIndex(indexRel)) {
|
||||
continue; /* only ubtree have index_delete routine */
|
||||
}
|
||||
/* only ubtree have index_delete routine */
|
||||
Assert(RelationIsUstoreIndex(indexRel));
|
||||
|
||||
Datum values[tupleDesc->natts];
|
||||
bool isNull[tupleDesc->natts];
|
||||
|
|
@ -5988,7 +5987,7 @@ bool DeleteGPITuplesForPartition(Oid partTableOid, Oid partOid)
|
|||
* Description :
|
||||
* Notes :
|
||||
*/
|
||||
void DeleteGPITuplesForSubPartition(Oid partTableOid, Oid partOid, Oid subPartOid)
|
||||
bool DeleteGPITuplesForSubPartition(Oid partTableOid, Oid partOid, Oid subPartOid)
|
||||
{
|
||||
Relation partTableRel = NULL;
|
||||
Relation partRel = NULL;
|
||||
|
|
@ -5999,6 +5998,7 @@ void DeleteGPITuplesForSubPartition(Oid partTableOid, Oid partOid, Oid subPartOi
|
|||
List* indexRelList = NIL;
|
||||
List* indexInfoList = NIL;
|
||||
ListCell* cell = NULL;
|
||||
bool all_ubtree = true;
|
||||
|
||||
partTableRel = heap_open(partTableOid, AccessShareLock);
|
||||
part = partitionOpen(partTableRel, partOid, AccessShareLock);
|
||||
|
|
@ -6012,6 +6012,12 @@ void DeleteGPITuplesForSubPartition(Oid partTableOid, Oid partOid, Oid subPartOi
|
|||
Relation indexRel = relation_open(indexOid, RowExclusiveLock);
|
||||
IndexInfo* indexInfo = BuildIndexInfo(indexRel);
|
||||
|
||||
if (!RelationIsUstoreIndex(indexRel)) {
|
||||
all_ubtree = false;
|
||||
relation_close(indexRel, RowExclusiveLock);
|
||||
continue;
|
||||
}
|
||||
|
||||
indexRelList = lappend(indexRelList, indexRel);
|
||||
indexInfoList = lappend(indexInfoList, indexInfo);
|
||||
}
|
||||
|
|
@ -6033,6 +6039,8 @@ void DeleteGPITuplesForSubPartition(Oid partTableOid, Oid partOid, Oid subPartOi
|
|||
releaseDummyRelation(&partRel);
|
||||
partitionClose(partTableRel, part, NoLock);
|
||||
heap_close(partTableRel, NoLock);
|
||||
|
||||
return all_ubtree;
|
||||
}
|
||||
|
||||
void mergeBTreeIndexes(List* mergingBtreeIndexes, List* srcPartMergeOffset, int2 bktId)
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ Oid RangeVarGetRelidExtended(const RangeVar* relation, LOCKMODE lockmode, bool m
|
|||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||
errmsg("temporary tables cannot specify a schema name")));
|
||||
}
|
||||
pfree_ext(errDetail);
|
||||
errDetail = get_relname_relid_extend(
|
||||
relation->relname, u_sess->catalog_cxt.myTempNamespace, &relId, isSupportSynonym, refSynOid);
|
||||
}
|
||||
|
|
@ -293,6 +294,7 @@ Oid RangeVarGetRelidExtended(const RangeVar* relation, LOCKMODE lockmode, bool m
|
|||
|
||||
/* use exact schema given */
|
||||
namespaceId = LookupExplicitNamespace(relation->schemaname);
|
||||
pfree_ext(errDetail);
|
||||
errDetail = get_relname_relid_extend(relation->relname, namespaceId, &relId, isSupportSynonym, refSynOid);
|
||||
|
||||
if (OidIsValid(relId) && namespaceId == u_sess->catalog_cxt.myTempNamespace)
|
||||
|
|
@ -300,6 +302,7 @@ Oid RangeVarGetRelidExtended(const RangeVar* relation, LOCKMODE lockmode, bool m
|
|||
} else {
|
||||
/* search the namespace path */
|
||||
if (isSupportSynonym) {
|
||||
pfree_ext(errDetail);
|
||||
errDetail = RelnameGetRelidExtended(relation->relname, &relId, refSynOid, detailInfo);
|
||||
} else {
|
||||
relId = RelnameGetRelid(relation->relname, detailInfo);
|
||||
|
|
@ -419,8 +422,8 @@ Oid RangeVarGetRelidExtended(const RangeVar* relation, LOCKMODE lockmode, bool m
|
|||
/* Skipping report error, but store the error detail info and report later. */
|
||||
appendStringInfo(detailInfo, _("%s"), errDetail);
|
||||
}
|
||||
pfree_ext(errDetail);
|
||||
}
|
||||
pfree_ext(errDetail);
|
||||
|
||||
if (!OidIsValid(relId) && !missing_ok) {
|
||||
if (relation->schemaname)
|
||||
|
|
|
|||
|
|
@ -377,6 +377,9 @@ void UpdatePgObjectChangecsn(Oid objectOid, PgObjectType objectType)
|
|||
if (!CheckObjectExist(objectOid, objectType)) {
|
||||
return;
|
||||
}
|
||||
if (u_sess->exec_cxt.isExecTrunc) {
|
||||
return;
|
||||
}
|
||||
relation = heap_open(PgObjectRelationId, RowExclusiveLock);
|
||||
tup = SearchSysCache2(PGOBJECTID, ObjectIdGetDatum(objectOid), CharGetDatum(objectType));
|
||||
if (!HeapTupleIsValid(tup)) {
|
||||
|
|
|
|||
|
|
@ -1425,3 +1425,41 @@ Oid GetBaseRelOidOfParition(Relation relation)
|
|||
return relation->parentId;
|
||||
}
|
||||
|
||||
/* NB: all operations on ADD_PARTITION_ACTION sequence lock must use TopTransactionResourceOwner. */
|
||||
void LockRelationForAddIntervalPartition(Relation rel)
|
||||
{
|
||||
ResourceOwner currentOwner = t_thrd.utils_cxt.CurrentResourceOwner;
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = t_thrd.utils_cxt.TopTransactionResourceOwner;
|
||||
LockPartition(RelationGetRelid(rel), ADD_PARTITION_ACTION,
|
||||
AccessExclusiveLock, PARTITION_SEQUENCE_LOCK);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
}
|
||||
|
||||
void LockRelationForAccessIntervalPartitionTab(Relation rel)
|
||||
{
|
||||
ResourceOwner currentOwner = t_thrd.utils_cxt.CurrentResourceOwner;
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = t_thrd.utils_cxt.TopTransactionResourceOwner;
|
||||
LockPartition(RelationGetRelid(rel), ADD_PARTITION_ACTION,
|
||||
AccessShareLock, PARTITION_SEQUENCE_LOCK);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
}
|
||||
|
||||
void UnlockRelationForAccessIntervalPartTabIfHeld(Relation rel)
|
||||
{
|
||||
ResourceOwner currentOwner = t_thrd.utils_cxt.CurrentResourceOwner;
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = t_thrd.utils_cxt.TopTransactionResourceOwner;
|
||||
|
||||
UnlockPartitionSeqIfHeld(RelationGetRelid(rel), ADD_PARTITION_ACTION, AccessShareLock);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
}
|
||||
|
||||
void UnlockRelationForAddIntervalPartition(Relation rel)
|
||||
{
|
||||
ResourceOwner currentOwner = t_thrd.utils_cxt.CurrentResourceOwner;
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = t_thrd.utils_cxt.TopTransactionResourceOwner;
|
||||
|
||||
UnlockPartition(RelationGetRelid(rel), ADD_PARTITION_ACTION,
|
||||
AccessExclusiveLock, PARTITION_SEQUENCE_LOCK);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ CREATE VIEW pg_rlspolicies AS
|
|||
END AS policypermissive,
|
||||
CASE
|
||||
WHEN pol.polroles = '{0}' THEN
|
||||
string_to_array('public', ' ')
|
||||
pg_catalog.string_to_array('public', ' ')
|
||||
ELSE
|
||||
ARRAY
|
||||
(
|
||||
|
|
@ -549,33 +549,33 @@ REVOKE ALL on pg_statistic FROM public;
|
|||
REVOKE ALL on pg_statistic_ext FROM public;
|
||||
|
||||
CREATE VIEW pg_locks AS
|
||||
SELECT * FROM pg_lock_status() AS L;
|
||||
SELECT * FROM pg_catalog.pg_lock_status() AS L;
|
||||
|
||||
CREATE VIEW pg_cursors AS
|
||||
SELECT * FROM pg_cursor() AS C;
|
||||
SELECT * FROM pg_catalog.pg_cursor() AS C;
|
||||
|
||||
CREATE VIEW pg_available_extensions AS
|
||||
SELECT E.name, E.default_version, X.extversion AS installed_version,
|
||||
E.comment
|
||||
FROM pg_available_extensions() AS E
|
||||
FROM pg_catalog.pg_available_extensions() AS E
|
||||
LEFT JOIN pg_extension AS X ON E.name = X.extname;
|
||||
|
||||
CREATE VIEW pg_available_extension_versions AS
|
||||
SELECT E.name, E.version, (X.extname IS NOT NULL) AS installed,
|
||||
E.superuser, E.relocatable, E.schema, E.requires, E.comment
|
||||
FROM pg_available_extension_versions() AS E
|
||||
FROM pg_catalog.pg_available_extension_versions() AS E
|
||||
LEFT JOIN pg_extension AS X
|
||||
ON E.name = X.extname AND E.version = X.extversion;
|
||||
|
||||
CREATE VIEW pg_prepared_xacts AS
|
||||
SELECT P.transaction, P.gid, P.prepared,
|
||||
U.rolname AS owner, D.datname AS database
|
||||
FROM pg_prepared_xact() AS P
|
||||
FROM pg_catalog.pg_prepared_xact() AS P
|
||||
LEFT JOIN pg_authid U ON P.ownerid = U.oid
|
||||
LEFT JOIN pg_database D ON P.dbid = D.oid;
|
||||
|
||||
CREATE VIEW pg_prepared_statements AS
|
||||
SELECT * FROM pg_prepared_statement() AS P;
|
||||
SELECT * FROM pg_catalog.pg_prepared_statement() AS P;
|
||||
|
||||
CREATE VIEW pg_seclabels AS
|
||||
SELECT
|
||||
|
|
@ -719,7 +719,7 @@ FROM
|
|||
JOIN pg_authid rol ON l.classoid = rol.tableoid AND l.objoid = rol.oid;
|
||||
|
||||
CREATE VIEW pg_settings AS
|
||||
SELECT * FROM pg_show_all_settings() AS A;
|
||||
SELECT * FROM pg_catalog.pg_show_all_settings() AS A;
|
||||
|
||||
CREATE RULE pg_settings_u AS
|
||||
ON UPDATE TO pg_settings
|
||||
|
|
@ -733,13 +733,13 @@ CREATE RULE pg_settings_n AS
|
|||
GRANT SELECT, UPDATE ON pg_settings TO PUBLIC;
|
||||
|
||||
CREATE VIEW pg_timezone_abbrevs AS
|
||||
SELECT * FROM pg_timezone_abbrevs();
|
||||
SELECT * FROM pg_catalog.pg_timezone_abbrevs();
|
||||
|
||||
CREATE VIEW pg_timezone_names AS
|
||||
SELECT * FROM pg_timezone_names();
|
||||
SELECT * FROM pg_catalog.pg_timezone_names();
|
||||
|
||||
CREATE VIEW pg_control_group_config AS
|
||||
SELECT * FROM pg_control_group_config();
|
||||
SELECT * FROM pg_catalog.pg_control_group_config();
|
||||
|
||||
-- Statistics views
|
||||
|
||||
|
|
@ -824,7 +824,7 @@ CREATE VIEW pg_statio_all_tables AS
|
|||
pg_catalog.pg_stat_get_blocks_hit(C.oid) AS heap_blks_hit,
|
||||
pg_catalog.sum(pg_catalog.pg_stat_get_blocks_fetched(I.indexrelid) -
|
||||
pg_catalog.pg_stat_get_blocks_hit(I.indexrelid))::bigint AS idx_blks_read,
|
||||
pg_catalog.sum(pg_stat_get_blocks_hit(I.indexrelid))::bigint AS idx_blks_hit,
|
||||
pg_catalog.sum(pg_catalog.pg_stat_get_blocks_hit(I.indexrelid))::bigint AS idx_blks_hit,
|
||||
pg_catalog.pg_stat_get_blocks_fetched(T.oid) -
|
||||
pg_catalog.pg_stat_get_blocks_hit(T.oid) AS toast_blks_read,
|
||||
pg_catalog.pg_stat_get_blocks_hit(T.oid) AS toast_blks_hit,
|
||||
|
|
@ -882,7 +882,7 @@ CREATE VIEW pg_statio_all_indexes AS
|
|||
N.nspname AS schemaname,
|
||||
C.relname AS relname,
|
||||
I.relname AS indexrelname,
|
||||
pg_stat_get_blocks_fetched(I.oid) -
|
||||
pg_catalog.pg_stat_get_blocks_fetched(I.oid) -
|
||||
pg_catalog.pg_stat_get_blocks_hit(I.oid) AS idx_blks_read,
|
||||
pg_catalog.pg_stat_get_blocks_hit(I.oid) AS idx_blks_hit
|
||||
FROM pg_class C JOIN
|
||||
|
|
@ -906,7 +906,7 @@ CREATE VIEW pg_statio_all_sequences AS
|
|||
C.oid AS relid,
|
||||
N.nspname AS schemaname,
|
||||
C.relname AS relname,
|
||||
pg_stat_get_blocks_fetched(C.oid) -
|
||||
pg_catalog.pg_stat_get_blocks_fetched(C.oid) -
|
||||
pg_catalog.pg_stat_get_blocks_hit(C.oid) AS blks_read,
|
||||
pg_catalog.pg_stat_get_blocks_hit(C.oid) AS blks_hit
|
||||
FROM pg_class C
|
||||
|
|
@ -1141,7 +1141,7 @@ SELECT
|
|||
FROM pg_stat_activity_ng AS S, pg_catalog.pg_stat_get_wlm_realtime_session_info(NULL) AS T
|
||||
WHERE S.pid = T.threadid;
|
||||
|
||||
CREATE OR REPLACE FUNCTION gs_wlm_get_all_user_resource_info()
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.gs_wlm_get_all_user_resource_info()
|
||||
RETURNS setof record
|
||||
AS $$
|
||||
DECLARE
|
||||
|
|
@ -1162,7 +1162,7 @@ DECLARE
|
|||
LANGUAGE 'plpgsql' NOT FENCED;
|
||||
|
||||
CREATE VIEW pg_total_user_resource_info_oid AS
|
||||
SELECT * FROM gs_wlm_get_all_user_resource_info() AS
|
||||
SELECT * FROM pg_catalog.gs_wlm_get_all_user_resource_info() AS
|
||||
(userid Oid,
|
||||
used_memory int,
|
||||
total_memory int,
|
||||
|
|
@ -1228,7 +1228,7 @@ create table gs_wlm_user_resource_history
|
|||
|
||||
REVOKE all on gs_wlm_user_resource_history FROM public;
|
||||
|
||||
CREATE OR REPLACE FUNCTION gs_wlm_persistent_user_resource_info()
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.gs_wlm_persistent_user_resource_info()
|
||||
RETURNS setof record
|
||||
AS $$
|
||||
DECLARE
|
||||
|
|
@ -1270,7 +1270,7 @@ create table gs_wlm_instance_history
|
|||
|
||||
REVOKE ALL on gs_wlm_instance_history FROM public;
|
||||
|
||||
CREATE OR REPLACE FUNCTION create_wlm_instance_statistics_info()
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.create_wlm_instance_statistics_info()
|
||||
RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
|
|
@ -1612,18 +1612,18 @@ CREATE VIEW gs_wlm_workload_records AS
|
|||
WHERE P.query_pid = S.threadpid AND
|
||||
S.usesysid = U.oid;
|
||||
|
||||
CREATE VIEW gs_os_run_info AS SELECT * FROM pv_os_run_info();
|
||||
CREATE VIEW gs_session_memory_context AS SELECT * FROM pv_session_memory_detail();
|
||||
CREATE VIEW gs_thread_memory_context AS SELECT * FROM pv_thread_memory_detail();
|
||||
CREATE VIEW gs_shared_memory_detail AS SELECT * FROM pg_shared_memory_detail();
|
||||
CREATE VIEW gs_instance_time AS SELECT * FROM pv_instance_time();
|
||||
CREATE VIEW gs_session_time AS SELECT * FROM pv_session_time();
|
||||
CREATE VIEW gs_session_memory AS SELECT * FROM pv_session_memory();
|
||||
CREATE VIEW gs_total_memory_detail AS SELECT * FROM pv_total_memory_detail();
|
||||
CREATE VIEW pg_total_memory_detail AS SELECT * FROM pv_total_memory_detail();
|
||||
CREATE VIEW gs_redo_stat AS SELECT * FROM pg_stat_get_redo_stat();
|
||||
CREATE VIEW gs_session_stat AS SELECT * FROM pv_session_stat();
|
||||
CREATE VIEW gs_file_stat AS SELECT * FROM pg_stat_get_file_stat();
|
||||
CREATE VIEW gs_os_run_info AS SELECT * FROM pg_catalog.pv_os_run_info();
|
||||
CREATE VIEW gs_session_memory_context AS SELECT * FROM pg_catalog.pv_session_memory_detail();
|
||||
CREATE VIEW gs_thread_memory_context AS SELECT * FROM pg_catalog.pv_thread_memory_detail();
|
||||
CREATE VIEW gs_shared_memory_detail AS SELECT * FROM pg_catalog.pg_shared_memory_detail();
|
||||
CREATE VIEW gs_instance_time AS SELECT * FROM pg_catalog.pv_instance_time();
|
||||
CREATE VIEW gs_session_time AS SELECT * FROM pg_catalog.pv_session_time();
|
||||
CREATE VIEW gs_session_memory AS SELECT * FROM pg_catalog.pv_session_memory();
|
||||
CREATE VIEW gs_total_memory_detail AS SELECT * FROM pg_catalog.pv_total_memory_detail();
|
||||
CREATE VIEW pg_total_memory_detail AS SELECT * FROM pg_catalog.pv_total_memory_detail();
|
||||
CREATE VIEW gs_redo_stat AS SELECT * FROM pg_catalog.pg_stat_get_redo_stat();
|
||||
CREATE VIEW gs_session_stat AS SELECT * FROM pg_catalog.pv_session_stat();
|
||||
CREATE VIEW gs_file_stat AS SELECT * FROM pg_catalog.pg_stat_get_file_stat();
|
||||
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.gs_session_memory_detail_tp(OUT sessid TEXT, OUT sesstype TEXT, OUT contextname TEXT, OUT level INT2, OUT parent TEXT, OUT totalsize INT8, OUT freesize INT8, OUT usedsize INT8)
|
||||
RETURNS setof record
|
||||
|
|
@ -1718,7 +1718,7 @@ BEGIN
|
|||
END; $$
|
||||
LANGUAGE plpgsql NOT FENCED;
|
||||
|
||||
CREATE VIEW gs_session_memory_detail AS SELECT * FROM gs_session_memory_detail_tp() ORDER BY sessid;
|
||||
CREATE VIEW gs_session_memory_detail AS SELECT * FROM pg_catalog.gs_session_memory_detail_tp() ORDER BY sessid;
|
||||
|
||||
CREATE VIEW pg_stat_replication AS
|
||||
SELECT
|
||||
|
|
@ -1754,7 +1754,7 @@ CREATE VIEW pg_replication_slots AS
|
|||
L.catalog_xmin,
|
||||
L.restart_lsn,
|
||||
L.dummy_standby
|
||||
FROM pg_get_replication_slots() AS L
|
||||
FROM pg_catalog.pg_get_replication_slots() AS L
|
||||
LEFT JOIN pg_database D ON (L.datoid = D.oid);
|
||||
|
||||
|
||||
|
|
@ -1819,17 +1819,17 @@ CREATE VIEW pg_stat_xact_user_functions AS
|
|||
|
||||
CREATE VIEW pg_stat_bgwriter AS
|
||||
SELECT
|
||||
pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,
|
||||
pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req,
|
||||
pg_stat_get_checkpoint_write_time() AS checkpoint_write_time,
|
||||
pg_stat_get_checkpoint_sync_time() AS checkpoint_sync_time,
|
||||
pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint,
|
||||
pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean,
|
||||
pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean,
|
||||
pg_stat_get_buf_written_backend() AS buffers_backend,
|
||||
pg_stat_get_buf_fsync_backend() AS buffers_backend_fsync,
|
||||
pg_stat_get_buf_alloc() AS buffers_alloc,
|
||||
pg_stat_get_bgwriter_stat_reset_time() AS stats_reset;
|
||||
pg_catalog.pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints_timed,
|
||||
pg_catalog.pg_stat_get_bgwriter_requested_checkpoints() AS checkpoints_req,
|
||||
pg_catalog.pg_stat_get_checkpoint_write_time() AS checkpoint_write_time,
|
||||
pg_catalog.pg_stat_get_checkpoint_sync_time() AS checkpoint_sync_time,
|
||||
pg_catalog.pg_stat_get_bgwriter_buf_written_checkpoints() AS buffers_checkpoint,
|
||||
pg_catalog.pg_stat_get_bgwriter_buf_written_clean() AS buffers_clean,
|
||||
pg_catalog.pg_stat_get_bgwriter_maxwritten_clean() AS maxwritten_clean,
|
||||
pg_catalog.pg_stat_get_buf_written_backend() AS buffers_backend,
|
||||
pg_catalog.pg_stat_get_buf_fsync_backend() AS buffers_backend_fsync,
|
||||
pg_catalog.pg_stat_get_buf_alloc() AS buffers_alloc,
|
||||
pg_catalog.pg_stat_get_bgwriter_stat_reset_time() AS stats_reset;
|
||||
|
||||
CREATE VIEW pg_user_mappings AS
|
||||
SELECT
|
||||
|
|
@ -1856,7 +1856,7 @@ REVOKE ALL on pg_user_mapping FROM public;
|
|||
-- these functions are added for supporting default format transformation
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.to_char(NUMERIC)
|
||||
RETURNS VARCHAR2
|
||||
AS $$ SELECT CAST(numeric_out($1) AS VARCHAR2) $$
|
||||
AS $$ SELECT CAST(pg_catalog.numeric_out($1) AS VARCHAR2) $$
|
||||
LANGUAGE SQL STRICT IMMUTABLE NOT FENCED;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.to_char(INT2)
|
||||
|
|
@ -1891,7 +1891,7 @@ LANGUAGE SQL STRICT IMMUTABLE NOT FENCED;
|
|||
|
||||
CREATE OR REPLACE FUNCTION pg_catalog.to_number(TEXT)
|
||||
RETURNS NUMERIC
|
||||
AS $$ SELECT pg_catalog.numeric_in(textout($1), 0::Oid, -1) $$
|
||||
AS $$ SELECT pg_catalog.numeric_in(pg_catalog.textout($1), 0::Oid, -1) $$
|
||||
LANGUAGE SQL STRICT IMMUTABLE NOT FENCED;
|
||||
|
||||
CREATE CAST (VARCHAR2 AS RAW) WITH FUNCTION pg_catalog.hextoraw(text) AS IMPLICIT;
|
||||
|
|
@ -2413,7 +2413,7 @@ begin
|
|||
end if;
|
||||
--source string to source_array
|
||||
for i in 1..pg_catalog.length($1) loop
|
||||
if substr($1,i,1) ~ '\n' then
|
||||
if pg_catalog.substr($1,i,1) ~ '\n' then
|
||||
if position = i then
|
||||
source_array(source_line) := '\n';
|
||||
else
|
||||
|
|
@ -2469,12 +2469,12 @@ begin
|
|||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
if left($2,1) = '^' then
|
||||
if pg_catalog.left($2,1) = '^' then
|
||||
regex_temp := pg_catalog.substr($2,2);
|
||||
else
|
||||
regex_temp := $2;
|
||||
end if;
|
||||
if right($2,1) = '$' then
|
||||
if pg_catalog.right($2,1) = '$' then
|
||||
regex_temp := pg_catalog.substr(regex_temp,1,pg_catalog.length(regex_temp)-1);
|
||||
end if;
|
||||
if flag then
|
||||
|
|
@ -2497,7 +2497,7 @@ begin
|
|||
return false;
|
||||
end if;
|
||||
end loop;
|
||||
case right($3, 1)
|
||||
case pg_catalog.right($3, 1)
|
||||
when 'i' then return $1 ~* $2;
|
||||
when 'c' then return $1 ~ $2;
|
||||
when 'm' then return pg_catalog.regex_like_m($1,$2);
|
||||
|
|
@ -2523,13 +2523,13 @@ SQL_STMT VARCHAR2(500);
|
|||
fail_cursor REFCURSOR;
|
||||
success_cursor REFCURSOR;
|
||||
BEGIN
|
||||
SELECT text(oid) FROM pg_catalog.pg_authid WHERE rolname=SESSION_USER INTO user_id;
|
||||
SELECT pg_catalog.text(oid) FROM pg_catalog.pg_authid WHERE rolname=SESSION_USER INTO user_id;
|
||||
SELECT SESSION_USER INTO user_name;
|
||||
SELECT pg_catalog.CURRENT_DATABASE() INTO db_name;
|
||||
IF flag = true THEN
|
||||
SQL_STMT := 'SELECT username,database,time,type,result,client_conninfo FROM pg_catalog.pg_query_audit(''1970-1-1'',''9999-12-31'') WHERE
|
||||
type IN (''login_success'') AND username =' || quote_literal(user_name) ||
|
||||
' AND database =' || quote_literal(db_name) || ' AND userid =' || quote_literal(user_id) || ';';
|
||||
type IN (''login_success'') AND username =' || pg_catalog.quote_literal(user_name) ||
|
||||
' AND database =' || pg_catalog.quote_literal(db_name) || ' AND userid =' || pg_catalog.quote_literal(user_id) || ';';
|
||||
OPEN success_cursor FOR EXECUTE SQL_STMT;
|
||||
--search bottom up for all the success login info
|
||||
FETCH LAST FROM success_cursor into username, database, logintime, mytype, result, client_conninfo;
|
||||
|
|
@ -2540,8 +2540,8 @@ BEGIN
|
|||
CLOSE success_cursor;
|
||||
ELSE
|
||||
SQL_STMT := 'SELECT username,database,time,type,result,client_conninfo FROM pg_catalog.pg_query_audit(''1970-1-1'',''9999-12-31'') WHERE
|
||||
type IN (''login_success'', ''login_failed'') AND username =' || quote_literal(user_name) ||
|
||||
' AND database =' || quote_literal(db_name) || ' AND userid =' || quote_literal(user_id) || ';';
|
||||
type IN (''login_success'', ''login_failed'') AND username =' || pg_catalog.quote_literal(user_name) ||
|
||||
' AND database =' || pg_catalog.quote_literal(db_name) || ' AND userid =' || pg_catalog.quote_literal(user_id) || ';';
|
||||
OPEN fail_cursor FOR EXECUTE SQL_STMT;
|
||||
--search bottom up
|
||||
FETCH LAST FROM fail_cursor into username, database, logintime, mytype, result, client_conninfo;
|
||||
|
|
@ -2580,15 +2580,15 @@ success_cursor REFCURSOR;
|
|||
mybackendid bigint;
|
||||
curSessionFound boolean;
|
||||
BEGIN
|
||||
SELECT text(oid) FROM pg_catalog.pg_authid WHERE rolname=SESSION_USER INTO user_id;
|
||||
SELECT pg_catalog.text(oid) FROM pg_catalog.pg_authid WHERE rolname=SESSION_USER INTO user_id;
|
||||
SELECT SESSION_USER INTO user_name;
|
||||
SELECT pg_catalog.CURRENT_DATABASE() INTO db_name;
|
||||
SELECT pg_catalog.pg_backend_pid() INTO mybackendid;
|
||||
curSessionFound = false;
|
||||
IF flag = true THEN
|
||||
SQL_STMT := 'SELECT username,database,time,type,result,client_conninfo, pg_catalog.split_part(thread_id,''@'',1) backendid FROM pg_catalog.pg_query_audit(''1970-1-1'',''9999-12-31'') WHERE
|
||||
type IN (''login_success'') AND username =' || quote_literal(user_name) ||
|
||||
' AND database =' || quote_literal(db_name) || ' AND userid =' || quote_literal(user_id) || ';';
|
||||
type IN (''login_success'') AND username =' || pg_catalog.quote_literal(user_name) ||
|
||||
' AND database =' || pg_catalog.quote_literal(db_name) || ' AND userid =' || pg_catalog.quote_literal(user_id) || ';';
|
||||
OPEN success_cursor FOR EXECUTE SQL_STMT;
|
||||
--search bottom up for all the success login info
|
||||
FETCH LAST FROM success_cursor into username, database, logintime, mytype, result, client_conninfo, backendid;
|
||||
|
|
@ -2785,14 +2785,14 @@ DECLARE
|
|||
execute_query text;
|
||||
BEGIN
|
||||
if row_num = 0 then
|
||||
EXECUTE 'select count(1) from ' || table_name into tolal_num;
|
||||
execute_query = 'select seqNum, count(1) as num
|
||||
from (select table_data_skewness(row(' || column_name ||'), ''H'') as seqNum from ' || table_name ||
|
||||
EXECUTE 'select pg_catalog.count(1) from ' || table_name into tolal_num;
|
||||
execute_query = 'select seqNum, pg_catalog.count(1) as num
|
||||
from (select pg_catalog.table_data_skewness(row(' || column_name ||'), ''H'') as seqNum from ' || table_name ||
|
||||
') group by seqNum order by num DESC';
|
||||
else
|
||||
tolal_num = row_num;
|
||||
execute_query = 'select seqNum, count(1) as num
|
||||
from (select table_data_skewness(row(' || column_name ||'), ''H'') as seqNum from ' || table_name ||
|
||||
execute_query = 'select seqNum, pg_catalog.count(1) as num
|
||||
from (select pg_catalog.table_data_skewness(row(' || column_name ||'), ''H'') as seqNum from ' || table_name ||
|
||||
' limit ' || row_num ||') group by seqNum order by num DESC';
|
||||
end if;
|
||||
|
||||
|
|
@ -2965,11 +2965,11 @@ DECLARE
|
|||
ec_username,
|
||||
ec_query,
|
||||
ec_libodbc_type
|
||||
FROM pg_stat_get_wlm_ec_operator_info(0) where ec_operator > 0';
|
||||
FROM pg_catalog.pg_stat_get_wlm_ec_operator_info(0) where ec_operator > 0';
|
||||
|
||||
query_plan_str := 'SELECT * FROM gs_stat_get_wlm_plan_operator_info(0)';
|
||||
query_plan_str := 'SELECT * FROM pg_catalog.gs_stat_get_wlm_plan_operator_info(0)';
|
||||
|
||||
query_str := 'SELECT * FROM pg_stat_get_wlm_operator_info(1)';
|
||||
query_str := 'SELECT * FROM pg_catalog.pg_stat_get_wlm_operator_info(1)';
|
||||
|
||||
IF flag > 0 THEN
|
||||
EXECUTE 'INSERT INTO gs_wlm_ec_operator_info ' || query_ec_str;
|
||||
|
|
@ -3060,7 +3060,7 @@ DECLARE
|
|||
dop = row_data.query_dop;
|
||||
condition = row_data.condition;
|
||||
projection = row_data.projection;
|
||||
query_str_encode := 'SELECT encode_plan_node($tag$'|| operation ||'$tag$,$tag$'|| orientation ||'$tag$,$tag$'|| strategy ||'$tag$,$tag$ '|| options || '$tag$,$tag$'|| dop ||'$tag$,$tag$' || condition || '$tag$,$tag$' || projection || '$tag$) as result;';
|
||||
query_str_encode := 'SELECT pg_catalog.encode_plan_node($tag$'|| operation ||'$tag$,$tag$'|| orientation ||'$tag$,$tag$'|| strategy ||'$tag$,$tag$ '|| options || '$tag$,$tag$'|| dop ||'$tag$,$tag$' || condition || '$tag$,$tag$' || projection || '$tag$) as result;';
|
||||
EXECUTE query_str_encode INTO encoded_data;
|
||||
encode = encoded_data.result;
|
||||
return next;
|
||||
|
|
@ -3255,7 +3255,7 @@ DECLARE
|
|||
IF row_info_data.parttype = 'n' THEN
|
||||
query_str := 'SELECT relname,oid from pg_class where oid= '||row_info_data.reldeltarelid||'';
|
||||
EXECUTE(query_str) INTO row_data;
|
||||
query_select_str := 'select count(*) from cstore.' || row_data.relname || '';
|
||||
query_select_str := 'select pg_catalog.count(*) from cstore.' || row_data.relname || '';
|
||||
EXECUTE (query_select_str) INTO live_tuple;
|
||||
query_size_str := 'select * from pg_catalog.pg_relation_size(' || row_data.oid || ')';
|
||||
EXECUTE (query_size_str) INTO data_size;
|
||||
|
|
@ -3268,7 +3268,7 @@ DECLARE
|
|||
query_str := 'SELECT relname,oid from pg_class where oid = '||row_part_info.reldeltarelid||'';
|
||||
part_name := row_part_info.relname;
|
||||
FOR row_data IN EXECUTE(query_str) LOOP
|
||||
query_select_str := 'select count(*) from cstore.' || row_data.relname || '';
|
||||
query_select_str := 'select pg_catalog.count(*) from cstore.' || row_data.relname || '';
|
||||
EXECUTE (query_select_str) INTO live_tuple;
|
||||
query_size_str := 'select * from pg_catalog.pg_relation_size(' || row_data.oid || ')';
|
||||
EXECUTE (query_size_str) INTO data_size;
|
||||
|
|
@ -3321,7 +3321,7 @@ DECLARE
|
|||
BEGIN
|
||||
query_database_oid := 'SELECT datname FROM pg_database WHERE datallowconn = true order by datname';
|
||||
for databse_name in EXECUTE(query_database_oid) LOOP
|
||||
unlock_str = format('SELECT * FROM pg_catalog.pgxc_unlock_for_sp_database(''%s'')', databse_name.datname);
|
||||
unlock_str = pg_catalog.format('SELECT * FROM pg_catalog.pgxc_unlock_for_sp_database(''%s'')', databse_name.datname);
|
||||
begin
|
||||
EXECUTE(unlock_str) into unlock_result;
|
||||
if unlock_result = 'f' then
|
||||
|
|
@ -3522,11 +3522,11 @@ CREATE VIEW pg_catalog.gs_db_privileges AS
|
|||
FROM pg_catalog.gs_db_privilege;
|
||||
|
||||
CREATE OR REPLACE VIEW pg_catalog.gs_gsc_memory_detail AS
|
||||
SELECT db_id, sum(totalsize) AS totalsize, sum(freesize) AS freesize, sum(usedsize) AS usedsize
|
||||
SELECT db_id, pg_catalog.sum(totalsize) AS totalsize, pg_catalog.sum(freesize) AS freesize, pg_catalog.sum(usedsize) AS usedsize
|
||||
FROM (
|
||||
SELECT
|
||||
CASE WHEN contextname like '%GlobalSysDBCacheEntryMemCxt%' THEN substring(contextname, 29)
|
||||
ELSE substring(parent, 29) END AS db_id,
|
||||
CASE WHEN contextname like '%GlobalSysDBCacheEntryMemCxt%' THEN pg_catalog.substring(contextname, 29)
|
||||
ELSE pg_catalog.substring(parent, 29) END AS db_id,
|
||||
totalsize,
|
||||
freesize,
|
||||
usedsize
|
||||
|
|
|
|||
|
|
@ -745,9 +745,11 @@ static void InitTempToastNamespace(void)
|
|||
|
||||
/* Advance command counter to make namespace visible */
|
||||
CommandCounterIncrement();
|
||||
|
||||
Assert(OidIsValid(u_sess->catalog_cxt.myTempNamespace) && OidIsValid(u_sess->catalog_cxt.myTempToastNamespace));
|
||||
|
||||
if (!OidIsValid(u_sess->catalog_cxt.myTempToastNamespace)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("Temp toast namespace create failed")));
|
||||
}
|
||||
u_sess->catalog_cxt.baseSearchPathValid = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include "tcop/utility.h"
|
||||
#include "pgxc/pgxc.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "funcapi.h"
|
||||
|
||||
const size_t ENCRYPTED_VALUE_MIN_LENGTH = 170;
|
||||
const size_t ENCRYPTED_VALUE_MAX_LENGTH = 1024;
|
||||
|
|
@ -1324,3 +1325,28 @@ ClientLogicColumnRef *get_column_enc_def(Oid rel_oid, const char *col_name)
|
|||
|
||||
return enc_def;
|
||||
}
|
||||
|
||||
Datum get_client_info(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ReturnSetInfo* rsinfo = (ReturnSetInfo*)fcinfo->resultinfo;
|
||||
TupleDesc tupdesc;
|
||||
Tuplestorestate* tupstore = NULL;
|
||||
const int COLUMN_NUM = 2;
|
||||
MemoryContext oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
|
||||
tupdesc = CreateTemplateTupleDesc(COLUMN_NUM, false, TAM_HEAP);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber)1, "sid", INT8OID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber)2, "client_info", TEXTOID, -1, 0);
|
||||
|
||||
tupstore = tuplestore_begin_heap(true, false, u_sess->attr.attr_memory.work_mem);
|
||||
rsinfo->returnMode = SFRM_Materialize;
|
||||
rsinfo->setResult = tupstore;
|
||||
rsinfo->setDesc = BlessTupleDesc(tupdesc);
|
||||
|
||||
(void)MemoryContextSwitchTo(oldcontext);
|
||||
if (ENABLE_THREAD_POOL) {
|
||||
g_threadPoolControler->GetSessionCtrl()->getSessionClientInfo(rsinfo->setResult, rsinfo->setDesc);
|
||||
}
|
||||
|
||||
tuplestore_donestoring(rsinfo->setResult);
|
||||
return (Datum)0;
|
||||
}
|
||||
|
|
@ -678,6 +678,9 @@ static void _outPruningResult(StringInfo str, PruningResult* node)
|
|||
if (t_thrd.proc->workingVersionNum >= num) {
|
||||
WRITE_NODE_FIELD(expr);
|
||||
}
|
||||
if (t_thrd.proc->workingVersionNum >= PBESINGLEPARTITION_VERSION_NUM) {
|
||||
WRITE_BOOL_FIELD(isPbeSinlePartition);
|
||||
}
|
||||
}
|
||||
|
||||
static void _outSubPartitionPruningResult(StringInfo str, SubPartitionPruningResult* node)
|
||||
|
|
|
|||
|
|
@ -3312,6 +3312,9 @@ static PruningResult* _readPruningResult(PruningResult* local_node)
|
|||
if (t_thrd.proc->workingVersionNum >= num) {
|
||||
READ_NODE_FIELD(expr);
|
||||
}
|
||||
IF_EXIST(isPbeSinlePartition) {
|
||||
READ_BOOL_FIELD(isPbeSinlePartition);
|
||||
}
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19590,6 +19590,11 @@ for_locking_items:
|
|||
for_locking_item:
|
||||
FOR UPDATE hint_string locked_rels_list opt_nowait
|
||||
{
|
||||
if (u_sess->parser_cxt.isTimeCapsule) {
|
||||
u_sess->parser_cxt.isTimeCapsule = false;
|
||||
ereport(errstate, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("SELECT TIMECAPSULE FOR UPDATE is not supported.")));
|
||||
}
|
||||
LockingClause *n = makeNode(LockingClause);
|
||||
n->lockedRels = $4;
|
||||
n->forUpdate = TRUE;
|
||||
|
|
@ -20193,22 +20198,22 @@ timecapsule_clause:
|
|||
TIMECAPSULE opt_timecapsule_clause { $$ = $2; }
|
||||
|
||||
opt_timecapsule_clause:
|
||||
CSN a_expr
|
||||
CSN {u_sess->parser_cxt.isTimeCapsule = true;} a_expr
|
||||
{
|
||||
TcapFeatureEnsure();
|
||||
RangeTimeCapsule *n = makeNode(RangeTimeCapsule);
|
||||
n->tvtype = TV_VERSION_CSN;
|
||||
n->tvver = (Node *)$2;
|
||||
n->location = @2;
|
||||
n->tvver = (Node *)$3;
|
||||
n->location = @3;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| TIMESTAMP a_expr
|
||||
| TIMESTAMP {u_sess->parser_cxt.isTimeCapsule = true;} a_expr
|
||||
{
|
||||
TcapFeatureEnsure();
|
||||
RangeTimeCapsule *n = makeNode(RangeTimeCapsule);
|
||||
n->tvtype = TV_VERSION_TIMESTAMP;
|
||||
n->tvver = (Node *)$2;
|
||||
n->location = @2;
|
||||
n->tvver = (Node *)$3;
|
||||
n->location = @3;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
;
|
||||
|
|
|
|||
|
|
@ -402,6 +402,10 @@ static void PredpushHintDesc(PredpushHint* hint, StringInfo buf)
|
|||
|
||||
relnamesToBuf(base_hint.relnames, buf);
|
||||
|
||||
if (hint->dest_name != NULL) {
|
||||
appendStringInfo(buf, ", %s", hint->dest_name);
|
||||
}
|
||||
|
||||
if (hint->candidates != NULL)
|
||||
appendStringInfo(buf, ")");
|
||||
|
||||
|
|
@ -3325,6 +3329,50 @@ static void transform_skew_hint(PlannerInfo* root, Query* parse, List* skew_hint
|
|||
parse->hintState->skew_hint = skew_hint_transf_l;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check Predpush hint rely on each other.
|
||||
*/
|
||||
static void check_predpush_cycle_hint(PlannerInfo *root,
|
||||
List *predpush_hint_list,
|
||||
PredpushHint *predpush_hint)
|
||||
{
|
||||
ListCell *lc = NULL;
|
||||
|
||||
if (bms_num_members(predpush_hint->candidates) != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (predpush_hint->dest_id == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cur_dest = predpush_hint->dest_id;
|
||||
foreach(lc, predpush_hint_list) {
|
||||
PredpushHint *prev_hint = (PredpushHint *)lfirst(lc);
|
||||
|
||||
if (prev_hint == predpush_hint) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (bms_num_members(prev_hint->candidates) != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prev_hint->dest_id == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int prev_dest = prev_hint->dest_id;
|
||||
if (bms_is_member(prev_dest, predpush_hint->candidates) &&
|
||||
bms_is_member(cur_dest, prev_hint->candidates)) {
|
||||
append_warning_to_list(
|
||||
root, (Hint*)predpush_hint, "Error hint:%s, Predpush cannot rely on each other.", hint_string);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* @Description: Transform predpush hint into processible type, including:
|
||||
* transfrom subquery name
|
||||
|
|
@ -3350,6 +3398,7 @@ static void transform_predpush_hint(PlannerInfo* root, Query* parse, List* predp
|
|||
}
|
||||
|
||||
predpush_hint->dest_id = relid;
|
||||
check_predpush_cycle_hint(root, predpush_hint_list, predpush_hint);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
@ -3866,4 +3915,4 @@ bool CheckNodeNameHint(HintState* hintstate)
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1134,6 +1134,11 @@ Relation parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockm
|
|||
TryUnlockAllAccounts();
|
||||
}
|
||||
|
||||
if (rel->partMap && rel->partMap->type == PART_TYPE_INTERVAL) {
|
||||
/* take AccessShareLock on ADD_PARTITION_ACTION to avoid concurrency with new partition operations. */
|
||||
LockRelationForAccessIntervalPartitionTab(rel);
|
||||
}
|
||||
|
||||
if (IS_PGXC_COORDINATOR && !IsConnFromCoord()) {
|
||||
if (u_sess->attr.attr_sql.enable_parallel_ddl && !isFirstNode && isCreateView) {
|
||||
UnlockRelation(rel, lockmode);
|
||||
|
|
|
|||
|
|
@ -1091,10 +1091,12 @@ static void transformStartWithClause(StartWithTransformContext *context, SelectS
|
|||
raw_expression_tree_walker((Node*)context->connectByExpr,
|
||||
(bool (*)())pseudo_level_rownum_walker, (Node*)context->connectByExpr);
|
||||
checkConnectByExprValidity((Node*)connectByExpr);
|
||||
StartWithWalker(context, connectByExpr);
|
||||
context->relInfoList = context->pstate->p_start_info;
|
||||
context->connect_by_type = CONNECT_BY_LEVEL;
|
||||
context->connectByLevelExpr = connectByExpr;
|
||||
context->connectByOtherExpr = NULL;
|
||||
if (context->connect_by_type != CONNECT_BY_PRIOR) {
|
||||
context->connectByLevelExpr = connectByExpr;
|
||||
context->connectByOtherExpr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* transform start with ... connect by's expr */
|
||||
|
|
@ -1103,12 +1105,24 @@ static void transformStartWithClause(StartWithTransformContext *context, SelectS
|
|||
StartWithWalker(context, connectByExpr);
|
||||
}
|
||||
|
||||
/* now handle where quals which could whole push down */
|
||||
/*
|
||||
* now handle where quals which might need to be pushed down.
|
||||
* 1. this is necessary only for implicitly joined tables
|
||||
* such as ... FROM t1,t2 WHERE t1.xx = t2.yy ...
|
||||
* 2. note that only join quals should be pushed down while
|
||||
* non-join quals such as (t1.xx < n) should be kept in the outer loop
|
||||
* of the CTE scan, otherwise the end-result will be different from
|
||||
* those produced by the standard swcb syntax.
|
||||
* (the issue here is that implicitly joined tables are difficult to handle
|
||||
* in our implementation of start with .. connect by .. syntax,
|
||||
* as we don't have a clear cut of join quals from the non-join quals at this stage.
|
||||
* users should be encouraged to use explicity joined tables whenever
|
||||
* possible before a clear-cut solution is implemented.)
|
||||
*/
|
||||
int lens = list_length(context->pstate->p_start_info);
|
||||
if (lens != 1) {
|
||||
Node *whereClause = (Node *)copyObject(stmt->whereClause);
|
||||
context->whereClause = whereClause;
|
||||
stmt->whereClause = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1256,6 +1270,36 @@ static void AddWithClauseToBranch(ParseState *pstate, SelectStmt *stmt, List *re
|
|||
return;
|
||||
}
|
||||
|
||||
static bool walker_to_exclude_non_join_quals(Node *node, Node *context_node)
|
||||
{
|
||||
if (node == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsA(node, A_Expr)) {
|
||||
return raw_expression_tree_walker(node, (bool (*)()) walker_to_exclude_non_join_quals, (void*)NULL);
|
||||
}
|
||||
|
||||
A_Expr* expr = (A_Expr*) node;
|
||||
/*
|
||||
* this is to achieve consistent result sets with those produced by the original
|
||||
* start with .. connect by syntax, which does not push filter quals down to connect quals.
|
||||
* if non-column item appears on any side of an operator, we guess that it is
|
||||
* not a join qual so should not be filtered in sw op, and force it to be true.
|
||||
* this rule is not always correct but should work fine most of the time.
|
||||
* could be improved later on, e.g. find better ways to extract non-join quals
|
||||
* from the where clause.
|
||||
*/
|
||||
if (expr->kind == AEXPR_OP &&
|
||||
(!IsA(expr->lexpr, ColumnRef) || !IsA(expr->rexpr, ColumnRef))) {
|
||||
expr->lexpr = makeBoolAConst(true, -1);
|
||||
expr->rexpr = makeBoolAConst(true, -1);
|
||||
expr->kind = AEXPR_OR;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------------------------
|
||||
* @Brief: Create SWCB's conversion CTE's inner branch, normally we add ConnectByExpr to
|
||||
|
|
@ -1314,6 +1358,10 @@ static SelectStmt *CreateStartWithCTEInnerBranch(ParseState* pstate,
|
|||
JoinExpr *final_join = (JoinExpr *)origin_table;
|
||||
/* pushdown requires deep copying of the quals */
|
||||
Node *whereCopy = (Node *)copyObject(whereClause);
|
||||
/* only join quals can be pushed down */
|
||||
raw_expression_tree_walker((Node *)whereCopy,
|
||||
(bool (*)())walker_to_exclude_non_join_quals, (void*)NULL);
|
||||
|
||||
if (final_join->quals == NULL) {
|
||||
final_join->quals = whereCopy;
|
||||
} else {
|
||||
|
|
@ -1420,11 +1468,18 @@ static SelectStmt *CreateStartWithCTEOuterBranch(ParseState *pstate,
|
|||
|
||||
/* push whereClause down to init part, taking care to avoid NULL in expr. */
|
||||
quals = (Node *)startWithExpr;
|
||||
Node* whereClauseCopy = (Node *)copyObject(whereClause);
|
||||
|
||||
if (whereClause != NULL) {
|
||||
/* only join quals can be pushed down */
|
||||
raw_expression_tree_walker((Node*)whereClauseCopy,
|
||||
(bool (*)())walker_to_exclude_non_join_quals, (void*)NULL);
|
||||
}
|
||||
|
||||
if (quals == NULL) {
|
||||
/* pushdown requires deep copying of the quals */
|
||||
quals = (Node *)copyObject(whereClause);
|
||||
quals = whereClauseCopy;
|
||||
} else if (whereClause != NULL) {
|
||||
quals = (Node *)makeA_Expr(AEXPR_AND, NULL, (Node *)copyObject(whereClause),
|
||||
quals = (Node *)makeA_Expr(AEXPR_AND, NULL, whereClauseCopy,
|
||||
(Node*)startWithExpr, -1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@
|
|||
|
||||
extern void resetOperatorPlusFlag();
|
||||
|
||||
static void resetIsTimeCapsuleFlag()
|
||||
{
|
||||
u_sess->parser_cxt.isTimeCapsule = false;
|
||||
}
|
||||
|
||||
static void resetCreateFuncFlag()
|
||||
{
|
||||
u_sess->parser_cxt.isCreateFuncOrProc = false;
|
||||
|
|
@ -48,6 +53,9 @@ List* raw_parser(const char* str, List** query_string_locationlist)
|
|||
/* reset u_sess->parser_cxt.stmt_contains_operator_plus */
|
||||
resetOperatorPlusFlag();
|
||||
|
||||
/* reset u_sess->parser_cxt.isTimeCapsule */
|
||||
resetIsTimeCapsuleFlag();
|
||||
|
||||
/* reset u_sess->parser_cxt.isCreateFuncOrProc */
|
||||
resetCreateFuncFlag();
|
||||
|
||||
|
|
|
|||
|
|
@ -871,12 +871,14 @@ static void ExecuteBarrier(const char* id, bool isSwitchoverBarrier)
|
|||
|
||||
/* Only obs-based disaster recovery needs the following processing */
|
||||
if (g_instance.archive_obs_cxt.archive_slot_num != 0 && g_instance.archive_obs_cxt.barrier_lsn_info != NULL) {
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (IS_HADR_BARRIER(id) || IS_CSN_BARRIER(id)) {
|
||||
SpinLockAcquire(&g_instance.archive_obs_cxt.barrier_lock);
|
||||
SaveAllNodeBarrierLsnInfo(id, conn_handles);
|
||||
g_instance.archive_obs_cxt.barrier_lsn_info[connCnt].barrierLsn = recptr;
|
||||
SpinLockRelease(&g_instance.archive_obs_cxt.barrier_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (t_thrd.role == BARRIER_CREATOR && !isSwitchoverBarrier) {
|
||||
UpdateGlobalBarrierListOnMedia(id, g_instance.attr.attr_common.PGXCNodeName);
|
||||
|
|
@ -1017,7 +1019,7 @@ static void RequestXLogFromStream()
|
|||
|
||||
static void barrier_redo_pause(char* barrierId)
|
||||
{
|
||||
if (!is_barrier_pausable(barrierId)) {
|
||||
if (!is_barrier_pausable(barrierId) || t_thrd.xlog_cxt.recoveryTarget == RECOVERY_TARGET_TIME_OBS) {
|
||||
return;
|
||||
}
|
||||
volatile WalRcvData *walrcv = t_thrd.walreceiverfuncs_cxt.WalRcv;
|
||||
|
|
@ -1035,7 +1037,7 @@ static void barrier_redo_pause(char* barrierId)
|
|||
SpinLockRelease(&walrcv->mutex);
|
||||
pg_usleep(1000L);
|
||||
RedoInterruptCallBack();
|
||||
if(IS_OBS_DISASTER_RECOVER_MODE) {
|
||||
if (IS_OBS_DISASTER_RECOVER_MODE) {
|
||||
update_recovery_barrier();
|
||||
} else if (IS_DISASTER_RECOVER_MODE) {
|
||||
RequestXLogFromStream();
|
||||
|
|
|
|||
|
|
@ -232,9 +232,9 @@ static char* pg_get_triggerdef_worker(Oid trigid, bool pretty);
|
|||
static void decompile_column_index_array(Datum column_index_array, Oid relId, StringInfo buf);
|
||||
static char* pg_get_ruledef_worker(Oid ruleoid, int prettyFlags);
|
||||
static char *pg_get_indexdef_worker(Oid indexrelid, int colno, const Oid *excludeOps, bool attrsOnly, bool showTblSpc,
|
||||
int prettyFlags, bool dumpSchemaOnly = false, bool showSubpartitionLocal = true);
|
||||
int prettyFlags, bool dumpSchemaOnly = false, bool showPartitionLocal = true, bool showSubpartitionLocal = true);
|
||||
static void pg_get_indexdef_partitions(Oid indexrelid, Form_pg_index idxrec, bool showTblSpc, StringInfoData *buf,
|
||||
bool dumpSchemaOnly, bool showSubpartitionLocal);
|
||||
bool dumpSchemaOnly, bool showPartitionLocal, bool showSubpartitionLocal);
|
||||
static char* pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, int prettyFlags);
|
||||
static text* pg_get_expr_worker(text* expr, Oid relid, const char* relname, int prettyFlags);
|
||||
static int print_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults);
|
||||
|
|
@ -2960,7 +2960,7 @@ Datum pg_get_indexdef_for_dump(PG_FUNCTION_ARGS)
|
|||
bool dumpSchemaOnly = PG_GETARG_BOOL(1);
|
||||
|
||||
PG_RETURN_TEXT_P(string_to_text(pg_get_indexdef_worker(indexrelid, 0, NULL, false, true, 0, dumpSchemaOnly,
|
||||
false)));
|
||||
true, false)));
|
||||
}
|
||||
|
||||
Datum pg_get_indexdef_ext(PG_FUNCTION_ARGS)
|
||||
|
|
@ -2972,7 +2972,7 @@ Datum pg_get_indexdef_ext(PG_FUNCTION_ARGS)
|
|||
|
||||
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT) : 0;
|
||||
PG_RETURN_TEXT_P(string_to_text(pg_get_indexdef_worker(indexrelid, colno, NULL, colno != 0, true, prettyFlags,
|
||||
false, false)));
|
||||
false, false, false)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -3051,7 +3051,7 @@ static void GetIndexdefForIntervalPartTabDumpSchemaOnly(Oid indexrelid, RangePar
|
|||
}
|
||||
|
||||
static void pg_get_indexdef_partitions(Oid indexrelid, Form_pg_index idxrec, bool showTblSpc, StringInfoData *buf,
|
||||
bool dumpSchemaOnly, bool showSubpartitionLocal)
|
||||
bool dumpSchemaOnly, bool showPartitionLocal, bool showSubpartitionLocal)
|
||||
{
|
||||
Oid relid = idxrec->indrelid;
|
||||
/*
|
||||
|
|
@ -3067,12 +3067,12 @@ static void pg_get_indexdef_partitions(Oid indexrelid, Form_pg_index idxrec, boo
|
|||
|
||||
appendStringInfo(buf, " LOCAL");
|
||||
/*
|
||||
* The LOCAL index information of the subpartition table is more.
|
||||
* The LOCAL index information of the partition and subpartition table is more.
|
||||
* And the meta-statements (e.g. \d \d+ \dS) are used more.
|
||||
* Therefore, when the meta-statement is called, the subpartition LOCAL index information is not displayed.
|
||||
* Therefore, when the meta-statement is called, the LOCAL index information is not displayed.
|
||||
*/
|
||||
bool isSub = RelationIsSubPartitioned(rel);
|
||||
if (isSub && !showSubpartitionLocal) {
|
||||
if ((!isSub && !showPartitionLocal) || (isSub && !showSubpartitionLocal)) {
|
||||
heap_close(rel, NoLock);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3112,7 +3112,7 @@ static void pg_get_indexdef_partitions(Oid indexrelid, Form_pg_index idxrec, boo
|
|||
* NULL then it points to an array of exclusion operator OIDs.
|
||||
*/
|
||||
static char *pg_get_indexdef_worker(Oid indexrelid, int colno, const Oid *excludeOps, bool attrsOnly, bool showTblSpc,
|
||||
int prettyFlags, bool dumpSchemaOnly, bool showSubpartitionLocal)
|
||||
int prettyFlags, bool dumpSchemaOnly, bool showPartitionLocal, bool showSubpartitionLocal)
|
||||
{
|
||||
/* might want a separate isConstraint parameter later */
|
||||
bool isConstraint = (excludeOps != NULL);
|
||||
|
|
@ -3316,7 +3316,8 @@ static char *pg_get_indexdef_worker(Oid indexrelid, int colno, const Oid *exclud
|
|||
|
||||
if (idxrelrec->parttype == PARTTYPE_PARTITIONED_RELATION &&
|
||||
idxrelrec->relkind != RELKIND_GLOBAL_INDEX) {
|
||||
pg_get_indexdef_partitions(indexrelid, idxrec, showTblSpc, &buf, dumpSchemaOnly, showSubpartitionLocal);
|
||||
pg_get_indexdef_partitions(indexrelid, idxrec, showTblSpc, &buf, dumpSchemaOnly,
|
||||
showPartitionLocal, showSubpartitionLocal);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@ static Datum text_length_huge(Datum str)
|
|||
*/
|
||||
Datum textlen(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Datum str = PG_GETARG_DATUM(0);
|
||||
Datum str = fetch_real_lob_if_need(PG_GETARG_DATUM(0));
|
||||
|
||||
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)DatumGetTextPP(str))) {
|
||||
return text_length_huge(str);
|
||||
|
|
@ -1899,7 +1899,7 @@ Datum textne(PG_FUNCTION_ARGS)
|
|||
{
|
||||
Datum arg1 = PG_GETARG_DATUM(0);
|
||||
Datum arg2 = PG_GETARG_DATUM(1);
|
||||
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1)) || VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg2))) {
|
||||
if (VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg1)) && VARATT_IS_HUGE_TOAST_POINTER(DatumGetPointer(arg2))) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("textne could not support more than 1GB clob/blob data")));
|
||||
}
|
||||
|
|
@ -2063,7 +2063,7 @@ Datum text_ge(PG_FUNCTION_ARGS)
|
|||
{
|
||||
text* arg1 = PG_GETARG_TEXT_PP(0);
|
||||
text* arg2 = PG_GETARG_TEXT_PP(1);
|
||||
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) || VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
|
||||
if (VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg1) && VARATT_IS_HUGE_TOAST_POINTER((varlena *)arg2)) {
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("text_ge could not support more than 1GB clob/blob data")));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ void LocalPartDefCache::Init()
|
|||
}
|
||||
m_global_partdefcache = t_thrd.lsc_cxt.lsc->GetGlobalPartDefCache();
|
||||
m_db_id = t_thrd.lsc_cxt.lsc->my_database_id;
|
||||
part_cache_need_eoxact_work = false;
|
||||
PartCacheNeedEOXActWork = false;
|
||||
m_is_inited = true;
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +298,7 @@ void LocalPartDefCache::AtEOXact_PartitionCache(bool isCommit)
|
|||
* transaction, even though we could clear it at subtransaction end in
|
||||
* some cases.
|
||||
*/
|
||||
if (!part_cache_need_eoxact_work
|
||||
if (!GetPartCacheNeedEOXActWork()
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
&& !assert_enabled
|
||||
#endif
|
||||
|
|
@ -356,7 +356,7 @@ void LocalPartDefCache::AtEOXact_PartitionCache(bool isCommit)
|
|||
}
|
||||
|
||||
/* Once done with the transaction, we can reset need_eoxact_work */
|
||||
part_cache_need_eoxact_work = false;
|
||||
SetPartCacheNeedEOXActWork(false);
|
||||
}
|
||||
|
||||
void LocalPartDefCache::AtEOSubXact_PartitionCache(bool isCommit, SubTransactionId mySubid,
|
||||
|
|
@ -366,7 +366,7 @@ void LocalPartDefCache::AtEOSubXact_PartitionCache(bool isCommit, SubTransaction
|
|||
* Skip the relcache scan if nothing to do --- see notes for
|
||||
* AtEOXact_PartitionCache.
|
||||
*/
|
||||
if (!part_cache_need_eoxact_work)
|
||||
if (!GetPartCacheNeedEOXActWork())
|
||||
return;
|
||||
|
||||
Dlelem *bucket_elt;
|
||||
|
|
|
|||
|
|
@ -432,7 +432,6 @@ Size *GetSizeVfdCachePtr()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int GetVfdNfile()
|
||||
{
|
||||
if (EnableLocalSysCache()) {
|
||||
|
|
@ -524,19 +523,49 @@ bool LocalSysDBCache::LocalSysDBCacheNeedClearMyDB(Oid db_id, const char *db_nam
|
|||
strcmp(t_thrd.proc_cxt.MyProgName, "BootStrap") == 0
|
||||
));
|
||||
}
|
||||
/* it is a weird design that we need access mydatabaseid before initsession.
|
||||
* but for GSC mode, we do need aquire lock when cache hit and there are invalid msgs
|
||||
* with session uninited and so u_sess->proc_cxt.MyDatabaseId is InvalidOid.
|
||||
* 1 the publication feature will send all rels' invalmsgs even no refered ddl.
|
||||
* 2 relations may have refcount leak, so we must rebuild them if cache hit.
|
||||
* when we rebuild a relation, the session may be not uninited,
|
||||
* and so u_sess->proc_cxt.MyDatabaseId is InvalidOid,
|
||||
* so we use t_thrd.lsc_cxt.lsc->my_database_id on GSC mode */
|
||||
Assert(CheckMyDatabaseMatch());
|
||||
Assert(m_global_db != NULL);
|
||||
/* if u_sess->proc_cxt.MyDatabaseId is InvalidOid, the session's status is uninit
|
||||
* we will call SetDatabase to rewrite it.
|
||||
* but beofre SetDatabase, we need the dbid to Accept Invalid msg */
|
||||
bool lock_db_advance = u_sess->proc_cxt.MyDatabaseId == InvalidOid && IS_THREAD_POOL_WORKER;
|
||||
|
||||
/* cache hit, when initsession, we lock db to avoid alter db */
|
||||
Oid old_db_id = t_thrd.proc->databaseId;
|
||||
if (u_sess->proc_cxt.MyDatabaseId == InvalidOid && IS_THREAD_POOL_WORKER) {
|
||||
LockSharedObject(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
|
||||
if (lock_db_advance) {
|
||||
Assert(u_sess->proc_cxt.MyDatabaseTableSpace == InvalidOid);
|
||||
Assert(u_sess->proc_cxt.DatabasePath == NULL);
|
||||
Assert(t_thrd.proc->databaseId == InvalidOid);
|
||||
|
||||
u_sess->proc_cxt.MyDatabaseId = my_database_id;
|
||||
u_sess->proc_cxt.MyDatabaseTableSpace = my_database_tablespace;
|
||||
/* use refer not copy, it will be rewritten when initsession */
|
||||
u_sess->proc_cxt.DatabasePath = my_database_path;
|
||||
|
||||
/* we dont want to accept inval msg here, so use LockSharedObjectForSession to avoid it. */
|
||||
LockSharedObjectForSession(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
|
||||
t_thrd.proc->databaseId = my_database_id;
|
||||
UnlockSharedObject(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
|
||||
}
|
||||
Assert(m_global_db != NULL);
|
||||
if (m_global_db->m_isDead) {
|
||||
t_thrd.proc->databaseId = old_db_id;
|
||||
UnlockSharedObjectForSession(DatabaseRelationId, my_database_id, 0, RowExclusiveLock);
|
||||
|
||||
/* when we acquired the dblock, alter db transaction happened, and we should clear cache of mydb. */
|
||||
if (m_global_db->m_isDead) {
|
||||
t_thrd.proc->databaseId = InvalidOid;
|
||||
u_sess->proc_cxt.MyDatabaseId = InvalidOid;
|
||||
u_sess->proc_cxt.MyDatabaseTableSpace = InvalidOid;
|
||||
u_sess->proc_cxt.DatabasePath = NULL;
|
||||
return true;
|
||||
}
|
||||
} else if (m_global_db->m_isDead) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -564,7 +593,6 @@ void LocalSysDBCache::LocalSysDBCacheClearMyDB(Oid db_id, const char *db_name)
|
|||
MemoryContextResetAndDeleteChildren(lsc_mydb_memcxt);
|
||||
|
||||
is_inited = false;
|
||||
other_space = ((AllocSet)lsc_top_memcxt)->totalSpace + ((AllocSet)lsc_share_memcxt)->totalSpace;
|
||||
rel_index_rule_space = 0;
|
||||
}
|
||||
|
||||
|
|
@ -593,29 +621,26 @@ void LocalSysDBCache::LocalSysDBCacheReSet()
|
|||
UnRegisterRelCacheCallBack(&inval_cxt, RelfilenodeMapInvalidateCallback);
|
||||
UnRegisterSysCacheCallBack(&inval_cxt, TABLESPACEOID, InvalidateTableSpaceCacheCallback);
|
||||
|
||||
MemoryContextResetAndDeleteChildren(lsc_mydb_memcxt);
|
||||
MemoryContextResetAndDeleteChildren(lsc_share_memcxt);
|
||||
MemoryContextDelete(lsc_mydb_memcxt);
|
||||
MemoryContextDelete(lsc_share_memcxt);
|
||||
lsc_share_memcxt =
|
||||
AllocSetContextCreate(lsc_top_memcxt, "LocalSysCacheShareMemoryContext", ALLOCSET_DEFAULT_MINSIZE,
|
||||
ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, STANDARD_CONTEXT);
|
||||
|
||||
lsc_mydb_memcxt =
|
||||
AllocSetContextCreate(lsc_top_memcxt, "LocalSysCacheMyDBMemoryContext", ALLOCSET_DEFAULT_MINSIZE,
|
||||
ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, STANDARD_CONTEXT);
|
||||
|
||||
MemoryContext old = MemoryContextSwitchTo(lsc_share_memcxt);
|
||||
knl_u_relmap_init(&relmap_cxt);
|
||||
MemoryContextSwitchTo(old);
|
||||
|
||||
other_space = ((AllocSet)lsc_top_memcxt)->totalSpace + ((AllocSet)lsc_share_memcxt)->totalSpace;
|
||||
rel_index_rule_space = 0;
|
||||
is_inited = false;
|
||||
is_closed = false;
|
||||
is_lsc_catbucket_created = false;
|
||||
}
|
||||
|
||||
static bool LSCMemroyOverflow(uint64 total_space)
|
||||
{
|
||||
const uint32 kb_bit_double = 10;
|
||||
if (unlikely(total_space < ((uint64)g_instance.attr.attr_memory.local_syscache_threshold << kb_bit_double))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LocalSysDBCache::LocalSysDBCacheNeedReBuild()
|
||||
{
|
||||
/* we have recovered from startup, redo may dont tell us inval msgs, so discard all lsc */
|
||||
|
|
@ -626,15 +651,21 @@ bool LocalSysDBCache::LocalSysDBCacheNeedReBuild()
|
|||
return true;
|
||||
}
|
||||
|
||||
/* it seems only fmgr_info_cxt has no resowner to avoid mem leak.
|
||||
* we assum 1kb memory leaked once */
|
||||
/* we assum 1kb memory leaked once */
|
||||
if (unlikely(abort_count > (uint64)g_instance.attr.attr_memory.local_syscache_threshold)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64 total_space = other_space + AllocSetContextUsedSpace((AllocSet)lsc_mydb_memcxt) +
|
||||
AllocSetContextUsedSpace((AllocSet)u_sess->cache_mem_cxt) + rel_index_rule_space;
|
||||
return LSCMemroyOverflow(total_space);
|
||||
uint64 total_space =
|
||||
((AllocSet)lsc_top_memcxt)->totalSpace +
|
||||
((AllocSet)lsc_share_memcxt)->totalSpace +
|
||||
((AllocSet)lsc_mydb_memcxt)->totalSpace +
|
||||
((AllocSet)u_sess->cache_mem_cxt)->totalSpace +
|
||||
rel_index_rule_space;
|
||||
|
||||
uint64 memory_upper_limit = ((uint64)g_instance.attr.attr_memory.local_syscache_threshold) << 10;
|
||||
|
||||
return total_space * (1 - MAX_LSC_FREESIZE_RATIO) > memory_upper_limit;
|
||||
}
|
||||
|
||||
/* rebuild cache on memcxt of mydb or share, call it only before initsyscache */
|
||||
|
|
@ -664,8 +695,23 @@ void LocalSysDBCache::LocalSysDBCacheReBuild()
|
|||
|
||||
bool LocalSysDBCache::LocalSysDBCacheNeedSwapOut()
|
||||
{
|
||||
uint64 total_space = other_space + rel_index_rule_space + ((AllocSet)lsc_mydb_memcxt)->totalSpace;
|
||||
return LSCMemroyOverflow(total_space);
|
||||
uint64 used_space =
|
||||
AllocSetContextUsedSpace((AllocSet)lsc_top_memcxt) +
|
||||
AllocSetContextUsedSpace((AllocSet)lsc_share_memcxt) +
|
||||
AllocSetContextUsedSpace((AllocSet)lsc_mydb_memcxt) +
|
||||
AllocSetContextUsedSpace((AllocSet)u_sess->cache_mem_cxt) +
|
||||
rel_index_rule_space;
|
||||
uint64 memory_upper_limit =
|
||||
(((uint64)g_instance.attr.attr_memory.local_syscache_threshold) << 10) * cur_swapout_ratio;
|
||||
bool need_swapout = used_space > memory_upper_limit;
|
||||
|
||||
/* swapout until memory used space is from MAX_LSC_SWAPOUT_RATIO=90% to MIN_LSC_SWAPOUT_RATIO=70% */
|
||||
if (unlikely(need_swapout && cur_swapout_ratio == MAX_LSC_SWAPOUT_RATIO)) {
|
||||
cur_swapout_ratio = MIN_LSC_SWAPOUT_RATIO;
|
||||
} else if (unlikely(!need_swapout && cur_swapout_ratio == MIN_LSC_SWAPOUT_RATIO)) {
|
||||
cur_swapout_ratio = MAX_LSC_SWAPOUT_RATIO;
|
||||
}
|
||||
return need_swapout;
|
||||
}
|
||||
|
||||
void LocalSysDBCache::CloseLocalSysDBCache()
|
||||
|
|
@ -688,7 +734,6 @@ void LocalSysDBCache::ClearSysCacheIfNecessary(Oid db_id, const char *db_name)
|
|||
if (unlikely(!is_inited)) {
|
||||
return;
|
||||
}
|
||||
other_space = ((AllocSet)lsc_top_memcxt)->totalSpace + ((AllocSet)lsc_share_memcxt)->totalSpace;
|
||||
/* rebuild if memory gt double of threshold */
|
||||
if (unlikely(LocalSysDBCacheNeedReBuild())) {
|
||||
recovery_finished = g_instance.global_sysdbcache.recovery_finished;
|
||||
|
|
@ -740,7 +785,6 @@ void LocalSysDBCache::CreateDBObject()
|
|||
knl_u_relmap_init(&relmap_cxt);
|
||||
MemoryContextSwitchTo(old);
|
||||
m_shared_global_db = g_instance.global_sysdbcache.GetSharedGSCEntry();
|
||||
other_space = ((AllocSet)lsc_top_memcxt)->totalSpace + ((AllocSet)lsc_share_memcxt)->totalSpace;
|
||||
rel_index_rule_space = 0;
|
||||
is_lsc_catbucket_created = false;
|
||||
}
|
||||
|
|
@ -753,9 +797,9 @@ void LocalSysDBCache::CreateCatBucket()
|
|||
MemoryContext old = MemoryContextSwitchTo(lsc_share_memcxt);
|
||||
systabcache.CreateCatBuckets();
|
||||
MemoryContextSwitchTo(old);
|
||||
other_space = ((AllocSet)lsc_top_memcxt)->totalSpace + ((AllocSet)lsc_share_memcxt)->totalSpace;
|
||||
rel_index_rule_space = 0;
|
||||
is_lsc_catbucket_created = true;
|
||||
cur_swapout_ratio = MAX_LSC_SWAPOUT_RATIO;
|
||||
}
|
||||
|
||||
void LocalSysDBCache::SetDatabaseName(const char *db_name)
|
||||
|
|
@ -924,6 +968,8 @@ LocalSysDBCache::LocalSysDBCache()
|
|||
got_pool_reload = false;
|
||||
m_shared_global_db = NULL;
|
||||
|
||||
cur_swapout_ratio = MAX_LSC_SWAPOUT_RATIO;
|
||||
|
||||
is_lsc_catbucket_created = false;
|
||||
is_closed = false;
|
||||
is_inited = false;
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ void LocalSysTupCache::InitPhase2Impl()
|
|||
{
|
||||
Assert(m_is_inited);
|
||||
Assert(!m_is_inited_phase2);
|
||||
Assert(m_db_id == InvalidOid);
|
||||
/* CacheIdGetGlobalSysTupCache maybe fail when memory fault */
|
||||
Assert(m_global_systupcache == NULL);
|
||||
/* for now we even dont know which db to connect */
|
||||
if (m_relinfo.cc_relisshared) {
|
||||
|
|
@ -509,7 +509,7 @@ LocalCatCTup *LocalSysTupCache::SearchTupleInternal(int nkeys, Datum v1, Datum v
|
|||
/* if not found, search from global cache */
|
||||
if (unlikely(!found)) {
|
||||
ct = SearchTupleFromGlobal(arguments, hash_value, hash_index, level);
|
||||
if (ct == NULL) {
|
||||
if (unlikely(ct == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -529,8 +529,10 @@ LocalCatCTup *LocalSysTupCache::SearchTupleInternal(int nkeys, Datum v1, Datum v
|
|||
cc_neg_hits++;
|
||||
ct = NULL;
|
||||
}
|
||||
if (unlikely(!found)) {
|
||||
RemoveTailTupleElements(hash_index);
|
||||
}
|
||||
|
||||
RemoveTailTupleElements(hash_index);
|
||||
return ct;
|
||||
}
|
||||
|
||||
|
|
@ -665,15 +667,16 @@ LocalCatCList *LocalSysTupCache::SearchListInternal(int nkeys, Datum v1, Datum v
|
|||
CACHE2_elog(DEBUG2, "SearchLocalCatCacheList(%s): found list", m_relinfo.cc_relname);
|
||||
cc_lhits++;
|
||||
found = true;
|
||||
ResourceOwnerRememberLocalCatCList(LOCAL_SYSDB_RESOWNER, cl);
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(!found)) {
|
||||
cl = SearchListFromGlobal(nkeys, arguments, hash_value, level);
|
||||
ResourceOwnerRememberLocalCatCList(LOCAL_SYSDB_RESOWNER, cl);
|
||||
RemoveTailListElements();
|
||||
}
|
||||
ResourceOwnerRememberLocalCatCList(LOCAL_SYSDB_RESOWNER, cl);
|
||||
|
||||
RemoveTailListElements();
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
|
@ -817,12 +820,14 @@ LocalCatCTup *LocalSysTupCache::SearchLocalCatCTupleForProcAllArgs(
|
|||
*/
|
||||
if (likely(ct->global_ct != NULL)) {
|
||||
CACHE3_elog(DEBUG2, "SearchLocalCatCache(%s): found in bucket %d", m_relinfo.cc_relname, hash_index);
|
||||
ResourceOwnerEnlargeLocalCatCTup(LOCAL_SYSDB_RESOWNER);
|
||||
ct->refcount++;
|
||||
cc_hits++;
|
||||
ResourceOwnerRememberLocalCatCTup(LOCAL_SYSDB_RESOWNER, ct);
|
||||
}
|
||||
|
||||
RemoveTailTupleElements(hash_index);
|
||||
if (unlikely(!found)) {
|
||||
RemoveTailTupleElements(hash_index);
|
||||
}
|
||||
|
||||
pfree_ext(argModes);
|
||||
return ct;
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ void LocalTabDefCache::Init()
|
|||
|
||||
relcacheInvalsReceived = 0;
|
||||
initFileRelationIds = NIL;
|
||||
need_eoxact_work = false;
|
||||
RelCacheNeedEOXActWork = false;
|
||||
|
||||
g_bucketmap_cache = NIL;
|
||||
max_bucket_map_size = BUCKET_MAP_SIZE;
|
||||
|
|
@ -816,8 +816,9 @@ void LocalTabDefCache::RememberToFreeTupleDescAtEOX(TupleDesc td)
|
|||
{
|
||||
if (EOXactTupleDescArray == NULL) {
|
||||
MemoryContext oldcxt = MemoryContextSwitchTo(LocalMyDBCacheMemCxt());
|
||||
EOXactTupleDescArrayLen = 16;
|
||||
EOXactTupleDescArray = (TupleDesc *)palloc(EOXactTupleDescArrayLen * sizeof(TupleDesc));
|
||||
const int default_len = 16;
|
||||
EOXactTupleDescArray = (TupleDesc *)palloc(default_len * sizeof(TupleDesc));
|
||||
EOXactTupleDescArrayLen = default_len;
|
||||
NextEOXactTupleDescNum = 0;
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
} else if (NextEOXactTupleDescNum >= EOXactTupleDescArrayLen) {
|
||||
|
|
@ -873,7 +874,7 @@ void LocalTabDefCache::AtEOXact_RelationCache(bool isCommit)
|
|||
* transaction, even though we could clear it at subtransaction end in
|
||||
* some cases.
|
||||
*/
|
||||
if (!LocalRelCacheNeedEOXactWork()
|
||||
if (!GetRelCacheNeedEOXActWork()
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
&& !assert_enabled
|
||||
#endif
|
||||
|
|
@ -962,7 +963,7 @@ void LocalTabDefCache::AtEOXact_RelationCache(bool isCommit)
|
|||
}
|
||||
}
|
||||
/* Once done with the transaction, we can reset u_sess->relcache_cxt.need_eoxact_work */
|
||||
SetLocalRelCacheNeedEOXactWork(false);
|
||||
SetRelCacheNeedEOXActWork(false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -979,7 +980,7 @@ void LocalTabDefCache::AtEOSubXact_RelationCache(bool isCommit, SubTransactionId
|
|||
* Skip the relcache scan if nothing to do --- see notes for
|
||||
* AtEOXact_RelationCache.
|
||||
*/
|
||||
if (!LocalRelCacheNeedEOXactWork())
|
||||
if (!GetRelCacheNeedEOXActWork())
|
||||
return;
|
||||
|
||||
Dlelem *bucket_elt;
|
||||
|
|
@ -1117,7 +1118,7 @@ void LocalTabDefCache::ResetInitFlag()
|
|||
|
||||
relcacheInvalsReceived = 0;
|
||||
initFileRelationIds = NIL;
|
||||
need_eoxact_work = false;
|
||||
RelCacheNeedEOXActWork = false;
|
||||
|
||||
g_bucketmap_cache = NIL;
|
||||
max_bucket_map_size = 0;
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ Partition PartitionBuildLocalPartition(const char *relname, Oid partid, Oid part
|
|||
part->pd_newRelfilenodeSubid = InvalidSubTransactionId;
|
||||
|
||||
/* must flag that we have rels created in this transaction */
|
||||
SetPartCacheNeedEoxactWork(true);
|
||||
SetPartCacheNeedEOXActWork(true);
|
||||
|
||||
/*
|
||||
* initialize partition tuple form (caller may add/override data later)
|
||||
|
|
@ -986,7 +986,7 @@ void AtEOXact_PartitionCache(bool isCommit)
|
|||
* transaction, even though we could clear it at subtransaction end in
|
||||
* some cases.
|
||||
*/
|
||||
if (!u_sess->cache_cxt.part_cache_need_eoxact_work
|
||||
if (!GetPartCacheNeedEOXActWork()
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
&& !assert_enabled
|
||||
#endif
|
||||
|
|
@ -1040,7 +1040,7 @@ void AtEOXact_PartitionCache(bool isCommit)
|
|||
}
|
||||
|
||||
/* Once done with the transaction, we can reset need_eoxact_work */
|
||||
u_sess->cache_cxt.part_cache_need_eoxact_work = false;
|
||||
SetPartCacheNeedEOXActWork(false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1063,7 +1063,7 @@ void AtEOSubXact_PartitionCache(bool isCommit, SubTransactionId mySubid, SubTran
|
|||
* Skip the relcache scan if nothing to do --- see notes for
|
||||
* AtEOXact_PartitionCache.
|
||||
*/
|
||||
if (!u_sess->cache_cxt.part_cache_need_eoxact_work)
|
||||
if (!GetPartCacheNeedEOXActWork())
|
||||
return;
|
||||
|
||||
hash_seq_init(&status, u_sess->cache_cxt.PartitionIdCache);
|
||||
|
|
@ -1705,7 +1705,7 @@ void PartitionSetNewRelfilenode(Relation parent, Partition part, TransactionId f
|
|||
part->pd_newRelfilenodeSubid = GetCurrentSubTransactionId();
|
||||
|
||||
/* ... and now we have eoxact cleanup work to do */
|
||||
SetPartCacheNeedEoxactWork(true);
|
||||
SetPartCacheNeedEOXActWork(true);
|
||||
}
|
||||
|
||||
static void PartitionParseRelOptions(Partition partition, HeapTuple tuple)
|
||||
|
|
|
|||
|
|
@ -2456,7 +2456,7 @@ void RelationInitPhysicalAddr(Relation relation)
|
|||
* tables and on user tables declared as additional catalog
|
||||
* tables.
|
||||
*/
|
||||
if (HistoricSnapshotActive() && RelationIsAccessibleInLogicalDecoding(relation) && IsTransactionState()) {
|
||||
if (HistoricSnapshotActive() && RelationIsAccessibleInLogicalDecoding(relation)) {
|
||||
HeapTuple phys_tuple;
|
||||
Form_pg_class physrel;
|
||||
|
||||
|
|
@ -4161,7 +4161,7 @@ void AtEOXact_RelationCache(bool isCommit)
|
|||
* transaction, even though we could clear it at subtransaction end in
|
||||
* some cases.
|
||||
*/
|
||||
if (!u_sess->relcache_cxt.need_eoxact_work
|
||||
if (!GetRelCacheNeedEOXActWork()
|
||||
#ifdef USE_ASSERT_CHECKING
|
||||
&& !assert_enabled
|
||||
#endif
|
||||
|
|
@ -4253,7 +4253,7 @@ void AtEOXact_RelationCache(bool isCommit)
|
|||
}
|
||||
|
||||
/* Once done with the transaction, we can reset u_sess->relcache_cxt.need_eoxact_work */
|
||||
u_sess->relcache_cxt.need_eoxact_work = false;
|
||||
SetRelCacheNeedEOXActWork(false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -4276,7 +4276,7 @@ void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTrans
|
|||
* Skip the relcache scan if nothing to do --- see notes for
|
||||
* AtEOXact_RelationCache.
|
||||
*/
|
||||
if (!u_sess->relcache_cxt.need_eoxact_work)
|
||||
if (!GetRelCacheNeedEOXActWork())
|
||||
return;
|
||||
|
||||
hash_seq_init(&status, u_sess->relcache_cxt.RelationIdCache);
|
||||
|
|
@ -4416,7 +4416,7 @@ Relation RelationBuildLocalRelation(const char* relname, Oid relnamespace, Tuple
|
|||
rel->rd_newRelfilenodeSubid = InvalidSubTransactionId;
|
||||
|
||||
/* must flag that we have rels created in this transaction */
|
||||
SetLocalRelCacheNeedEOXactWork(true);
|
||||
SetRelCacheNeedEOXActWork(true);
|
||||
|
||||
/*
|
||||
* create a new tuple descriptor from the one passed in. We do this
|
||||
|
|
@ -4784,7 +4784,7 @@ void RelationSetNewRelfilenode(Relation relation, TransactionId freezeXid, Multi
|
|||
*/
|
||||
relation->rd_newRelfilenodeSubid = GetCurrentSubTransactionId();
|
||||
/* ... and now we have eoxact cleanup work to do */
|
||||
SetLocalRelCacheNeedEOXactWork(true);
|
||||
SetRelCacheNeedEOXActWork(true);
|
||||
}
|
||||
|
||||
RelFileNodeBackend CreateNewRelfilenode(Relation relation, TransactionId freezeXid)
|
||||
|
|
@ -6064,7 +6064,7 @@ void RelationSetIndexList(Relation relation, List* indexIds, Oid oidIndex)
|
|||
relation->rd_pkindex = InvalidOid;
|
||||
relation->rd_indexvalid = 2; /* mark list as forced */
|
||||
/* must flag that we have a forced index list */
|
||||
SetLocalRelCacheNeedEOXactWork(true);
|
||||
SetRelCacheNeedEOXActWork(true);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -3945,6 +3945,10 @@ void getElevelAndSqlstate(int* eLevel, int* sqlState)
|
|||
*sqlState = t_thrd.log_cxt.errordata[t_thrd.log_cxt.errordata_stack_depth].sqlerrcode;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the SQL statement is truncated, this function cannot perform normal password masking.
|
||||
* maskPassword will return null if the statement does not need to be masked or any error occurs.
|
||||
*/
|
||||
char* maskPassword(const char* query_string)
|
||||
{
|
||||
char* mask_string = NULL;
|
||||
|
|
@ -4232,6 +4236,19 @@ static void inline ClearYylval(const core_YYSTYPE *yylval)
|
|||
securec_check(rc, "\0", "\0");
|
||||
}
|
||||
|
||||
static int get_reallen_of_credential(char *param)
|
||||
{
|
||||
int len = 0;
|
||||
for (int i = 0; param[i] != '\0'; i++) {
|
||||
if (param[i] == '\'') {
|
||||
len += 2;
|
||||
} else {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mask the password in statment CREATE ROLE, CREATE USER, ALTER ROLE, ALTER USER, CREATE GROUP
|
||||
* SET ROLE, CREATE DATABASE LINK, and some function
|
||||
|
|
@ -4248,7 +4265,9 @@ static char* mask_Password_internal(const char* query_string)
|
|||
bool isPassword = false;
|
||||
char* mask_string = NULL;
|
||||
/* the function list need mask */
|
||||
const char* funcs[] = {"dblink_connect", "create_credential", "pg_create_physical_replication_slot_extern"};
|
||||
const char* funcs[] = {"dblink_connect", "create_credential"};
|
||||
bool is_create_credential = false;
|
||||
bool is_create_credential_passwd = false;
|
||||
int funcNum = sizeof(funcs) / sizeof(funcs[0]);
|
||||
int position[16] = {0};
|
||||
int length[16] = {0};
|
||||
|
|
@ -4260,7 +4279,8 @@ static char* mask_Password_internal(const char* query_string)
|
|||
YYLTYPE conninfoStartPos = 0; /* connection start postion for CreateSubscriptionStmt */
|
||||
|
||||
/* the functions need to mask all contents */
|
||||
const char* funCrypt[] = {"gs_encrypt_aes128", "gs_decrypt_aes128", "gs_encrypt", "gs_decrypt"};
|
||||
const char* funCrypt[] = {"gs_encrypt_aes128", "gs_decrypt_aes128", "gs_encrypt", "gs_decrypt",
|
||||
"pg_create_physical_replication_slot_extern"};
|
||||
int funCryptNum = sizeof(funCrypt) / sizeof(funCrypt[0]);
|
||||
bool isCryptFunc = false;
|
||||
|
||||
|
|
@ -4365,10 +4385,11 @@ static char* mask_Password_internal(const char* query_string)
|
|||
if (subQueryLen < childStmtLen) {
|
||||
/* Need more space, enlarge length is (childStmtLen - subQueryLen) */
|
||||
maskStringLen += (childStmtLen - subQueryLen) + 1;
|
||||
char* maskStrNew = (char*)selfpalloc0(maskStringLen);
|
||||
char* maskStrNew = (char*)MemoryContextAllocZero(
|
||||
SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_SECURITY), maskStringLen);
|
||||
rc = memcpy_s(maskStrNew, maskStringLen, mask_string, strlen(mask_string));
|
||||
securec_check(rc, "\0", "\0");
|
||||
selfpfree(mask_string);
|
||||
pfree_ext(mask_string);
|
||||
mask_string = maskStrNew;
|
||||
}
|
||||
|
||||
|
|
@ -4409,7 +4430,18 @@ static char* mask_Password_internal(const char* query_string)
|
|||
/* Calcute the difference between origin password length and mask password length */
|
||||
position[idx] -= truncateLen;
|
||||
|
||||
length[idx] = strlen(yylval.str);
|
||||
if (!is_create_credential) {
|
||||
length[idx] = strlen(yylval.str);
|
||||
} else if (isPassword) {
|
||||
is_create_credential_passwd = true;
|
||||
length[idx] = strlen(yylval.str);
|
||||
} else {
|
||||
if (idx == 2 && !is_create_credential_passwd) {
|
||||
length[idx] = get_reallen_of_credential(yylval.str);
|
||||
} else {
|
||||
length[idx] = 0;
|
||||
}
|
||||
}
|
||||
++idx;
|
||||
|
||||
/* record the conninfo start pos, we will use it to calculate the actual length of conninfo */
|
||||
|
|
@ -4463,10 +4495,11 @@ static char* mask_Password_internal(const char* query_string)
|
|||
if (length[i] < maskLen) {
|
||||
/* need more space. */
|
||||
int plen = strlen(mask_string) + maskLen - length[i] + 1;
|
||||
char* maskStrNew = (char*)selfpalloc0(plen);
|
||||
char* maskStrNew = (char*)MemoryContextAllocZero(
|
||||
SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_SECURITY), plen);
|
||||
rc = memcpy_s(maskStrNew, plen, mask_string, strlen(mask_string));
|
||||
securec_check(rc, "\0", "\0");
|
||||
selfpfree(mask_string);
|
||||
pfree_ext(mask_string);
|
||||
mask_string = maskStrNew;
|
||||
}
|
||||
|
||||
|
|
@ -4597,6 +4630,10 @@ static char* mask_Password_internal(const char* query_string)
|
|||
/* first, check funcs[] */
|
||||
for (i = 0; i < funcNum; ++i) {
|
||||
if (pg_strcasecmp(yylval.str, funcs[i]) == 0) {
|
||||
is_create_credential = false;
|
||||
if (pg_strcasecmp(yylval.str, "create_credential") == 0) {
|
||||
is_create_credential = true;
|
||||
}
|
||||
curStmtType = 8;
|
||||
break;
|
||||
}
|
||||
|
|
@ -4962,6 +4999,7 @@ static char* mask_Password_internal(const char* query_string)
|
|||
}
|
||||
|
||||
return mask_string;
|
||||
|
||||
}
|
||||
|
||||
static void eraseSingleQuotes(char* query_string)
|
||||
|
|
|
|||
|
|
@ -59,12 +59,13 @@ bool open_join_children = true;
|
|||
bool will_shutdown = false;
|
||||
|
||||
/* hard-wired binary version number */
|
||||
const uint32 GRAND_VERSION_NUM = 92604;
|
||||
const uint32 GRAND_VERSION_NUM = 92605;
|
||||
|
||||
const uint32 PREDPUSH_SAME_LEVEL_VERSION_NUM = 92522;
|
||||
const uint32 UPSERT_WHERE_VERSION_NUM = 92514;
|
||||
const uint32 FUNC_PARAM_COL_VERSION_NUM = 92500;
|
||||
const uint32 SUBPARTITION_VERSION_NUM = 92436;
|
||||
const uint32 PBESINGLEPARTITION_VERSION_NUM = 92523;
|
||||
const uint32 DEFAULT_MAT_CTE_NUM = 92429;
|
||||
const uint32 MATERIALIZED_CTE_NUM = 92424;
|
||||
const uint32 HINT_ENHANCEMENT_VERSION_NUM = 92359;
|
||||
|
|
@ -113,6 +114,8 @@ const uint32 SUPPORT_HASH_XLOG_VERSION_NUM = 92603;
|
|||
/* This variable indicates wheather the instance is in progress of upgrade as a whole */
|
||||
uint32 volatile WorkingGrandVersionNum = GRAND_VERSION_NUM;
|
||||
|
||||
const uint32 INVALID_INVISIBLE_TUPLE_VERSION = 92605;
|
||||
|
||||
const uint32 ENHANCED_TUPLE_LOCK_VERSION_NUM = 92583;
|
||||
|
||||
const uint32 TWOPHASE_FILE_VERSION = 92414;
|
||||
|
|
@ -129,6 +132,8 @@ bool InplaceUpgradePrecommit = false;
|
|||
|
||||
const uint32 DISASTER_READ_VERSION_NUM = 92592;
|
||||
|
||||
const uint32 PITR_INIT_VERSION_NUM = 92599;
|
||||
|
||||
#ifdef PGXC
|
||||
bool useLocalXid = false;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
#include "storage/ipc.h"
|
||||
#include "storage/smgr/knl_usync.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "storage/predicate.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/procsignal.h"
|
||||
|
|
@ -2031,7 +2032,6 @@ void PostgresInitializer::InitThread()
|
|||
on_shmem_exit(ShutdownXLOG, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PostgresInitializer::InitLoadLocalSysCache(Oid db_oid, const char *db_name)
|
||||
{
|
||||
if(!EnableLocalSysCache()) {
|
||||
|
|
@ -2068,6 +2068,11 @@ void PostgresInitializer::InitLoadLocalSysCache(Oid db_oid, const char *db_name)
|
|||
ResourceOwnerRelease(t_thrd.lsc_cxt.lsc->local_sysdb_resowner, RESOURCE_RELEASE_LOCKS, false, true);
|
||||
ResourceOwnerRelease(t_thrd.lsc_cxt.lsc->local_sysdb_resowner, RESOURCE_RELEASE_AFTER_LOCKS, false, true);
|
||||
|
||||
/* we are not in transaction, so resowner cannot help us release proclocks and predicatelocks.
|
||||
* we do nothing above except init and load syscache, so no undowork need. ProcReleaseLocks always need
|
||||
* */
|
||||
ProcReleaseLocks(false);
|
||||
ReleasePredicateLocks(false);
|
||||
/* lwlocks arre released at sigsetjmp */
|
||||
|
||||
/* recovery CurrentResourceOwner */
|
||||
|
|
@ -2590,8 +2595,9 @@ void PostgresInitializer::SetDatabasePath()
|
|||
|
||||
ValidatePgVersion(m_fullpath);
|
||||
|
||||
/* This should happen only once per process */
|
||||
Assert(!u_sess->proc_cxt.DatabasePath);
|
||||
/* This should happen only once per process, for gsc, it may equal the pointer belongs to lsc */
|
||||
Assert(!u_sess->proc_cxt.DatabasePath ||
|
||||
(EnableLocalSysCache() && u_sess->proc_cxt.DatabasePath == t_thrd.lsc_cxt.lsc->my_database_path));
|
||||
u_sess->proc_cxt.DatabasePath = MemoryContextStrdup(
|
||||
SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_EXECUTOR), m_fullpath);
|
||||
if (EnableLocalSysCache()) {
|
||||
|
|
|
|||
|
|
@ -829,10 +829,6 @@ int pg_mbstrlen_with_len_toast(const char* mbstr, int* limit)
|
|||
{
|
||||
int len = 0;
|
||||
|
||||
/* optimization for single byte encoding */
|
||||
if (pg_database_encoding_max_length() == 1) {
|
||||
return *limit;
|
||||
}
|
||||
while (*limit > 0 && *mbstr) {
|
||||
int l = pg_mblen(mbstr);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,15 +26,6 @@
|
|||
#include "utils/oidrbtree.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
MemoryContext GetOidRBTreeMemory()
|
||||
{
|
||||
if (!t_thrd.security_policy_cxt.OidRBTreeMemoryContext) {
|
||||
t_thrd.security_policy_cxt.OidRBTreeMemoryContext = AllocSetContextCreate(TopMemoryContext, "OidRBTreeMemory",
|
||||
ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE);
|
||||
}
|
||||
return t_thrd.security_policy_cxt.OidRBTreeMemoryContext;
|
||||
}
|
||||
|
||||
void DeleteOidRBTreeMemory()
|
||||
{
|
||||
if (t_thrd.security_policy_cxt.OidRBTreeMemoryContext != NULL) {
|
||||
|
|
@ -72,9 +63,7 @@ static void OidRBCombine(RBNode* existing, const RBNode* newdata, void* arg)
|
|||
/* Allocator function for oid rbtree */
|
||||
static RBNode* OidRBAlloc(void* arg)
|
||||
{
|
||||
MemoryContext oldContext = MemoryContextSwitchTo(GetOidRBTreeMemory());
|
||||
OidRBNode* oidRBNode = static_cast<OidRBNode*>(palloc(sizeof(OidRBNode)));
|
||||
(void)MemoryContextSwitchTo(oldContext);
|
||||
return (RBNode*)oidRBNode;
|
||||
}
|
||||
|
||||
|
|
@ -87,9 +76,7 @@ static void OidRBDealloc(RBNode* rbNode, void* arg)
|
|||
|
||||
OidRBTree* CreateOidRBTree()
|
||||
{
|
||||
MemoryContext oldContext = MemoryContextSwitchTo(GetOidRBTreeMemory());
|
||||
OidRBTree* oidRBTree = rb_create(sizeof(OidRBNode), OidRBComparator, OidRBCombine, OidRBAlloc, OidRBDealloc, NULL);
|
||||
(void)MemoryContextSwitchTo(oldContext);
|
||||
return oidRBTree;
|
||||
}
|
||||
|
||||
|
|
@ -97,14 +84,12 @@ static List* OidRBTreeGetNodeList(OidRBTree& oidRBtree)
|
|||
{
|
||||
List* nodeList = NIL;
|
||||
OidRBTree* tree = &oidRBtree;
|
||||
MemoryContext oldContext = MemoryContextSwitchTo(GetOidRBTreeMemory());
|
||||
rb_begin_iterate(tree, InvertedWalk);
|
||||
RBNode *node = rb_iterate(tree);
|
||||
while (node != NULL) {
|
||||
nodeList = lappend(nodeList, node);
|
||||
node = rb_iterate(tree);
|
||||
}
|
||||
(void)MemoryContextSwitchTo(oldContext);
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,9 @@
|
|||
#include "catalog/pg_hashbucket_fn.h"
|
||||
|
||||
/*
|
||||
* ResourceOwner objects look like this
|
||||
* ResourceOwner objects look like this. When tracking new types of resource,
|
||||
* you must at least add the 'Remember' interface for that resource and adapt
|
||||
* the 'ResourceOwnerConcat' function.
|
||||
*/
|
||||
typedef struct ResourceOwnerData {
|
||||
ResourceOwner parent; /* NULL if no parent (toplevel owner) */
|
||||
|
|
@ -542,6 +544,174 @@ void ResourceOwnerDelete(ResourceOwner owner)
|
|||
ResourceOwnerFreeOwner(owner, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* Part 1 of 'ResourceOwnerConcat'. Concatenate the top 12 resources of two owners.
|
||||
*/
|
||||
static void ResourceOwnerConcatPart1(ResourceOwner target, ResourceOwner source)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < source->nbuffers; i++) {
|
||||
ResourceOwnerEnlargeBuffers(target);
|
||||
ResourceOwnerRememberBuffer(target, source->buffers[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nlocalcatclist; i++) {
|
||||
ResourceOwnerEnlargeLocalCatCList(target);
|
||||
ResourceOwnerRememberLocalCatCList(target, source->localcatclists[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nlocalcatctup; i++) {
|
||||
ResourceOwnerEnlargeLocalCatCTup(target);
|
||||
ResourceOwnerRememberLocalCatCTup(target, source->localcatctups[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nglobalcatctup; i++) {
|
||||
ResourceOwnerEnlargeGlobalCatCTup(target);
|
||||
ResourceOwnerRememberGlobalCatCTup(target, source->globalcatctups[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nglobalcatclist; i++) {
|
||||
ResourceOwnerEnlargeGlobalCatCList(target);
|
||||
ResourceOwnerRememberGlobalCatCList(target, source->globalcatclists[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nglobalbaseentry; i++) {
|
||||
ResourceOwnerEnlargeGlobalBaseEntry(target);
|
||||
ResourceOwnerRememberGlobalBaseEntry(target, source->globalbaseentries[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nglobaldbentry; i++) {
|
||||
ResourceOwnerEnlargeGlobalDBEntry(target);
|
||||
ResourceOwnerRememberGlobalDBEntry(target, source->globaldbentries[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nglobalisexclusive; i++) {
|
||||
ResourceOwnerEnlargeGlobalIsExclusive(target);
|
||||
ResourceOwnerRememberGlobalIsExclusive(target, source->globalisexclusives[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->ncatrefs; i++) {
|
||||
ResourceOwnerEnlargeCatCacheRefs(target);
|
||||
ResourceOwnerRememberCatCacheRef(target, source->catrefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->ncatlistrefs; i++) {
|
||||
ResourceOwnerEnlargeCatCacheListRefs(target);
|
||||
ResourceOwnerRememberCatCacheListRef(target, source->catlistrefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nrelrefs; i++) {
|
||||
ResourceOwnerEnlargeRelationRefs(target);
|
||||
ResourceOwnerRememberRelationRef(target, source->relrefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->npartrefs; i++) {
|
||||
ResourceOwnerEnlargePartitionRefs(target);
|
||||
ResourceOwnerRememberPartitionRef(target, source->partrefs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Part 2 of 'ResourceOwnerConcat'. Concatenate the remaining resources of two owners.
|
||||
*/
|
||||
static void ResourceOwnerConcatPart2(ResourceOwner target, ResourceOwner source)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < source->nfakerelrefs; i++) {
|
||||
dlist_push_tail(&(target->fakerelrefs_list), dlist_pop_head_node(&(source->fakerelrefs_list)));
|
||||
target->nfakerelrefs++;
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nfakepartrefs; i++) {
|
||||
ResourceOwnerEnlargeFakepartRefs(target);
|
||||
ResourceOwnerRememberFakepartRef(target, source->fakepartrefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nplanrefs; i++) {
|
||||
ResourceOwnerEnlargePlanCacheRefs(target);
|
||||
ResourceOwnerRememberPlanCacheRef(target, source->planrefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->ntupdescs; i++) {
|
||||
ResourceOwnerEnlargeTupleDescs(target);
|
||||
ResourceOwnerRememberTupleDesc(target, source->tupdescs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nsnapshots; i++) {
|
||||
ResourceOwnerEnlargeSnapshots(target);
|
||||
ResourceOwnerRememberSnapshot(target, source->snapshots[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nfiles; i++) {
|
||||
ResourceOwnerEnlargeFiles(target);
|
||||
ResourceOwnerRememberFile(target, source->files[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nDataCacheSlots; i++) {
|
||||
ResourceOwnerEnlargeDataCacheSlot(target);
|
||||
ResourceOwnerRememberDataCacheSlot(target, source->dataCacheSlots[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nMetaCacheSlots; i++) {
|
||||
ResourceOwnerEnlargeMetaCacheSlot(target);
|
||||
ResourceOwnerRememberMetaCacheSlot(target, source->metaCacheSlots[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nPthreadMutex; i++) {
|
||||
ResourceOwnerEnlargePthreadMutex(target);
|
||||
ResourceOwnerRememberPthreadMutex(target, source->pThdMutexs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nPthreadRWlock; i++) {
|
||||
ResourceOwnerEnlargePthreadRWlock(target);
|
||||
ResourceOwnerRememberPthreadRWlock(target, source->pThdRWlocks[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->npartmaprefs; i++) {
|
||||
ResourceOwnerEnlargePartitionMapRefs(target);
|
||||
ResourceOwnerRememberPartitionMapRef(target, source->partmaprefs[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < source->nglobalMemContext; i++) {
|
||||
ResourceOwnerEnlargeGMemContext(target);
|
||||
ResourceOwnerRememberGMemContext(target, source->globalMemContexts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ResourceOwnerConcat
|
||||
* Concatenate two owners.
|
||||
*
|
||||
* The resources traced by the 'source' are placed in the 'target' for tracing.
|
||||
* The advantage is that the memory occupied by the 'source' owner can be released
|
||||
* to reduce the memory consumed by tracing resources. When using a stream-plan,
|
||||
* this is useful for preventing "memory is temporarily unavailable" error when
|
||||
* executing a large number of SQLs in a single transaction/procedure.
|
||||
*
|
||||
* Note: After the invoking is complete, the memory of the 'source' should be release.
|
||||
*/
|
||||
void ResourceOwnerConcat(ResourceOwner target, ResourceOwner source)
|
||||
{
|
||||
Assert(target && source);
|
||||
/*
|
||||
* When modifying the structure of ResourceOwnerData, note that the ResourceOwnerConcat
|
||||
* function needs to be adapted when tracing new types of resources.
|
||||
*/
|
||||
Assert(sizeof(ResourceOwnerData) == 448); /* The current size of ResourceOwnerData is 448 */
|
||||
|
||||
while (source->firstchild != NULL) {
|
||||
ResourceOwnerConcat(target, source->firstchild);
|
||||
}
|
||||
|
||||
/*
|
||||
* ResourceOwner traces too many resources. To reduce cyclomatic complexity,
|
||||
* the Concatenate operation is divided into two parts.
|
||||
*/
|
||||
ResourceOwnerConcatPart1(target, source);
|
||||
ResourceOwnerConcatPart2(target, source);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch parent of a ResourceOwner (returns NULL if top-level owner)
|
||||
*/
|
||||
|
|
@ -575,6 +745,14 @@ ResourceOwner ResourceOwnerGetFirstChild(ResourceOwner owner)
|
|||
return owner->firstchild;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch memory context of a ResourceOwner
|
||||
*/
|
||||
MemoryContext ResourceOwnerGetMemCxt(ResourceOwner owner)
|
||||
{
|
||||
return owner->memCxt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reassign a ResourceOwner to have a new parent
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2958,11 +2958,18 @@ for_control : for_variable K_IN
|
|||
if ($1.rec)
|
||||
{
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && IMPLICIT_FOR_LOOP_VARIABLE) {
|
||||
/* only A format and not in upgrade, IMPLICIT_FOR_LOOP_VARIABLE is valid */
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT
|
||||
&& IMPLICIT_FOR_LOOP_VARIABLE
|
||||
&& u_sess->attr.attr_common.upgrade_mode == 0) {
|
||||
BuildForQueryVariable(expr1, &newp->row, &newp->rec, $1.name, $1.lineno);
|
||||
check_assignable((PLpgSQL_datum *)newp->rec ?
|
||||
(PLpgSQL_datum *)newp->rec : (PLpgSQL_datum *)newp->row, @1);
|
||||
} else {
|
||||
/* check the sql */
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && ALLOW_PROCEDURE_COMPILE_CHECK) {
|
||||
(void)getCursorTupleDesc(expr1, false, true);
|
||||
}
|
||||
newp->rec = $1.rec;
|
||||
check_assignable((PLpgSQL_datum *) newp->rec, @1);
|
||||
}
|
||||
|
|
@ -2974,11 +2981,18 @@ for_control : for_variable K_IN
|
|||
else if ($1.row)
|
||||
{
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && IMPLICIT_FOR_LOOP_VARIABLE) {
|
||||
/* only A format and not in upgrade, IMPLICIT_FOR_LOOP_VARIABLE is valid */
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT
|
||||
&& IMPLICIT_FOR_LOOP_VARIABLE
|
||||
&& u_sess->attr.attr_common.upgrade_mode == 0) {
|
||||
BuildForQueryVariable(expr1, &newp->row, &newp->rec, $1.name, $1.lineno);
|
||||
check_assignable((PLpgSQL_datum *)newp->rec ?
|
||||
(PLpgSQL_datum *)newp->rec : (PLpgSQL_datum *)newp->row, @1);
|
||||
} else {
|
||||
/* check the sql */
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && ALLOW_PROCEDURE_COMPILE_CHECK) {
|
||||
(void)getCursorTupleDesc(expr1, false, true);
|
||||
}
|
||||
newp->row = $1.row;
|
||||
check_assignable((PLpgSQL_datum *) newp->row, @1);
|
||||
}
|
||||
|
|
@ -2990,11 +3004,18 @@ for_control : for_variable K_IN
|
|||
else if ($1.scalar)
|
||||
{
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && IMPLICIT_FOR_LOOP_VARIABLE) {
|
||||
/* only A format and not in upgrade, IMPLICIT_FOR_LOOP_VARIABLE is valid */
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT
|
||||
&& IMPLICIT_FOR_LOOP_VARIABLE
|
||||
&& u_sess->attr.attr_common.upgrade_mode == 0) {
|
||||
BuildForQueryVariable(expr1, &newp->row, &newp->rec, $1.name, $1.lineno);
|
||||
check_assignable((PLpgSQL_datum *)newp->rec ?
|
||||
(PLpgSQL_datum *)newp->rec : (PLpgSQL_datum *)newp->row, @1);
|
||||
} else {
|
||||
/* check the sql */
|
||||
if (u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && ALLOW_PROCEDURE_COMPILE_CHECK) {
|
||||
(void)getCursorTupleDesc(expr1, false, true);
|
||||
}
|
||||
/* convert single scalar to list */
|
||||
newp->row = make_scalar_list1($1.name, $1.scalar, $1.dno, $1.lineno, @1);
|
||||
/* no need for check_assignable */
|
||||
|
|
@ -4342,6 +4363,7 @@ stmt_open : K_OPEN cursor_variable
|
|||
yyerror("syntax error");
|
||||
}
|
||||
}
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
if (newp->query != NULL && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && ALLOW_PROCEDURE_COMPILE_CHECK) {
|
||||
(void)getCursorTupleDesc(newp->query, false, true);
|
||||
}
|
||||
|
|
@ -4349,6 +4371,7 @@ stmt_open : K_OPEN cursor_variable
|
|||
{
|
||||
(void)getCursorTupleDesc(newp->dynquery, false, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -8773,9 +8796,11 @@ make_execsql_stmt(int firsttoken, int location)
|
|||
pfree_ext(ds.data);
|
||||
|
||||
check_sql_expr(expr->query, location, 0);
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
if (firsttoken == K_SELECT && u_sess->attr.attr_sql.sql_compatibility == A_FORMAT && ALLOW_PROCEDURE_COMPILE_CHECK) {
|
||||
(void)getCursorTupleDesc(expr, false, true);
|
||||
}
|
||||
#endif
|
||||
execsql = (PLpgSQL_stmt_execsql *)palloc(sizeof(PLpgSQL_stmt_execsql));
|
||||
execsql->cmd_type = PLPGSQL_STMT_EXECSQL;
|
||||
execsql->lineno = plpgsql_location_to_lineno(location);
|
||||
|
|
|
|||
|
|
@ -752,6 +752,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
|||
func->resolve_option = GetResolveOption();
|
||||
func->invalItems = NIL;
|
||||
func->is_autonomous = false;
|
||||
func->is_insert_gs_source = false;
|
||||
|
||||
func->pkg_oid = pkgoid;
|
||||
func->fn_searchpath->addCatalog = true;
|
||||
|
|
@ -1420,6 +1421,7 @@ PLpgSQL_function* plpgsql_compile_inline(char* proc_source)
|
|||
func->fn_retbyval = true;
|
||||
func->fn_rettyplen = sizeof(int32);
|
||||
func->is_autonomous = false;
|
||||
func->is_insert_gs_source = false;
|
||||
getTypeInputInfo(VOIDOID, &typinput, &func->fn_rettypioparam);
|
||||
fmgr_info(typinput, &(func->fn_retinput));
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ static PLpgSQL_rec* copyPLpgsqlRec(PLpgSQL_rec* src);
|
|||
static PLpgSQL_recfield* copyPLpgsqlRecfield(PLpgSQL_recfield* src);
|
||||
static List* invalid_depend_func_and_packgae(Oid pkgOid);
|
||||
static void ReportCompileConcurrentError(const char* objName, bool isPackage);
|
||||
|
||||
static Datum CopyFcinfoArgValue(Oid typOid, Datum value);
|
||||
/* ----------
|
||||
* plpgsql_check_line_validity Called by the debugger plugin for
|
||||
* validating a given linenumber
|
||||
|
|
@ -838,9 +838,7 @@ Datum plpgsql_exec_autonm_function(PLpgSQL_function* func,
|
|||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
uint64 sessionId = IS_THREAD_POOL_WORKER ? u_sess->session_id : t_thrd.proc_cxt.MyProcPid;
|
||||
/* add session package values to global for autonm session, to restore package values */
|
||||
if (OidIsValid(func->fn_oid)) {
|
||||
BuildSessionPackageRuntimeForAutoSession(sessionId, u_sess->autonomous_parent_sessionid, &estate, func);
|
||||
}
|
||||
BuildSessionPackageRuntimeForAutoSession(sessionId, u_sess->autonomous_parent_sessionid, &estate, func);
|
||||
#endif
|
||||
|
||||
/* Statement concatenation. If the block is an anonymous block, the entire anonymous block is returned. */
|
||||
|
|
@ -1011,8 +1009,7 @@ Datum plpgsql_exec_function(PLpgSQL_function* func, FunctionCallInfo fcinfo, boo
|
|||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
check_debug(func, &estate);
|
||||
bool isExecAutoFunc = OidIsValid(func->fn_oid) &&
|
||||
u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0;
|
||||
bool isExecAutoFunc = u_sess->is_autonomous_session == true && u_sess->SPI_cxt._connected == 0;
|
||||
/* when exec autonomous transaction procedure, need update package values by parent session */
|
||||
if (isExecAutoFunc) {
|
||||
initAutoSessionPkgsValue(u_sess->autonomous_parent_sessionid);
|
||||
|
|
@ -1083,12 +1080,12 @@ Datum plpgsql_exec_function(PLpgSQL_function* func, FunctionCallInfo fcinfo, boo
|
|||
while (argmodes[outArgCnt] == PROARGMODE_OUT) {
|
||||
outArgCnt++;
|
||||
}
|
||||
var->value = fcinfo->arg[outArgCnt];
|
||||
var->value = CopyFcinfoArgValue(fcinfo->argTypes[outArgCnt], fcinfo->arg[outArgCnt]);
|
||||
var->isnull = fcinfo->argnull[outArgCnt];
|
||||
var->freeval = false;
|
||||
outArgCnt++;
|
||||
} else {
|
||||
var->value = fcinfo->arg[i];
|
||||
var->value = CopyFcinfoArgValue(fcinfo->argTypes[i], fcinfo->arg[i]);
|
||||
var->isnull = fcinfo->argnull[i];
|
||||
var->freeval = false;
|
||||
}
|
||||
|
|
@ -1469,6 +1466,25 @@ Datum plpgsql_exec_function(PLpgSQL_function* func, FunctionCallInfo fcinfo, boo
|
|||
return estate.retval;
|
||||
}
|
||||
|
||||
static Datum CopyFcinfoArgValue(Oid typOid, Datum value)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
return value;
|
||||
#endif
|
||||
if (!OidIsValid(typOid)) {
|
||||
return value;
|
||||
}
|
||||
/*
|
||||
* For centralized database, package value may be in param.
|
||||
* In this case, the value should be copyed, becaues the ref
|
||||
* value may be influenced by procedure.
|
||||
*/
|
||||
bool typByVal = false;
|
||||
int16 typLen;
|
||||
get_typlenbyval(typOid, &typLen, &typByVal);
|
||||
return datumCopy(value, typByVal, typLen);
|
||||
}
|
||||
|
||||
static void RecordSetGeneratedField(PLpgSQL_rec *recNew)
|
||||
{
|
||||
int natts = recNew->tupdesc->natts;
|
||||
|
|
@ -4580,16 +4596,10 @@ static int exec_stmt_return(PLpgSQL_execstate* estate, PLpgSQL_stmt_return* stmt
|
|||
case PLPGSQL_DTYPE_VAR: {
|
||||
PLpgSQL_var* var = (PLpgSQL_var*)retvar;
|
||||
Datum value = var->value;
|
||||
if (is_external_clob(var->datatype->typoid, var->isnull, value)) {
|
||||
bool is_null = false;
|
||||
bool is_have_huge_clob = false;
|
||||
struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(value));
|
||||
value = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob);
|
||||
if (is_have_huge_clob) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as return parameter")));
|
||||
}
|
||||
if (is_huge_clob(var->datatype->typoid, var->isnull, value)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as return parameter")));
|
||||
}
|
||||
if (need_param_seperation) {
|
||||
estate->paramval = value;
|
||||
|
|
@ -5435,7 +5445,7 @@ static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* st
|
|||
bool has_alloc = false;
|
||||
|
||||
TransactionId oldTransactionId = SPI_get_top_transaction_id();
|
||||
|
||||
|
||||
/*
|
||||
* On the first call for this statement generate the plan, and detect
|
||||
* whether the statement is INSERT/UPDATE/DELETE/MERGE
|
||||
|
|
@ -5467,7 +5477,19 @@ static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* st
|
|||
if (ENABLE_CN_GPC && g_instance.plan_cache->CheckRecreateSPICachePlan(expr->plan)) {
|
||||
g_instance.plan_cache->RecreateSPICachePlan(expr->plan);
|
||||
}
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
ListCell* l = NULL;
|
||||
bool isforbid = true;
|
||||
bool savedisAllowCommitRollback = false;
|
||||
bool needResetErrMsg = false;
|
||||
foreach (l, SPI_plan_get_plan_sources(expr->plan)) {
|
||||
CachedPlanSource* plansource = (CachedPlanSource*)lfirst(l);
|
||||
isforbid = CheckElementParsetreeTag(plansource->raw_parse_tree);
|
||||
if (isforbid) {
|
||||
needResetErrMsg = stp_disable_xact_and_set_err_msg(&savedisAllowCommitRollback, STP_XACT_COMPL_SQL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Set up ParamListInfo (hook function and possibly data values)
|
||||
*/
|
||||
|
|
@ -5513,10 +5535,6 @@ static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* st
|
|||
|
||||
plpgsql_estate = estate;
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
t_thrd.xact_cxt.isSelectInto = stmt->into;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Execute the plan
|
||||
*/
|
||||
|
|
@ -5529,7 +5547,11 @@ static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* st
|
|||
// This is used for nested STP. If the transaction Id changed,
|
||||
// then need to create new econtext for the TopTransaction.
|
||||
stp_check_transaction_and_create_econtext(estate,oldTransactionId);
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
if (isforbid) {
|
||||
stp_reset_xact_state_and_err_msg(savedisAllowCommitRollback, needResetErrMsg);
|
||||
}
|
||||
#endif
|
||||
plpgsql_estate = NULL;
|
||||
|
||||
/*
|
||||
|
|
@ -5721,7 +5743,6 @@ static int exec_stmt_execsql(PLpgSQL_execstate* estate, PLpgSQL_stmt_execsql* st
|
|||
|
||||
estate->cursor_return_data = saved_cursor_data;
|
||||
estate->cursor_return_numbers = saved_cursor_numbers;
|
||||
t_thrd.xact_cxt.isSelectInto = false;
|
||||
return PLPGSQL_RC_OK;
|
||||
}
|
||||
|
||||
|
|
@ -5900,6 +5921,9 @@ static int exec_stmt_dynexecute(PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecu
|
|||
bool savedisAllowCommitRollback = false;
|
||||
bool needResetErrMsg = false;
|
||||
needResetErrMsg = stp_disable_xact_and_set_err_msg(&savedisAllowCommitRollback, STP_XACT_USED_AS_EXPR);
|
||||
#else
|
||||
/* Saves the status of whether to send commandId. */
|
||||
bool saveSetSendCommandId = IsSendCommandId();
|
||||
#endif
|
||||
/*
|
||||
* First we evaluate the string expression after the EXECUTE keyword. Its
|
||||
|
|
@ -5994,6 +6018,8 @@ static int exec_stmt_dynexecute(PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecu
|
|||
FormatCallStack* plcallstack = t_thrd.log_cxt.call_stack;
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
estate_cursor_set(plcallstack);
|
||||
#else
|
||||
SetSendCommandId(saveSetSendCommandId);
|
||||
#endif
|
||||
if (plcallstack != NULL) {
|
||||
t_thrd.log_cxt.call_stack = plcallstack->prev;
|
||||
|
|
@ -6004,6 +6030,10 @@ static int exec_stmt_dynexecute(PLpgSQL_execstate* estate, PLpgSQL_stmt_dynexecu
|
|||
}
|
||||
PG_END_TRY();
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
SetSendCommandId(saveSetSendCommandId);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is used for nested STP. If the transaction Id changed,
|
||||
* then need to create new econtext for the TopTransaction.
|
||||
|
|
@ -6485,7 +6515,10 @@ static int exec_stmt_open(PLpgSQL_execstate* estate, PLpgSQL_stmt_open* stmt)
|
|||
errmsg("cursor \"%s\" already in use in OPEN statement.", curname)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
/* In distributed mode, the commandId is sent when a cursor is opened. */
|
||||
SetSendCommandId(true);
|
||||
#endif
|
||||
/* ----------
|
||||
* Process the OPEN according to it's type.
|
||||
* ----------
|
||||
|
|
@ -7395,16 +7428,10 @@ void exec_assign_value(PLpgSQL_execstate* estate, PLpgSQL_datum* target, Datum v
|
|||
MemoryContext oldcontext = NULL;
|
||||
AttrNumber attrno = ((PLpgSQL_arrayelem*)target)->assignattrno;
|
||||
|
||||
if (is_external_clob(valtype, *isNull, value)) {
|
||||
bool is_null = false;
|
||||
bool is_have_huge_clob = false;
|
||||
struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(value));
|
||||
value = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob);
|
||||
if (is_have_huge_clob) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as array element.")));
|
||||
}
|
||||
if (is_huge_clob(valtype, *isNull, value)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as array element.")));
|
||||
}
|
||||
/*
|
||||
* We need to do subscript evaluation, which might require
|
||||
|
|
@ -7683,16 +7710,10 @@ void exec_assign_value(PLpgSQL_execstate* estate, PLpgSQL_datum* target, Datum v
|
|||
MemoryContext oldcontext = NULL;
|
||||
AttrNumber attrno = ((PLpgSQL_tableelem*)target)->assignattrno;
|
||||
|
||||
if (is_external_clob(valtype, *isNull, value)) {
|
||||
bool is_null = false;
|
||||
bool is_have_huge_clob = false;
|
||||
struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(value));
|
||||
value = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob);
|
||||
if (is_have_huge_clob) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as table of element.")));
|
||||
}
|
||||
if (is_huge_clob(valtype, *isNull, value)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as table of element.")));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -7965,17 +7986,6 @@ void exec_assign_value(PLpgSQL_execstate* estate, PLpgSQL_datum* target, Datum v
|
|||
/*
|
||||
* Target has a assign list
|
||||
*/
|
||||
if (is_external_clob(valtype, *isNull, value)) {
|
||||
bool is_null = false;
|
||||
bool is_have_huge_clob = false;
|
||||
struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(value));
|
||||
value = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob);
|
||||
if (is_have_huge_clob) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as record element.")));
|
||||
}
|
||||
}
|
||||
PLpgSQL_assignlist* assignvar = (PLpgSQL_assignlist*)target;
|
||||
List* assignlist = assignvar->assignlist;
|
||||
PLpgSQL_datum* assigntarget = estate->datums[assignvar->targetno];
|
||||
|
|
@ -9422,7 +9432,7 @@ static Datum exec_eval_expr(PLpgSQL_execstate* estate, PLpgSQL_expr* expr, bool*
|
|||
static int exec_run_select(PLpgSQL_execstate* estate, PLpgSQL_expr* expr, long maxtuples,
|
||||
Portal* portalP, bool isCollectParam)
|
||||
{
|
||||
ParamListInfo paramLI;
|
||||
ParamListInfo paramLI = NULL;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
|
|
@ -9437,8 +9447,12 @@ static int exec_run_select(PLpgSQL_execstate* estate, PLpgSQL_expr* expr, long m
|
|||
|
||||
/*
|
||||
* Set up ParamListInfo (hook function and possibly data values)
|
||||
* For validation estate->datums should be NULL, since there is
|
||||
* no parameter set vo validation
|
||||
*/
|
||||
paramLI = setup_param_list(estate, expr);
|
||||
if (estate->datums) {
|
||||
paramLI = setup_param_list(estate, expr);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a portal was requested, put the query into the portal
|
||||
|
|
@ -10646,12 +10660,6 @@ static void exec_move_row(PLpgSQL_execstate* estate,
|
|||
valtype = InvalidOid;
|
||||
}
|
||||
|
||||
if (valtype == CLOBOID && !isnull && VARATT_IS_HUGE_TOAST_POINTER(value)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support as record element.")));
|
||||
}
|
||||
|
||||
/* accept function's return value for cursor */
|
||||
if (isnull == false && CheckTypeIsCursor(row, valtype, fnum) &&
|
||||
estate->cursor_return_data != NULL) {
|
||||
|
|
@ -10773,17 +10781,10 @@ HeapTuple make_tuple_from_row(PLpgSQL_execstate* estate, PLpgSQL_row* row, Tuple
|
|||
exec_eval_datum(estate, estate->datums[row->varnos[i]], &fieldtypeid, &fieldtypmod, &dvalues[i], &nulls[i]);
|
||||
}
|
||||
|
||||
if (is_external_clob(fieldtypeid, nulls[i], dvalues[i])) {
|
||||
bool is_null = false;
|
||||
bool is_have_huge_clob = false;
|
||||
struct varatt_lob_pointer* lob_pointer = (varatt_lob_pointer*)(VARDATA_EXTERNAL(dvalues[i]));
|
||||
dvalues[i] = fetch_lob_value_from_tuple(lob_pointer, InvalidOid, &is_null, &is_have_huge_clob);
|
||||
if (is_have_huge_clob) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support concat a row")));
|
||||
}
|
||||
nulls[i] = is_null;
|
||||
if (is_huge_clob(fieldtypeid, nulls[i], dvalues[i])) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("huge clob do not support concat a row")));
|
||||
}
|
||||
|
||||
if (estate->is_exception && fieldtypeid == REFCURSOROID) {
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ static SessionPackageRuntime* CopySessionPackageRuntime(SessionPackageRuntime *r
|
|||
sessPkgRuntime->portalContext = CopyPortalContexts(runtime->portalContext);
|
||||
sessPkgRuntime->portalData = CopyPortalDatas(runtime);
|
||||
sessPkgRuntime->funcValInfo = CopyFuncInfoDatas(runtime);
|
||||
sessPkgRuntime->is_insert_gs_source = runtime->is_insert_gs_source;
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
return sessPkgRuntime;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -219,7 +219,9 @@ static void InsertGsSource(Oid objId, Oid nspid, const char* name, const char* t
|
|||
{
|
||||
(void)CompileStatusSwtichTo(NONE_STATUS);
|
||||
u_sess->plsql_cxt.curr_compile_context = NULL;
|
||||
u_sess->plsql_cxt.is_insert_gs_source = true;
|
||||
ExecuteDoStmt(stmt, true);
|
||||
u_sess->plsql_cxt.is_insert_gs_source = false;
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
|
|
@ -228,6 +230,7 @@ static void InsertGsSource(Oid objId, Oid nspid, const char* name, const char* t
|
|||
}
|
||||
(void)CompileStatusSwtichTo(save_compile_status);
|
||||
u_sess->plsql_cxt.curr_compile_context = save_compile_context;
|
||||
u_sess->plsql_cxt.is_insert_gs_source = false;
|
||||
clearCompileContextList(save_compile_list_length);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
|
|
@ -745,6 +748,8 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||
u_sess->opt_cxt.is_stream = true;
|
||||
u_sess->opt_cxt.is_stream_support = true;
|
||||
}
|
||||
/* Saves the status of whether to send commandId. */
|
||||
bool saveSetSendCommandId = IsSendCommandId();
|
||||
#else
|
||||
int outerDop = u_sess->opt_cxt.query_dop;
|
||||
u_sess->opt_cxt.query_dop = 1;
|
||||
|
|
@ -821,6 +826,7 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||
PLpgSQL_compile_context* save_compile_context = u_sess->plsql_cxt.curr_compile_context;
|
||||
int save_compile_list_length = list_length(u_sess->plsql_cxt.compile_context_list);
|
||||
int save_compile_status = u_sess->plsql_cxt.compile_status;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
/*
|
||||
|
|
@ -873,7 +879,6 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||
estate_cursor_set(plcallstack);
|
||||
|
||||
#endif
|
||||
|
||||
if (plcallstack != NULL) {
|
||||
t_thrd.log_cxt.call_stack = plcallstack->prev;
|
||||
}
|
||||
|
|
@ -970,7 +975,9 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||
if (u_sess->SPI_cxt._connected == 0) {
|
||||
t_thrd.utils_cxt.STPSavedResourceOwner = NULL;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
SetSendCommandId(saveSetSendCommandId);
|
||||
#endif
|
||||
/* ErrorData could be allocted in SPI's MemoryContext, copy it. */
|
||||
oldContext = MemoryContextSwitchTo(oldContext);
|
||||
ErrorData *edata = CopyErrorData();
|
||||
|
|
@ -992,6 +999,10 @@ Datum plpgsql_call_handler(PG_FUNCTION_ARGS)
|
|||
if (u_sess->SPI_cxt._connected == 0) {
|
||||
t_thrd.utils_cxt.STPSavedResourceOwner = NULL;
|
||||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
SetSendCommandId(saveSetSendCommandId);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Disconnect from SPI manager
|
||||
*/
|
||||
|
|
@ -1039,8 +1050,12 @@ Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
|
|||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
int outerDop = u_sess->opt_cxt.query_dop;
|
||||
u_sess->opt_cxt.query_dop = 1;
|
||||
#else
|
||||
/* Saves the status of whether to send commandId. */
|
||||
bool saveSetSendCommandId = IsSendCommandId();
|
||||
#endif
|
||||
|
||||
|
||||
_PG_init();
|
||||
|
||||
AssertEreport(IsA(codeblock, InlineCodeBlock), MOD_PLSQL, "Inline code block is required.");
|
||||
|
|
@ -1075,6 +1090,7 @@ Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
|
|||
PG_END_TRY();
|
||||
PGSTAT_END_PLSQL_TIME_RECORD(PL_COMPILATION_TIME);
|
||||
|
||||
func->is_insert_gs_source = u_sess->plsql_cxt.is_insert_gs_source;
|
||||
/* Mark packages the function use, so them can't be deleted from under us */
|
||||
AddPackageUseCount(func);
|
||||
/* Mark the function as busy, just pro forma */
|
||||
|
|
@ -1093,7 +1109,6 @@ Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
|
|||
fake_fcinfo.flinfo = &flinfo;
|
||||
flinfo.fn_oid = InvalidOid;
|
||||
flinfo.fn_mcxt = CurrentMemoryContext;
|
||||
|
||||
PGSTAT_START_PLSQL_TIME_RECORD();
|
||||
/* save flag for nest plpgsql compile */
|
||||
save_compile_context = u_sess->plsql_cxt.curr_compile_context;
|
||||
|
|
@ -1135,11 +1150,18 @@ Datum plpgsql_inline_handler(PG_FUNCTION_ARGS)
|
|||
clearCompileContextList(save_compile_list_length);
|
||||
/* AutonomousSession Disconnecting and releasing resources */
|
||||
DestoryAutonomousSession(true);
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
SetSendCommandId(saveSetSendCommandId);
|
||||
#endif
|
||||
|
||||
PG_RE_THROW();
|
||||
}
|
||||
PG_END_TRY();
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
SetSendCommandId(saveSetSendCommandId);
|
||||
#endif
|
||||
|
||||
/* Disconnecting and releasing resources */
|
||||
DestoryAutonomousSession(false);
|
||||
|
||||
|
|
|
|||
|
|
@ -1399,12 +1399,10 @@ void instr_stmt_report_basic_info()
|
|||
}
|
||||
if (to_update_db_name || to_update_user_name || to_update_client_addr) {
|
||||
ResourceOwner old_cur_owner = t_thrd.utils_cxt.CurrentResourceOwner;
|
||||
MemoryContext old_ctx = MemoryContextSwitchTo(t_thrd.mem_cxt.msg_mem_cxt);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = ResourceOwnerCreate(NULL, "Full/Slow SQL",
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = ResourceOwnerCreate(old_cur_owner, "Full/Slow SQL",
|
||||
THREAD_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_DFX));
|
||||
(void)MemoryContextSwitchTo(old_ctx);
|
||||
|
||||
old_ctx = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt);
|
||||
MemoryContext old_ctx = MemoryContextSwitchTo(u_sess->statement_cxt.stmt_stat_cxt);
|
||||
if (to_update_db_name) {
|
||||
u_sess->statement_cxt.db_name = get_database_name(beentry->st_databaseid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -494,30 +494,6 @@ void UpdateUniqueSQLVecSortStats(Batchsortstate* state, uint64 spill_count, Time
|
|||
}
|
||||
}
|
||||
|
||||
static void mask_unique_sql_str(UniqueSQL* unique_sql)
|
||||
{
|
||||
errno_t rc;
|
||||
|
||||
/* hide password */
|
||||
if (unique_sql->unique_sql != NULL) {
|
||||
char* mask_str = NULL;
|
||||
mask_str = maskPassword(unique_sql->unique_sql);
|
||||
if (mask_str != NULL) {
|
||||
rc = memset_s(unique_sql->unique_sql, UNIQUE_SQL_MAX_LEN - 1, 0, UNIQUE_SQL_MAX_LEN - 1);
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
/* after calling maskPassword, mask_str can be longer than original string,
|
||||
* now the length of masked password('*..*') is fixed to 'password_min_length'(GUC) */
|
||||
size_t valid_mask_len = strlen(mask_str) > (size_t)(UNIQUE_SQL_MAX_LEN - 1)
|
||||
? (size_t)(UNIQUE_SQL_MAX_LEN - 1)
|
||||
: strlen(mask_str);
|
||||
rc = memcpy_s(unique_sql->unique_sql, UNIQUE_SQL_MAX_LEN - 1, mask_str, valid_mask_len);
|
||||
securec_check(rc, "\0", "\0");
|
||||
pfree(mask_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_unique_sql_string_in_entry(UniqueSQL* entry, Query* query, const char* sql, int32 multi_sql_offset)
|
||||
{
|
||||
errno_t rc = EOK;
|
||||
|
|
@ -536,7 +512,6 @@ static void set_unique_sql_string_in_entry(UniqueSQL* entry, Query* query, const
|
|||
// generate and store normalized query string
|
||||
if (normalized_unique_querystring(query, sql, entry->unique_sql, UNIQUE_SQL_MAX_LEN - 1,
|
||||
multi_sql_offset)) {
|
||||
mask_unique_sql_str(entry);
|
||||
entry->unique_sql = trim(entry->unique_sql);
|
||||
} else {
|
||||
ereport(LOG,
|
||||
|
|
|
|||
|
|
@ -203,12 +203,11 @@ bool normalized_unique_querystring(Query* query, const char* query_string, char*
|
|||
}
|
||||
|
||||
bool result = true;
|
||||
char* norm_query = NULL;
|
||||
char *norm_query = NULL, *mask_str = NULL;
|
||||
int encoding = GetDatabaseEncoding();
|
||||
int query_len;
|
||||
pgssJumbleState jstate;
|
||||
errno_t rc;
|
||||
rc = memset_s(&jstate, sizeof(jstate), 0, sizeof(jstate));
|
||||
errno_t rc = memset_s(&jstate, sizeof(jstate), 0, sizeof(jstate));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
query_len = strlen(query_string);
|
||||
|
|
@ -221,6 +220,12 @@ bool normalized_unique_querystring(Query* query, const char* query_string, char*
|
|||
result = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mask_str = maskPassword(query_string);
|
||||
if (mask_str != NULL) {
|
||||
query_string = mask_str;
|
||||
query_len = strlen(mask_str);
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
|
@ -235,6 +240,7 @@ bool normalized_unique_querystring(Query* query, const char* query_string, char*
|
|||
query_string = builtin_unique_sql->unique_sql;
|
||||
query_len = builtin_unique_sql->unique_sql_len;
|
||||
}
|
||||
|
||||
if (query_len > buf_len) {
|
||||
query_len = pg_encoding_mbcliplen(encoding, query_string, query_len,
|
||||
g_instance.attr.attr_common.pgstat_track_activity_query_size - 1);
|
||||
|
|
@ -245,6 +251,7 @@ bool normalized_unique_querystring(Query* query, const char* query_string, char*
|
|||
}
|
||||
}
|
||||
|
||||
pfree_ext(mask_str);
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -936,7 +936,7 @@ void RebuildPartitonMap(PartitionMap* oldMap, PartitionMap* newMap)
|
|||
}
|
||||
} else {
|
||||
oldMap->isDirty = true;
|
||||
SetLocalRelCacheNeedEOXactWork(true);
|
||||
SetRelCacheNeedEOXActWork(true);
|
||||
elog(LOG, "map refcount is not zero when RebuildPartitonMap ");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ set(CMAKE_MODULE_PATH
|
|||
add_subdirectory(kernel)
|
||||
add_subdirectory(db4ai)
|
||||
|
||||
if(NOT "${ENABLE_LITE_MODE}" STREQUAL "ON")
|
||||
if(NOT "${ENABLE_LITE_MODE}" STREQUAL "ON" AND "${ENABLE_MULTIPLE_NODES}" STREQUAL "OFF")
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tools/ DESTINATION bin/dbmind)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gs_dbmind
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
|
|
|
|||
|
|
@ -257,8 +257,9 @@ static Datum pca_predict(const Matrix *features, const Matrix *weights,
|
|||
static HyperparameterDefinition pca_hyperparameter_definitions[] = {
|
||||
HYPERPARAMETER_INT4("number_components", 1, 1, true, INT32_MAX, true, HyperparametersGD, number_dimensions,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("batch_size", 1000, 1, true, INT32_MAX, true, HyperparametersGD, batch_size, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("max_iterations", 100, 1, true, INT32_MAX, true, HyperparametersGD, max_iterations,
|
||||
HYPERPARAMETER_INT4("batch_size", 1000, 1, true, MAX_BATCH_SIZE, true, HyperparametersGD, batch_size,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("max_iterations", 100, 1, true, ITER_MAX, true, HyperparametersGD, max_iterations,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("max_seconds", 0, 0, true, INT32_MAX, true, HyperparametersGD, max_seconds, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_FLOAT8("tolerance", 0.0005, 0.0, true, DBL_MAX, true, HyperparametersGD, tolerance, HP_NO_AUTOML()),
|
||||
|
|
|
|||
|
|
@ -1041,10 +1041,11 @@ HyperparameterDefinition kmeans_hyperparameter_definitions[] = {
|
|||
HYPERPARAMETER_INT4("verbose", 0, 0, true, 2, true, HyperparametersKMeans, verbosity, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("num_centroids", 1, 1, true, 1000000, true, HyperparametersKMeans, num_centroids,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("max_iterations", 10, 1, true, INT32_MAX, true, HyperparametersKMeans, num_iterations,
|
||||
HYPERPARAMETER_INT4("max_iterations", 10, 1, true, ITER_MAX, true, HyperparametersKMeans, num_iterations,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("num_features", 0, 1, true, INT32_MAX, true, HyperparametersKMeans, n_features, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("batch_size", 1000, 1, true, 1000000, true, HyperparametersKMeans, batch_size, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("batch_size", 1000, 1, true, MAX_BATCH_SIZE, true, HyperparametersKMeans, batch_size,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("seed", 0, 0, true, INT32_MAX, true, HyperparametersKMeans, external_seed,
|
||||
HP_AUTOML_INT(1, INT32_MAX, 1, ProbabilityDistribution::UNIFORM_RANGE)),
|
||||
HYPERPARAMETER_FLOAT8("tolerance", 0.00001, 0.0, false, 1.0, true, HyperparametersKMeans, tolerance,
|
||||
|
|
|
|||
|
|
@ -80,8 +80,11 @@ static MemoryContext g_xgboostMcxt = NULL;
|
|||
#define safe_xgboost(call) { \
|
||||
int err = (call); \
|
||||
if (err != 0) { \
|
||||
char *str = const_cast<char*>(g_xgboostApi->XGBGetLastError()); \
|
||||
char *res = strchr(str, '\n'); \
|
||||
*res = '\0'; \
|
||||
ereport(ERROR, (errmodule(MOD_DB4AI), errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
|
||||
errmsg("%s:%d: error in %s: %s\n", __FILE__, __LINE__, #call, g_xgboostApi->XGBGetLastError()))); \
|
||||
errmsg("%s", strrchr(str, ':') + 1))); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
|
@ -225,14 +228,15 @@ const char *xgboost_boost_str[] = {"gbtree", "gblinear", "dart"};
|
|||
const char *xgboost_tree_method_str[] = {"auto", "exact", "approx", "hist", "gpu_hist"};
|
||||
const char *xgboost_eval_metric_str[] = {"rmse", "rmsle", "map", "mae", "auc", "aucpr" };
|
||||
static HyperparameterDefinition xgboost_hyperparameter_definitions[] = {
|
||||
HYPERPARAMETER_INT4("n_iter", 10, 1, true, INT32_MAX, true, HyperparamsXGBoost, n_iterations, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("batch_size", 10000, 1, true, INT32_MAX, true, HyperparamsXGBoost, batch_size, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("n_iter", 10, 1, true, ITER_MAX, true, HyperparamsXGBoost, n_iterations, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("batch_size", 10000, 1, true, MAX_BATCH_SIZE, true, HyperparamsXGBoost, batch_size,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("max_depth", 5, 0, true, INT32_MAX, true, HyperparamsXGBoost, max_depth, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("min_child_weight", 1, 0, true, INT32_MAX, true, HyperparamsXGBoost, min_child_weight,
|
||||
HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_FLOAT8("gamma", 0.0, 0.0, true, 1, true, HyperparamsXGBoost, gamma, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_FLOAT8("gamma", 0.0, 0.0, true, DBL_MAX, true, HyperparamsXGBoost, gamma, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_FLOAT8("eta", 0.3, 0.0, true, 1, true, HyperparamsXGBoost, eta, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("nthread", 1, 0, true, INT32_MAX, true, HyperparamsXGBoost, nthread, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("nthread", 1, 0, true, 100, true, HyperparamsXGBoost, nthread, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("verbosity", 1, 0, true, 3, true, HyperparamsXGBoost, verbosity, HP_NO_AUTOML()),
|
||||
HYPERPARAMETER_INT4("seed", 0, 0, true, INT32_MAX, true, HyperparamsXGBoost, seed,
|
||||
HP_AUTOML_INT(1, INT32_MAX, 1, ProbabilityDistribution::UNIFORM_RANGE)),
|
||||
|
|
@ -548,12 +552,6 @@ static void xgboost_run(AlgorithmAPI *self, TrainModelState *pstate, Model **mod
|
|||
|
||||
ModelTuple const *outer_tuple_slot = nullptr;
|
||||
|
||||
// Check max_depth parameter
|
||||
if (xg_hyperp->max_depth == 0 && (0 != strcmp(xgboost_boost_str[BOOST_GBLINEAR_IDX], xg_hyperp->booster))) {
|
||||
ereport(ERROR, (errmodule(MOD_DB4AI),
|
||||
errmsg("Max_depth must be larger than 0 when booster is non_linear value.")));
|
||||
}
|
||||
|
||||
load_xgboost_library();
|
||||
|
||||
// data holder for in-between (chunk-wise) invocation of XGBoost training algorithm
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ except ImportError:
|
|||
import sys
|
||||
import os
|
||||
|
||||
curr_path = os.path.dirname(os.path.abspath(__file__))
|
||||
curr_path = os.path.dirname(os.path.realpath(__file__))
|
||||
root_path = os.path.dirname(curr_path)
|
||||
sys.path.append(root_path)
|
||||
from dbmind.cmd import main
|
||||
|
|
|
|||
|
|
@ -11,25 +11,57 @@
|
|||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
import os
|
||||
import re
|
||||
from configparser import ConfigParser
|
||||
from configparser import NoSectionError, NoOptionError
|
||||
|
||||
from dbmind import constants
|
||||
from dbmind.common import security
|
||||
from dbmind.common.exceptions import InvalidPasswordException, ConfigSettingError
|
||||
from dbmind.metadatabase.dao.dynamic_config import dynamic_config_get, dynamic_config_set
|
||||
from dbmind.common.utils import write_to_terminal
|
||||
from dbmind.metadatabase.dao.dynamic_config import dynamic_config_get, dynamic_config_set
|
||||
|
||||
DBMIND_CONF_HEADER = """\
|
||||
# Copyright (c) 2022 Huawei Technologies Co.,Ltd.
|
||||
#
|
||||
# openGauss is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
#
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
# Notice:
|
||||
# 1. (null) explicitly represents empty or null. Meanwhile blank represents undefined.
|
||||
# 2. DBMind encrypts password parameters. Hence, there is no plain-text password after initialization.
|
||||
# 3. Users can only configure the plain-text password in this file before initializing
|
||||
# (that is, using the --initialize option),
|
||||
# and then if users want to modify the password-related information,
|
||||
# users need to use the 'set' sub-command to achieve.
|
||||
# 4. If users use relative path in this file, the current working directory is the directory where this file is located.
|
||||
"""
|
||||
|
||||
NULL_TYPE = '(null)' # empty text.
|
||||
ENCRYPTED_SIGNAL = 'Encrypted->'
|
||||
|
||||
# Used by check_config_validity().
|
||||
CONFIG_OPTIONS = {
|
||||
'TSDB-name': ['prometheus'],
|
||||
'METADATABASE-dbtype': ['sqlite', 'opengauss', 'postgresql'],
|
||||
'WORKER-type': ['local', 'dist'],
|
||||
'LOG-level': ['DEBUG', 'INFO', 'WARNING', 'ERROR']
|
||||
}
|
||||
|
||||
def check_config_validity(section, option, value, inline_comment=None):
|
||||
|
||||
def check_config_validity(section, option, value):
|
||||
config_item = '%s-%s' % (section, option)
|
||||
# exceptional cases:
|
||||
if config_item == 'METADATABASE-port':
|
||||
return True, None
|
||||
|
||||
# normal inspection process:
|
||||
if 'port' in option:
|
||||
valid_port = str.isdigit(value) and 0 < int(value) <= 65535
|
||||
|
|
@ -38,16 +70,14 @@ def check_config_validity(section, option, value, inline_comment=None):
|
|||
if 'database' in option:
|
||||
if value == NULL_TYPE or value.strip() == '':
|
||||
return False, 'Unspecified database name'
|
||||
if 'Options:' in inline_comment:
|
||||
# determine setting option whether choose from option list.
|
||||
results = re.findall(r'Options: (.*)?\.', inline_comment)
|
||||
if len(results) > 0:
|
||||
options = list(map(str.strip, results[0].split(',')))
|
||||
if value not in options:
|
||||
return False, 'Invalid choice: %s' % value
|
||||
|
||||
options = CONFIG_OPTIONS.get(config_item)
|
||||
if options and value not in options:
|
||||
return False, 'Invalid choice: %s' % value
|
||||
|
||||
if 'dbtype' in option and value == 'opengauss':
|
||||
write_to_terminal(
|
||||
'WARN: default PostgresSQL connector (psycopg2-binary) does not support openGauss.\n'
|
||||
'WARN: default PostgreSQL connector (psycopg2-binary) does not support openGauss.\n'
|
||||
'It would help if you compiled psycopg2 with openGauss manually or '
|
||||
'created a connection user after setting the GUC password_encryption_type to 1.',
|
||||
color='yellow'
|
||||
|
|
@ -96,13 +126,16 @@ def load_sys_configs(confile):
|
|||
class ConfigUpdater:
|
||||
def __init__(self, filepath):
|
||||
self.config = ConfigParser(inline_comment_prefixes=None)
|
||||
self.filepath = os.path.abspath(filepath)
|
||||
self.filepath = os.path.realpath(filepath)
|
||||
self.fp = None
|
||||
self.readonly = True
|
||||
|
||||
def get(self, section, option):
|
||||
value = self.config.get(section, option)
|
||||
default_value, inline_comment = map(str.strip, value.rsplit('#', 1))
|
||||
try:
|
||||
default_value, inline_comment = map(str.strip, value.rsplit('#', 1))
|
||||
except ValueError:
|
||||
default_value, inline_comment = value.strip(), ''
|
||||
if default_value == '':
|
||||
default_value = NULL_TYPE
|
||||
return default_value, inline_comment
|
||||
|
|
@ -132,10 +165,7 @@ class ConfigUpdater:
|
|||
# output configurations
|
||||
self.fp.truncate(0)
|
||||
self.fp.seek(0)
|
||||
with open(
|
||||
file=os.path.join(constants.MISC_PATH, constants.CONFILE_HEADER_NAME)
|
||||
) as header_fp:
|
||||
self.fp.writelines(header_fp.readlines())
|
||||
self.fp.write(DBMIND_CONF_HEADER)
|
||||
self.config.write(self.fp)
|
||||
self.fp.flush()
|
||||
self.fp.close()
|
||||
|
|
@ -163,7 +193,7 @@ def set_config_parameter(confpath, section: str, option: str, value: str):
|
|||
old_value, comment = config.get(section, option)
|
||||
except (NoSectionError, NoOptionError):
|
||||
raise ConfigSettingError('Not found the parameter %s-%s.' % (section, option))
|
||||
valid, reason = check_config_validity(section, option, value, comment)
|
||||
valid, reason = check_config_validity(section, option, value)
|
||||
if not valid:
|
||||
raise ConfigSettingError('Incorrect value due to %s.' % reason)
|
||||
# If user wants to change password, we should encrypt the plain-text password first.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import signal
|
||||
import sys
|
||||
import traceback
|
||||
|
|
@ -55,7 +56,6 @@ def _check_confpath(confpath):
|
|||
def _process_clean(force=False):
|
||||
global_vars.worker.terminate(cancel_futures=force)
|
||||
TimedTaskManager.stop()
|
||||
logging.shutdown()
|
||||
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
|
|
@ -67,7 +67,10 @@ def signal_handler(signum, frame):
|
|||
elif signum == signal.SIGUSR2:
|
||||
# used for debugging
|
||||
utils.write_to_terminal('Stack frames:', color='green')
|
||||
traceback.print_stack(frame)
|
||||
for th in threading.enumerate():
|
||||
print(th)
|
||||
traceback.print_stack(sys._current_frames()[th.ident])
|
||||
print()
|
||||
elif signum == signal.SIGTERM:
|
||||
signal.signal(signal.SIGTERM, signal.SIG_IGN)
|
||||
logging.info('DBMind received exit signal.')
|
||||
|
|
@ -87,7 +90,7 @@ class DBMindMain(Daemon):
|
|||
if not _check_confpath(confpath):
|
||||
raise SetupError("Invalid directory '%s', please set up first." % confpath)
|
||||
|
||||
self.confpath = os.path.abspath(confpath)
|
||||
self.confpath = os.path.realpath(confpath)
|
||||
self.worker = None
|
||||
|
||||
pid_file = os.path.join(confpath, constants.PIDFILE_NAME)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ from dbmind import constants, global_vars
|
|||
from dbmind.cmd.config_utils import (
|
||||
ConfigUpdater, check_config_validity,
|
||||
DynamicConfig, load_sys_configs,
|
||||
NULL_TYPE, ENCRYPTED_SIGNAL
|
||||
NULL_TYPE, ENCRYPTED_SIGNAL, DBMIND_CONF_HEADER
|
||||
)
|
||||
from dbmind.cmd.edbmind import SKIP_LIST
|
||||
from dbmind.common import utils, security
|
||||
|
|
@ -35,7 +35,7 @@ from dbmind.metadatabase.dao.dynamic_config import dynamic_config_set, dynamic_c
|
|||
def initialize_and_check_config(confpath, interactive=False):
|
||||
if not os.path.exists(confpath):
|
||||
raise SetupError('Not found the directory %s.' % confpath)
|
||||
confpath = os.path.abspath(confpath) # in case of dir changed.
|
||||
confpath = os.path.realpath(confpath) # in case of dir changed.
|
||||
os.chdir(confpath)
|
||||
dbmind_conf_path = os.path.join(confpath, constants.CONFILE_NAME)
|
||||
dynamic_config_path = os.path.join(confpath, constants.DYNAMIC_CONFIG)
|
||||
|
|
@ -70,7 +70,7 @@ def initialize_and_check_config(confpath, interactive=False):
|
|||
for section, section_comment in config.sections(SKIP_LIST):
|
||||
for option, value, inline_comment in config.items(section):
|
||||
valid, invalid_reason = check_config_validity(
|
||||
section, option, value, inline_comment
|
||||
section, option, value
|
||||
)
|
||||
if not valid:
|
||||
raise SetupError(
|
||||
|
|
@ -151,7 +151,10 @@ def setup_directory_interactive(confpath):
|
|||
utils.write_to_terminal(section_comment, color='yellow')
|
||||
# Get each configuration item.
|
||||
for option, values in config.items(section):
|
||||
default_value, inline_comment = map(str.strip, values.rsplit('#', 1))
|
||||
try:
|
||||
default_value, inline_comment = map(str.strip, values.rsplit('#', 1))
|
||||
except ValueError:
|
||||
default_value, inline_comment = values.strip(), ''
|
||||
# If not set default value, the default value is null.
|
||||
if default_value.strip() == '':
|
||||
default_value = NULL_TYPE
|
||||
|
|
@ -170,7 +173,7 @@ def setup_directory_interactive(confpath):
|
|||
input_value = default_value
|
||||
|
||||
valid, invalid_reason = check_config_validity(
|
||||
section, option, input_value, inline_comment
|
||||
section, option, input_value
|
||||
)
|
||||
if not valid:
|
||||
utils.write_to_terminal(
|
||||
|
|
@ -190,8 +193,7 @@ def setup_directory_interactive(confpath):
|
|||
# output configurations
|
||||
with open(file=config_dst, mode='w+') as fp:
|
||||
# Add header comments (including license and notice).
|
||||
with open(file=os.path.join(confpath, constants.CONFILE_HEADER_NAME)) as header_fp:
|
||||
fp.writelines(header_fp.readlines())
|
||||
fp.write(DBMIND_CONF_HEADER)
|
||||
config.write(fp)
|
||||
|
||||
initialize_and_check_config(confpath, interactive=True)
|
||||
|
|
@ -221,8 +223,7 @@ def setup_directory(confpath):
|
|||
with open(file=os.path.join(confpath, constants.CONFILE_NAME), mode='r+') as fp:
|
||||
old = fp.readlines()
|
||||
# Add header comments (including license and notice).
|
||||
with open(file=os.path.join(constants.MISC_PATH, constants.CONFILE_HEADER_NAME)) as header_fp:
|
||||
fp.seek(0)
|
||||
fp.writelines(header_fp.readlines())
|
||||
fp.seek(0)
|
||||
fp.write(DBMIND_CONF_HEADER)
|
||||
fp.writelines(old)
|
||||
utils.write_to_terminal("Configure directory '%s' has been created successfully." % confpath, color='green')
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class Daemon:
|
|||
RUNNING = 1
|
||||
|
||||
def __init__(self, pid_file, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||
self.pid_file = os.path.abspath(pid_file)
|
||||
self.pid_file = os.path.realpath(pid_file)
|
||||
self.stdin = stdin
|
||||
self.stdout = stdout
|
||||
self.stderr = stderr
|
||||
|
|
|
|||
|
|
@ -293,3 +293,10 @@ class PrometheusClient(TsdbClient):
|
|||
"HTTP Status Code {} ({!r})".format(response.status_code, response.content)
|
||||
)
|
||||
return _standardize(data)
|
||||
|
||||
def timestamp(self):
|
||||
seq = self.get_current_metric_value('prometheus_remote_storage_highest_timestamp_in_seconds')
|
||||
if len(seq) == 0 or len(seq[0]) == 0:
|
||||
return 0
|
||||
return seq[0].timestamps[0]
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
|
|
@ -48,3 +49,8 @@ class TsdbClient(object):
|
|||
params: dict = None):
|
||||
"""get metric target from tsdb"""
|
||||
pass
|
||||
|
||||
def timestamp(self):
|
||||
"""get the current unix-timestamp from the time-series database."""
|
||||
return int(time.time() * 1000)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
from dbmind.common.exceptions import ApiClientException
|
||||
from dbmind.common.tsdb.tsdb_client import TsdbClient
|
||||
|
|
@ -46,3 +47,9 @@ class TsdbClientFactory(object):
|
|||
cls.tsdb_client = client
|
||||
if cls.tsdb_client is None:
|
||||
raise ApiClientException("Failed to init TSDB client, please check config file")
|
||||
|
||||
if abs(cls.tsdb_client.timestamp() - time.time() * 1000) > 60 * 1000: # threshold is 1 minute.
|
||||
raise ApiClientException('Found clock drift between TSDB client and server, '
|
||||
'please check and synchronize system clocks.')
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -153,25 +153,28 @@ class MultiProcessingRFHandler(RotatingFileHandler):
|
|||
|
||||
self._queue = multiprocessing.Queue(-1)
|
||||
self._should_exit = False
|
||||
self._receiv_thr = threading.Thread(target=self._receive)
|
||||
self._receiv_thr = threading.Thread(target=self._receive, name='LoggingReceiverThread')
|
||||
self._receiv_thr.daemon = True
|
||||
self._receiv_thr.start()
|
||||
|
||||
def _receive(self):
|
||||
while True:
|
||||
try:
|
||||
record = self._queue.get_nowait()
|
||||
if self._should_exit and self._queue.empty():
|
||||
break
|
||||
record = self._queue.get(timeout=.2)
|
||||
super().emit(record)
|
||||
except Empty:
|
||||
time.sleep(.1)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except EOFError:
|
||||
except (OSError, EOFError):
|
||||
break
|
||||
except Empty:
|
||||
pass
|
||||
except:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
if self._should_exit and self._queue.empty():
|
||||
break
|
||||
|
||||
self._queue.close()
|
||||
self._queue.join_thread()
|
||||
|
||||
def _send(self, s):
|
||||
self._queue.put_nowait(s)
|
||||
|
||||
|
|
@ -181,6 +184,7 @@ class MultiProcessingRFHandler(RotatingFileHandler):
|
|||
record.msg = record.msg % record.args
|
||||
record.args = None
|
||||
if record.exc_info:
|
||||
self.format(record)
|
||||
record.exc_info = None
|
||||
self._send(record)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
|
|
@ -189,8 +193,10 @@ class MultiProcessingRFHandler(RotatingFileHandler):
|
|||
self.handleError(record)
|
||||
|
||||
def close(self):
|
||||
super().close()
|
||||
self._should_exit = True
|
||||
if not self._should_exit:
|
||||
self._should_exit = True
|
||||
self._receiv_thr.join(5)
|
||||
super().close()
|
||||
|
||||
|
||||
class ExceptionCatch:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from dbmind.common.utils import where_am_i
|
|||
|
||||
def list_components():
|
||||
"""Return all components in current directory."""
|
||||
curr_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
curr_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
components = list(
|
||||
map(lambda tup: tup[1],
|
||||
pkgutil.iter_modules((curr_dir,)))
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ def show(metric, host, start_time, end_time):
|
|||
for row_ in result:
|
||||
row = [str(getattr(row_, field)).strip() for field in field_names]
|
||||
csv_writer.writerow(row)
|
||||
write_to_terminal('Dumped file is %s.' % os.path.abspath(dump_file_name))
|
||||
write_to_terminal('Dumped file is %s.' % os.path.realpath(dump_file_name))
|
||||
elif char == 'N':
|
||||
print(output_table)
|
||||
print('(%d rows)' % nb_rows)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright (c) 2022 Huawei Technologies Co.,Ltd.
|
||||
#
|
||||
# openGauss is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
#
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from dbmind.components.index_advisor import main
|
||||
except ImportError:
|
||||
libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
|
||||
sys.path.append(libpath)
|
||||
from index_advisor import main
|
||||
|
||||
main(sys.argv[1:])
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -11,11 +11,13 @@
|
|||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from dbmind.components.opengauss_exporter import main
|
||||
except ImportError:
|
||||
sys.path.append('..')
|
||||
libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
|
||||
sys.path.append(libpath)
|
||||
from opengauss_exporter import main
|
||||
|
||||
main(sys.argv[1:])
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ from . import controller
|
|||
from . import service
|
||||
from .. import __version__
|
||||
|
||||
ROOT_DIR_PATH = os.path.abspath(
|
||||
ROOT_DIR_PATH = os.path.realpath(
|
||||
os.path.join(os.path.dirname(__file__), '..')
|
||||
)
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ def wipe_off_password(dsn):
|
|||
|
||||
def path_type(path):
|
||||
if os.path.exists(path):
|
||||
return os.path.abspath(path)
|
||||
return os.path.realpath(path)
|
||||
else:
|
||||
raise argparse.ArgumentTypeError('%s is not a valid path.' % path)
|
||||
|
||||
|
|
@ -102,7 +102,7 @@ def parse_argv(argv):
|
|||
parser.add_argument('--ssl-certfile', type=path_type, help='set the path of ssl certificate file')
|
||||
parser.add_argument('--parallel', default=5, type=int,
|
||||
help='not collect pg_settings.yml metrics.')
|
||||
parser.add_argument('--log.filepath', type=os.path.abspath, default=os.path.join(os.getcwd(), DEFAULT_LOGFILE),
|
||||
parser.add_argument('--log.filepath', type=os.path.realpath, default=os.path.join(os.getcwd(), DEFAULT_LOGFILE),
|
||||
help='the path to log')
|
||||
parser.add_argument('--log.level', default='info', choices=('debug', 'info', 'warn', 'error', 'fatal'),
|
||||
help='only log messages with the given severity or above.'
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@
|
|||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from dbmind.components.reprocessing_exporter import main
|
||||
except ImportError:
|
||||
sys.path.append('..')
|
||||
libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
|
||||
sys.path.append(libpath)
|
||||
from reprocessing_exporter import main
|
||||
|
||||
main(sys.argv[1:])
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from . import dao
|
|||
from . import service
|
||||
from .. import __version__
|
||||
|
||||
CURR_DIR = os.path.abspath(
|
||||
CURR_DIR = os.path.realpath(
|
||||
os.path.join(os.path.dirname(__file__), '..')
|
||||
)
|
||||
DEFAULT_YAML = 'reprocessing_exporter.yml'
|
||||
|
|
@ -35,7 +35,7 @@ with tempfile.NamedTemporaryFile(suffix='.pid') as fp:
|
|||
|
||||
def path_type(path):
|
||||
if os.path.exists(path):
|
||||
return os.path.abspath(path)
|
||||
return os.path.realpath(path)
|
||||
else:
|
||||
raise argparse.ArgumentTypeError('%s is not a valid path.' % path)
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ def parse_argv(argv):
|
|||
help='listen port to expose metrics and web interface')
|
||||
parser.add_argument('--collector.config', type=path_type, default=os.path.join(CURR_DIR, DEFAULT_YAML),
|
||||
help='according to the content of the yaml file for metric collection')
|
||||
parser.add_argument('--log.filepath', type=os.path.abspath,
|
||||
parser.add_argument('--log.filepath', type=os.path.realpath,
|
||||
default=os.path.join(os.getcwd(), DEFAULT_LOGFILE),
|
||||
help='the path to log')
|
||||
parser.add_argument('--log.level', default='info', choices=('debug', 'info', 'warn', 'error', 'fatal'),
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ def show(query, start_time, end_time):
|
|||
dump_file_name = 'slow_queries_%s.txt' % int(time.time())
|
||||
with open(dump_file_name, 'w+') as fp:
|
||||
fp.write(str(output_table))
|
||||
write_to_terminal('Dumped file is %s.' % os.path.abspath(dump_file_name))
|
||||
write_to_terminal('Dumped file is %s.' % os.path.realpath(dump_file_name))
|
||||
elif char == 'N':
|
||||
print(output_table)
|
||||
print('(%d rows)' % nb_rows)
|
||||
|
|
|
|||
|
|
@ -12,11 +12,13 @@
|
|||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from dbmind.components.sqldiag import main
|
||||
except ImportError:
|
||||
sys.path.append('..')
|
||||
libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
|
||||
sys.path.append(libpath)
|
||||
from sqldiag import main
|
||||
|
||||
main(sys.argv[1:])
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ def check_time_legality(time_string):
|
|||
def is_valid_conf(filepath):
|
||||
if os.path.exists(filepath):
|
||||
file_abs_path = filepath
|
||||
elif os.path.exists(os.path.abspath(os.path.join(os.getcwd(), filepath))):
|
||||
file_abs_path = os.path.abspath(os.path.join(os.getcwd(), filepath))
|
||||
elif os.path.exists(os.path.realpath(os.path.join(os.getcwd(), filepath))):
|
||||
file_abs_path = os.path.realpath(os.path.join(os.getcwd(), filepath))
|
||||
else:
|
||||
print("FATAL: Not found the configuration file %s." % filepath, file=sys.stderr)
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -12,11 +12,14 @@
|
|||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from dbmind.components.xtuner.tuner.main import main
|
||||
except ImportError:
|
||||
sys.path.append('..')
|
||||
libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
|
||||
sys.path.append(libpath)
|
||||
|
||||
from xtuner.tuner.main import main
|
||||
|
||||
main(sys.argv[1:])
|
||||
|
|
|
|||
|
|
@ -166,10 +166,10 @@ class Knob:
|
|||
return
|
||||
|
||||
self._scale = self._max - self._min
|
||||
if self._scale < 0:
|
||||
if self._scale <= 0:
|
||||
raise ValueError('Knob %s is incorrectly configured. '
|
||||
'The max value must be greater than '
|
||||
'or equal to the min value.' % self.name)
|
||||
'the min value.' % self.name)
|
||||
if type(self.user_set) is str:
|
||||
self.current = self.to_numeric(self.user_set)
|
||||
elif type(self.user_set) in (int, float):
|
||||
|
|
|
|||
|
|
@ -15,11 +15,10 @@ import os
|
|||
__version__ = '1.0.0'
|
||||
__description__ = 'openGauss DBMind: An autonomous platform for openGauss'
|
||||
|
||||
DBMIND_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
DBMIND_PATH = os.path.dirname(os.path.realpath(__file__))
|
||||
MISC_PATH = os.path.join(DBMIND_PATH, 'misc')
|
||||
|
||||
CONFILE_NAME = 'dbmind.conf' # the name of configuration file
|
||||
CONFILE_HEADER_NAME = 'dbmind.conf.header'
|
||||
PIDFILE_NAME = 'dbmind.pid'
|
||||
LOGFILE_NAME = 'dbmind.log'
|
||||
METRIC_MAP_CONFIG = 'metric_map.conf'
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
# Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
||||
#
|
||||
# openGauss is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
#
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
# Notice:
|
||||
# 1. (null) explicitly represents empty or null. Meanwhile blank represents undefined.
|
||||
# 2. DBMind encrypts password parameters. Hence, there is no plain-text password after initialization.
|
||||
# 3. Users can only configure the plain-text password in this file before initializing
|
||||
# (that is, using the --initialize option),
|
||||
# and then if users want to modify the password-related information,
|
||||
# users need to use the 'set' sub-command to achieve.
|
||||
# 4. If users use relative path in this file, the current working directory is the directory where this file is located.
|
||||
|
||||
|
|
@ -1,19 +1,439 @@
|
|||
# Copyright (c) 2022 Huawei Technologies Co.,Ltd.
|
||||
#
|
||||
# openGauss is licensed under Mulan PSL v2.
|
||||
# You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
# You may obtain a copy of Mulan PSL v2 at:
|
||||
#
|
||||
# http://license.coscl.org.cn/MulanPSL2
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
# See the Mulan PSL v2 for more details.
|
||||
|
||||
|
||||
# The name of different metric collectors may be different,
|
||||
# so we converte the different metric name here.
|
||||
|
||||
# For example, users can get the full list of metrics from Prometheus via the following URI:
|
||||
# /api/v1/label/__name__/values
|
||||
|
||||
# Format:
|
||||
# metric name in the DBMind = metric name in the collector (e.g., Prometheus-exporter, Agent)
|
||||
#
|
||||
os_disk_io_cnt = os_disk_io_cnt
|
||||
os_disk_io_load = os_disk_io_load
|
||||
os_disk_read_bytes = os_disk_read_bytes
|
||||
os_disk_read_time = os_disk_read_time
|
||||
os_disk_write_bytes = os_disk_write_bytes
|
||||
os_disk_write_time = os_disk_write_time
|
||||
os_cpu_usage = os_cpu_usage
|
||||
os_system_cpu_usage = os_system_cpu_usage
|
||||
os_user_cpu_usage = os_user_cpu_usage
|
||||
opengauss_blocks_read_time = opengauss_blocks_read_time
|
||||
opengauss_blocks_write_time = opengauss_blocks_write_time
|
||||
opengauss_sql_cpu_time_rate = opengauss_sql_cpu_time_rate
|
||||
disk_usage = disk_usage
|
||||
gaussdb_qps_by_instance = gaussdb_qps_by_instance
|
||||
io_queue_number = io_queue_number
|
||||
io_read_bytes = io_read_bytes
|
||||
io_read_delay_time = io_read_delay_time
|
||||
io_read_total = io_read_total
|
||||
io_write_bytes = io_write_bytes
|
||||
io_write_delay_time = io_write_delay_time
|
||||
io_write_total = io_write_total
|
||||
node_arp_entries = node_arp_entries
|
||||
node_boot_time_seconds = node_boot_time_seconds
|
||||
node_context_switches_total = node_context_switches_total
|
||||
node_cooling_device_cur_state = node_cooling_device_cur_state
|
||||
node_cooling_device_max_state = node_cooling_device_max_state
|
||||
node_cpu_core_throttles_total = node_cpu_core_throttles_total
|
||||
node_cpu_frequency_max_hertz = node_cpu_frequency_max_hertz
|
||||
node_cpu_frequency_min_hertz = node_cpu_frequency_min_hertz
|
||||
node_cpu_guest_seconds_total = node_cpu_guest_seconds_total
|
||||
node_cpu_package_throttles_total = node_cpu_package_throttles_total
|
||||
node_cpu_scaling_frequency_hertz = node_cpu_scaling_frequency_hertz
|
||||
node_cpu_scaling_frequency_max_hertz = node_cpu_scaling_frequency_max_hertz
|
||||
node_cpu_scaling_frequency_min_hertz = node_cpu_scaling_frequency_min_hertz
|
||||
node_cpu_seconds_total = node_cpu_seconds_total
|
||||
node_disk_io_now = node_disk_io_now
|
||||
node_disk_io_time_seconds_total = node_disk_io_time_seconds_total
|
||||
node_disk_io_time_weighted_seconds_total = node_disk_io_time_weighted_seconds_total
|
||||
node_disk_read_bytes_total = node_disk_read_bytes_total
|
||||
node_disk_read_time_seconds_total = node_disk_read_time_seconds_total
|
||||
node_disk_reads_completed_total = node_disk_reads_completed_total
|
||||
node_disk_reads_merged_total = node_disk_reads_merged_total
|
||||
node_disk_write_time_seconds_total = node_disk_write_time_seconds_total
|
||||
node_disk_writes_completed_total = node_disk_writes_completed_total
|
||||
node_disk_writes_merged_total = node_disk_writes_merged_total
|
||||
node_disk_written_bytes_total = node_disk_written_bytes_total
|
||||
node_edac_correctable_errors_total = node_edac_correctable_errors_total
|
||||
node_edac_csrow_correctable_errors_total = node_edac_csrow_correctable_errors_total
|
||||
node_edac_csrow_uncorrectable_errors_total = node_edac_csrow_uncorrectable_errors_total
|
||||
node_edac_uncorrectable_errors_total = node_edac_uncorrectable_errors_total
|
||||
node_entropy_available_bits = node_entropy_available_bits
|
||||
node_entropy_pool_size_bits = node_entropy_pool_size_bits
|
||||
node_exporter_build_info = node_exporter_build_info
|
||||
node_filefd_allocated = node_filefd_allocated
|
||||
node_filefd_maximum = node_filefd_maximum
|
||||
node_filesystem_avail_bytes = node_filesystem_avail_bytes
|
||||
node_filesystem_device_error = node_filesystem_device_error
|
||||
node_filesystem_files = node_filesystem_files
|
||||
node_filesystem_files_free = node_filesystem_files_free
|
||||
node_filesystem_free_bytes = node_filesystem_free_bytes
|
||||
node_filesystem_readonly = node_filesystem_readonly
|
||||
node_filesystem_size_bytes = node_filesystem_size_bytes
|
||||
node_forks_total = node_forks_total
|
||||
node_hwmon_chip_names = node_hwmon_chip_names
|
||||
node_hwmon_power_average_interval_max_seconds = node_hwmon_power_average_interval_max_seconds
|
||||
node_hwmon_power_average_interval_min_seconds = node_hwmon_power_average_interval_min_seconds
|
||||
node_hwmon_power_average_interval_seconds = node_hwmon_power_average_interval_seconds
|
||||
node_hwmon_power_average_watt = node_hwmon_power_average_watt
|
||||
node_hwmon_power_is_battery_watt = node_hwmon_power_is_battery_watt
|
||||
node_hwmon_sensor_label = node_hwmon_sensor_label
|
||||
node_hwmon_temp_celsius = node_hwmon_temp_celsius
|
||||
node_hwmon_temp_crit_alar_celsius = node_hwmon_temp_crit_alar_celsius
|
||||
node_hwmon_temp_crit_alarm_celsius = node_hwmon_temp_crit_alarm_celsius
|
||||
node_hwmon_temp_crit_celsius = node_hwmon_temp_crit_celsius
|
||||
node_hwmon_temp_max_celsius = node_hwmon_temp_max_celsius
|
||||
node_intr_total = node_intr_total
|
||||
node_load1 = node_load1
|
||||
node_load15 = node_load15
|
||||
node_load5 = node_load5
|
||||
node_memory_Active_anon_bytes = node_memory_Active_anon_bytes
|
||||
node_memory_Active_bytes = node_memory_Active_bytes
|
||||
node_memory_Active_file_bytes = node_memory_Active_file_bytes
|
||||
node_memory_AnonHugePages_bytes = node_memory_AnonHugePages_bytes
|
||||
node_memory_AnonPages_bytes = node_memory_AnonPages_bytes
|
||||
node_memory_Bounce_bytes = node_memory_Bounce_bytes
|
||||
node_memory_Buffers_bytes = node_memory_Buffers_bytes
|
||||
node_memory_Cached_bytes = node_memory_Cached_bytes
|
||||
node_memory_CmaFree_bytes = node_memory_CmaFree_bytes
|
||||
node_memory_CmaTotal_bytes = node_memory_CmaTotal_bytes
|
||||
node_memory_CommitLimit_bytes = node_memory_CommitLimit_bytes
|
||||
node_memory_Committed_AS_bytes = node_memory_Committed_AS_bytes
|
||||
node_memory_DirectMap1G_bytes = node_memory_DirectMap1G_bytes
|
||||
node_memory_DirectMap2M_bytes = node_memory_DirectMap2M_bytes
|
||||
node_memory_DirectMap4k_bytes = node_memory_DirectMap4k_bytes
|
||||
node_memory_Dirty_bytes = node_memory_Dirty_bytes
|
||||
node_memory_HardwareCorrupted_bytes = node_memory_HardwareCorrupted_bytes
|
||||
node_memory_HugePages_Free = node_memory_HugePages_Free
|
||||
node_memory_HugePages_Rsvd = node_memory_HugePages_Rsvd
|
||||
node_memory_HugePages_Surp = node_memory_HugePages_Surp
|
||||
node_memory_HugePages_Total = node_memory_HugePages_Total
|
||||
node_memory_Hugepagesize_bytes = node_memory_Hugepagesize_bytes
|
||||
node_memory_Inactive_anon_bytes = node_memory_Inactive_anon_bytes
|
||||
node_memory_Inactive_bytes = node_memory_Inactive_bytes
|
||||
node_memory_Inactive_file_bytes = node_memory_Inactive_file_bytes
|
||||
node_memory_KernelStack_bytes = node_memory_KernelStack_bytes
|
||||
node_memory_Mapped_bytes = node_memory_Mapped_bytes
|
||||
node_memory_MemAvailable_bytes = node_memory_MemAvailable_bytes
|
||||
node_memory_MemFree_bytes = node_memory_MemFree_bytes
|
||||
node_memory_MemTotal_bytes = node_memory_MemTotal_bytes
|
||||
node_memory_Mlocked_bytes = node_memory_Mlocked_bytes
|
||||
node_memory_NFS_Unstable_bytes = node_memory_NFS_Unstable_bytes
|
||||
node_memory_PageTables_bytes = node_memory_PageTables_bytes
|
||||
node_memory_SReclaimable_bytes = node_memory_SReclaimable_bytes
|
||||
node_memory_SUnreclaim_bytes = node_memory_SUnreclaim_bytes
|
||||
node_memory_Shmem_bytes = node_memory_Shmem_bytes
|
||||
node_memory_Slab_bytes = node_memory_Slab_bytes
|
||||
node_memory_SwapCached_bytes = node_memory_SwapCached_bytes
|
||||
node_memory_SwapFree_bytes = node_memory_SwapFree_bytes
|
||||
node_memory_SwapTotal_bytes = node_memory_SwapTotal_bytes
|
||||
node_memory_Unevictable_bytes = node_memory_Unevictable_bytes
|
||||
node_memory_VmallocChunk_bytes = node_memory_VmallocChunk_bytes
|
||||
node_memory_VmallocTotal_bytes = node_memory_VmallocTotal_bytes
|
||||
node_memory_VmallocUsed_bytes = node_memory_VmallocUsed_bytes
|
||||
node_memory_WritebackTmp_bytes = node_memory_WritebackTmp_bytes
|
||||
node_memory_Writeback_bytes = node_memory_Writeback_bytes
|
||||
node_netstat_Icmp6_InErrors = node_netstat_Icmp6_InErrors
|
||||
node_netstat_Icmp6_InMsgs = node_netstat_Icmp6_InMsgs
|
||||
node_netstat_Icmp6_OutMsgs = node_netstat_Icmp6_OutMsgs
|
||||
node_netstat_Icmp_InErrors = node_netstat_Icmp_InErrors
|
||||
node_netstat_Icmp_InMsgs = node_netstat_Icmp_InMsgs
|
||||
node_netstat_Icmp_OutMsgs = node_netstat_Icmp_OutMsgs
|
||||
node_netstat_Ip6_InOctets = node_netstat_Ip6_InOctets
|
||||
node_netstat_Ip6_OutOctets = node_netstat_Ip6_OutOctets
|
||||
node_netstat_IpExt_InOctets = node_netstat_IpExt_InOctets
|
||||
node_netstat_IpExt_OutOctets = node_netstat_IpExt_OutOctets
|
||||
node_netstat_Ip_Forwarding = node_netstat_Ip_Forwarding
|
||||
node_netstat_TcpExt_ListenDrops = node_netstat_TcpExt_ListenDrops
|
||||
node_netstat_TcpExt_ListenOverflows = node_netstat_TcpExt_ListenOverflows
|
||||
node_netstat_TcpExt_SyncookiesFailed = node_netstat_TcpExt_SyncookiesFailed
|
||||
node_netstat_TcpExt_SyncookiesRecv = node_netstat_TcpExt_SyncookiesRecv
|
||||
node_netstat_TcpExt_SyncookiesSent = node_netstat_TcpExt_SyncookiesSent
|
||||
node_netstat_TcpExt_TCPSynRetrans = node_netstat_TcpExt_TCPSynRetrans
|
||||
node_netstat_Tcp_ActiveOpens = node_netstat_Tcp_ActiveOpens
|
||||
node_netstat_Tcp_CurrEstab = node_netstat_Tcp_CurrEstab
|
||||
node_netstat_Tcp_InErrs = node_netstat_Tcp_InErrs
|
||||
node_netstat_Tcp_InSegs = node_netstat_Tcp_InSegs
|
||||
node_netstat_Tcp_OutRsts = node_netstat_Tcp_OutRsts
|
||||
node_netstat_Tcp_OutSegs = node_netstat_Tcp_OutSegs
|
||||
node_netstat_Tcp_PassiveOpens = node_netstat_Tcp_PassiveOpens
|
||||
node_netstat_Tcp_RetransSegs = node_netstat_Tcp_RetransSegs
|
||||
node_netstat_Udp6_InDatagrams = node_netstat_Udp6_InDatagrams
|
||||
node_netstat_Udp6_InErrors = node_netstat_Udp6_InErrors
|
||||
node_netstat_Udp6_NoPorts = node_netstat_Udp6_NoPorts
|
||||
node_netstat_Udp6_OutDatagrams = node_netstat_Udp6_OutDatagrams
|
||||
node_netstat_Udp6_RcvbufErrors = node_netstat_Udp6_RcvbufErrors
|
||||
node_netstat_Udp6_SndbufErrors = node_netstat_Udp6_SndbufErrors
|
||||
node_netstat_UdpLite6_InErrors = node_netstat_UdpLite6_InErrors
|
||||
node_netstat_UdpLite_InErrors = node_netstat_UdpLite_InErrors
|
||||
node_netstat_Udp_InDatagrams = node_netstat_Udp_InDatagrams
|
||||
node_netstat_Udp_InErrors = node_netstat_Udp_InErrors
|
||||
node_netstat_Udp_NoPorts = node_netstat_Udp_NoPorts
|
||||
node_netstat_Udp_OutDatagrams = node_netstat_Udp_OutDatagrams
|
||||
node_netstat_Udp_RcvbufErrors = node_netstat_Udp_RcvbufErrors
|
||||
node_netstat_Udp_SndbufErrors = node_netstat_Udp_SndbufErrors
|
||||
node_network_address_assign_type = node_network_address_assign_type
|
||||
node_network_carrier = node_network_carrier
|
||||
node_network_carrier_changes_total = node_network_carrier_changes_total
|
||||
node_network_device_id = node_network_device_id
|
||||
node_network_dormant = node_network_dormant
|
||||
node_network_flags = node_network_flags
|
||||
node_network_iface_id = node_network_iface_id
|
||||
node_network_iface_link = node_network_iface_link
|
||||
node_network_iface_link_mode = node_network_iface_link_mode
|
||||
node_network_info = node_network_info
|
||||
node_network_mtu_bytes = node_network_mtu_bytes
|
||||
node_network_net_dev_group = node_network_net_dev_group
|
||||
node_network_protocol_type = node_network_protocol_type
|
||||
node_network_receive_bytes_total = node_network_receive_bytes_total
|
||||
node_network_receive_compressed_total = node_network_receive_compressed_total
|
||||
node_network_receive_drop_total = node_network_receive_drop_total
|
||||
node_network_receive_errs_total = node_network_receive_errs_total
|
||||
node_network_receive_fifo_total = node_network_receive_fifo_total
|
||||
node_network_receive_frame_total = node_network_receive_frame_total
|
||||
node_network_receive_multicast_total = node_network_receive_multicast_total
|
||||
node_network_receive_packets_total = node_network_receive_packets_total
|
||||
node_network_speed_bytes = node_network_speed_bytes
|
||||
node_network_transmit_bytes_total = node_network_transmit_bytes_total
|
||||
node_network_transmit_carrier_total = node_network_transmit_carrier_total
|
||||
node_network_transmit_colls_total = node_network_transmit_colls_total
|
||||
node_network_transmit_compressed_total = node_network_transmit_compressed_total
|
||||
node_network_transmit_drop_total = node_network_transmit_drop_total
|
||||
node_network_transmit_errs_total = node_network_transmit_errs_total
|
||||
node_network_transmit_fifo_total = node_network_transmit_fifo_total
|
||||
node_network_transmit_packets_total = node_network_transmit_packets_total
|
||||
node_network_transmit_queue_length = node_network_transmit_queue_length
|
||||
node_network_up = node_network_up
|
||||
node_nf_conntrack_entries = node_nf_conntrack_entries
|
||||
node_nf_conntrack_entries_limit = node_nf_conntrack_entries_limit
|
||||
node_procs_blocked = node_procs_blocked
|
||||
node_procs_running = node_procs_running
|
||||
node_rapl_dram_joules_total = node_rapl_dram_joules_total
|
||||
node_rapl_package_joules_total = node_rapl_package_joules_total
|
||||
node_schedstat_running_seconds_total = node_schedstat_running_seconds_total
|
||||
node_schedstat_timeslices_total = node_schedstat_timeslices_total
|
||||
node_schedstat_waiting_seconds_total = node_schedstat_waiting_seconds_total
|
||||
node_scrape_collector_duration_seconds = node_scrape_collector_duration_seconds
|
||||
node_scrape_collector_success = node_scrape_collector_success
|
||||
node_sockstat_FRAG6_inuse = node_sockstat_FRAG6_inuse
|
||||
node_sockstat_FRAG6_memory = node_sockstat_FRAG6_memory
|
||||
node_sockstat_FRAG_inuse = node_sockstat_FRAG_inuse
|
||||
node_sockstat_FRAG_memory = node_sockstat_FRAG_memory
|
||||
node_sockstat_RAW6_inuse = node_sockstat_RAW6_inuse
|
||||
node_sockstat_RAW_inuse = node_sockstat_RAW_inuse
|
||||
node_sockstat_TCP6_inuse = node_sockstat_TCP6_inuse
|
||||
node_sockstat_TCP_alloc = node_sockstat_TCP_alloc
|
||||
node_sockstat_TCP_inuse = node_sockstat_TCP_inuse
|
||||
node_sockstat_TCP_mem = node_sockstat_TCP_mem
|
||||
node_sockstat_TCP_mem_bytes = node_sockstat_TCP_mem_bytes
|
||||
node_sockstat_TCP_orphan = node_sockstat_TCP_orphan
|
||||
node_sockstat_TCP_tw = node_sockstat_TCP_tw
|
||||
node_sockstat_UDP6_inuse = node_sockstat_UDP6_inuse
|
||||
node_sockstat_UDPLITE6_inuse = node_sockstat_UDPLITE6_inuse
|
||||
node_sockstat_UDPLITE_inuse = node_sockstat_UDPLITE_inuse
|
||||
node_sockstat_UDP_inuse = node_sockstat_UDP_inuse
|
||||
node_sockstat_UDP_mem = node_sockstat_UDP_mem
|
||||
node_sockstat_UDP_mem_bytes = node_sockstat_UDP_mem_bytes
|
||||
node_sockstat_sockets_used = node_sockstat_sockets_used
|
||||
node_softnet_dropped_total = node_softnet_dropped_total
|
||||
node_softnet_processed_total = node_softnet_processed_total
|
||||
node_softnet_times_squeezed_total = node_softnet_times_squeezed_total
|
||||
node_textfile_scrape_error = node_textfile_scrape_error
|
||||
node_time_seconds = node_time_seconds
|
||||
node_timex_estimated_error_seconds = node_timex_estimated_error_seconds
|
||||
node_timex_frequency_adjustment_ratio = node_timex_frequency_adjustment_ratio
|
||||
node_timex_loop_time_constant = node_timex_loop_time_constant
|
||||
node_timex_maxerror_seconds = node_timex_maxerror_seconds
|
||||
node_timex_offset_seconds = node_timex_offset_seconds
|
||||
node_timex_pps_calibration_total = node_timex_pps_calibration_total
|
||||
node_timex_pps_error_total = node_timex_pps_error_total
|
||||
node_timex_pps_frequency_hertz = node_timex_pps_frequency_hertz
|
||||
node_timex_pps_jitter_seconds = node_timex_pps_jitter_seconds
|
||||
node_timex_pps_jitter_total = node_timex_pps_jitter_total
|
||||
node_timex_pps_shift_seconds = node_timex_pps_shift_seconds
|
||||
node_timex_pps_stability_exceeded_total = node_timex_pps_stability_exceeded_total
|
||||
node_timex_pps_stability_hertz = node_timex_pps_stability_hertz
|
||||
node_timex_status = node_timex_status
|
||||
node_timex_sync_status = node_timex_sync_status
|
||||
node_timex_tai_offset_seconds = node_timex_tai_offset_seconds
|
||||
node_timex_tick_seconds = node_timex_tick_seconds
|
||||
node_udp_queues = node_udp_queues
|
||||
node_uname_info = node_uname_info
|
||||
node_vmstat_pgfault = node_vmstat_pgfault
|
||||
node_vmstat_pgmajfault = node_vmstat_pgmajfault
|
||||
node_vmstat_pgpgin = node_vmstat_pgpgin
|
||||
node_vmstat_pgpgout = node_vmstat_pgpgout
|
||||
node_vmstat_pswpin = node_vmstat_pswpin
|
||||
node_vmstat_pswpout = node_vmstat_pswpout
|
||||
og_context_memory_totalsize = og_context_memory_totalsize
|
||||
og_context_memory_usedsize = og_context_memory_usedsize
|
||||
og_cpu_load_total_cpu = og_cpu_load_total_cpu
|
||||
og_memory_info_memorymbytes = og_memory_info_memorymbytes
|
||||
og_session_memory_totalsize = og_session_memory_totalsize
|
||||
og_session_memory_usedsize = og_session_memory_usedsize
|
||||
og_state_memory_totalsize = og_state_memory_totalsize
|
||||
os_cpu_iowait = os_cpu_iowait
|
||||
os_cpu_processor_number = os_cpu_processor_number
|
||||
os_cpu_usage = os_cpu_usage
|
||||
os_disk_iocapacity = os_disk_iocapacity
|
||||
os_disk_iops = os_disk_iops
|
||||
os_disk_ioutils = os_disk_ioutils
|
||||
os_disk_usage = os_disk_usage
|
||||
os_mem_usage = os_mem_usage
|
||||
pg_active_slowsql_query_runtime = pg_active_slowsql_query_runtime
|
||||
pg_activity_count = pg_activity_count
|
||||
pg_activity_max_conn_duration = pg_activity_max_conn_duration
|
||||
pg_activity_max_duration = pg_activity_max_duration
|
||||
pg_activity_max_tx_duration = pg_activity_max_tx_duration
|
||||
pg_boot_time = pg_boot_time
|
||||
pg_checkpoint_checkpoint_lsn = pg_checkpoint_checkpoint_lsn
|
||||
pg_checkpoint_elapse = pg_checkpoint_elapse
|
||||
pg_checkpoint_full_page_writes = pg_checkpoint_full_page_writes
|
||||
pg_checkpoint_newest_commit_ts_xid = pg_checkpoint_newest_commit_ts_xid
|
||||
pg_checkpoint_next_multi_offset = pg_checkpoint_next_multi_offset
|
||||
pg_checkpoint_next_multixact_id = pg_checkpoint_next_multixact_id
|
||||
pg_checkpoint_next_oid = pg_checkpoint_next_oid
|
||||
pg_checkpoint_next_xid = pg_checkpoint_next_xid
|
||||
pg_checkpoint_next_xid_epoch = pg_checkpoint_next_xid_epoch
|
||||
pg_checkpoint_oldest_active_xid = pg_checkpoint_oldest_active_xid
|
||||
pg_checkpoint_oldest_commit_ts_xid = pg_checkpoint_oldest_commit_ts_xid
|
||||
pg_checkpoint_oldest_multi_dbid = pg_checkpoint_oldest_multi_dbid
|
||||
pg_checkpoint_oldest_multi_xid = pg_checkpoint_oldest_multi_xid
|
||||
pg_checkpoint_oldest_xid = pg_checkpoint_oldest_xid
|
||||
pg_checkpoint_oldest_xid_dbid = pg_checkpoint_oldest_xid_dbid
|
||||
pg_checkpoint_prev_tli = pg_checkpoint_prev_tli
|
||||
pg_checkpoint_redo_lsn = pg_checkpoint_redo_lsn
|
||||
pg_checkpoint_time = pg_checkpoint_time
|
||||
pg_checkpoint_tli = pg_checkpoint_tli
|
||||
pg_class_relage = pg_class_relage
|
||||
pg_class_relpages = pg_class_relpages
|
||||
pg_class_relsize = pg_class_relsize
|
||||
pg_class_reltuples = pg_class_reltuples
|
||||
pg_conf_reload_time = pg_conf_reload_time
|
||||
pg_connections_max_conn = pg_connections_max_conn
|
||||
pg_connections_res_for_normal = pg_connections_res_for_normal
|
||||
pg_connections_used_conn = pg_connections_used_conn
|
||||
pg_database_age = pg_database_age
|
||||
pg_database_allow_conn = pg_database_allow_conn
|
||||
pg_database_conn_limit = pg_database_conn_limit
|
||||
pg_database_frozen_xid = pg_database_frozen_xid
|
||||
pg_database_is_template = pg_database_is_template
|
||||
pg_database_size_bytes = pg_database_size_bytes
|
||||
pg_db_blk_read_time = pg_db_blk_read_time
|
||||
pg_db_blk_write_time = pg_db_blk_write_time
|
||||
pg_db_blks_access = pg_db_blks_access
|
||||
pg_db_blks_hit = pg_db_blks_hit
|
||||
pg_db_blks_read = pg_db_blks_read
|
||||
pg_db_confl_bufferpin = pg_db_confl_bufferpin
|
||||
pg_db_confl_deadlock = pg_db_confl_deadlock
|
||||
pg_db_confl_lock = pg_db_confl_lock
|
||||
pg_db_confl_snapshot = pg_db_confl_snapshot
|
||||
pg_db_confl_tablespace = pg_db_confl_tablespace
|
||||
pg_db_conflicts = pg_db_conflicts
|
||||
pg_db_deadlocks = pg_db_deadlocks
|
||||
pg_db_numbackends = pg_db_numbackends
|
||||
pg_db_stats_reset = pg_db_stats_reset
|
||||
pg_db_temp_bytes = pg_db_temp_bytes
|
||||
pg_db_temp_files = pg_db_temp_files
|
||||
pg_db_tup_deleted = pg_db_tup_deleted
|
||||
pg_db_tup_fetched = pg_db_tup_fetched
|
||||
pg_db_tup_inserted = pg_db_tup_inserted
|
||||
pg_db_tup_returned = pg_db_tup_returned
|
||||
pg_db_tup_updated = pg_db_tup_updated
|
||||
pg_db_xact_commit = pg_db_xact_commit
|
||||
pg_db_xact_rollback = pg_db_xact_rollback
|
||||
pg_downstream_count = pg_downstream_count
|
||||
pg_flush_lsn = pg_flush_lsn
|
||||
pg_index_idx_blks_hit = pg_index_idx_blks_hit
|
||||
pg_index_idx_blks_read = pg_index_idx_blks_read
|
||||
pg_index_idx_scan = pg_index_idx_scan
|
||||
pg_index_idx_tup_fetch = pg_index_idx_tup_fetch
|
||||
pg_index_idx_tup_read = pg_index_idx_tup_read
|
||||
pg_insert_lsn = pg_insert_lsn
|
||||
pg_is_in_recovery = pg_is_in_recovery
|
||||
pg_is_wal_replay_paused = pg_is_wal_replay_paused
|
||||
pg_lag = pg_lag
|
||||
pg_last_replay_time = pg_last_replay_time
|
||||
pg_lock_count = pg_lock_count
|
||||
pg_lock_sql_locked_times = pg_lock_sql_locked_times
|
||||
pg_locker_count = pg_locker_count
|
||||
pg_lsn = pg_lsn
|
||||
pg_meta_info = pg_meta_info
|
||||
pg_need_indexes_idx_scan = pg_need_indexes_idx_scan
|
||||
pg_need_indexes_idx_tup_fetch = pg_need_indexes_idx_tup_fetch
|
||||
pg_need_indexes_rate = pg_need_indexes_rate
|
||||
pg_need_indexes_seq_scan = pg_need_indexes_seq_scan
|
||||
pg_need_indexes_seq_tup_read = pg_need_indexes_seq_tup_read
|
||||
pg_never_used_indexes_index_size = pg_never_used_indexes_index_size
|
||||
pg_node_info_uptime = pg_node_info_uptime
|
||||
pg_receive_lsn = pg_receive_lsn
|
||||
pg_replay_lsn = pg_replay_lsn
|
||||
pg_replication_slots_active = pg_replication_slots_active
|
||||
pg_replication_slots_delay_lsn = pg_replication_slots_delay_lsn
|
||||
pg_run_times_db_role = pg_run_times_db_role
|
||||
pg_run_times_run_time = pg_run_times_run_time
|
||||
pg_session_connection_count = pg_session_connection_count
|
||||
pg_setting_block_size = pg_setting_block_size
|
||||
pg_setting_max_connections = pg_setting_max_connections
|
||||
pg_setting_max_locks_per_transaction = pg_setting_max_locks_per_transaction
|
||||
pg_setting_max_prepared_transactions = pg_setting_max_prepared_transactions
|
||||
pg_setting_max_replication_slots = pg_setting_max_replication_slots
|
||||
pg_setting_max_wal_senders = pg_setting_max_wal_senders
|
||||
pg_setting_wal_log_hints = pg_setting_wal_log_hints
|
||||
pg_settings_setting = pg_settings_setting
|
||||
pg_sql_statement_full_count = pg_sql_statement_full_count
|
||||
pg_sql_statement_history_exc_time = pg_sql_statement_history_exc_time
|
||||
pg_table_analyze_count = pg_table_analyze_count
|
||||
pg_table_analyze_delay = pg_table_analyze_delay
|
||||
pg_table_autoanalyze_count = pg_table_autoanalyze_count
|
||||
pg_table_autovacuum_count = pg_table_autovacuum_count
|
||||
pg_table_heap_blks_hit = pg_table_heap_blks_hit
|
||||
pg_table_heap_blks_read = pg_table_heap_blks_read
|
||||
pg_table_idx_blks_hit = pg_table_idx_blks_hit
|
||||
pg_table_idx_blks_read = pg_table_idx_blks_read
|
||||
pg_table_idx_scan = pg_table_idx_scan
|
||||
pg_table_idx_tup_fetch = pg_table_idx_tup_fetch
|
||||
pg_table_n_dead_tup = pg_table_n_dead_tup
|
||||
pg_table_n_live_tup = pg_table_n_live_tup
|
||||
pg_table_n_mod_since_analyze = pg_table_n_mod_since_analyze
|
||||
pg_table_n_tup_del = pg_table_n_tup_del
|
||||
pg_table_n_tup_hot_upd = pg_table_n_tup_hot_upd
|
||||
pg_table_n_tup_ins = pg_table_n_tup_ins
|
||||
pg_table_n_tup_mod = pg_table_n_tup_mod
|
||||
pg_table_n_tup_upd = pg_table_n_tup_upd
|
||||
pg_table_seq_scan = pg_table_seq_scan
|
||||
pg_table_seq_tup_read = pg_table_seq_tup_read
|
||||
pg_table_tbl_scan = pg_table_tbl_scan
|
||||
pg_table_tidx_blks_hit = pg_table_tidx_blks_hit
|
||||
pg_table_tidx_blks_read = pg_table_tidx_blks_read
|
||||
pg_table_toast_blks_hit = pg_table_toast_blks_hit
|
||||
pg_table_toast_blks_read = pg_table_toast_blks_read
|
||||
pg_table_tup_read = pg_table_tup_read
|
||||
pg_table_vacuum_count = pg_table_vacuum_count
|
||||
pg_table_vacuum_delay = pg_table_vacuum_delay
|
||||
pg_tables_expansion_rate_analyze_count = pg_tables_expansion_rate_analyze_count
|
||||
pg_tables_expansion_rate_autoanalyze_count = pg_tables_expansion_rate_autoanalyze_count
|
||||
pg_tables_expansion_rate_autovacuum_count = pg_tables_expansion_rate_autovacuum_count
|
||||
pg_tables_expansion_rate_dead_rate = pg_tables_expansion_rate_dead_rate
|
||||
pg_tables_expansion_rate_vacuum_count = pg_tables_expansion_rate_vacuum_count
|
||||
pg_tables_size_bytes = pg_tables_size_bytes
|
||||
pg_tables_size_indexsize = pg_tables_size_indexsize
|
||||
pg_tables_size_relsize = pg_tables_size_relsize
|
||||
pg_tables_size_toastsize = pg_tables_size_toastsize
|
||||
pg_thread_pool_listener = pg_thread_pool_listener
|
||||
pg_timestamp = pg_timestamp
|
||||
pg_uptime = pg_uptime
|
||||
pg_wait_events_total_wait_time = pg_wait_events_total_wait_time
|
||||
pg_wait_events_wait = pg_wait_events_wait
|
||||
pg_write_lsn = pg_write_lsn
|
||||
process_cpu_seconds_total = process_cpu_seconds_total
|
||||
process_max_fds = process_max_fds
|
||||
process_open_fds = process_open_fds
|
||||
process_resident_memory_bytes = process_resident_memory_bytes
|
||||
process_start_time_seconds = process_start_time_seconds
|
||||
process_virtual_memory_bytes = process_virtual_memory_bytes
|
||||
process_virtual_memory_max_bytes = process_virtual_memory_max_bytes
|
||||
statement_responsetime_percentile_p80 = statement_responsetime_percentile_p80
|
||||
statement_responsetime_percentile_p95 = statement_responsetime_percentile_p95
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,11 @@ from dbmind.common.types import Sequence
|
|||
from dbmind.common.types.misc import SlowQuery
|
||||
from dbmind.metadatabase import dao
|
||||
|
||||
|
||||
# Singleton pattern with starving formula
|
||||
# will capture exception in the main thread.
|
||||
TsdbClientFactory.get_tsdb_client()
|
||||
|
||||
# Notice: 'DISTINGUISHING_INSTANCE_LABEL' is a magic string, i.e., our own name.
|
||||
# Thus, not all collection agents (such as Prometheus's openGauss-exporter)
|
||||
# distinguish different instance addresses through this one.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import dbmind.common.process
|
|||
from dbmind.common.daemon import Daemon
|
||||
from dbmind.common.platform import WIN32
|
||||
|
||||
BASEPATH = os.path.abspath(os.path.dirname(__file__))
|
||||
BASEPATH = os.path.realpath(os.path.dirname(__file__))
|
||||
PID_NAME = 'tester.pid'
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import os
|
|||
from dbmind.constants import METRIC_MAP_CONFIG, MISC_PATH
|
||||
from dbmind.common import utils
|
||||
|
||||
CURR_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
CURR_DIR = os.path.realpath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def test_read_simple_conf_file():
|
||||
|
|
|
|||
|
|
@ -1920,6 +1920,15 @@ double CopyUHeapDataInternal(Relation oldHeap, Relation oldIndex, Relation newHe
|
|||
return tups_vacuumed;
|
||||
}
|
||||
|
||||
static inline bool tuple_invisible_not_hotupdate(HeapTuple tuple, Relation relation)
|
||||
{
|
||||
if (HeapKeepInvisibleTuple(tuple, RelationGetDescr(relation)) && !HeapTupleIsHotUpdated(tuple)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
double copy_heap_data_internal(Relation OldHeap, Relation OldIndex, Relation NewHeap, TransactionId OldestXmin,
|
||||
TransactionId FreezeXid, bool verbose, bool use_sort, AdaptMem* memUsage)
|
||||
{
|
||||
|
|
@ -2071,7 +2080,7 @@ double copy_heap_data_internal(Relation OldHeap, Relation OldIndex, Relation New
|
|||
switch (HeapTupleSatisfiesVacuum(tuple, OldestXmin, buf)) {
|
||||
case HEAPTUPLE_DEAD:
|
||||
/* Definitely dead */
|
||||
isdead = true;
|
||||
isdead = tuple_invisible_not_hotupdate(tuple, OldHeap);
|
||||
break;
|
||||
case HEAPTUPLE_RECENTLY_DEAD:
|
||||
tups_recently_dead += 1;
|
||||
|
|
|
|||
|
|
@ -454,6 +454,15 @@ void ExplainQuery(
|
|||
*/
|
||||
if (es.format == EXPLAIN_FORMAT_TEXT)
|
||||
appendStringInfoString(es.str, "Query rewrites to nothing\n");
|
||||
|
||||
/*
|
||||
* In centralized mode, non-stream plans only support EXPLAIN_NORMAL.
|
||||
* So set explain_perf_mode to EXPLAIN_NORMAL here.
|
||||
*/
|
||||
if (t_thrd.explain_cxt.explain_perf_mode != EXPLAIN_NORMAL &&
|
||||
!(IS_STREAM_PLAN && u_sess->exec_cxt.under_stream_runtime)) {
|
||||
t_thrd.explain_cxt.explain_perf_mode = EXPLAIN_NORMAL;
|
||||
}
|
||||
} else {
|
||||
ListCell* l = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -6159,6 +6159,11 @@ void renamePartition(RenameStmt* stmt)
|
|||
|
||||
/* Do the work */
|
||||
renamePartitionInternal(partitionedTableOid, partitionOid, stmt->newname);
|
||||
|
||||
Relation parentRel = heap_openrv(stmt->relation, AccessExclusiveLock);
|
||||
Oid relid = RelationGetRelid(parentRel);
|
||||
UpdatePgObjectChangecsn(relid, parentRel->rd_rel->relkind);
|
||||
heap_close(parentRel, NoLock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -6232,6 +6237,11 @@ void renamePartitionIndex(RenameStmt* stmt)
|
|||
|
||||
/* Do the work */
|
||||
renamePartitionInternal(partitionedTableIndexOid, partitionIndexOid, stmt->newname);
|
||||
|
||||
Oid parRelOid = IndexGetRelation(partitionedTableIndexOid, false);
|
||||
Relation partRel = RelationIdGetRelation(parRelOid);
|
||||
UpdatePgObjectChangecsn(parRelOid, partRel->rd_rel->relkind);
|
||||
RelationClose(partRel);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -6993,7 +7003,7 @@ static LOCKMODE GetPartitionLockLevel(AlterTableType subType)
|
|||
case AT_DropSubPartition:
|
||||
case AT_ExchangePartition:
|
||||
case AT_TruncatePartition:
|
||||
cmdLockMode = RowExclusiveLock;
|
||||
cmdLockMode = ShareUpdateExclusiveLock;
|
||||
break;
|
||||
default:
|
||||
cmdLockMode = AccessExclusiveLock;
|
||||
|
|
@ -20816,29 +20826,36 @@ static void renamePartitionIndexes(Oid partitionedTableOid, Oid partitionOid, ch
|
|||
* Description :
|
||||
* Notes :
|
||||
*/
|
||||
static void heap_truncate_one_part_new(const AlterTableCmd* cmd, Relation rel, Oid srcPartOid) {
|
||||
static void heap_truncate_one_part_new(const AlterTableCmd* cmd, Relation partRel, Oid srcPartOid,
|
||||
Relation rel = InvalidRelation)
|
||||
{
|
||||
Partition srcPart = NULL;
|
||||
bool renameTargetPart = false;
|
||||
char* destPartitionName = NULL;
|
||||
|
||||
Oid destPartOid = AddTemporaryPartitionForAlterPartitions(cmd, rel, srcPartOid, &renameTargetPart);
|
||||
Oid destPartOid = AddTemporaryPartitionForAlterPartitions(cmd, partRel, srcPartOid, &renameTargetPart);
|
||||
|
||||
List* indexList = RelationGetSpecificKindIndexList(rel, false);
|
||||
List* indexList = NULL;
|
||||
if (RelationIsPartitionOfSubPartitionTable(partRel) && RelationIsValid(rel)) {
|
||||
indexList = RelationGetSpecificKindIndexList(rel, false);
|
||||
} else {
|
||||
indexList = RelationGetSpecificKindIndexList(partRel, false);
|
||||
}
|
||||
char** partitionIndexNames = getPartitionIndexesName(srcPartOid, indexList);
|
||||
|
||||
srcPart = partitionOpen(rel, srcPartOid, AccessExclusiveLock);
|
||||
srcPart = partitionOpen(partRel, srcPartOid, AccessExclusiveLock);
|
||||
destPartitionName = pstrdup(PartitionGetPartitionName(srcPart));
|
||||
partitionClose(rel, srcPart, NoLock);
|
||||
partitionClose(partRel, srcPart, NoLock);
|
||||
|
||||
CommandCounterIncrement();
|
||||
fastDropPartition(rel, srcPartOid, "TRUNCATE PARTITION");
|
||||
fastDropPartition(partRel, srcPartOid, "TRUNCATE PARTITION");
|
||||
|
||||
CommandCounterIncrement();
|
||||
renamePartitionIndexes(rel->rd_id, destPartOid, partitionIndexNames, indexList);
|
||||
renamePartitionIndexes(partRel->rd_id, destPartOid, partitionIndexNames, indexList);
|
||||
|
||||
if (renameTargetPart) {
|
||||
CommandCounterIncrement();
|
||||
renamePartitionInternal(rel->rd_id, destPartOid, destPartitionName);
|
||||
renamePartitionInternal(partRel->rd_id, destPartOid, destPartitionName);
|
||||
}
|
||||
|
||||
list_free_ext(indexList);
|
||||
|
|
@ -20861,13 +20878,20 @@ static void ATExecTruncatePartitionForSubpartitionTable(Relation rel, Oid partOi
|
|||
}
|
||||
foreach (subPartOidCell, subPartOidList) {
|
||||
Oid subPartOid = lfirst_oid(subPartOidCell);
|
||||
bool all_ubtree = true;
|
||||
|
||||
AlterSubPartitionedSetWaitCleanGPI(cmd->alterGPI, rel, partOid, subPartOid);
|
||||
if (cmd->alterGPI) {
|
||||
/* Delete subpartition tuples in GPI and add parent to pending vacuum list */
|
||||
DeleteGPITuplesForSubPartition(RelationGetRelid(rel), partOid, subPartOid);
|
||||
all_ubtree = DeleteGPITuplesForSubPartition(RelationGetRelid(rel), partOid, subPartOid);
|
||||
AlterSubPartitionedSetWaitCleanGPI(cmd->alterGPI, rel, partOid, subPartOid);
|
||||
}
|
||||
|
||||
if (all_ubtree) {
|
||||
/* If no nbtree global index exists */
|
||||
heap_truncate_one_part(partRel, subPartOid);
|
||||
} else {
|
||||
heap_truncate_one_part_new(cmd, partRel, subPartOid, rel);
|
||||
}
|
||||
heap_truncate_one_part(partRel, subPartOid);
|
||||
pgstat_report_truncate(subPartOid, partRel->rd_id, partRel->rd_rel->relisshared);
|
||||
}
|
||||
|
||||
|
|
@ -21029,6 +21053,7 @@ static void ATExecTruncateSubPartition(Relation rel, AlterTableCmd* cmd)
|
|||
List* oidList = NULL;
|
||||
List* relid = lappend_oid(NULL, rel->rd_id);
|
||||
Oid subPartOid = InvalidOid;
|
||||
bool all_ubtree = true;
|
||||
|
||||
oidList = heap_truncate_find_FKs(relid);
|
||||
if (PointerIsValid(oidList)) {
|
||||
|
|
@ -21066,17 +21091,21 @@ static void ATExecTruncateSubPartition(Relation rel, AlterTableCmd* cmd)
|
|||
Partition part = partitionOpen(rel, partOid, AccessExclusiveLock);
|
||||
Relation partRel = partitionGetRelation(rel, part);
|
||||
|
||||
AlterSubPartitionedSetWaitCleanGPI(cmd->alterGPI, rel, partOid, subPartOid);
|
||||
|
||||
if (!cmd->alterGPI) {
|
||||
// Unusable Global Index
|
||||
ATUnusableGlobalIndex(rel);
|
||||
} else {
|
||||
/* Delete subpartition tuples in GPI and add parent to pending vacuum list */
|
||||
DeleteGPITuplesForSubPartition(RelationGetRelid(rel), partOid, subPartOid);
|
||||
all_ubtree = DeleteGPITuplesForSubPartition(RelationGetRelid(rel), partOid, subPartOid);
|
||||
AlterSubPartitionedSetWaitCleanGPI(cmd->alterGPI, rel, partOid, subPartOid);
|
||||
}
|
||||
|
||||
heap_truncate_one_part(partRel, subPartOid);
|
||||
if (all_ubtree) {
|
||||
/* If no nbtree global index exists */
|
||||
heap_truncate_one_part(partRel, subPartOid);
|
||||
} else {
|
||||
heap_truncate_one_part_new(cmd, partRel, subPartOid, rel);
|
||||
}
|
||||
pgstat_report_truncate(subPartOid, partRel->rd_id, partRel->rd_rel->relisshared);
|
||||
|
||||
releaseDummyRelation(&partRel);
|
||||
|
|
@ -24406,11 +24435,11 @@ static char* GenTemporaryPartitionName(Relation partTableRel, int sequence)
|
|||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
static Oid GetNewPartitionOid(Relation pgPartRel, Relation partTableRel, Node *partDef, Oid bucketOid,
|
||||
bool *isTimestamptz, StorageType stype, Datum new_reloptions)
|
||||
bool *isTimestamptz, StorageType stype, Datum new_reloptions, bool isSubpartition)
|
||||
{
|
||||
#else
|
||||
static Oid GetNewPartitionOid(Relation pgPartRel, Relation partTableRel, Node *partDef,
|
||||
Oid bucketOid, bool *isTimestamptz, StorageType stype)
|
||||
Oid bucketOid, bool *isTimestamptz, StorageType stype, bool isSubpartition)
|
||||
{
|
||||
Datum new_reloptions = (Datum)0;
|
||||
#endif
|
||||
|
|
@ -24426,7 +24455,9 @@ static Oid GetNewPartitionOid(Relation pgPartRel, Relation partTableRel, Node *p
|
|||
(Datum)new_reloptions,
|
||||
isTimestamptz,
|
||||
stype,
|
||||
AccessExclusiveLock);
|
||||
AccessExclusiveLock,
|
||||
NULL,
|
||||
isSubpartition);
|
||||
break;
|
||||
case T_ListPartitionDefState:
|
||||
newPartOid = HeapAddListPartition(pgPartRel,
|
||||
|
|
@ -24437,7 +24468,9 @@ static Oid GetNewPartitionOid(Relation pgPartRel, Relation partTableRel, Node *p
|
|||
partTableRel->rd_rel->relowner,
|
||||
(Datum)new_reloptions,
|
||||
isTimestamptz,
|
||||
stype);
|
||||
stype,
|
||||
NULL,
|
||||
isSubpartition);
|
||||
break;
|
||||
case T_HashPartitionDefState:
|
||||
newPartOid = HeapAddHashPartition(pgPartRel,
|
||||
|
|
@ -24448,7 +24481,9 @@ static Oid GetNewPartitionOid(Relation pgPartRel, Relation partTableRel, Node *p
|
|||
partTableRel->rd_rel->relowner,
|
||||
(Datum)new_reloptions,
|
||||
isTimestamptz,
|
||||
stype);
|
||||
stype,
|
||||
NULL,
|
||||
isSubpartition);
|
||||
break;
|
||||
default:
|
||||
ereport(ERROR,
|
||||
|
|
@ -24480,17 +24515,20 @@ static Oid AddTemporaryPartition(Relation partTableRel, Node* partDef)
|
|||
Datum rel_reloptions;
|
||||
Datum new_reloptions;
|
||||
List* old_reloptions = NIL;
|
||||
bool isPartitionOfSubPartition = RelationIsPartitionOfSubPartitionTable(partTableRel);
|
||||
|
||||
bool* isTimestamptz = CheckPartkeyHasTimestampwithzone(partTableRel);
|
||||
bucketOid = RelationGetBucketOid(partTableRel);
|
||||
pgPartRel = relation_open(PartitionRelationId, RowExclusiveLock);
|
||||
|
||||
/* add new partition entry in pg_partition */
|
||||
tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(partTableRel->rd_id));
|
||||
Oid relOid = isPartitionOfSubPartition ?
|
||||
ObjectIdGetDatum(partTableRel->parentId) : ObjectIdGetDatum(partTableRel->rd_id);
|
||||
tuple = SearchSysCache1(RELOID, relOid);
|
||||
if (!HeapTupleIsValid(tuple)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_CACHE_LOOKUP_FAILED),
|
||||
(errmsg("cache lookup failed"), errdetail("cache lookup failed for relation %u", partTableRel->rd_id),
|
||||
(errmsg("cache lookup failed"), errdetail("cache lookup failed for relation %u", relOid),
|
||||
errcause("The oid of the target relation is invalid."),
|
||||
erraction("Check whether the target relation is correct."))));
|
||||
}
|
||||
|
|
@ -24508,18 +24546,25 @@ static Oid AddTemporaryPartition(Relation partTableRel, Node* partDef)
|
|||
/* Temporary tables do not use segment-page */
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
newPartOid = GetNewPartitionOid(pgPartRel, partTableRel, partDef, bucketOid,
|
||||
isTimestamptz, RelationGetStorageType(partTableRel), new_reloptions);
|
||||
isTimestamptz, RelationGetStorageType(partTableRel), new_reloptions, isPartitionOfSubPartition);
|
||||
#else
|
||||
newPartOid = GetNewPartitionOid(
|
||||
pgPartRel, partTableRel, partDef, bucketOid, isTimestamptz, RelationGetStorageType(partTableRel));
|
||||
newPartOid = GetNewPartitionOid(pgPartRel, partTableRel, partDef, bucketOid, isTimestamptz,
|
||||
RelationGetStorageType(partTableRel), isPartitionOfSubPartition);
|
||||
|
||||
#endif
|
||||
// We must bump the command counter to make the newly-created
|
||||
// partition tuple visible for opening.
|
||||
CommandCounterIncrement();
|
||||
|
||||
addIndexForPartition(partTableRel, newPartOid);
|
||||
if (isPartitionOfSubPartition) {
|
||||
Relation rel = heap_open(partTableRel->parentId, AccessShareLock);
|
||||
addIndexForPartition(rel, newPartOid);
|
||||
heap_close(rel, NoLock);
|
||||
} else {
|
||||
addIndexForPartition(partTableRel, newPartOid);
|
||||
}
|
||||
|
||||
addToastTableForNewPartition(partTableRel, newPartOid);
|
||||
addToastTableForNewPartition(partTableRel, newPartOid, isPartitionOfSubPartition);
|
||||
|
||||
// invalidate relation
|
||||
CacheInvalidateRelcache(partTableRel);
|
||||
|
|
|
|||
|
|
@ -6052,6 +6052,9 @@ static Datum gs_calculate_encrypted_sm3_password(const char* password, const cha
|
|||
Datum calculate_encrypted_password(bool is_encrypted, const char* password, const char* rolname,
|
||||
const char* salt_string)
|
||||
{
|
||||
if (password == NULL || password[0] == '\0') {
|
||||
ereport(ERROR, (errcode(ERRCODE_INVALID_PASSWORD), errmsg("The password could not be NULL.")));
|
||||
}
|
||||
errno_t rc = EOK;
|
||||
char encrypted_md5_password[MD5_PASSWD_LEN + 1] = {0};
|
||||
Datum datum_value;
|
||||
|
|
|
|||
|
|
@ -130,7 +130,8 @@ static void DropEmptyPartitionDirectories(Oid relid);
|
|||
static THR_LOCAL BufferAccessStrategy vac_strategy;
|
||||
static THR_LOCAL int elevel = -1;
|
||||
|
||||
static void UstoreVacuumGPIPartition(Oid relid, Relation rel);
|
||||
static void UstoreVacuumMainPartitionGPIs(Relation onerel, const VacuumStmt* vacstmt,
|
||||
LOCKMODE lockmode, BufferAccessStrategy bstrategy);
|
||||
|
||||
static void vac_truncate_clog(TransactionId frozenXID, MultiXactId frozenMulti);
|
||||
static bool vacuum_rel(Oid relid, VacuumStmt* vacstmt, bool do_toast);
|
||||
|
|
@ -2436,13 +2437,13 @@ static bool vacuum_rel(Oid relid, VacuumStmt* vacstmt, bool do_toast)
|
|||
* relation.
|
||||
*/
|
||||
|
||||
bool isUstoreGPI = RelationIsUstoreIndex(onerel) && RelationIsGlobalIndex(onerel);
|
||||
bool isPartitionedUHeap = RelationIsUstoreFormat(onerel) && RelationIsPartitioned(onerel);
|
||||
if (onerel->rd_rel->relkind != RELKIND_RELATION &&
|
||||
#ifdef ENABLE_MOT
|
||||
!(RelationIsForeignTable(onerel) && isMOTFromTblOid(onerel->rd_id)) &&
|
||||
#endif
|
||||
onerel->rd_rel->relkind != RELKIND_MATVIEW &&
|
||||
onerel->rd_rel->relkind != RELKIND_TOASTVALUE && !isUstoreGPI) {
|
||||
onerel->rd_rel->relkind != RELKIND_TOASTVALUE && !isPartitionedUHeap) {
|
||||
|
||||
if (vacstmt->options & VACOPT_VERBOSE)
|
||||
messageLevel = VERBOSEMESSAGE;
|
||||
|
|
@ -2755,16 +2756,16 @@ static bool vacuum_rel(Oid relid, VacuumStmt* vacstmt, bool do_toast)
|
|||
}
|
||||
} else if (vacuumMainPartition((uint32)(vacstmt->flags))) {
|
||||
pgstat_report_waitstatus_relname(STATE_VACUUM, get_nsp_relname(relid));
|
||||
GPIVacuumMainPartition(onerel, vacstmt, lmode, vac_strategy);
|
||||
CBIVacuumMainPartition(onerel, vacstmt, lmode, vac_strategy);
|
||||
if (isPartitionedUHeap) {
|
||||
UstoreVacuumMainPartitionGPIs(onerel, vacstmt, lmode, vac_strategy);
|
||||
} else {
|
||||
GPIVacuumMainPartition(onerel, vacstmt, lmode, vac_strategy);
|
||||
CBIVacuumMainPartition(onerel, vacstmt, lmode, vac_strategy);
|
||||
}
|
||||
pgstat_report_vacuum(relid, InvalidOid, false, 0);
|
||||
} else {
|
||||
pgstat_report_waitstatus_relname(STATE_VACUUM, get_nsp_relname(relid));
|
||||
if (isUstoreGPI) {
|
||||
UstoreVacuumGPIPartition(relid, onerel);
|
||||
} else {
|
||||
TableRelationVacuum(onerel, vacstmt, vac_strategy);
|
||||
}
|
||||
TableRelationVacuum(onerel, vacstmt, vac_strategy);
|
||||
}
|
||||
}
|
||||
(void)pgstat_report_waitstatus(oldStatus);
|
||||
|
|
@ -4406,99 +4407,73 @@ static void GPIOpenGlobalIndexes(Relation onerel, LOCKMODE lockmode, int* nindex
|
|||
}
|
||||
|
||||
|
||||
static void UstoreVacuumGPIPartition(Oid relid, Relation rel)
|
||||
static void UstoreVacuumMainPartitionGPIs(Relation onerel, const VacuumStmt* vacstmt,
|
||||
LOCKMODE lockmode, BufferAccessStrategy bstrategy)
|
||||
{
|
||||
ScanKeyData skey[2];
|
||||
/* Open pg_index to find out the relation owning current GPI. */
|
||||
Relation pgIndex = heap_open(IndexRelationId, AccessShareLock);
|
||||
ScanKeyInit(&skey[0], Anum_pg_index_indexrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid));
|
||||
SysScanDesc scanIndexes = systable_beginscan(pgIndex, IndexRelidIndexId, true, NULL, 1, skey);
|
||||
HeapTuple indexTuple = systable_getnext(scanIndexes);
|
||||
if (!HeapTupleIsValid(indexTuple)) {
|
||||
systable_endscan(scanIndexes);
|
||||
heap_close(pgIndex, NoLock);
|
||||
return;
|
||||
OidRBTree* invisibleParts = CreateOidRBTree();
|
||||
Oid parentOid = RelationGetRelid(onerel);
|
||||
|
||||
if (vacstmt->options & VACOPT_VERBOSE) {
|
||||
elevel = VERBOSEMESSAGE;
|
||||
} else {
|
||||
elevel = DEBUG2;
|
||||
}
|
||||
/* Get the Oid of relation. */
|
||||
Form_pg_index indexTupleForm = (Form_pg_index)GETSTRUCT(indexTuple);
|
||||
Oid indexOfRelOid = indexTupleForm->indrelid;
|
||||
systable_endscan(scanIndexes);
|
||||
heap_close(pgIndex, NoLock);
|
||||
/* Here we first get the main partition of the relation, and then check its
|
||||
* wait_cleanup_gpi flag is 'y' or 'n':
|
||||
* 1. If wait_cleanup_gpi=y, which means we need to vacuum the GPI.
|
||||
* 2. If wait_cleanup_gpi=n, which means we do not need to vacuum the GPI.
|
||||
*/
|
||||
Relation pgPartition = heap_open(PartitionRelationId, RowExclusiveLock);
|
||||
ScanKeyInit(&skey[0], Anum_pg_partition_parttype, BTEqualStrategyNumber,
|
||||
F_CHAREQ, CharGetDatum(PART_OBJ_TYPE_PARTED_TABLE));
|
||||
ScanKeyInit(&skey[1], Anum_pg_partition_parentid, BTEqualStrategyNumber,
|
||||
F_OIDEQ, ObjectIdGetDatum(indexOfRelOid));
|
||||
SysScanDesc scanParts = systable_beginscan(pgPartition, PartitionParentOidIndexId,
|
||||
true, NULL, 2, skey);
|
||||
HeapTuple partTuple = systable_getnext(scanParts);
|
||||
if (!HeapTupleIsValid(partTuple)) {
|
||||
systable_endscan(scanParts);
|
||||
heap_close(pgPartition, NoLock);
|
||||
return;
|
||||
}
|
||||
Form_pg_partition partTupleForm = (Form_pg_partition)GETSTRUCT(partTuple);
|
||||
partTuple = SearchSysCache3(PARTPARTOID, PointerGetDatum(partTupleForm->relname.data),
|
||||
CharGetDatum(PART_OBJ_TYPE_PARTED_TABLE), ObjectIdGetDatum(indexOfRelOid));
|
||||
systable_endscan(scanParts);
|
||||
if (!HeapTupleIsValid(partTuple)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_CACHE_LOOKUP_FAILED),
|
||||
errmsg("cache lookup failed for partition %u", indexOfRelOid)));
|
||||
}
|
||||
/* Use PartitionInvisibleMetadataKeep to judge the wait_cleanup_gpi flag. */
|
||||
bool isNull = false;
|
||||
Datum partOptions = fastgetattr(partTuple, Anum_pg_partition_reloptions,
|
||||
RelationGetDescr(pgPartition), &isNull);
|
||||
if (isNull || !PartitionInvisibleMetadataKeep(partOptions)) {
|
||||
ReleaseSysCache(partTuple);
|
||||
heap_close(pgPartition, NoLock);
|
||||
return;
|
||||
}
|
||||
/* Find out the invisible parts of the relation. */
|
||||
OidRBTree *invisibleParts = CreateOidRBTree();
|
||||
if (ConditionalLockPartition(indexOfRelOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK)) {
|
||||
PartitionGetAllInvisibleParts(indexOfRelOid, &invisibleParts);
|
||||
UnlockPartition(indexOfRelOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK);
|
||||
|
||||
/* Get invisable parts */
|
||||
if (ConditionalLockPartition(parentOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK)) {
|
||||
PartitionGetAllInvisibleParts(parentOid, &invisibleParts);
|
||||
UnlockPartition(parentOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK);
|
||||
}
|
||||
|
||||
/* In rbtree, rb_leftmost will return NULL if rbtree is empty. */
|
||||
if (rb_leftmost(invisibleParts) == NULL) {
|
||||
DestroyOidRBTree(&invisibleParts);
|
||||
ReleaseSysCache(partTuple);
|
||||
heap_close(pgPartition, NoLock);
|
||||
return;
|
||||
}
|
||||
/* Start the cleanup process and collect the info needed */
|
||||
IndexVacuumInfo ivinfo;
|
||||
ivinfo.index = rel;
|
||||
ivinfo.analyze_only = false;
|
||||
ivinfo.estimated_count = false;
|
||||
ivinfo.message_level = elevel;
|
||||
ivinfo.num_heap_tuples = -1;
|
||||
ivinfo.strategy = vac_strategy;
|
||||
ivinfo.invisibleParts = invisibleParts;
|
||||
/* Cleanup process of index */
|
||||
index_vacuum_cleanup(&ivinfo, NULL);
|
||||
OidRBTree *cleanedParts = CreateOidRBTree();
|
||||
|
||||
vac_strategy = bstrategy;
|
||||
|
||||
/* Open all global indexes of the main partition */
|
||||
Relation* iRel = NULL;
|
||||
int nIndexes;
|
||||
GPIOpenGlobalIndexes(onerel, lockmode, &nIndexes, &iRel);
|
||||
Relation classRel = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
for (int i = 0; i < nIndexes; i++) {
|
||||
/* Start the cleanup process and collect the info needed */
|
||||
IndexVacuumInfo ivinfo;
|
||||
ivinfo.index = iRel[i];
|
||||
ivinfo.analyze_only = false;
|
||||
ivinfo.estimated_count = false;
|
||||
ivinfo.message_level = elevel;
|
||||
ivinfo.num_heap_tuples = -1;
|
||||
ivinfo.strategy = vac_strategy;
|
||||
ivinfo.invisibleParts = invisibleParts;
|
||||
|
||||
/* Cleanup process of index */
|
||||
index_bulk_delete(&ivinfo, NULL, NULL, NULL);
|
||||
|
||||
index_close(iRel[i], lockmode);
|
||||
}
|
||||
heap_close(classRel, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
* Before clearing the global partition index of a partition table,
|
||||
* acquire a AccessShareLock on ADD_PARTITION_ACTION, and make sure that the interval partition
|
||||
* creation process will not be performed concurrently.
|
||||
*/
|
||||
OidRBTree* cleanedParts = CreateOidRBTree();
|
||||
OidRBTreeUnionOids(cleanedParts, invisibleParts);
|
||||
if (ConditionalLockPartition(indexOfRelOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK)) {
|
||||
PartitionSetEnabledClean(indexOfRelOid, cleanedParts, invisibleParts, true);
|
||||
UnlockPartition(indexOfRelOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK);
|
||||
if (ConditionalLockPartition(parentOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK)) {
|
||||
PartitionSetEnabledClean(parentOid, cleanedParts, invisibleParts, true);
|
||||
UnlockPartition(parentOid, ADD_PARTITION_ACTION, AccessShareLock, PARTITION_SEQUENCE_LOCK);
|
||||
} else {
|
||||
/* Updates reloptions of cleanedParts in pg_partition after GPI vacuum is executed */
|
||||
PartitionSetEnabledClean(indexOfRelOid, cleanedParts, invisibleParts, false);
|
||||
PartitionSetEnabledClean(parentOid, cleanedParts, invisibleParts, false);
|
||||
}
|
||||
|
||||
DestroyOidRBTree(&invisibleParts);
|
||||
DestroyOidRBTree(&cleanedParts);
|
||||
/* Set wait_cleanup_gpi=n after we finish the vacuum cleanup. */
|
||||
UpdateWaitCleanGpiRelOptions(pgPartition, partTuple, false, true);
|
||||
ReleaseSysCache(partTuple);
|
||||
heap_close(pgPartition, NoLock);
|
||||
pfree_ext(iRel);
|
||||
}
|
||||
|
||||
// vacuum main partition table to delete invisible tuple in global partition index
|
||||
|
|
|
|||
|
|
@ -1051,9 +1051,11 @@ static IndexBulkDeleteResult** lazy_scan_heap(
|
|||
OffsetNumber offnum, maxoff;
|
||||
bool tupgone = false;
|
||||
bool hastup = false;
|
||||
bool keepThisInvisbleTuple = false;
|
||||
bool keepThisInvisibleTuple = false;
|
||||
int prev_dead_count;
|
||||
OffsetNumber invalid[MaxOffsetNumber];
|
||||
OffsetNumber frozen[MaxOffsetNumber];
|
||||
int ninvalid = 0;
|
||||
int nfrozen;
|
||||
Size freespace;
|
||||
bool all_visible_according_to_vm = false;
|
||||
|
|
@ -1335,7 +1337,7 @@ static IndexBulkDeleteResult** lazy_scan_heap(
|
|||
tuple.t_bucketId = RelationGetBktid(onerel);
|
||||
HeapTupleCopyBaseFromPage(&tuple, page);
|
||||
tupgone = false;
|
||||
keepThisInvisbleTuple = false;
|
||||
keepThisInvisibleTuple = false;
|
||||
|
||||
if (u_sess->attr.attr_storage.enable_debug_vacuum)
|
||||
t_thrd.utils_cxt.pRelatedRel = onerel;
|
||||
|
|
@ -1358,8 +1360,8 @@ static IndexBulkDeleteResult** lazy_scan_heap(
|
|||
* cheaper to get rid of it in the next pruning pass than
|
||||
* to treat it like an indexed tuple.
|
||||
*/
|
||||
keepThisInvisbleTuple = HeapKeepInvisbleTuple(&tuple, RelationGetDescr(onerel));
|
||||
if (HeapTupleIsHotUpdated(&tuple) || HeapTupleIsHeapOnly(&tuple) || keepThisInvisbleTuple) {
|
||||
keepThisInvisibleTuple = HeapKeepInvisibleTuple(&tuple, RelationGetDescr(onerel));
|
||||
if (HeapTupleIsHotUpdated(&tuple) || HeapTupleIsHeapOnly(&tuple) || keepThisInvisibleTuple) {
|
||||
nkeep += 1;
|
||||
} else {
|
||||
tupgone = true; /* we can delete the tuple */
|
||||
|
|
@ -1437,8 +1439,15 @@ static IndexBulkDeleteResult** lazy_scan_heap(
|
|||
|
||||
tups_vacuumed += 1;
|
||||
has_dead_tuples = true;
|
||||
} else if (keepThisInvisbleTuple) {
|
||||
vacrelstats->hasKeepInvisbleTuples = true;
|
||||
} else if (keepThisInvisibleTuple) {
|
||||
if (t_thrd.proc->workingVersionNum >= INVALID_INVISIBLE_TUPLE_VERSION
|
||||
&& !HeapTupleIsHotUpdated(&tuple)) {
|
||||
heap_invalid_invisible_tuple(&tuple);
|
||||
Assert(tuple.t_tableOid == PartitionRelationId);
|
||||
invalid[ninvalid++] = offnum;
|
||||
} else {
|
||||
vacrelstats->hasKeepInvisbleTuples = true;
|
||||
}
|
||||
} else {
|
||||
num_tuples += 1;
|
||||
hastup = true;
|
||||
|
|
@ -1478,6 +1487,23 @@ static IndexBulkDeleteResult** lazy_scan_heap(
|
|||
}
|
||||
}
|
||||
|
||||
if (ninvalid > 0) {
|
||||
START_CRIT_SECTION();
|
||||
MarkBufferDirty(buf);
|
||||
if (RelationNeedsWAL(onerel)) {
|
||||
XLogRecPtr recptr;
|
||||
|
||||
recptr = log_heap_invalid(onerel, buf, u_sess->cmd_cxt.FreezeLimit,
|
||||
invalid, ninvalid);
|
||||
PageSetLSN(page, recptr);
|
||||
}
|
||||
END_CRIT_SECTION();
|
||||
if (TransactionIdPrecedes(((HeapPageHeader)page)->pd_xid_base, u_sess->utils_cxt.RecentXmin)) {
|
||||
if (u_sess->utils_cxt.RecentXmin - ((HeapPageHeader)page)->pd_xid_base > CHANGE_XID_BASE)
|
||||
(void)heap_change_xidbase_after_freeze(onerel, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are no indexes then we can vacuum the page right now
|
||||
* instead of doing a second scan.
|
||||
|
|
|
|||
|
|
@ -873,6 +873,31 @@ static void SetPlainReSizeWithPruningRatio(RelOptInfo *rel, double pruningRatio)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function applies only to single partition key of range partitioned tables in PBE mode.
|
||||
*/
|
||||
static bool IsPbeSinglePartition(Relation rel, RelOptInfo* relInfo)
|
||||
{
|
||||
if (relInfo->pruning_result->paramArg == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (RelationIsSubPartitioned(rel)) {
|
||||
return false;
|
||||
}
|
||||
if (rel->partMap->type != PART_TYPE_RANGE) {
|
||||
return false;
|
||||
}
|
||||
RangePartitionMap* partMap = (RangePartitionMap*)rel->partMap;
|
||||
int partKeyNum = partMap->partitionKey->dim1;
|
||||
if (partKeyNum > 1) {
|
||||
return false;
|
||||
}
|
||||
if (relInfo->pruning_result->isPbeSinlePartition) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* set_plain_rel_size
|
||||
* Set size estimates for a plain relation (no subquery, no inheritance)
|
||||
|
|
@ -896,8 +921,7 @@ static void set_plain_rel_size(PlannerInfo* root, RelOptInfo* rel, RangeTblEntry
|
|||
|
||||
Assert(rel->pruning_result);
|
||||
|
||||
|
||||
if (rel->pruning_result->expr != NULL) {
|
||||
if (IsPbeSinglePartition(relation, rel)) {
|
||||
rel->partItrs = 1;
|
||||
} else {
|
||||
/* set flag for dealing with partintioned table */
|
||||
|
|
|
|||
|
|
@ -222,6 +222,8 @@ static bool relIsDeltaNode(PlannerInfo* root, RelOptInfo* relOptInfo);
|
|||
|
||||
static void ModifyWorktableWtParam(Node* planNode, int oldWtParam, int newWtParam);
|
||||
|
||||
static bool ScanQualsViolateNotNullConstr(PlannerInfo* root, RelOptInfo* rel, Path* best_path);
|
||||
|
||||
#define SATISFY_INFORMATIONAL_CONSTRAINT(joinPlan, joinType) \
|
||||
(u_sess->attr.attr_sql.enable_constraint_optimization && true == innerPlan((joinPlan))->hasUniqueResults && \
|
||||
JOIN_SEMI != (joinType) && JOIN_ANTI != (joinType))
|
||||
|
|
@ -752,11 +754,49 @@ static Plan* create_scan_plan(PlannerInfo* root, Path* best_path)
|
|||
*/
|
||||
if (root->hasPseudoConstantQuals) {
|
||||
plan = create_gating_plan(root, plan, scan_clauses);
|
||||
} else if (ScanQualsViolateNotNullConstr(root, rel, best_path)) {
|
||||
/*
|
||||
* If there is IS NULL qual on a known NOT-NULL attribute, insert a Result node to prevent needless execution.
|
||||
*/
|
||||
plan = (Plan*)make_result(root, plan->targetlist, (Node*)list_make1(makeBoolConst(false, false)), plan);
|
||||
}
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
||||
static bool IsScanPath(NodeTag type)
|
||||
{
|
||||
return (
|
||||
type == T_CStoreScan || type == T_CStoreIndexScan || type == T_CStoreIndexHeapScan || type == T_SeqScan ||
|
||||
type == T_DfsScan || type == T_IndexScan || type == T_IndexOnlyScan || type == T_BitmapHeapScan
|
||||
);
|
||||
}
|
||||
|
||||
static bool ScanQualsViolateNotNullConstr(PlannerInfo* root, RelOptInfo* rel, Path* best_path)
|
||||
{
|
||||
/* For now, we only support table scan optimization */
|
||||
if (rel->rtekind != RTE_RELATION || !IsScanPath(best_path->pathtype)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List* scan_clauses = rel->baserestrictinfo;
|
||||
ListCell* lc = NULL;
|
||||
foreach (lc, scan_clauses) {
|
||||
Node* clause = (Node*)lfirst(lc);
|
||||
if (IsA(clause, RestrictInfo) && IsA(((RestrictInfo*)clause)->clause, NullTest)) {
|
||||
NullTest* expr = (NullTest*)((RestrictInfo*)clause)->clause;
|
||||
/* For attribute with NOT-NULL constraint, IS-NULL expression can be short-circuited */
|
||||
if (expr->nulltesttype != IS_NULL || !IsA(expr->arg, Var)) {
|
||||
continue;
|
||||
}
|
||||
if (check_var_nonnullable(root->parse, (Node*)expr->arg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a target list (ie, a list of TargetEntry) for a relation.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -67,6 +67,43 @@
|
|||
#include "utils/fmgroids.h"
|
||||
#include "access/heapam.h"
|
||||
|
||||
/*
|
||||
* Check whether the current statement supports Stream based on the status of 'context' and 'query'.
|
||||
* If Stream is supported, a copy of the 'query' is returned as a backup in case generating a plan
|
||||
* with Stream fails.
|
||||
*/
|
||||
static Query* check_shippable(bool *stream_unsupport, Query* query, shipping_context* context)
|
||||
{
|
||||
if (u_sess->attr.attr_sql.rewrite_rule & PARTIAL_PUSH) {
|
||||
*stream_unsupport = !context->query_shippable;
|
||||
} else {
|
||||
*stream_unsupport = !context->global_shippable;
|
||||
}
|
||||
|
||||
if (u_sess->attr.attr_sql.enable_dngather) {
|
||||
u_sess->opt_cxt.is_dngather_support = !context->disable_dn_gather;
|
||||
} else {
|
||||
u_sess->opt_cxt.is_dngather_support = false;
|
||||
}
|
||||
|
||||
/* single node do not support parallel query in cursor */
|
||||
if (query->utilityStmt && IsA(query->utilityStmt, DeclareCursorStmt)) {
|
||||
*stream_unsupport = true;
|
||||
}
|
||||
|
||||
if (*stream_unsupport || !IS_STREAM) {
|
||||
output_unshipped_log();
|
||||
set_stream_off();
|
||||
} else {
|
||||
/*
|
||||
* make a copy of query, so we can retry to create an unshippable plan
|
||||
* when we fail to generate a stream plan
|
||||
*/
|
||||
return (Query*)copyObject(query);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PlannedStmt* pgxc_planner(Query* query, int cursorOptions, ParamListInfo boundParams)
|
||||
{
|
||||
PlannedStmt* result = NULL;
|
||||
|
|
@ -91,33 +128,7 @@ PlannedStmt* pgxc_planner(Query* query, int cursorOptions, ParamListInfo boundPa
|
|||
(void)stream_walker((Node*)query, (void*)(&context));
|
||||
disable_unshipped_log(query, &context);
|
||||
|
||||
if (u_sess->attr.attr_sql.rewrite_rule & PARTIAL_PUSH) {
|
||||
stream_unsupport = !context.query_shippable;
|
||||
} else {
|
||||
stream_unsupport = !context.global_shippable;
|
||||
}
|
||||
|
||||
if (u_sess->attr.attr_sql.enable_dngather) {
|
||||
u_sess->opt_cxt.is_dngather_support = !context.disable_dn_gather;
|
||||
} else {
|
||||
u_sess->opt_cxt.is_dngather_support = false;
|
||||
}
|
||||
|
||||
/* single node do not support parallel query in cursor */
|
||||
if (query->utilityStmt && IsA(query->utilityStmt, DeclareCursorStmt)) {
|
||||
stream_unsupport = true;
|
||||
}
|
||||
|
||||
if (stream_unsupport || !IS_STREAM) {
|
||||
output_unshipped_log();
|
||||
set_stream_off();
|
||||
} else {
|
||||
/*
|
||||
* make a copy of query, so we can retry to create an unshippable plan
|
||||
* when we fail to generate a stream plan
|
||||
*/
|
||||
re_query = (Query*)copyObject(query);
|
||||
}
|
||||
re_query = check_shippable(&stream_unsupport, query, &context);
|
||||
} else {
|
||||
errno_t sprintf_rc = sprintf_s(u_sess->opt_cxt.not_shipping_info->not_shipping_reason,
|
||||
NOTPLANSHIPPING_LENGTH,
|
||||
|
|
@ -141,9 +152,26 @@ PlannedStmt* pgxc_planner(Query* query, int cursorOptions, ParamListInfo boundPa
|
|||
*/
|
||||
MemoryContext current_context = CurrentMemoryContext;
|
||||
ResourceOwner currentOwner = t_thrd.utils_cxt.CurrentResourceOwner;
|
||||
ResourceOwner tempOwner = ResourceOwnerCreate(t_thrd.utils_cxt.CurrentResourceOwner, "pgxc_planner",
|
||||
SESS_GET_MEM_CXT_GROUP(MEMORY_CONTEXT_OPTIMIZER));
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = tempOwner;
|
||||
ResourceOwner tempOwner = NULL;
|
||||
/*
|
||||
* If the stream-plan is not used, the currentOwner is used to trace resources instead of
|
||||
* applying for a temporary owner. This prevents the "memory temporarily unavailable" error
|
||||
* caused by memory stacking.
|
||||
*/
|
||||
if (IS_STREAM_PLAN) {
|
||||
/*
|
||||
* If the stream-plan is used, a temporary owner is used to trace resources. This helps release
|
||||
* resources in a unified manner when a stream-plan fails to be generated, preventing resource
|
||||
* leakage.
|
||||
*/
|
||||
tempOwner = ResourceOwnerCreate(t_thrd.utils_cxt.CurrentResourceOwner, "pgxc_planner",
|
||||
/*
|
||||
* The memory context of the temporary owner must be the same as the currentOwner to ensure
|
||||
* that they have the same lifecycle
|
||||
*/
|
||||
ResourceOwnerGetMemCxt(currentOwner));
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = tempOwner;
|
||||
}
|
||||
|
||||
/* we need Coordinator for evaluation, invoke standard planner */
|
||||
PG_TRY();
|
||||
|
|
@ -175,8 +203,19 @@ PlannedStmt* pgxc_planner(Query* query, int cursorOptions, ParamListInfo boundPa
|
|||
result->ng_use_planA = use_planA;
|
||||
ReSetNgQueryMem(result);
|
||||
}
|
||||
/* release resource applied in standard_planner */
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
/* If tempOwner is not NULL, the current plan is a stream-plan using the SMP technology. */
|
||||
if (tempOwner != NULL) {
|
||||
/*
|
||||
* When the stream-plan is successfully generated, the temporary owner tracks the
|
||||
* resources opened during the plan generation. Now we put the resources of the
|
||||
* stream-plan into the currentOwner for tracking, and release the tempOwner to
|
||||
* further reduce the memory. This greatly avoid the "memory temporarily unavailable"
|
||||
* error, caused by a large amount of SQLs being executed in a transaction/procedure.
|
||||
*/
|
||||
ResourceOwnerConcat(currentOwner, tempOwner);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
ResourceOwnerDelete(tempOwner);
|
||||
}
|
||||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
|
|
@ -198,11 +237,13 @@ PlannedStmt* pgxc_planner(Query* query, int cursorOptions, ParamListInfo boundPa
|
|||
* Release resources applied in standard_planner, release the tempOwner and reinstate the currentOwner
|
||||
* before PG_RE_THROW().
|
||||
*/
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_BEFORE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_AFTER_LOCKS, false, false);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
ResourceOwnerDelete(tempOwner);
|
||||
if (tempOwner != NULL) {
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_BEFORE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_AFTER_LOCKS, false, false);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
ResourceOwnerDelete(tempOwner);
|
||||
}
|
||||
MemoryContextSwitchTo(ecxt);
|
||||
PG_RE_THROW();
|
||||
}
|
||||
|
|
@ -216,11 +257,13 @@ PlannedStmt* pgxc_planner(Query* query, int cursorOptions, ParamListInfo boundPa
|
|||
}
|
||||
|
||||
/* release resource applied in standard_planner of the PG_TRY. */
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_BEFORE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_AFTER_LOCKS, false, false);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
ResourceOwnerDelete(tempOwner);
|
||||
if (tempOwner != NULL) {
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_BEFORE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_LOCKS, false, false);
|
||||
ResourceOwnerRelease(tempOwner, RESOURCE_RELEASE_AFTER_LOCKS, false, false);
|
||||
t_thrd.utils_cxt.CurrentResourceOwner = currentOwner;
|
||||
ResourceOwnerDelete(tempOwner);
|
||||
}
|
||||
|
||||
#ifdef STREAMPLAN
|
||||
if (OidIsValid(lc_replan_nodegroup)) {
|
||||
|
|
|
|||
|
|
@ -107,8 +107,10 @@ static Node *pull_up_sublinks_targetlist(PlannerInfo *root, Node *node,
|
|||
Node *jtnode, Relids *relids,
|
||||
Node **newTargetList,
|
||||
Node *whereQuals);
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
static bool find_rownum_in_quals(PlannerInfo *root);
|
||||
static bool contains_swctes(const PlannerInfo *root);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -154,6 +156,34 @@ void replace_empty_jointree(Query *parse)
|
|||
parse->jointree->fromlist = list_make1(rtr);
|
||||
}
|
||||
|
||||
#ifndef ENABLE_MULTIPLE_NODES
|
||||
/*
|
||||
* helper function to check if SWCB ctes contaisn in current SubQuery, normally help us to
|
||||
* idenfity if it is OK to appy SWCB related optimization steps
|
||||
*/
|
||||
static bool contains_swctes(const PlannerInfo *root)
|
||||
{
|
||||
if (root->parse == NULL || root->parse->cteList == NIL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List *cteList = root->parse->cteList;
|
||||
ListCell *lc = NULL;
|
||||
bool found = false;
|
||||
foreach(lc, cteList) {
|
||||
CommonTableExpr *cte = (CommonTableExpr *)lfirst(lc);
|
||||
|
||||
/* check if cte from parse->ctelist is a swcb converted */
|
||||
if (cte->swoptions != NULL) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pull_up_sublinks
|
||||
* Attempt to pull up ANY and EXISTS SubLinks to be treated as
|
||||
|
|
@ -192,6 +222,11 @@ void pull_up_sublinks(PlannerInfo* root)
|
|||
if (find_rownum_in_quals(root)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* check existance of SWCB converted */
|
||||
if (contains_swctes(root)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Begin recursion through the jointree */
|
||||
|
|
|
|||
|
|
@ -409,6 +409,7 @@ bool TryConnectRemoteServer(AiEngineConnInfo* conninfo, char** buf)
|
|||
if (!CheckConnParams(conninfo)) {
|
||||
return false;
|
||||
}
|
||||
bool exceptionCaught = false;
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
|
|
@ -444,14 +445,19 @@ bool TryConnectRemoteServer(AiEngineConnInfo* conninfo, char** buf)
|
|||
}
|
||||
PG_CATCH();
|
||||
{
|
||||
exceptionCaught = true;
|
||||
t_thrd.int_cxt.ImmediateInterruptOK = immediateInterruptOKOld;
|
||||
DestoryAiHandle(connHandle);
|
||||
if (buf != NULL) {
|
||||
*buf = NULL;
|
||||
}
|
||||
return false;
|
||||
FlushErrorState();
|
||||
}
|
||||
PG_END_TRY();
|
||||
if (exceptionCaught) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf != NULL) {
|
||||
*buf = pstrdup(connHandle->rec_buf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ static void acquireSamplesForPartitionedRelation(
|
|||
continue;
|
||||
}
|
||||
|
||||
part = partitionOpen(relation, partitionOid, lmode);
|
||||
part = partitionOpen(relation, partitionOid, NoLock);
|
||||
currentPartPages = PartitionGetNumberOfBlocksInFork(relation, part, MAIN_FORKNUM, true);
|
||||
partitionClose(relation, part, lmode);
|
||||
|
||||
|
|
|
|||
|
|
@ -460,17 +460,21 @@ PruningResult* partitionPruningForExpr(PlannerInfo* root, RangeTblEntry* rte, Re
|
|||
context->pruningType = PruningPartition;
|
||||
|
||||
if (rel->partMap != NULL && (rel->partMap->type == PART_TYPE_LIST || rel->partMap->type == PART_TYPE_HASH)) {
|
||||
// for List/Hash partitioned table
|
||||
result = partitionEqualPruningWalker(rel->partMap->type, expr, context);
|
||||
} else {
|
||||
// for Range/Interval partitioned table
|
||||
result = partitionPruningWalker(expr, context);
|
||||
}
|
||||
|
||||
if (result->exprPart != NULL || result->paramArg != NULL) {
|
||||
Param* paramArg = (Param *)copyObject(result->paramArg);
|
||||
bool isPbeSinlePartition = result->isPbeSinlePartition;
|
||||
destroyPruningResult(result);
|
||||
result = getFullPruningResult(rel);
|
||||
result->expr = expr;
|
||||
result->paramArg = paramArg;
|
||||
result->isPbeSinlePartition = isPbeSinlePartition;
|
||||
return result;
|
||||
}
|
||||
/* Never happen, just to be self-contained */
|
||||
|
|
@ -535,10 +539,12 @@ PruningResult* partitionPruningWalker(Expr* expr, PruningContext* pruningCtx)
|
|||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
}
|
||||
result->isPbeSinlePartition = false;
|
||||
} break;
|
||||
default: {
|
||||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
|
@ -619,6 +625,7 @@ static PruningResult* partitionPruningFromBoolExpr(const BoolExpr* expr, Pruning
|
|||
if (expr->boolop == NOT_EXPR) {
|
||||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -638,6 +645,7 @@ static PruningResult* partitionPruningFromBoolExpr(const BoolExpr* expr, Pruning
|
|||
break;
|
||||
case OR_EXPR:
|
||||
result = unionChildPruningResult(resultList, context);
|
||||
result->isPbeSinlePartition = false;
|
||||
break;
|
||||
case NOT_EXPR:
|
||||
default:
|
||||
|
|
@ -750,6 +758,7 @@ static PruningResult* partitionPruningFromNullTest(NullTest* expr, PruningContex
|
|||
}
|
||||
|
||||
result->state = PRUNING_RESULT_SUBSET;
|
||||
result->isPbeSinlePartition = true;
|
||||
|
||||
result->bm_rangeSelectedPartitions = bms_make_singleton(partMap->rangeElementsNum - 1);
|
||||
|
||||
|
|
@ -832,6 +841,7 @@ static PruningResult* intersectChildPruningResult(const List* resultList, Prunin
|
|||
AssertEreport(iteratorResult, MOD_OPT, "iteratorResult context is NNULL.");
|
||||
if (iteratorResult->state == PRUNING_RESULT_EMPTY) {
|
||||
result->state = PRUNING_RESULT_EMPTY;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
} else if (iteratorResult->state == PRUNING_RESULT_FULL) {
|
||||
continue;
|
||||
|
|
@ -875,17 +885,22 @@ static PruningResult* intersectChildPruningResult(const List* resultList, Prunin
|
|||
|
||||
if (BoundaryIsEmpty(result->boundary)) {
|
||||
result->state = PRUNING_RESULT_EMPTY;
|
||||
result->isPbeSinlePartition = false;
|
||||
break;
|
||||
}
|
||||
|
||||
result->state = PRUNING_RESULT_SUBSET;
|
||||
}
|
||||
if (result->state != PRUNING_RESULT_EMPTY && iteratorResult->isPbeSinlePartition) {
|
||||
result->isPbeSinlePartition = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (PruningResultIsEmpty(result)) {
|
||||
destroyPruningResult(result);
|
||||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_EMPTY;
|
||||
result->isPbeSinlePartition = false;
|
||||
result->intervalOffset = -1;
|
||||
}
|
||||
|
||||
|
|
@ -981,6 +996,7 @@ static PruningResult* partitionPruningFromScalarArrayOpExpr
|
|||
if (T_Var != nodeTag(larg) || (T_ArrayExpr != nodeTag(rarg) && T_Const != nodeTag(rarg))) {
|
||||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1079,6 +1095,7 @@ static PruningResult* partitionPruningFromScalarArrayOpExpr
|
|||
} else {
|
||||
result = makeNode(PruningResult);
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1258,6 +1275,7 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
/* length of args MUST be 2 */
|
||||
if (!PointerIsValid(expr) || list_length(expr->args) != 2 || !PointerIsValid(opName = get_opname(expr->opno))) {
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1296,6 +1314,7 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
((T_Const == nodeTag(rightArg) || T_Param == nodeTag(rightArg)
|
||||
|| T_OpExpr == nodeTag(rightArg)) && T_Var == nodeTag(leftArg)))) {
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1325,6 +1344,7 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
if (context->rte != NULL &&
|
||||
context->rte->relid != context->relation->rd_id) {
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1334,6 +1354,7 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
paramArg != NULL ||
|
||||
exprPart != NULL) {
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1351,25 +1372,32 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
if (exprPart != NULL) {
|
||||
if (!PartitionMapIsRange(partMap)) {
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
} else {
|
||||
result->exprPart = exprPart;
|
||||
result->state = PRUNING_RESULT_SUBSET;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
} else if (paramArg != NULL) {
|
||||
if (paramArg->paramkind != PARAM_EXTERN || !PartitionMapIsRange(partMap)) {
|
||||
result->state = PRUNING_RESULT_FULL;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
} else {
|
||||
result->paramArg = paramArg;
|
||||
result->state = PRUNING_RESULT_SUBSET;
|
||||
if (0 == strcmp("=", opName)) {
|
||||
result->isPbeSinlePartition = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (constArg->constisnull) {
|
||||
result->state = PRUNING_RESULT_EMPTY;
|
||||
result->isPbeSinlePartition = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -1377,6 +1405,7 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
result->boundary = makePruningBoundary(partKeyNum);
|
||||
|
||||
boundary = result->boundary;
|
||||
result->isPbeSinlePartition = false;
|
||||
|
||||
/* decide the const is the top or bottom of boundary */
|
||||
if ((0 == strcmp(">", opName) && rightArgIsConst) || (0 == strcmp("<", opName) && !rightArgIsConst)) {
|
||||
|
|
@ -1409,6 +1438,7 @@ static PruningResult* recordBoundaryFromOpExpr(const OpExpr* expr, PruningContex
|
|||
|
||||
boundary->state = PRUNING_RESULT_SUBSET;
|
||||
result->state = PRUNING_RESULT_SUBSET;
|
||||
result->isPbeSinlePartition = true;
|
||||
} else if ((0 == strcmp("<=", opName) && rightArgIsConst) || (0 == strcmp(">=", opName) && !rightArgIsConst)) {
|
||||
boundary->maxClose[attrOffset] = true;
|
||||
boundary->max[attrOffset] = PointerGetDatum(constArg);
|
||||
|
|
|
|||
|
|
@ -2070,6 +2070,25 @@ static void do_autovacuum(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Here we skipped relation_support_autoavac() and relation_needs_vacanalyze() checks
|
||||
* for Ustore partitioned tables
|
||||
*/
|
||||
bytea *rawRelopts = extractRelOptions(tuple, pg_class_desc, InvalidOid);
|
||||
if (rawRelopts != NULL && RelationIsTableAccessMethodUStoreType(rawRelopts) &&
|
||||
isPartitionedRelation(classForm)) {
|
||||
vacObj = (vacuum_object*)palloc(sizeof(vacuum_object));
|
||||
vacObj->tab_oid = relid;
|
||||
vacObj->parent_oid = InvalidOid;
|
||||
vacObj->dovacuum = true;
|
||||
vacObj->dovacuum_toast = false;
|
||||
vacObj->doanalyze = false;
|
||||
vacObj->need_freeze = false;
|
||||
vacObj->is_internal_relation = false;
|
||||
vacObj->flags = VACFLG_MAIN_PARTITION;
|
||||
table_oids = lappend(table_oids, vacObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Fetch reloptions for this table */
|
||||
relopts = extract_autovac_opts(tuple, pg_class_desc);
|
||||
|
||||
|
|
@ -2176,7 +2195,6 @@ static void do_autovacuum(void)
|
|||
pfree_ext(relopts);
|
||||
}
|
||||
}
|
||||
|
||||
tableam_scan_end(relScan);
|
||||
DEBUG_MOD_STOP_TIMER(MOD_AUTOVAC, "AUTOVAC TIMER: Scan pg_class to determine which tables to vacuum");
|
||||
|
||||
|
|
@ -2277,7 +2295,6 @@ static void do_autovacuum(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the pg_partition */
|
||||
tableam_scan_end(partScan);
|
||||
heap_close(partRel, AccessShareLock);
|
||||
|
|
@ -2376,51 +2393,9 @@ static void do_autovacuum(void)
|
|||
pfree_ext(relopts);
|
||||
}
|
||||
}
|
||||
|
||||
tableam_scan_end(relScan);
|
||||
DEBUG_MOD_STOP_TIMER(MOD_AUTOVAC, "AUTOVAC TIMER: Scan pg_class to determine which toast tables to vacuum");
|
||||
|
||||
/* On the fourth pass: check USTORE GPI tables */
|
||||
ScanKeyInit(&key[0], Anum_pg_class_relkind, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(RELKIND_GLOBAL_INDEX));
|
||||
relScan = tableam_scan_begin(classRel, SnapshotNow, 1, &key[0]);
|
||||
while ((tuple = (HeapTuple)tableam_scan_getnexttuple(relScan, ForwardScanDirection)) != NULL) {
|
||||
Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
|
||||
Oid relid = HeapTupleGetOid(tuple);
|
||||
AutoVacOpts *relopts = NULL;
|
||||
/*
|
||||
* We cannot safely process other backends' temp tables, so skip them.
|
||||
*/
|
||||
if (classForm->relpersistence == RELPERSISTENCE_TEMP ||
|
||||
classForm->relpersistence == RELPERSISTENCE_GLOBAL_TEMP)
|
||||
continue;
|
||||
/* only UBTree supports vacuum independently */
|
||||
if (classForm->relam != UBTREE_AM_OID) {
|
||||
continue;
|
||||
}
|
||||
/* fetch reloptions */
|
||||
relopts = extract_autovac_opts(tuple, pg_class_desc);
|
||||
/* only UBTree supports vacuum, and enabled will be set true */
|
||||
if (relopts == NULL || !relopts->enabled) {
|
||||
continue;
|
||||
}
|
||||
/* we skipped relation_support_autoavac() and relation_needs_vacanalyze() checks here */
|
||||
vacObj = (vacuum_object*)palloc(sizeof(vacuum_object));
|
||||
vacObj->tab_oid = relid;
|
||||
vacObj->parent_oid = InvalidOid;
|
||||
vacObj->dovacuum = true;
|
||||
vacObj->dovacuum_toast = false;
|
||||
vacObj->doanalyze = false;
|
||||
vacObj->need_freeze = false;
|
||||
vacObj->is_internal_relation = false;
|
||||
/* VACFLG_MAIN_PARTITION makes no sense when vacuuming UBTree */
|
||||
vacObj->flags = VACFLG_SIMPLE_HEAP; /* ignore this flag as we will not use it,
|
||||
* and to be safe we can use VACFLG_SIMPLE_HEAP.
|
||||
*/
|
||||
table_oids = lappend(table_oids, vacObj);
|
||||
}
|
||||
tableam_scan_end(relScan);
|
||||
heap_close(classRel, AccessShareLock);
|
||||
DEBUG_MOD_STOP_TIMER(MOD_AUTOVAC, "AUTOVAC TIMER: Scan pg_class to determine which UBTree tables to vacuum");
|
||||
DEBUG_MOD_STOP_TIMER(MOD_AUTOVAC, "AUTOVAC TIMER: Scan pg_class to determine which toast tables to vacuum");
|
||||
|
||||
/*
|
||||
* Create one buffer access strategy object per buffer pool for VACUUM to use.
|
||||
|
|
@ -2754,8 +2729,7 @@ AutoVacOpts* extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
|
|||
|
||||
Assert(((Form_pg_class)GETSTRUCT(tup))->relkind == RELKIND_RELATION ||
|
||||
((Form_pg_class) GETSTRUCT(tup))->relkind == RELKIND_MATVIEW ||
|
||||
((Form_pg_class)GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE ||
|
||||
((Form_pg_class)GETSTRUCT(tup))->relkind == RELKIND_GLOBAL_INDEX);
|
||||
((Form_pg_class)GETSTRUCT(tup))->relkind == RELKIND_TOASTVALUE);
|
||||
|
||||
relopts = extractRelOptions(tup, pg_class_desc, InvalidOid);
|
||||
if (relopts == NULL)
|
||||
|
|
@ -2765,15 +2739,9 @@ AutoVacOpts* extract_autovac_opts(HeapTuple tup, TupleDesc pg_class_desc)
|
|||
rc = memcpy_s(av, sizeof(AutoVacOpts), &(((StdRdOptions*)relopts)->autovacuum), sizeof(AutoVacOpts));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
/* autovacuum for ustore table is disabled */
|
||||
/* autovacuum for ustore unpartitioned table is disabled */
|
||||
if (RelationIsTableAccessMethodUStoreType(relopts)) {
|
||||
av->enabled = false;
|
||||
}
|
||||
|
||||
/* force set av->enabled in ustore's GPI */
|
||||
if ((((Form_pg_class)GETSTRUCT(tup))->relkind == RELKIND_GLOBAL_INDEX) &&
|
||||
RelationIsTableAccessMethodUStoreType(relopts)) {
|
||||
av->enabled = true;
|
||||
av->enabled = isPartitionedRelation((Form_pg_class)GETSTRUCT(tup));
|
||||
}
|
||||
|
||||
pfree_ext(relopts);
|
||||
|
|
@ -2898,8 +2866,10 @@ static autovac_table* table_recheck_autovac(
|
|||
if (!HeapTupleIsValid(classTup))
|
||||
return NULL;
|
||||
classForm = (Form_pg_class)GETSTRUCT(classTup);
|
||||
/* this is UBTree, use another bypass */
|
||||
if (classForm->relam == UBTREE_AM_OID) {
|
||||
bytea *rawRelopts = extractRelOptions(classTup, pg_class_desc, InvalidOid);
|
||||
/* this is Ustore partitioned table, use another bypass */
|
||||
if (rawRelopts != NULL && RelationIsTableAccessMethodUStoreType(rawRelopts) &&
|
||||
isPartitionedRelation(classForm)) {
|
||||
avopts = extract_autovac_opts(classTup, pg_class_desc);
|
||||
tab = calculate_vacuum_cost_and_freezeages(avopts, false, false);
|
||||
if (tab != NULL) {
|
||||
|
|
|
|||
|
|
@ -57,13 +57,14 @@ void GetCsnBarrierName(char* barrierRet, bool isSwitchoverBarrier)
|
|||
struct timeval tv;
|
||||
int rc;
|
||||
CommitSeqNo csn;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (GTM_MODE)
|
||||
csn = GetCSNGTM();
|
||||
else
|
||||
csn = CommitCSNGTM(false);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (isSwitchoverBarrier) {
|
||||
rc = snprintf_s(barrierRet, BARRIER_NAME_LEN, BARRIER_NAME_LEN - 1, CSN_SWITCHOVER_BARRIER_PATTREN_STR, csn);
|
||||
} else {
|
||||
|
|
@ -206,6 +207,7 @@ uint64 GetObsFirstCNBarrierTimeline(const List *archiveSlotNames)
|
|||
return timeline;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void AllocBarrierLsnInfo(int nodeSize)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -216,6 +218,7 @@ static void AllocBarrierLsnInfo(int nodeSize)
|
|||
sizeof(ArchiveBarrierLsnInfo) * nodeSize);
|
||||
securec_check(rc, "", "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
static void BarrierCreatorPoolerReload(void)
|
||||
|
|
@ -402,6 +405,7 @@ void barrier_creator_main(void)
|
|||
long time_diff = last_barrier_time - current_time;
|
||||
ereport(LOG, (errmsg("[BarrierCreator] current time %ld is smaller than barrier time %ld, and sleep %ld ms",
|
||||
current_time, last_barrier_time, time_diff)));
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
pg_usleep(time_diff * 1000L);
|
||||
} while (1);
|
||||
if (t_thrd.barrier_creator_cxt.is_first_barrier) {
|
||||
|
|
@ -410,6 +414,7 @@ void barrier_creator_main(void)
|
|||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
while (!START_AUTO_CSN_BARRIER) {
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
pg_usleep(1000000L);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -436,6 +441,7 @@ void barrier_creator_main(void)
|
|||
t_thrd.barrier_creator_cxt.barrier_update_last_time_info = (BarrierUpdateLastTimeInfo*)palloc0(
|
||||
sizeof(BarrierUpdateLastTimeInfo) * g_instance.attr.attr_storage.max_replication_slots);
|
||||
}
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
if (g_instance.archive_obs_cxt.barrier_lsn_info == NULL) {
|
||||
int nodeSize = *t_thrd.pgxc_cxt.shmemNumCoords + *t_thrd.pgxc_cxt.shmemNumDataNodes;
|
||||
AllocBarrierLsnInfo(nodeSize);
|
||||
|
|
@ -443,6 +449,7 @@ void barrier_creator_main(void)
|
|||
g_instance.archive_obs_cxt.max_node_cnt = nodeSize;
|
||||
SpinLockRelease(&g_instance.archive_obs_cxt.barrier_lock);
|
||||
}
|
||||
#endif
|
||||
archiveSlotNames = GetAllArchiveSlotsName();
|
||||
if (archiveSlotNames == NIL || archiveSlotNames->length == 0) {
|
||||
ereport(WARNING, (errmsg("[BarrierCreator] could not get archive slot name when barrier start")));
|
||||
|
|
|
|||
|
|
@ -173,10 +173,11 @@ void BarrierPreParseMain(void)
|
|||
XLogReaderState *xlogreader = NULL;
|
||||
char *errormsg = NULL;
|
||||
XLogPageReadPrivate readprivate;
|
||||
XLogRecPtr startLSN;
|
||||
XLogRecPtr preStartLSN;
|
||||
XLogRecPtr startLSN = InvalidXLogRecPtr;
|
||||
XLogRecPtr preStartLSN = InvalidXLogRecPtr;
|
||||
XLogRecPtr lastReadLSN = InvalidXLogRecPtr;
|
||||
bool found = false;
|
||||
XLogRecPtr barrierLSN;
|
||||
XLogRecPtr barrierLSN = InvalidXLogRecPtr;
|
||||
char *xLogBarrierId = NULL;
|
||||
char barrierId[MAX_BARRIER_ID_LENGTH] = {0};
|
||||
const uint32 shiftSize = 32;
|
||||
|
|
@ -258,10 +259,13 @@ void BarrierPreParseMain(void)
|
|||
|
||||
found = false;
|
||||
preStartLSN = startLSN;
|
||||
ereport(DEBUG1, (errmsg("[BarrierPreParse] start to preparse at: %08X/%08X",
|
||||
(uint32)(startLSN >> shiftSize), (uint32)startLSN)));
|
||||
startLSN = XLogFindNextRecord(xlogreader, startLSN);
|
||||
if (XLogRecPtrIsInvalid(startLSN)) {
|
||||
startLSN = preStartLSN;
|
||||
if (!XLByteEQ(walrcv->receiver_flush_location, startLSN)) {
|
||||
if (!XLByteEQ(walrcv->receiver_flush_location, startLSN) &&
|
||||
!XLByteEQ(walrcv->lastRecoveredBarrierLSN, startLSN)) {
|
||||
/* reset startLSN */
|
||||
startLSN = walrcv->lastRecoveredBarrierLSN;
|
||||
ereport(LOG, (errmsg("[BarrierPreParse] reset startLSN with lastRecoveredBarrierLSN: %08X/%08X",
|
||||
|
|
@ -275,6 +279,7 @@ void BarrierPreParseMain(void)
|
|||
if (record == NULL) {
|
||||
break;
|
||||
}
|
||||
lastReadLSN = xlogreader->EndRecPtr;
|
||||
uint8 info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK;
|
||||
if (NEED_INSERT_INTO_HASH) {
|
||||
xLogBarrierId = XLogRecGetData(xlogreader);
|
||||
|
|
@ -304,7 +309,7 @@ void BarrierPreParseMain(void)
|
|||
SetBarrieID(barrierId, barrierLSN);
|
||||
}
|
||||
|
||||
startLSN = XLogRecPtrIsInvalid(xlogreader->ReadRecPtr) ? preStartLSN : xlogreader->ReadRecPtr;
|
||||
startLSN = XLogRecPtrIsInvalid(lastReadLSN) ? preStartLSN : lastReadLSN;
|
||||
|
||||
if (XLogRecPtrIsInvalid(xlogreader->ReadRecPtr) && errormsg) {
|
||||
ereport(LOG, (errmsg("[BarrierPreParse] preparse thread get an error info %s", errormsg)));
|
||||
|
|
|
|||
|
|
@ -1216,9 +1216,12 @@ static void HandlePageWriterMainInterrupts()
|
|||
ProcessConfigFile(PGC_SIGHUP);
|
||||
}
|
||||
|
||||
if (t_thrd.pagewriter_cxt.sync_requested) {
|
||||
if (t_thrd.pagewriter_cxt.sync_requested || t_thrd.pagewriter_cxt.sync_retry) {
|
||||
t_thrd.pagewriter_cxt.sync_requested = false;
|
||||
|
||||
t_thrd.pagewriter_cxt.sync_retry = true;
|
||||
PageWriterSyncWithAbsorption();
|
||||
t_thrd.pagewriter_cxt.sync_retry = false;
|
||||
}
|
||||
|
||||
/* main thread should finally exit. */
|
||||
|
|
|
|||
|
|
@ -425,6 +425,7 @@ static void pgarch_MainLoop(void)
|
|||
XLogRecPtr replayPtr;
|
||||
bool got_recptr = false;
|
||||
bool amSync = false;
|
||||
int retryTimes = 3;
|
||||
/* FlushPtr <= ConsensusPtr on DCF mode */
|
||||
if (IS_PGXC_COORDINATOR || g_instance.attr.attr_storage.dcf_attr.enable_dcf) {
|
||||
flushPtr = GetFlushRecPtr();
|
||||
|
|
@ -441,8 +442,16 @@ static void pgarch_MainLoop(void)
|
|||
"and init last lsn is %08X%08X", (uint32)(t_thrd.arch.pitr_task_last_lsn >> 32),
|
||||
(uint32)t_thrd.arch.pitr_task_last_lsn)));
|
||||
}
|
||||
got_recptr = SyncRepGetSyncRecPtr(&receivePtr, &writePtr, &flushPtr, &replayPtr, &amSync, false);
|
||||
if (got_recptr != true) {
|
||||
while (retryTimes--) {
|
||||
got_recptr =
|
||||
SyncRepGetSyncRecPtr(&receivePtr, &writePtr, &flushPtr, &replayPtr, &amSync, false);
|
||||
if (got_recptr == true) {
|
||||
break;
|
||||
} else {
|
||||
pg_usleep(1000000L);
|
||||
}
|
||||
}
|
||||
if (got_recptr == false) {
|
||||
ereport(ERROR,
|
||||
(errmsg("pgarch_ArchiverObsCopyLoop failed when call SyncRepGetSyncRecPtr")));
|
||||
}
|
||||
|
|
@ -739,6 +748,10 @@ static void pgarch_ArchiverObsCopyLoop(XLogRecPtr flushPtr, doArchive fun)
|
|||
(uint32)(targetLsn >> 32), (uint32)(targetLsn))));
|
||||
pg_usleep(1000000L); /* wait a bit before retrying */
|
||||
} else {
|
||||
if (g_instance.roach_cxt.isXLogForceRecycled && !g_instance.roach_cxt.forceAdvanceSlotTigger) {
|
||||
g_instance.roach_cxt.isXLogForceRecycled = false;
|
||||
ereport(LOG, (errmsg("PgArch force advance slot success")));
|
||||
}
|
||||
gettimeofday(&tv, NULL);
|
||||
currTimestamp = TIME_GET_MILLISEC(tv);
|
||||
t_thrd.arch.pitr_task_last_lsn = targetLsn;
|
||||
|
|
@ -1026,6 +1039,11 @@ static void pgarch_archiveRoachForPitrStandby()
|
|||
(uint32)(archive_task_status->archive_task.targetLsn),
|
||||
archive_task_status->archive_task.term,
|
||||
archive_task_status->archive_task.sub_term)));
|
||||
if (archive_task_status->archive_task.targetLsn == InvalidXLogSegPtr) {
|
||||
volatile unsigned int *pitr_task_status = &archive_task_status->pitr_task_status;
|
||||
pg_atomic_write_u32(pitr_task_status, PITR_TASK_NONE);
|
||||
ereport(LOG, (errmsg("PgArch standby receive invalid lsn for slot force advance")));
|
||||
}
|
||||
if (ArchiveReplicationAchiver(&archive_task_status->archive_task) == 0) {
|
||||
archive_task_status->pitr_finish_result = true;
|
||||
} else {
|
||||
|
|
@ -1057,6 +1075,11 @@ static bool pgarch_archiveRoachForPitrMaster(XLogRecPtr targetLsn)
|
|||
archive_task_status->archive_task.tli = get_controlfile_timeline();
|
||||
archive_task_status->archive_task.term = Max(g_instance.comm_cxt.localinfo_cxt.term_from_file,
|
||||
g_instance.comm_cxt.localinfo_cxt.term_from_xlog);
|
||||
if (g_instance.roach_cxt.forceAdvanceSlotTigger) {
|
||||
archive_task_status->archive_task.targetLsn = InvalidXLogRecPtr;
|
||||
g_instance.roach_cxt.forceAdvanceSlotTigger = false;
|
||||
ereport(LOG, (errmsg("PgArch need force advance this time in primary")));
|
||||
}
|
||||
/* subterm update when walsender changed */
|
||||
int rc = strcpy_s(archive_task_status->archive_task.slot_name, NAMEDATALEN, t_thrd.arch.slot_name);
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
|
@ -1085,8 +1108,8 @@ static bool pgarch_archiveRoachForPitrMaster(XLogRecPtr targetLsn)
|
|||
return false;
|
||||
}
|
||||
/*
|
||||
* check targetLsn and g_instance.archive_obs_cxt.archive_task.targetLsn for deal message with wrong order
|
||||
*/
|
||||
* check targetLsn and g_instance.archive_obs_cxt.archive_task.targetLsn for deal message with wrong order
|
||||
*/
|
||||
if (archive_task_status->pitr_finish_result == true
|
||||
&& XLByteEQ(archive_task_status->archive_task.targetLsn, targetLsn)) {
|
||||
archive_task_status->pitr_finish_result = false;
|
||||
|
|
@ -1191,6 +1214,26 @@ static WalSnd* pgarch_chooseWalsnd(XLogRecPtr targetLsn)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static XLogRecPtr GetLastTaskLsnFromServer(ArchiveSlotConfig* obs_archive_slot)
|
||||
{
|
||||
ArchiveXlogMessage obs_archive_info;
|
||||
XLogRecPtr pitr_task_last_lsn;
|
||||
|
||||
if (archive_replication_get_last_xlog(&obs_archive_info, &obs_archive_slot->archive_config) == 0) {
|
||||
pitr_task_last_lsn = obs_archive_info.targetLsn;
|
||||
ereport(LOG,
|
||||
(errmsg("initLastTaskLsn update lsn to %X/%X from server", (uint32)(pitr_task_last_lsn >> 32),
|
||||
(uint32)(pitr_task_last_lsn))));
|
||||
} else {
|
||||
XLogRecPtr targetLsn = GetFlushRecPtr();
|
||||
pitr_task_last_lsn = targetLsn - (targetLsn % XLogSegSize);
|
||||
ereport(LOG,
|
||||
(errmsg("initLastTaskLsn update lsn to %X/%X from local", (uint32)(pitr_task_last_lsn >> 32),
|
||||
(uint32)(pitr_task_last_lsn))));
|
||||
}
|
||||
return pitr_task_last_lsn;
|
||||
}
|
||||
|
||||
static void InitArchiverLastTaskLsn(ArchiveSlotConfig* obs_archive_slot)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
|
@ -1207,8 +1250,19 @@ static void InitArchiverLastTaskLsn(ArchiveSlotConfig* obs_archive_slot)
|
|||
ReplicationSlot *slot = &t_thrd.slot_cxt.ReplicationSlotCtl->replication_slots[*slot_idx];
|
||||
SpinLockAcquire(&slot->mutex);
|
||||
if (slot->in_use == true && slot->archive_config != NULL) {
|
||||
t_thrd.arch.pitr_task_last_lsn = slot->data.restart_lsn;
|
||||
SpinLockRelease(&slot->mutex);
|
||||
/*
|
||||
* In old version(<92599), the last task lsn is initialized from archive server or current flush
|
||||
* position, but in new version is initialized from local slot.
|
||||
* During the upgrade, the local restart lsn may be 0, so initialize it with old version way.
|
||||
*/
|
||||
if (slot->data.restart_lsn == InvalidXLogRecPtr &&
|
||||
t_thrd.proc->workingVersionNum < PITR_INIT_VERSION_NUM) {
|
||||
SpinLockRelease(&slot->mutex);
|
||||
t_thrd.arch.pitr_task_last_lsn = GetLastTaskLsnFromServer(obs_archive_slot);
|
||||
} else {
|
||||
t_thrd.arch.pitr_task_last_lsn = slot->data.restart_lsn;
|
||||
SpinLockRelease(&slot->mutex);
|
||||
}
|
||||
} else {
|
||||
SpinLockRelease(&slot->mutex);
|
||||
ereport(ERROR, (errcode_for_file_access(), errmsg("slot idx not valid, obs slot %X/%X not advance ",
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ typedef struct AuditIndexItem {
|
|||
* Brief : audit index table
|
||||
* Description :
|
||||
*/
|
||||
typedef struct AuditIndexTable {
|
||||
typedef struct AuditIndexTableNew {
|
||||
uint32 maxnum; /* max count of the audit index item */
|
||||
uint32 begidx; /* the position of the first audit index item */
|
||||
uint32 thread_num; /* the running audit thread num */
|
||||
|
|
@ -212,25 +212,25 @@ typedef struct AuditIndexTable {
|
|||
uint32 count; /* the count of the audit index item */
|
||||
pg_time_t last_audit_time; /* the audit time of the latest audit record */
|
||||
AuditIndexItem data[1];
|
||||
} AuditIndexTable;
|
||||
} AuditIndexTableNew;
|
||||
|
||||
/*
|
||||
* Brief : old audit index table
|
||||
* Description :
|
||||
*/
|
||||
typedef struct AuditIndexTableOld {
|
||||
typedef struct AuditIndexTable {
|
||||
uint32 maxnum; /* max count of the audit index item */
|
||||
uint32 begidx; /* the position of the first audit index item */
|
||||
uint32 curidx; /* the position of the current audit index item */
|
||||
uint32 count; /* the count of the audit index item */
|
||||
pg_time_t last_audit_time; /* the audit time of the latest audit record */
|
||||
AuditIndexItem data[1];
|
||||
} AuditIndexTableOld;
|
||||
} AuditIndexTable;
|
||||
|
||||
static const char audit_indextbl_file[] = "index_table_new";
|
||||
static const char audit_indextbl_old_file[] = "index_table";
|
||||
static const int indextbl_header_size = offsetof(AuditIndexTable, data);
|
||||
static const int old_indextbl_header_size = offsetof(AuditIndexTableOld, data);
|
||||
static const int indextbl_header_size = offsetof(AuditIndexTableNew, data);
|
||||
static const int old_indextbl_header_size = offsetof(AuditIndexTable, data);
|
||||
|
||||
static const char* AuditTypeDescs[] = {"unknown",
|
||||
"login_success",
|
||||
|
|
@ -401,7 +401,6 @@ static void pgaudit_indexfile_upgrade(void);
|
|||
static void pgaudit_indexfile_sync(const char* mode, bool allow_errors);
|
||||
static void pgaudit_rewrite_indexfile(void);
|
||||
static void pgaudit_indextbl_init_new(void);
|
||||
void extracted836(errno_t &errorno, int thread_num);
|
||||
static void pgaudit_reset_indexfile();
|
||||
static const char* pgaudit_string_field(AuditData* adata, int num);
|
||||
static void deserialization_to_tuple(Datum (&values)[PGAUDIT_QUERY_COLS],
|
||||
|
|
@ -808,11 +807,11 @@ void pgaudit_stop_all(void)
|
|||
{
|
||||
for (int i = 0; i < g_instance.audit_cxt.thread_num; ++i) {
|
||||
if (g_instance.pid_cxt.PgAuditPID[i] != 0) {
|
||||
Assert(!dummyStandbyMode);
|
||||
signal_child(g_instance.pid_cxt.PgAuditPID[i], SIGQUIT, -1);
|
||||
}
|
||||
}
|
||||
audit_process_cxt_exit();
|
||||
ereport(LOG, (errmsg("parameter audit_enabled is set to false, terminate auditor process.")));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1471,7 +1470,6 @@ static void pgaudit_cleanup(void)
|
|||
if (g_instance.audit_cxt.audit_indextbl->count > 0) {
|
||||
--g_instance.audit_cxt.audit_indextbl->count;
|
||||
}
|
||||
g_instance.audit_cxt.audit_indextbl->begidx = (index + 1) % g_instance.audit_cxt.audit_indextbl->maxnum;
|
||||
errorno = memset_s(item, sizeof(AuditIndexItem), 0, sizeof(AuditIndexItem));
|
||||
securec_check(errorno, "\0", "\0");
|
||||
|
||||
|
|
@ -1487,7 +1485,9 @@ static void pgaudit_cleanup(void)
|
|||
if (index == earliest_idx) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* udpate audit index for next loop */
|
||||
g_instance.audit_cxt.audit_indextbl->begidx = (index + 1) % g_instance.audit_cxt.audit_indextbl->maxnum;
|
||||
index = g_instance.audit_cxt.audit_indextbl->begidx;
|
||||
}
|
||||
LWLockRelease(g_instance.audit_cxt.index_file_lock);
|
||||
|
|
@ -2018,7 +2018,7 @@ static void pgaudit_read_indexfile(const char* audit_directory)
|
|||
struct stat statbuf;
|
||||
char tblfile_path[MAXPGPATH] = {0};
|
||||
size_t nread = 0;
|
||||
AuditIndexTable indextbl;
|
||||
AuditIndexTableNew indextbl;
|
||||
|
||||
int rc = snprintf_s(tblfile_path, MAXPGPATH, MAXPGPATH - 1, "%s/%s", audit_directory, audit_indextbl_file);
|
||||
securec_check_intval(rc,,);
|
||||
|
|
@ -2057,7 +2057,7 @@ static void pgaudit_read_indexfile(const char* audit_directory)
|
|||
pfree_ext(g_instance.audit_cxt.audit_indextbl);
|
||||
|
||||
/* read the whole audit index table */
|
||||
g_instance.audit_cxt.audit_indextbl = (AuditIndexTable *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.audit_indextbl = (AuditIndexTableNew *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.global_audit_context,
|
||||
(indextbl.maxnum * sizeof(AuditIndexItem) + indextbl_header_size));
|
||||
errorno =
|
||||
|
|
@ -2258,7 +2258,7 @@ static void pgaudit_rewrite_indexfile(void)
|
|||
FILE* fp = NULL;
|
||||
char tblfile_path[MAXPGPATH] = {0};
|
||||
size_t nread = 0;
|
||||
AuditIndexTableOld old_index_tbl;
|
||||
AuditIndexTable old_index_tbl;
|
||||
|
||||
int rc = snprintf_s(tblfile_path,
|
||||
MAXPGPATH,
|
||||
|
|
@ -2288,7 +2288,7 @@ static void pgaudit_rewrite_indexfile(void)
|
|||
pfree_ext(g_instance.audit_cxt.audit_indextbl);
|
||||
pfree_ext(g_instance.audit_cxt.audit_indextbl_old);
|
||||
/* read the whole audit index table */
|
||||
g_instance.audit_cxt.audit_indextbl_old = (AuditIndexTableOld *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.audit_indextbl_old = (AuditIndexTable *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.global_audit_context,
|
||||
(old_index_tbl.maxnum * sizeof(AuditIndexItem) + old_indextbl_header_size));
|
||||
errorno = memcpy_s(g_instance.audit_cxt.audit_indextbl_old,
|
||||
|
|
@ -2296,7 +2296,7 @@ static void pgaudit_rewrite_indexfile(void)
|
|||
&old_index_tbl, old_indextbl_header_size);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
/* rewrite old index table to new index table */
|
||||
g_instance.audit_cxt.audit_indextbl = (AuditIndexTable *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.audit_indextbl = (AuditIndexTableNew *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.global_audit_context,
|
||||
(old_index_tbl.maxnum * sizeof(AuditIndexItem) + indextbl_header_size));
|
||||
g_instance.audit_cxt.audit_indextbl->maxnum = old_index_tbl.maxnum;
|
||||
|
|
@ -2334,7 +2334,7 @@ static void pgaudit_indextbl_init_new(void)
|
|||
if (g_instance.audit_cxt.audit_indextbl == NULL) {
|
||||
ereport(LOG, (errmsg("pgaudit_indextbl_init_new first init")));
|
||||
g_instance.audit_cxt.audit_indextbl =
|
||||
(AuditIndexTable *)MemoryContextAllocZero(g_instance.audit_cxt.global_audit_context,
|
||||
(AuditIndexTableNew *)MemoryContextAllocZero(g_instance.audit_cxt.global_audit_context,
|
||||
(u_sess->attr.attr_security.Audit_RemainThreshold + 1) * sizeof(AuditIndexItem) + indextbl_header_size);
|
||||
g_instance.audit_cxt.audit_indextbl->maxnum = u_sess->attr.attr_security.Audit_RemainThreshold + 1;
|
||||
g_instance.audit_cxt.audit_indextbl->count = 0; /* audit files count will be updated by auditfile_open */
|
||||
|
|
@ -2417,27 +2417,31 @@ static void pgaudit_indextbl_init_new(void)
|
|||
return;
|
||||
}
|
||||
|
||||
static void pgaudit_udpate_maxnum()
|
||||
static void pgaudit_update_maxnum()
|
||||
{
|
||||
errno_t errorno = EOK;
|
||||
int thread_num = g_instance.attr.attr_security.audit_thread_num;
|
||||
|
||||
int new_indextbl_data_lenth = (u_sess->attr.attr_security.Audit_RemainThreshold + 1) * sizeof(AuditIndexItem);
|
||||
AuditIndexTable *new_indextbl = (AuditIndexTable *)MemoryContextAllocZero(
|
||||
AuditIndexTableNew *new_indextbl = (AuditIndexTableNew *)MemoryContextAllocZero(
|
||||
g_instance.audit_cxt.global_audit_context, new_indextbl_data_lenth + indextbl_header_size);
|
||||
|
||||
/* curidx and latest_idx should be updated later from old index table file */
|
||||
new_indextbl->begidx = 0;
|
||||
new_indextbl->maxnum = u_sess->attr.attr_security.Audit_RemainThreshold + 1;
|
||||
new_indextbl->last_audit_time = g_instance.audit_cxt.audit_indextbl->last_audit_time;
|
||||
new_indextbl->thread_num = g_instance.audit_cxt.audit_indextbl->thread_num;
|
||||
|
||||
if (g_instance.audit_cxt.audit_indextbl->count > 0) {
|
||||
AuditIndexItem *item = NULL;
|
||||
uint32 latest_idx = g_instance.audit_cxt.audit_indextbl->latest_idx;
|
||||
uint32 last_idx = (latest_idx == 0) ? (g_instance.audit_cxt.audit_indextbl->maxnum - 1): (latest_idx - 1);
|
||||
uint32 index = g_instance.audit_cxt.audit_indextbl->begidx;
|
||||
uint32 pos = new_indextbl->begidx;
|
||||
do {
|
||||
item = g_instance.audit_cxt.audit_indextbl->data + index;
|
||||
errorno = memcpy_s(new_indextbl->data + pos, (new_indextbl_data_lenth - pos), item, sizeof(AuditIndexItem));
|
||||
errorno = memcpy_s(new_indextbl->data + pos, (new_indextbl_data_lenth - (pos * sizeof(AuditIndexItem))),
|
||||
item, sizeof(AuditIndexItem));
|
||||
securec_check(errorno, "\0", "\0");
|
||||
new_indextbl->count++;
|
||||
|
||||
|
|
@ -2445,11 +2449,11 @@ static void pgaudit_udpate_maxnum()
|
|||
* finished copy old index table file from range [begin, latest_idx)
|
||||
* then update new index table file curidxes
|
||||
*/
|
||||
if (index == (latest_idx - 1)) {
|
||||
if (index == last_idx) {
|
||||
for (int i = 0; i < thread_num; ++i) {
|
||||
new_indextbl->curidx[i] = pos - thread_num + i;
|
||||
new_indextbl->curidx[i] = pos - thread_num + 1 + i;
|
||||
}
|
||||
new_indextbl->latest_idx = pos;
|
||||
new_indextbl->latest_idx = pos + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2487,7 +2491,7 @@ static void pgaudit_reset_indexfile()
|
|||
/* If file remain threshold parameter changed, than copy the old audit index table to the new table */
|
||||
if (old_maxnum != (uint32)u_sess->attr.attr_security.Audit_RemainThreshold + 1) {
|
||||
LWLockAcquire(g_instance.audit_cxt.index_file_lock, LW_EXCLUSIVE);
|
||||
pgaudit_udpate_maxnum();
|
||||
pgaudit_update_maxnum();
|
||||
LWLockRelease(g_instance.audit_cxt.index_file_lock);
|
||||
}
|
||||
|
||||
|
|
@ -2996,17 +3000,19 @@ Datum pg_query_audit(PG_FUNCTION_ARGS)
|
|||
* load the index audit table from global index audit table instance
|
||||
* then use the local thread one when iterate all audit files
|
||||
*/
|
||||
pgaudit_read_indexfile(audit_dir);
|
||||
LWLockAcquire(g_instance.audit_cxt.index_file_lock, LW_SHARED);
|
||||
t_thrd.audit.audit_indextbl = NULL;
|
||||
int indextbl_len =
|
||||
(u_sess->attr.attr_security.Audit_RemainThreshold + 1) * sizeof(AuditIndexItem) + indextbl_header_size;
|
||||
t_thrd.audit.audit_indextbl = (AuditIndexTable *)palloc0(indextbl_len);
|
||||
error_t errorno =
|
||||
memcpy_s(t_thrd.audit.audit_indextbl, indextbl_len, g_instance.audit_cxt.audit_indextbl, indextbl_len);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
|
||||
pfree_ext(t_thrd.audit.audit_indextbl);
|
||||
if (g_instance.audit_cxt.audit_indextbl != NULL) {
|
||||
int indextbl_len =
|
||||
(u_sess->attr.attr_security.Audit_RemainThreshold + 1) * sizeof(AuditIndexItem) + indextbl_header_size;
|
||||
t_thrd.audit.audit_indextbl = (AuditIndexTableNew *)palloc0(indextbl_len);
|
||||
error_t errorno =
|
||||
memcpy_s(t_thrd.audit.audit_indextbl, indextbl_len, g_instance.audit_cxt.audit_indextbl, indextbl_len);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
}
|
||||
LWLockRelease(g_instance.audit_cxt.index_file_lock);
|
||||
|
||||
|
||||
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
|
||||
oldcontext = MemoryContextSwitchTo(per_query_ctx);
|
||||
|
||||
|
|
@ -3017,8 +3023,6 @@ Datum pg_query_audit(PG_FUNCTION_ARGS)
|
|||
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
ereport(DEBUG1,
|
||||
(errmsg("pg_query_audit count: %d indextbl_len: %d", t_thrd.audit.audit_indextbl->count, indextbl_len)));
|
||||
if (begtime < endtime && t_thrd.audit.audit_indextbl != NULL && t_thrd.audit.audit_indextbl->count > 0) {
|
||||
bool satisfied = false;
|
||||
uint32 index = 0;
|
||||
|
|
@ -3073,14 +3077,17 @@ Datum pg_delete_audit(PG_FUNCTION_ARGS)
|
|||
* load the index audit table from global index audit table instance
|
||||
* then use the local thread one when iterate all audit files
|
||||
*/
|
||||
pgaudit_read_indexfile(g_instance.attr.attr_security.Audit_directory);
|
||||
LWLockAcquire(g_instance.audit_cxt.index_file_lock, LW_SHARED);
|
||||
pfree_ext(t_thrd.audit.audit_indextbl);
|
||||
int indextbl_len =
|
||||
(u_sess->attr.attr_security.Audit_RemainThreshold + 1) * sizeof(AuditIndexItem) + indextbl_header_size;
|
||||
t_thrd.audit.audit_indextbl = (AuditIndexTable *)palloc0(indextbl_len);
|
||||
error_t errorno =
|
||||
memcpy_s(t_thrd.audit.audit_indextbl, indextbl_len, g_instance.audit_cxt.audit_indextbl, indextbl_len);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
if (g_instance.audit_cxt.audit_indextbl != NULL) {
|
||||
int indextbl_len =
|
||||
(u_sess->attr.attr_security.Audit_RemainThreshold + 1) * sizeof(AuditIndexItem) + indextbl_header_size;
|
||||
t_thrd.audit.audit_indextbl = (AuditIndexTableNew *)palloc0(indextbl_len);
|
||||
error_t errorno =
|
||||
memcpy_s(t_thrd.audit.audit_indextbl, indextbl_len, g_instance.audit_cxt.audit_indextbl, indextbl_len);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
}
|
||||
LWLockRelease(g_instance.audit_cxt.index_file_lock);
|
||||
|
||||
int thread_num = g_instance.audit_cxt.thread_num;
|
||||
|
|
|
|||
|
|
@ -3532,9 +3532,29 @@ void pgstat_report_activity(BackendState state, const char* cmd_str)
|
|||
beentry->st_state_start_timestamp = current_timestamp;
|
||||
|
||||
if (cmd_str != NULL) {
|
||||
rc = memcpy_s(
|
||||
(char*)beentry->st_activity, g_instance.attr.attr_common.pgstat_track_activity_query_size, cmd_str, len);
|
||||
securec_check(rc, "\0", "\0");
|
||||
char *mask_string = NULL;
|
||||
if (len == g_instance.attr.attr_common.pgstat_track_activity_query_size - 1 &&
|
||||
t_thrd.mem_cxt.mask_password_mem_cxt != NULL) {
|
||||
/* mask the cmd_str when the cmd_str is truncated. */
|
||||
mask_string = maskPassword(cmd_str);
|
||||
}
|
||||
|
||||
/* If mask successfully, store the mask_string. Otherwise, the cmd_str is recorded. */
|
||||
if (mask_string == NULL) {
|
||||
rc = memcpy_s((char*)beentry->st_activity, g_instance.attr.attr_common.pgstat_track_activity_query_size,
|
||||
cmd_str, len);
|
||||
securec_check(rc, "\0", "\0");
|
||||
} else {
|
||||
int copy_len = strlen(mask_string);
|
||||
if (len < copy_len) {
|
||||
copy_len = len;
|
||||
}
|
||||
rc = memcpy_s((char*)beentry->st_activity, g_instance.attr.attr_common.pgstat_track_activity_query_size,
|
||||
mask_string, copy_len);
|
||||
securec_check(rc, "\0", "\0");
|
||||
pfree(mask_string);
|
||||
}
|
||||
|
||||
beentry->st_activity[len] = '\0';
|
||||
beentry->st_activity_start_timestamp = start_timestamp;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue