diff --git a/docs/assets/scss/_tables.scss b/docs/assets/scss/_tables.scss index c10daa78c4a1..4273bf36ca5a 100644 --- a/docs/assets/scss/_tables.scss +++ b/docs/assets/scss/_tables.scss @@ -9,19 +9,20 @@ main { margin: 20px 0; max-width: 828px; - > table{ + > table { margin: 0 !important; border: none; box-shadow: none; - @media(max-width:900px){ - min-width:650px; - } - tbody{ + + @media (max-width:900px) { + min-width:650px; + } + + tbody { border-bottom:0; - tr:last-child{ - //background: red; - td{ + tr:last-child { + td { border-bottom:0px; } } @@ -70,7 +71,8 @@ main { } &.sno-last { - tr th:last-child, tr td:last-child { + tr th:last-child, + tr td:last-child { width: 1%; } } @@ -97,6 +99,46 @@ main { } } + &.sortable tr { + th { + position: relative; + + &.empty-th .sort-btn { + display: none; + } + + .sort-btn { + font-size: 0; + width: 5px; + height: 20px; + display: inline-block; + vertical-align: middle; + text-align: center; + cursor: pointer; + position: absolute; + + &::after { + color: #97a5b0; + display: inline-block; + font-size: 14px; + width: 0; + height: 0; + background-size: contain; + border-radius: 4px; + margin-top: 0; + margin-left: 5px; + transition: all 300ms linear; + content: "\f0d7"; + font-family: "Font Awesome 6 Pro"; + } + + &.sorted::after { + content: "\f0d8"; + } + } + } + } + tr { &:not(:last-child) { border-color: #e9eef2; @@ -131,8 +173,6 @@ main { } } - - @media (min-width: 1024px) { main { .td-content { diff --git a/docs/src/index.js b/docs/src/index.js index b3fac6050e22..b1ce364fc45b 100644 --- a/docs/src/index.js +++ b/docs/src/index.js @@ -506,6 +506,90 @@ $(document).ready(() => { } }); + /** + Sort option in table. + */ + (() => { + const tables = document.querySelectorAll('.td-content .table-responsive table.sortable'); + tables.forEach(table => { + const headersEmpty = table.querySelectorAll('th:empty'); + headersEmpty.forEach((innerDiv) => { + innerDiv.classList.add('empty-th'); + }); + + const headers = table.querySelectorAll('th'); + const tbody = table.tBodies[0]; + const totalRows = tbody.querySelectorAll('tr'); + + let sortOrder = 1; + if (totalRows.length > 1) { + headers.forEach((header, index) => { + const sortSpan = document.createElement('span'); + const tdsEmpty = table.querySelectorAll(`td:nth-child(${index + 1})`); + + let emptyCellsCount = 0; + tdsEmpty.forEach((emptyCell) => { + if (emptyCell.textContent.trim() !== '') { + emptyCellsCount += 1; + } + }); + + if (emptyCellsCount === 0) { + table.querySelector(`thead th:nth-child(${index + 1})`).classList.add('empty-th'); + } + + sortSpan.textContent = 'Sort'; + sortSpan.classList.add('sort-btn'); + header.appendChild(sortSpan); + sortSpan.addEventListener('click', (ev) => { + ev.target.classList.toggle('sorted'); + sortTableByColumn(table, index, sortOrder); + sortOrder *= -1; + }); + }); + } + }); + + function sortTableByColumn(table, columnIndex, sortOrder) { + const tbody = table.tBodies[0]; + const rows = Array.from(tbody.querySelectorAll('tr')); + const sortedRows = rows.sort((a, b) => { + let aText = ''; + let bText = ''; + let returnVal = ''; + + if (a.cells[columnIndex] && a.cells[columnIndex].textContent) { + aText = a.cells[columnIndex].textContent.replace(/[,\-(]/g, '').trim(); + } + + if (b.cells[columnIndex] && b.cells[columnIndex].textContent) { + bText = b.cells[columnIndex].textContent.replace(/[,\-(]/g, '').trim(); + } + + if (aText === '' && bText === '') { + returnVal = 0; + } else if (aText === '') { + returnVal = 1; + } else if (bText === '') { + returnVal = -1; + } else { + returnVal = sortOrder * aText.localeCompare(bText, 'en', { + numeric: true, + sensitivity: 'base', + }); + } + + return returnVal; + }); + + while (tbody.firstChild) { + tbody.removeChild(tbody.firstChild); + } + + tbody.append(...sortedRows); + } + })(); + if ($('.component-box').length > 0) { $('.component-box li p a').each(function () { $(this).parents('li').addClass('linked-box'); diff --git a/java/yb-cql/src/test/java/org/yb/cql/TestBindVariable.java b/java/yb-cql/src/test/java/org/yb/cql/TestBindVariable.java index d538c6510f74..2c9db1cc83ae 100644 --- a/java/yb-cql/src/test/java/org/yb/cql/TestBindVariable.java +++ b/java/yb-cql/src/test/java/org/yb/cql/TestBindVariable.java @@ -146,6 +146,17 @@ public void testSelectBind() throws Exception { assertNull(row); } + { + // Ensure that this doesn't crash the tserver + String selectStmt = "SELECT ? FROM test_bind;"; + try { + ResultSet rs = session.execute(selectStmt, new Integer(1)); + fail("Statement \"" + selectStmt + "\" did not fail undefined bind variable name"); + } catch (com.datastax.driver.core.exceptions.InvalidQueryException e) { + LOG.info("Expected exception ", e); + } + } + LOG.info("End test"); } diff --git a/java/yb-ysql-conn-mgr/src/test/java/org/yb/ysqlconnmgr/TestStatsAndMetrics.java b/java/yb-ysql-conn-mgr/src/test/java/org/yb/ysqlconnmgr/TestStatsAndMetrics.java index 16d4c68871e8..69da320c3a0e 100644 --- a/java/yb-ysql-conn-mgr/src/test/java/org/yb/ysqlconnmgr/TestStatsAndMetrics.java +++ b/java/yb-ysql-conn-mgr/src/test/java/org/yb/ysqlconnmgr/TestStatsAndMetrics.java @@ -27,7 +27,7 @@ public class TestStatsAndMetrics extends BaseYsqlConnMgr { "user_name", "active_logical_connections", "queued_logical_connections", - "idle_or_pending_logical_connections", + "waiting_logical_connections", "active_physical_connections", "idle_physical_connections", "avg_wait_time_ns", @@ -117,7 +117,7 @@ private void testNumLogicalConnections(String db_name, int num_logical_conn = pool.get("active_logical_connections").getAsInt() + pool.get("queued_logical_connections").getAsInt() + - pool.get("idle_or_pending_logical_connections").getAsInt(); + pool.get("waiting_logical_connections").getAsInt(); assertEquals("Did not get the expected number of logical connections for pool with user " + user_name + " and database " + db_name, exp_val, num_logical_conn); } diff --git a/managed/src/main/java/com/yugabyte/yw/common/config/ProviderConfKeys.java b/managed/src/main/java/com/yugabyte/yw/common/config/ProviderConfKeys.java index 9ee58c2d125d..004824663ca9 100644 --- a/managed/src/main/java/com/yugabyte/yw/common/config/ProviderConfKeys.java +++ b/managed/src/main/java/com/yugabyte/yw/common/config/ProviderConfKeys.java @@ -96,7 +96,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "Min Python Version (inclusive)", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo maxPyVer = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.max_python_version", @@ -104,7 +104,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "Max Python Version (exclusive)", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo defaultAwsVolumeCount = new ConfKeyInfo<>( "yb.aws.default_volume_count", @@ -208,7 +208,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "User", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo userGroup = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.user_group", @@ -216,7 +216,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "User Group", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo minPrometheusSpaceMb = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.min_prometheus_space_mb", @@ -224,7 +224,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "Min Prometheus Space MB", "", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo minTempDirSpaceMb = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.min_tmp_dir_space_mb", @@ -232,7 +232,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "Min Temp Dir Space MB", "", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo minHomeDirSpaceMb = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.min_home_dir_space_mb", @@ -240,7 +240,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "Min Home Space MB", "", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo minMountPointDirSpaceMb = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.min_mount_point_dir_space_mb", @@ -248,7 +248,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "Min Mount Point Dir Space MB", "", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo ulimitCore = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.ulimit_core", @@ -256,7 +256,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "ulimit core ", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo ulimitOpenFiles = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.ulimit_open_files", @@ -264,7 +264,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "ulimit open files", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo ulimitUserProcesses = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.ulimit_user_processes", @@ -272,7 +272,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "ulimit user processes", "", ConfDataType.StringType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo swappiness = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.swappiness", @@ -280,7 +280,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "swappiness", "", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo sshTimeout = new ConfKeyInfo<>( "yb.node_agent.preflight_checks.ssh_timeout", @@ -288,7 +288,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "SSH connection timeout", "", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo enableNodeAgentClient = new ConfKeyInfo<>( @@ -306,7 +306,7 @@ public class ProviderConfKeys extends RuntimeConfigKeysModule { "VM max map count", "Max count of memory-mapped regions allowed in the system.", ConfDataType.IntegerType, - ImmutableList.of(ConfKeyTags.BETA)); + ImmutableList.of(ConfKeyTags.INTERNAL)); public static final ConfKeyInfo enableAnsibleOffloading = new ConfKeyInfo<>( "yb.node_agent.ansible_offloading.enabled", diff --git a/managed/src/main/java/com/yugabyte/yw/models/configs/validators/KubernetesProviderValidator.java b/managed/src/main/java/com/yugabyte/yw/models/configs/validators/KubernetesProviderValidator.java index 6b71fff54527..df874a350fb7 100644 --- a/managed/src/main/java/com/yugabyte/yw/models/configs/validators/KubernetesProviderValidator.java +++ b/managed/src/main/java/com/yugabyte/yw/models/configs/validators/KubernetesProviderValidator.java @@ -130,11 +130,15 @@ private Map> getCloudInfoPerAZ(JsonNode provider, config.putAll(zoneConfig); config.put("zoneCode", zoneCodeNode); - if (!config.containsKey("kubeConfigContent")) { + // New providers have kubeConfigContent and + // during edit we have kubeConfig if the + // kubeconfig is unchanged. + if (!config.containsKey("kubeConfigContent") + && !config.containsKey("kubeConfig")) { log.warn( "No kubeconfig found at any level, using in-cluster credentials"); config.put( - "kubeConfigContent", + "kubeConfig", // TODO: the jsonPath could be different // like $.in-cluster-credentials? Json.newObject().put("jsonPath", "$").put("value", "")); @@ -185,7 +189,7 @@ private void validateZoneLabels( try { regionToZone = KubernetesUtil.computeKubernetesRegionToZoneInfo( - ImmutableMap.of("KUBECONFIG", getStringValue(k8sInfo.get("kubeConfigContent"))), + ImmutableMap.of("KUBECONFIG", getStringValue(getKubeConfigNode(k8sInfo))), kubernetesManagerFactory); } catch (RuntimeException e) { if (e.getMessage().contains("Error from server (Forbidden): nodes")) { @@ -220,7 +224,7 @@ private void validateStorageClass( kubernetesManagerFactory .getManager() .getStorageClass( - ImmutableMap.of("KUBECONFIG", getStringValue(k8sInfo.get("kubeConfigContent"))), + ImmutableMap.of("KUBECONFIG", getStringValue(getKubeConfigNode(k8sInfo))), getStringValue(storageClassNode)); } catch (RuntimeException e) { if (e.getMessage().contains("Error from server (NotFound): storageclasses")) { @@ -259,13 +263,13 @@ private void validateNamespace( kubernetesManagerFactory .getManager() .dbNamespaceExists( - ImmutableMap.of("KUBECONFIG", getStringValue(k8sInfo.get("kubeConfigContent"))), + ImmutableMap.of("KUBECONFIG", getStringValue(getKubeConfigNode(k8sInfo))), getStringValue(namespaceNode)); } catch (RuntimeException e) { if (e.getMessage().contains("error: failed to create secret secrets is forbidden") || e.getMessage().contains("Error from server (Forbidden): secrets is forbidden")) { validationErrors.put( - getJsonPath(k8sInfo.get("kubeConfigContent")), + getJsonPath(getKubeConfigNode(k8sInfo)), "Missing permission to create secrets in " + getStringValue(namespaceNode)); return; } @@ -282,7 +286,7 @@ private void validateCertManagerIssuer( // given preference in KubernetesCommandExecutor. Map config = - ImmutableMap.of("KUBECONFIG", getStringValue(k8sInfo.get("kubeConfigContent"))); + ImmutableMap.of("KUBECONFIG", getStringValue(getKubeConfigNode(k8sInfo))); JsonNode clusterIssuerNode = k8sInfo.get("certManagerClusterIssuer"); if (clusterIssuerNode != null) { @@ -332,6 +336,9 @@ private void validateCertManagerIssuer( validationErrors.put( getJsonPath(issuerNode), "Cluster doesn't have Issuer resource type, ensure cert-manager is installed"); + } else if (e.getMessage().contains("Error from server (NotFound): namespaces")) { + validationErrors.put( + getJsonPath(namespaceNode), "Namespace doesn't exist in the cluster"); } else if (e.getMessage().contains("Error from server (Forbidden): issuers")) { log.warn("Unable to validate cert-manager Issuer: {}", e.getMessage()); } else { @@ -362,4 +369,10 @@ private String getStringValue(JsonNode node) { private String getJsonPath(JsonNode node) { return node.get("jsonPath").asText(); } + + private JsonNode getKubeConfigNode(Map k8sInfo) { + // A new or modified kubeconfig is preferred + // i.e. kubeConfigContent + return k8sInfo.getOrDefault("kubeConfigContent", k8sInfo.get("kubeConfig")); + } } diff --git a/managed/src/main/resources/reference.conf b/managed/src/main/resources/reference.conf index e2b3230cf02d..e30750aee2ce 100644 --- a/managed/src/main/resources/reference.conf +++ b/managed/src/main/resources/reference.conf @@ -209,7 +209,7 @@ yb { # This can contain comma separated values, like "/,/tmp," monitored_mount_roots = "/" vm_os_patching = true - kubernetes_provider_validation = false + kubernetes_provider_validation = true azure_provider_validation = true gcp_provider_validation = true } diff --git a/managed/yba-installer/cmd/init.go b/managed/yba-installer/cmd/init.go index 9210c56b1291..85501f5bab79 100644 --- a/managed/yba-installer/cmd/init.go +++ b/managed/yba-installer/cmd/init.go @@ -117,6 +117,18 @@ func handleRootCheck(cmdName string) { log.Fatal("Could not determine current user: " + err.Error()) } + if !viper.IsSet("as_root") && cmdName == "yba-ctl upgrade" { + // Upgrading from before "as_root" exists. perform legacy check for /opt/yba-ctl + _, err := os.Stat(common.YbactlRootInstallDir) + if user.Uid == "0" && err != nil { + log.Fatal("no root install found at /opt/yba-ctl, cannot upgrade with root") + } else if user.Uid != "0" && err == nil { + log.Fatal("Detected root install at /opt/yba-ctl, cannot upgrade as non-root") + } + log.Debug("legacy root check passed for upgrade") + return + } + // First, validate that the user (root access) matches the config 'as_root' if user.Uid == "0" && !viper.GetBool("as_root") { log.Fatal("running as root user with 'as_root' set to false is not supported") @@ -124,10 +136,10 @@ func handleRootCheck(cmdName string) { (viper.GetBool("as_root") || common.Exists(common.YbactlRootInstallDir)) { // Allow running certain commands as non-root in root install mode switch cmdName { - case "yba-ctl version", "yba-ctl status", "yba-ctl createBackup": - break - default: - log.Fatal("running as non-root user with 'as_root' set to true is not supported") + case "yba-ctl version", "yba-ctl status", "yba-ctl createBackup": + break + default: + log.Fatal("running as non-root user with 'as_root' set to true is not supported") } } } diff --git a/managed/yba-installer/cmd/install.go b/managed/yba-installer/cmd/install.go index db221293bf19..5345e9af8204 100644 --- a/managed/yba-installer/cmd/install.go +++ b/managed/yba-installer/cmd/install.go @@ -23,7 +23,12 @@ var installCmd = &cobra.Command{ `, Args: cobra.NoArgs, PreRun: func(cmd *cobra.Command, args []string) { - if _, err := os.Stat(common.YbaInstalledMarker()); err == nil { + state, err := ybactlstate.Initialize() + if err != nil { + if _, err := os.Stat(common.YbaInstalledMarker()); err != nil { + log.Fatal("YugabyteDB Anywhere already installed, cannot install twice.") + } + } else if state.CurrentStatus == ybactlstate.InstalledStatus { log.Fatal("YugabyteDB Anywhere already installed, cannot install twice.") } if common.RunFromInstalled() { diff --git a/managed/yba-installer/cmd/log_gen.go b/managed/yba-installer/cmd/log_gen.go index 8d02b37433f9..0a221cb60d6f 100644 --- a/managed/yba-installer/cmd/log_gen.go +++ b/managed/yba-installer/cmd/log_gen.go @@ -55,8 +55,6 @@ other useful data.`, common.YbactlLogFile(), filepath.Join(common.YbactlInstallDir(), ybactlstate.StateFileName), filepath.Join(common.YbactlInstallDir(), common.VersionMetadataJSON), - common.YbaInstalledMarker(), - common.YbaInstallingMarker(), common.LicenseFile(), filepath.Join(common.YbactlInstallDir(), common.GoBinaryName), diff --git a/managed/yba-installer/cmd/upgrade.go b/managed/yba-installer/cmd/upgrade.go index 3d8f5f50251f..5afb658bc08f 100644 --- a/managed/yba-installer/cmd/upgrade.go +++ b/managed/yba-installer/cmd/upgrade.go @@ -128,11 +128,6 @@ func upgradeCmd() *cobra.Command { log.Fatal("preflight failed") } - state.CurrentStatus = ybactlstate.UpgradingStatus - if err := ybactlstate.StoreState(state); err != nil { - log.Fatal("could not update state: " + err.Error()) - } - // Take a backup of YBA as a safety measure backupDir := filepath.Join(common.GetDataRoot(), "upgradeYbaBackup") if err := common.MkdirAll(backupDir, common.DirMode); err == nil { diff --git a/managed/yba-installer/pkg/common/common.go b/managed/yba-installer/pkg/common/common.go index 182724209ea9..8e91a5c66717 100644 --- a/managed/yba-installer/pkg/common/common.go +++ b/managed/yba-installer/pkg/common/common.go @@ -29,12 +29,6 @@ import ( // all services. func Install(version string) error { log.Info("Starting Common install") - // Hidden file written on first install (.installCompleted) at the end of the install, - // if the file already exists then it means that an installation has already taken place, - // and that future installs are prohibited. - if _, err := os.Stat(YbaInstalledMarker()); err == nil { - log.Fatal("Install of YBA already completed, cannot perform reinstall without clean.") - } // Change into the dir we are in so that we can specify paths relative to ourselves // TODO(minor): probably not a good idea in the long run @@ -596,18 +590,23 @@ func WaitForYBAReady(version string) error { var resp *http.Response var err error - // Check YBA version every 10 seconds - retriesCount := 20 - for i := 0; i < retriesCount; i++ { + waitSecs := viper.GetInt("wait_for_yba_ready_secs") + endTime := time.Now().Add(time.Duration(waitSecs) * time.Second) + success := false + for time.Now().Before(endTime) { resp, err = http.Get(url) if err != nil { log.Info(fmt.Sprintf("YBA at %s not ready. Checking again in 10 seconds.", url)) time.Sleep(10 * time.Second) } else { + success = true break } } + if !success { + return fmt.Errorf("YBA at %s not ready after %d minutes", url, waitSecs/60) + } if resp != nil { defer resp.Body.Close() diff --git a/managed/yba-installer/pkg/preflight/checks/diskavail.go b/managed/yba-installer/pkg/preflight/checks/diskavail.go index 41aa1a4434fb..7acae63df1d2 100644 --- a/managed/yba-installer/pkg/preflight/checks/diskavail.go +++ b/managed/yba-installer/pkg/preflight/checks/diskavail.go @@ -14,6 +14,7 @@ import ( "github.com/dustin/go-humanize" "github.com/yugabyte/yugabyte-db/managed/yba-installer/pkg/common" log "github.com/yugabyte/yugabyte-db/managed/yba-installer/pkg/logging" + "github.com/yugabyte/yugabyte-db/managed/yba-installer/pkg/ybactlstate" ) const minFreeDiskInstall uint64 = 200 * 1024 * 1024 * 1024 // 200 GB @@ -54,8 +55,13 @@ func (r diskAvailCheck) Execute() Result { } minDiskReq := minFreeDiskInstall - _, err = os.Stat(common.YbaInstalledMarker()) - if err == nil { + state, err := ybactlstate.Initialize() + if err != nil { + if _, err := os.Stat(common.YbaInstalledMarker()); err != nil { + // upgrade + minDiskReq = minFreeDiskUpgrade + } + } else if state.CurrentStatus == ybactlstate.UpgradingStatus { // upgrade minDiskReq = minFreeDiskUpgrade } diff --git a/managed/yba-installer/pkg/ybactlstate/migration.go b/managed/yba-installer/pkg/ybactlstate/migration.go index f3afba24afce..4d1c1e279654 100644 --- a/managed/yba-installer/pkg/ybactlstate/migration.go +++ b/managed/yba-installer/pkg/ybactlstate/migration.go @@ -19,9 +19,13 @@ const ymlTypeFixMV = 4 const promOomConfgMV = 5 const promTLSCipherSuites = 6 const asRoot = 7 +const ybaWait = 8 + +// Please do not use this in ybactlstate package, only use getSchemaVersion() +var schemaVersionCache = -1 func handleMigration(state *State) error { - for state._internalFields.SchemaVersion < schemaVersion { + for state._internalFields.SchemaVersion < getSchemaVersion() { nextSchema := state._internalFields.SchemaVersion + 1 migrate := getMigrationHandler(nextSchema) if err := migrate(state); err != nil { @@ -183,7 +187,24 @@ func migrateAsRootConfig(state *State) error { return nil } -// TODO: Also need to remember to update schemaVersion when adding migration! (automate testing?) +func migrateYbaWait(state *State) error { + if !viper.IsSet("wait_for_yba_ready_secs") { + log.Info("wait for ready not set") + viper.ReadConfig(bytes.NewBufferString(config.ReferenceYbaCtlConfig)) + log.Info(fmt.Sprintf("setting to %d", viper.GetInt("wait_for_yba_ready_secs"))) + err := common.SetYamlValue(common.InputFile(), "wait_for_yba_ready_secs", + viper.GetInt("wait_for_yba_ready_secs")) + if err != nil { + return fmt.Errorf("Error migrating yb_wait config: %s", err.Error()) + } + } else { + log.Info("wait for ready set") + } + + common.InitViper() + return nil +} + var migrations map[int]migrator = map[int]migrator{ defaultMigratorValue: defaultMigrate, promConfigMV: migratePrometheus, @@ -192,6 +213,7 @@ var migrations map[int]migrator = map[int]migrator{ promOomConfgMV: migratePrometheusOOMConfig, promTLSCipherSuites: migratePrometheusTLSCipherSuites, asRoot: migrateAsRootConfig, + ybaWait: migrateYbaWait, } func getMigrationHandler(toSchema int) migrator { @@ -201,3 +223,14 @@ func getMigrationHandler(toSchema int) migrator { } return m } + +func getSchemaVersion() int { + if schemaVersionCache == -1 { + for k := range migrations { + if k > schemaVersionCache { + schemaVersionCache = k + } + } + } + return schemaVersionCache +} diff --git a/managed/yba-installer/pkg/ybactlstate/state.go b/managed/yba-installer/pkg/ybactlstate/state.go index 9a747a2e37c7..caa5a9301108 100644 --- a/managed/yba-installer/pkg/ybactlstate/state.go +++ b/managed/yba-installer/pkg/ybactlstate/state.go @@ -9,8 +9,7 @@ import ( ) const ( - StateFileName = ".yba_installer.state" - schemaVersion int = 6 + StateFileName = ".yba_installer.state" ) type State struct { @@ -63,7 +62,7 @@ func New() *State { }, _internalFields: internalFields{ ChangeID: 0, - SchemaVersion: schemaVersion, + SchemaVersion: getSchemaVersion(), }, } } diff --git a/managed/yba-installer/yba-ctl.yml.reference b/managed/yba-installer/yba-ctl.yml.reference index fc69079fef22..74aade5bc1bb 100644 --- a/managed/yba-installer/yba-ctl.yml.reference +++ b/managed/yba-installer/yba-ctl.yml.reference @@ -30,6 +30,9 @@ service_username: "yugabyte" # by service_username. as_root: true +# Number of seconds to wait for yba to start +wait_for_yba_ready_secs: 300 + # Config parameters for YB-Platform: # ======================================= diff --git a/src/odyssey/sources/cron.c b/src/odyssey/sources/cron.c index 3b47d8891341..2061e6ec4188 100644 --- a/src/odyssey/sources/cron.c +++ b/src/odyssey/sources/cron.c @@ -80,7 +80,7 @@ static int od_cron_stat_cb(od_route_t *route, od_stat_t *current, route->client_pool.count_active; instance->yb_stats[index].queued_clients = route->client_pool.count_queue; - instance->yb_stats[index].idle_or_pending_clients = + instance->yb_stats[index].waiting_clients = route->client_pool.count_pending; instance->yb_stats[index].active_servers = route->server_pool.count_active; diff --git a/src/postgres/src/backend/tcop/postgres.c b/src/postgres/src/backend/tcop/postgres.c index 46c28b3b5c3e..a7535e03f168 100644 --- a/src/postgres/src/backend/tcop/postgres.c +++ b/src/postgres/src/backend/tcop/postgres.c @@ -98,6 +98,7 @@ /* YB includes */ #include "replication/walsender_private.h" +#include "utils/guc_tables.h" /* ---------------- * global variables @@ -3632,6 +3633,44 @@ check_stack_depth(void) bool stack_is_too_deep(void) { +#ifdef ADDRESS_SANITIZER + // Postgres analyzes/limits stack depth based on local variables address + // offset. + // This method works well in case of regular call stack (i.e. when all + // stack frames are allocated in stack). + // But for the detect_stack_use_after_return ASAN uses fake stack. In case + // of using it stack frames are allocated in the heap. As a result it is + // not possible to estimate stack depth base on local variables address + // offset. + // To make stack_is_too_deep return predictable results in case of ASAN it + // is reasonable to return false all the time. + // Note: + // YSQL has some unit tests which checks that Postgres can detect too + // deep recursion. These tests change the `max_stack_depth` GUC variable + // to lower value. And later restore the original value with the + // `RESET max_stack_depth` statement. + // To make these tests works under the ASAN the function returns true in + // case the `max_stack_depth` GUC contains non default value and number of + // call stack frames is huge enough. + // The check of call stack frames is required to avoid undesired failure on + // attempt to restore original value for the `max_stack_depth` GUC with + // the `RESET max_stack_depth` statement. + if (get_guc_variables()) { + const char* max_stack_depth_GUC = "max_stack_depth"; + const char* current_value = + GetConfigOption(max_stack_depth_GUC, false, false); + const char* default_value = + GetConfigOptionResetString(max_stack_depth_GUC); + if (strcmp(current_value, default_value) != 0) { + static const int MAX_STACK_FRAMES = 64; + void* frames[MAX_STACK_FRAMES]; + int frames_count = + YBCGetCallStackFrames(frames, MAX_STACK_FRAMES, 0); + return frames_count >= MAX_STACK_FRAMES; + } + } + return false; +#endif char stack_top_loc; long stack_depth; diff --git a/src/postgres/src/backend/utils/misc/yb_ysql_conn_mgr_helper.c b/src/postgres/src/backend/utils/misc/yb_ysql_conn_mgr_helper.c index 802303ae18a5..f51a5e3f5e1f 100644 --- a/src/postgres/src/backend/utils/misc/yb_ysql_conn_mgr_helper.c +++ b/src/postgres/src/backend/utils/misc/yb_ysql_conn_mgr_helper.c @@ -903,7 +903,7 @@ YbGetNumYsqlConnMgrConnections(const char *db_name, const char *user_name, * can get changed while reading the shared memory segment. */ *num_logical_conn += shmp[itr].active_clients + - shmp[itr].idle_or_pending_clients + + shmp[itr].waiting_clients + shmp[itr].queued_clients; *num_physical_conn += shmp[itr].active_servers + shmp[itr].idle_servers; } diff --git a/src/yb/common/common_types.proto b/src/yb/common/common_types.proto index 194a76b06cbc..56f0a2e92717 100644 --- a/src/yb/common/common_types.proto +++ b/src/yb/common/common_types.proto @@ -159,6 +159,12 @@ enum ReplicationErrorPb { // The AutoFlags config has changed and the new version is not compatible, or // has not yet been validated. REPLICATION_AUTO_FLAG_CONFIG_VERSION_MISMATCH = 6; + + // Error connecting to the source universe. + REPLICATION_SOURCE_UNREACHABLE = 7; + + // There was a generic system error. + REPLICATION_SYSTEM_ERROR = 8; } // Stateful services. diff --git a/src/yb/integration-tests/xcluster/xcluster-test.cc b/src/yb/integration-tests/xcluster/xcluster-test.cc index e3fcbeb8bcfe..dd1c897fc196 100644 --- a/src/yb/integration-tests/xcluster/xcluster-test.cc +++ b/src/yb/integration-tests/xcluster/xcluster-test.cc @@ -3936,6 +3936,61 @@ TEST_F_EX(XClusterTest, ReplicationErrorAfterMasterFailover, XClusterTestNoParam ASSERT_OK(VerifyReplicationError(consumer_table_->id(), stream_id, std::nullopt)); } +// Make sure we get SOURCE_UNREACHABLE when the source universe is not reachable. +TEST_F_EX(XClusterTest, NetworkReplicationError, XClusterTestNoParam) { + // Send metrics report including the xCluster status in every heartbeat. + const auto short_metric_report_interval_ms = 250; + ANNOTATE_UNPROTECTED_WRITE(FLAGS_heartbeat_interval_ms) = short_metric_report_interval_ms * 2; + ANNOTATE_UNPROTECTED_WRITE(FLAGS_tserver_heartbeat_metrics_interval_ms) = + short_metric_report_interval_ms; + + ASSERT_OK(SetUpWithParams( + {1}, {1}, /* replication_factor */ 1, /* num_masters */ 1, /* num_tservers */ 1)); + ASSERT_OK(SetupReplication()); + ASSERT_OK(CorrectlyPollingAllTablets(1)); + const auto stream_id = ASSERT_RESULT(GetCDCStreamID(producer_table_->id())); + + ASSERT_OK(VerifyReplicationError(consumer_table_->id(), stream_id, std::nullopt)); + + ANNOTATE_UNPROTECTED_WRITE(FLAGS_cdc_read_rpc_timeout_ms) = 5 * 1000; + + producer_cluster()->mini_tablet_server(0)->Shutdown(); + + ASSERT_OK(VerifyReplicationError( + consumer_table_->id(), stream_id, ReplicationErrorPb::REPLICATION_SOURCE_UNREACHABLE, + kRpcTimeout)); + + ASSERT_OK(producer_cluster()->mini_tablet_server(0)->Start()); + + ASSERT_OK(VerifyReplicationError(consumer_table_->id(), stream_id, std::nullopt)); +} + +// Make sure we get SYSTEM_ERROR when apply fails. +TEST_F_EX(XClusterTest, ApplyReplicationError, XClusterTestNoParam) { + // Send metrics report including the xCluster status in every heartbeat. + const auto short_metric_report_interval_ms = 250; + ANNOTATE_UNPROTECTED_WRITE(FLAGS_heartbeat_interval_ms) = short_metric_report_interval_ms * 2; + ANNOTATE_UNPROTECTED_WRITE(FLAGS_tserver_heartbeat_metrics_interval_ms) = + short_metric_report_interval_ms; + + ASSERT_OK(SetUpWithParams( + {1}, {1}, /* replication_factor */ 1, /* num_masters */ 1, /* num_tservers */ 1)); + ASSERT_OK(SetupReplication()); + ASSERT_OK(CorrectlyPollingAllTablets(1)); + const auto stream_id = ASSERT_RESULT(GetCDCStreamID(producer_table_->id())); + + ASSERT_OK(VerifyReplicationError(consumer_table_->id(), stream_id, std::nullopt)); + + ANNOTATE_UNPROTECTED_WRITE(FLAGS_TEST_xcluster_simulate_random_failure_after_apply) = 1; + + ASSERT_OK(VerifyReplicationError( + consumer_table_->id(), stream_id, ReplicationErrorPb::REPLICATION_SYSTEM_ERROR)); + + ANNOTATE_UNPROTECTED_WRITE(FLAGS_TEST_xcluster_simulate_random_failure_after_apply) = 0; + + ASSERT_OK(VerifyReplicationError(consumer_table_->id(), stream_id, std::nullopt)); +} + // Test deleting inbound replication group without performing source stream cleanup. TEST_F_EX(XClusterTest, DeleteWithoutStreamCleanup, XClusterTestNoParam) { constexpr int kNTabletsPerTable = 1; diff --git a/src/yb/integration-tests/xcluster/xcluster_test_base.cc b/src/yb/integration-tests/xcluster/xcluster_test_base.cc index 232c72935d37..851d7fbcaa41 100644 --- a/src/yb/integration-tests/xcluster/xcluster_test_base.cc +++ b/src/yb/integration-tests/xcluster/xcluster_test_base.cc @@ -822,7 +822,7 @@ Status XClusterTestBase::WaitForReplicationDrain( Status XClusterTestBase::VerifyReplicationError( const std::string& consumer_table_id, const xrepl::StreamId& stream_id, - const std::optional expected_replication_error) { + const std::optional expected_replication_error, int timeout_secs) { // 1. Verify that the RPC contains the expected error. master::GetReplicationStatusRequestPB req; master::GetReplicationStatusResponsePB resp; @@ -858,7 +858,7 @@ Status XClusterTestBase::VerifyReplicationError( return resp.statuses()[0].errors_size() == 0; } }, - MonoDelta::FromSeconds(30), "Waiting for replication error")); + MonoDelta::FromSeconds(timeout_secs), "Waiting for replication error")); // 2. Verify that the yb-admin output contains the expected error. auto admin_out = diff --git a/src/yb/integration-tests/xcluster/xcluster_test_base.h b/src/yb/integration-tests/xcluster/xcluster_test_base.h index 1bec8f992ff6..37b7775d60fa 100644 --- a/src/yb/integration-tests/xcluster/xcluster_test_base.h +++ b/src/yb/integration-tests/xcluster/xcluster_test_base.h @@ -339,7 +339,7 @@ class XClusterTestBase : public YBTest { Status VerifyReplicationError( const std::string& consumer_table_id, const xrepl::StreamId& stream_id, - const std::optional expected_replication_error); + const std::optional expected_replication_error, int timeout_secs = 30); Result GetCDCStreamID(const TableId& producer_table_id); diff --git a/src/yb/master/catalog_manager.cc b/src/yb/master/catalog_manager.cc index 4b9ced7801e8..6004d9fed685 100644 --- a/src/yb/master/catalog_manager.cc +++ b/src/yb/master/catalog_manager.cc @@ -3980,7 +3980,7 @@ Status CatalogManager::CreateTable(const CreateTableRequestPB* orig_req, TabletInfoPtr colocated_tablet = nullptr; { - LockGuard lock(mutex_); + UniqueLock lock(mutex_); auto ns_lock = ns->LockForRead(); TRACE("Acquired catalog manager lock"); @@ -4149,6 +4149,7 @@ Status CatalogManager::CreateTable(const CreateTableRequestPB* orig_req, auto tablet = tablegroup ? tablegroup->tablet() : colocated_db_tablets_map_[ns->id()]; + lock.unlock(); RSTATUS_DCHECK( tablet->colocated(), InternalError, Format("Colocation group tablet $0 should be marked as colocated", diff --git a/src/yb/tserver/metrics_snapshotter.cc b/src/yb/tserver/metrics_snapshotter.cc index d87a283288db..544495f0bcab 100644 --- a/src/yb/tserver/metrics_snapshotter.cc +++ b/src/yb/tserver/metrics_snapshotter.cc @@ -377,7 +377,7 @@ Status MetricsSnapshotter::Thread::DoYsqlConnMgrMetricsSnapshot(const client::Ta if (strcmp(stat.database_name, "control_connection") != 0) { total_logical_connections += stat.active_clients + stat.queued_clients + - stat.idle_or_pending_clients; + stat.waiting_clients; total_physical_connections += stat.active_servers + stat.idle_servers; } } diff --git a/src/yb/tserver/xcluster_poller.cc b/src/yb/tserver/xcluster_poller.cc index 7158f6e2867d..f38bfd05c3c9 100644 --- a/src/yb/tserver/xcluster_poller.cc +++ b/src/yb/tserver/xcluster_poller.cc @@ -412,6 +412,12 @@ void XClusterPoller::HandleGetChangesResponse( if (!status.ok()) { LOG_WITH_PREFIX(WARNING) << "XClusterPoller GetChanges failure: " << status.ToString(); + if (status.IsTimedOut() || status.IsNetworkError()) { + StoreReplicationError(ReplicationErrorPb::REPLICATION_SOURCE_UNREACHABLE); + } else { + StoreNOKReplicationError(); + } + if (FLAGS_enable_xcluster_stat_collection) { poll_stats_history_.SetError(std::move(status)); } @@ -487,6 +493,8 @@ void XClusterPoller::VerifyApplyChangesResponse(XClusterOutputClientResponse res RandomActWithProbability(FLAGS_TEST_xcluster_simulate_random_failure_after_apply)) { LOG_WITH_PREFIX(WARNING) << "ApplyChanges failure: " << response.status; + StoreNOKReplicationError(); + if (FLAGS_enable_xcluster_stat_collection) { poll_stats_history_.SetError(std::move(response.status)); } @@ -511,6 +519,9 @@ void XClusterPoller::HandleApplyChangesResponse(XClusterOutputClientResponse res if (!s.ok()) { // If processing ddl_queue table fails, then retry just this part (don't repeat ApplyChanges). YB_LOG_EVERY_N(WARNING, 30) << "ProcessDDLQueueTable Error: " << s << " " << THROTTLE_MSG; + + StoreNOKReplicationError(); + if (FLAGS_enable_xcluster_stat_collection) { poll_stats_history_.SetError(std::move(s)); } @@ -668,6 +679,17 @@ void XClusterPoller::StoreReplicationError(ReplicationErrorPb error) { } } +void XClusterPoller::StoreNOKReplicationError() { + { + std::lock_guard l(replication_error_mutex_); + if (previous_replication_error_ != ReplicationErrorPb::REPLICATION_OK) { + return; + } + } + + StoreReplicationError(ReplicationErrorPb::REPLICATION_SYSTEM_ERROR); +} + void XClusterPoller::ClearReplicationError() { StoreReplicationError(ReplicationErrorPb::REPLICATION_OK); } diff --git a/src/yb/tserver/xcluster_poller.h b/src/yb/tserver/xcluster_poller.h index d562c67bc85a..c0021d0e2e48 100644 --- a/src/yb/tserver/xcluster_poller.h +++ b/src/yb/tserver/xcluster_poller.h @@ -106,6 +106,8 @@ class XClusterPoller : public XClusterAsyncExecutor { void MarkFailed(const std::string& reason, const Status& status = Status::OK()) override; // Stores a replication error and detail. This overwrites a previously stored 'error'. void StoreReplicationError(ReplicationErrorPb error) EXCLUDES(replication_error_mutex_); + // Stores a non OK replication error if one has not already been set. + void StoreNOKReplicationError() EXCLUDES(replication_error_mutex_); void ClearReplicationError() EXCLUDES(replication_error_mutex_); void TEST_IncrementNumSuccessfulWriteRpcs(); void ApplyChangesCallback(XClusterOutputClientResponse&& response); diff --git a/src/yb/yql/cql/ql/ptree/pt_expr.h b/src/yb/yql/cql/ql/ptree/pt_expr.h index 4af696839545..662a65d842a1 100644 --- a/src/yb/yql/cql/ql/ptree/pt_expr.h +++ b/src/yb/yql/cql/ql/ptree/pt_expr.h @@ -1358,7 +1358,8 @@ class PTBindVar : public PTExpr { std::string QLName( qlexpr::QLNameOption option = qlexpr::QLNameOption::kUserOriginalName) const override { - std::string qlname = (user_pos_) ? user_pos_->ToString() : name()->c_str(); + std::string qlname = (user_pos_) ? user_pos_->ToString() + : (name() ? name()->c_str() : default_bindvar_name().c_str()); return ":" + qlname; } diff --git a/src/yb/yql/pggate/util/ybc_util.cc b/src/yb/yql/pggate/util/ybc_util.cc index bb2bb8cd627f..416783f17879 100644 --- a/src/yb/yql/pggate/util/ybc_util.cc +++ b/src/yb/yql/pggate/util/ybc_util.cc @@ -35,6 +35,7 @@ #include "yb/util/random_util.h" #include "yb/util/scope_exit.h" #include "yb/util/status_format.h" +#include "yb/util/stack_trace.h" #include "yb/util/thread.h" #include "yb/yql/pggate/util/ybc-internal.h" @@ -486,6 +487,10 @@ uint8_t YBCGetQueryIdForCatalogRequests() { return static_cast(ash::FixedQueryId::kQueryIdForCatalogRequests); } +int YBCGetCallStackFrames(void** result, int max_depth, int skip_count) { + return google::GetStackTrace(result, max_depth, skip_count); +} + } // extern "C" } // namespace yb::pggate diff --git a/src/yb/yql/pggate/util/ybc_util.h b/src/yb/yql/pggate/util/ybc_util.h index 1092016c3afc..3e03d28186fd 100644 --- a/src/yb/yql/pggate/util/ybc_util.h +++ b/src/yb/yql/pggate/util/ybc_util.h @@ -338,6 +338,8 @@ const char* YBCGetWaitEventComponent(uint32_t wait_event_info); const char* YBCGetWaitEventType(uint32_t wait_event_info); uint8_t YBCGetQueryIdForCatalogRequests(); +int YBCGetCallStackFrames(void** result, int max_depth, int skip_count); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/yb/yql/pggate/webserver/pgsql_webserver_wrapper.cc b/src/yb/yql/pggate/webserver/pgsql_webserver_wrapper.cc index 47df7bb14d3a..c96d1c895140 100644 --- a/src/yb/yql/pggate/webserver/pgsql_webserver_wrapper.cc +++ b/src/yb/yql/pggate/webserver/pgsql_webserver_wrapper.cc @@ -202,8 +202,8 @@ void emitYsqlConnectionManagerMetrics(PrometheusWriter *pwriter) { for (ConnectionStats stats : stats_list) { ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_active_clients", stats.active_clients}); ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_queued_clients", stats.queued_clients}); - ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_idle_or_pending_clients", - stats.idle_or_pending_clients}); + ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_waiting_clients", + stats.waiting_clients}); ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_active_servers", stats.active_servers}); ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_idle_servers", stats.idle_servers}); ysql_conn_mgr_metrics.push_back({"ysql_conn_mgr_query_rate", stats.query_rate}); @@ -422,8 +422,8 @@ static void PgLogicalRpczHandler(const Webserver::WebRequest &req, Webserver::We // Number of logical connections which are either idle (i.e. no ongoing transaction) or waiting // for the worker thread to be processed (i.e. waiting for od_router_attach to be called). - writer.String("idle_or_pending_logical_connections"); - writer.Int64(stat.idle_or_pending_clients); + writer.String("waiting_logical_connections"); + writer.Int64(stat.waiting_clients); // Number of physical connections which currently attached to a logical connection. writer.String("active_physical_connections"); diff --git a/src/yb/yql/ysql_conn_mgr_wrapper/ysql_conn_mgr_stats.h b/src/yb/yql/ysql_conn_mgr_wrapper/ysql_conn_mgr_stats.h index 36ba731777c3..45208f0c3beb 100644 --- a/src/yb/yql/ysql_conn_mgr_wrapper/ysql_conn_mgr_stats.h +++ b/src/yb/yql/ysql_conn_mgr_wrapper/ysql_conn_mgr_stats.h @@ -29,7 +29,7 @@ struct ConnectionStats { uint64_t active_clients; uint64_t queued_clients; - uint64_t idle_or_pending_clients; + uint64_t waiting_clients; uint64_t active_servers; uint64_t idle_servers; uint64_t query_rate; diff --git a/yugabyted-ui/apiserver/cmd/server/.docs/api/openapi.yaml b/yugabyted-ui/apiserver/cmd/server/.docs/api/openapi.yaml index bd6251340ab7..0444bbe45902 100644 --- a/yugabyted-ui/apiserver/cmd/server/.docs/api/openapi.yaml +++ b/yugabyted-ui/apiserver/cmd/server/.docs/api/openapi.yaml @@ -2615,7 +2615,7 @@ components: queued_logical_connections: format: int64 type: integer - idle_or_pending_logical_connections: + waiting_logical_connections: format: int64 type: integer active_physical_connections: @@ -2637,7 +2637,7 @@ components: - active_logical_connections - active_physical_connections - avg_wait_time_ns - - idle_or_pending_logical_connections + - waiting_logical_connections - idle_physical_connections - qps - queued_logical_connections diff --git a/yugabyted-ui/apiserver/cmd/server/handlers/api_cluster_info.go b/yugabyted-ui/apiserver/cmd/server/handlers/api_cluster_info.go index 64a33024233c..e0df1d6332e5 100644 --- a/yugabyted-ui/apiserver/cmd/server/handlers/api_cluster_info.go +++ b/yugabyted-ui/apiserver/cmd/server/handlers/api_cluster_info.go @@ -1724,8 +1724,7 @@ func (c *Container) GetClusterConnections(ctx echo.Context) error { UserName: connectionPool.UserName, ActiveLogicalConnections: connectionPool.ActiveLogicalConnections, QueuedLogicalConnections: connectionPool.QueuedLogicalConnections, - IdleOrPendingLogicalConnections: - connectionPool.IdleOrPendingLogicalConnections, + WaitingLogicalConnections: connectionPool.WaitingLogicalConnections, ActivePhysicalConnections: connectionPool.ActivePhysicalConnections, IdlePhysicalConnections: connectionPool.IdlePhysicalConnections, AvgWaitTimeNs: connectionPool.AvgWaitTimeNs, diff --git a/yugabyted-ui/apiserver/cmd/server/helpers/connections_http_request.go b/yugabyted-ui/apiserver/cmd/server/helpers/connections_http_request.go index b4d24ecc6a2c..7a1d7df052bc 100644 --- a/yugabyted-ui/apiserver/cmd/server/helpers/connections_http_request.go +++ b/yugabyted-ui/apiserver/cmd/server/helpers/connections_http_request.go @@ -13,7 +13,7 @@ type ConnectionPool struct { UserName string `json:"user_name"` ActiveLogicalConnections int64 `json:"active_logical_connections"` QueuedLogicalConnections int64 `json:"queued_logical_connections"` - IdleOrPendingLogicalConnections int64 `json:"idle_or_pending_logical_connections"` + WaitingLogicalConnections int64 `json:"waiting_logical_connections"` ActivePhysicalConnections int64 `json:"active_physical_connections"` IdlePhysicalConnections int64 `json:"idle_physical_connections"` AvgWaitTimeNs int64 `json:"avg_wait_time_ns"` diff --git a/yugabyted-ui/apiserver/cmd/server/models/model_connection_stats_item.go b/yugabyted-ui/apiserver/cmd/server/models/model_connection_stats_item.go index 6c4b8928acf3..c37334a03aea 100644 --- a/yugabyted-ui/apiserver/cmd/server/models/model_connection_stats_item.go +++ b/yugabyted-ui/apiserver/cmd/server/models/model_connection_stats_item.go @@ -10,7 +10,7 @@ type ConnectionStatsItem struct { QueuedLogicalConnections int64 `json:"queued_logical_connections"` - IdleOrPendingLogicalConnections int64 `json:"idle_or_pending_logical_connections"` + WaitingLogicalConnections int64 `json:"waiting_logical_connections"` ActivePhysicalConnections int64 `json:"active_physical_connections"` diff --git a/yugabyted-ui/apiserver/conf/openapi.yml b/yugabyted-ui/apiserver/conf/openapi.yml index e5066d56eabd..e02417c9ba65 100644 --- a/yugabyted-ui/apiserver/conf/openapi.yml +++ b/yugabyted-ui/apiserver/conf/openapi.yml @@ -1570,7 +1570,7 @@ components: queued_logical_connections: type: integer format: int64 - idle_or_pending_logical_connections: + waiting_logical_connections: type: integer format: int64 active_physical_connections: @@ -1591,7 +1591,7 @@ components: required: - active_logical_connections - queued_logical_connections - - idle_or_pending_logical_connections + - waiting_logical_connections - active_physical_connections - idle_physical_connections - avg_wait_time_ns diff --git a/yugabyted-ui/apiserver/conf/openapi/schemas/_index.yaml b/yugabyted-ui/apiserver/conf/openapi/schemas/_index.yaml index cee43f5151c9..f51590fe1173 100644 --- a/yugabyted-ui/apiserver/conf/openapi/schemas/_index.yaml +++ b/yugabyted-ui/apiserver/conf/openapi/schemas/_index.yaml @@ -1176,7 +1176,7 @@ ConnectionStatsItem: queued_logical_connections: type: integer format: int64 - idle_or_pending_logical_connections: + waiting_logical_connections: type: integer format: int64 active_physical_connections: @@ -1197,7 +1197,7 @@ ConnectionStatsItem: required: - active_logical_connections - queued_logical_connections - - idle_or_pending_logical_connections + - waiting_logical_connections - active_physical_connections - idle_physical_connections - avg_wait_time_ns diff --git a/yugabyted-ui/ui/src/api/src/models/ConnectionStats.ts b/yugabyted-ui/ui/src/api/src/models/ConnectionStats.ts index e00f204aaf36..9b88e262e9b0 100644 --- a/yugabyted-ui/ui/src/api/src/models/ConnectionStats.ts +++ b/yugabyted-ui/ui/src/api/src/models/ConnectionStats.ts @@ -37,7 +37,7 @@ export interface ConnectionStats { * @type {number} * @memberof ConnectionStats */ - idle_or_pending_logical_connections: number; + waiting_logical_connections: number; /** * * @type {number} diff --git a/yugabyted-ui/ui/src/api/src/models/ConnectionStatsItem.ts b/yugabyted-ui/ui/src/api/src/models/ConnectionStatsItem.ts index e0b5520d7af0..735b1979921d 100644 --- a/yugabyted-ui/ui/src/api/src/models/ConnectionStatsItem.ts +++ b/yugabyted-ui/ui/src/api/src/models/ConnectionStatsItem.ts @@ -49,7 +49,7 @@ export interface ConnectionStatsItem { * @type {number} * @memberof ConnectionStatsItem */ - idle_or_pending_logical_connections: number; + waiting_logical_connections: number; /** * * @type {number}