Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/ansible/roles/clickhouse/files/default-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@
<user_directories>
<users_xml>
<!-- Path to configuration file with predefined users. -->
<path>users.xml</path>
<path>default-users.xml</path>
</users_xml>
<local_directory>
<!-- Path to folder where users created by SQL commands are stored. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@
<user_directories>
<users_xml>
<!-- Path to configuration file with predefined users. -->
<path>users.xml</path>
<path>low-memory-users.xml</path>
</users_xml>
<local_directory>
<!-- Path to folder where users created by SQL commands are stored. -->
Expand Down
58 changes: 5 additions & 53 deletions build/ansible/roles/clickhouse/files/switch-config.sh
Original file line number Diff line number Diff line change
@@ -1,55 +1,7 @@
#!/bin/bash
# Usage: switch-config.sh [low|default]
# Switches /etc/clickhouse-server/config.xml
# switch-config.sh is deprecated and will be removed in a future PMM release.
# Use the PMM_CLICKHOUSE_CONFIG environment variable instead.

set -e
CONFIG_DIR="/etc/clickhouse-server"
PROFILE="$1"

if [ -z "$PROFILE" ]; then
echo "Usage: $0 [low|default]" >&2
exit 1
fi

case "$PROFILE" in
low)
CONFIG_TARGET="low-memory-config.xml"
USERS_TARGET="low-memory-users.xml"
;;
default)
CONFIG_TARGET="default-config.xml"
USERS_TARGET="default-users.xml"
;;
*)
echo "Usage: $0 [low|default]" >&2
exit 1
;;
esac

if [ ! -e "$CONFIG_DIR/$CONFIG_TARGET" ]; then
echo "Config profile $CONFIG_TARGET does not exist in $CONFIG_DIR." >&2
exit 2
fi
if [ ! -e "$CONFIG_DIR/$USERS_TARGET" ]; then
echo "Users profile $USERS_TARGET does not exist in $CONFIG_DIR." >&2
exit 2
fi

echo "Stopping clickhouse..."
if ! supervisorctl stop clickhouse; then
echo "Failed to stop clickhouse!" >&2
exit 3
fi

ln -sf "$CONFIG_TARGET" "$CONFIG_DIR/config.xml"
ln -sf "$USERS_TARGET" "$CONFIG_DIR/users.xml"
echo "Switched config.xml to $CONFIG_TARGET."
echo "Switched users.xml to $USERS_TARGET."

echo "Starting clickhouse..."
if ! supervisorctl start clickhouse; then
echo "Failed to start clickhouse!" >&2
exit 4
fi

exit 0
echo "switch-config.sh is deprecated and will be removed in a future PMM release." >&2
echo "Set PMM_CLICKHOUSE_CONFIG=default|low-memory" >&2
exit 1
2 changes: 1 addition & 1 deletion build/ansible/roles/supervisord/files/pmm.ini
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ redirect_stderr = true

[program:clickhouse]
priority = 2
command = /usr/bin/clickhouse-server --config-file=/etc/clickhouse-server/config.xml
command = /usr/bin/clickhouse-server --config-file=/etc/clickhouse-server/default-config.xml
autorestart = true
autostart = true
startretries = 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ Fine-tune data retention and collection intervals to balance monitoring detail w
!!! tip "Performance impact"
Higher resolution (lower values) provides more detailed metrics but increases storage requirements and system load. For high-traffic production environments, consider increasing these values.

### Built-in ClickHouse configuration
Select the configuration profile for the built-in ClickHouse instance

| Variable | Default | Description | Example |
|----------|---------|-------------|----------|
| `PMM_CLICKHOUSE_CONFIG` | `default` | Use `low-memory` for PMM Server environments with less than 16 GB RAM. | `low-memory` |

!!! note "low-memory config"
While this configuration attempts to optimize ClickHouse for low-memory environments, we highly recommend users to follow our configuration guide.
For details, see [ClickHouse memory issues](../../../../troubleshoot/qan_issues.md#clickhouse-memory-issues-in-low-memory-environments).

### Feature controls
Enable or disable specific PMM features:

Expand Down Expand Up @@ -262,4 +273,4 @@ docker run \
```

## Related topic
[Preview environment variables](../docker/preview_env_var.md)
[Preview environment variables](../docker/preview_env_var.md)
23 changes: 4 additions & 19 deletions documentation/docs/troubleshoot/qan_issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,32 +92,17 @@ PMM includes two ClickHouse profiles:

### Switch to low-memory configuration

```bash
docker exec -it -u pmm pmm-server ./switch-config.sh low
```
Select the profile with the `PMM_CLICKHOUSE_CONFIG` environment variable when you create the container:

To switch back:
```bash
docker exec -it -u pmm pmm-server ./switch-config.sh default
docker run -e PMM_CLICKHOUSE_CONFIG=low-memory ... percona/pmm-server:3
```

The script stops ClickHouse, updates the configuration, and restarts the service.

### Persistent configuration

If you run PMM Server with the `--rm` flag, run the switch script each time the container starts. For systemd, add to your unit file:
```ini
ExecStartPost=/usr/bin/docker exec -u pmm pmm-server ./switch-config.sh low
```

See [Install PMM Server with Podman](../install-pmm/install-pmm-server/deployment-options/podman/index.md) for systemd configuration examples.

!!! note "Configuration details"
Both configuration files are located in `/etc/clickhouse-server/` inside the PMM Server container:

- `default-config.xml`: default profile
- `low-memory-config.xml`: low-memory profile

The script is available at `/etc/clickhouse-server/switch-config.sh` or `/opt/switch-config.sh`.

When switching profiles, both `config.xml` and `users.xml` are updated to point to the selected profile.

The `switch-config.sh` script is deprecated and will be removed in a future PMM release; use `PMM_CLICKHOUSE_CONFIG` instead.
1 change: 1 addition & 0 deletions managed/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ PMM supports HA via **Raft consensus** (`services/ha/`):
- Don't skip `make gen` after proto/model changes
- Don't comment on every line — only where clarity is needed
- Don't inline comments (`code // comment`) — put comments on separate lines
- Don't inline `err != nil` checks (`if err := f(); err != nil`) — assign on one line, check on the next
- Don't use named return values in functions
- Don't commit test binaries or artifacts
- Don't create subshells in Makefiles without reason
Expand Down
10 changes: 8 additions & 2 deletions managed/cmd/pmm-managed-init/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import (
"github.com/sirupsen/logrus"

"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/clickhouse"
"github.com/percona/pmm/managed/services/supervisord"
"github.com/percona/pmm/managed/utils/env"
"github.com/percona/pmm/managed/utils/envvars"
"github.com/percona/pmm/utils/logger"
)
Expand All @@ -36,6 +38,10 @@ func main() {
logrus.SetLevel(logrus.TraceLevel)
}
envSettings, errs, warns := envvars.ParseEnvVars(os.Environ())
clickHouseConfig, err := clickhouse.GetClickHouseConfig(os.Getenv(env.ClickHouseConfig))
if err != nil {
errs = append(errs, err)
}
for _, warn := range warns {
logrus.Warnf("Configuration warning: %s", warn)
}
Expand All @@ -46,8 +52,7 @@ func main() {
os.Exit(1)
}

err := models.ValidateSettings(envSettings)
if err != nil {
if err := models.ValidateSettings(envSettings); err != nil {
Comment thread
4nte marked this conversation as resolved.
logrus.Errorf("Configuration error: %s.", err)
os.Exit(1)
}
Expand All @@ -56,6 +61,7 @@ func main() {
pmmConfigParams["DisableInternalDB"], _ = strconv.ParseBool(os.Getenv("PMM_DISABLE_BUILTIN_POSTGRES"))
pmmConfigParams["DisableInternalClickhouse"], _ = strconv.ParseBool(os.Getenv("PMM_DISABLE_BUILTIN_CLICKHOUSE"))
pmmConfigParams["AgentConfigFilePath"] = models.AgentConfigFilePath
pmmConfigParams["ClickHouseConfig"] = clickHouseConfig

isHAEnabled, _ := strconv.ParseBool(os.Getenv("PMM_HA_ENABLE"))
if isHAEnabled {
Expand Down
80 changes: 80 additions & 0 deletions managed/services/clickhouse/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

// Package clickhouse provides facilities for working with clickhouse.
package clickhouse

import (
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
)

const (
defaultClickHouseConfig = "default"
clickHouseConfigDir = "/etc/clickhouse-server"
)

// GetClickHouseConfig returns the config name if the matching
// <config>-config.xml files exist on disk.
// Empty input falls back to defaultClickHouseConfig.
func GetClickHouseConfig(config string) (string, error) {
if config == "" {
return defaultClickHouseConfig, nil
}

return config, validateClickHouseConfigAt(config, clickHouseConfigDir)
}

// validateClickHouseConfigAt returns an error if configuration files are missing for given config
func validateClickHouseConfigAt(config, dir string) error {
availableConfigs, err := availableClickHouseConfigs(dir)
if err != nil {
return fmt.Errorf("unable to get available ClickHouse configs: %w", err)
}

path := filepath.Join(dir, config+"-config.xml")
if _, err := os.Stat(path); err != nil {
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf(
"invalid PMM_CLICKHOUSE_CONFIG=%s: %s not found; available configs: %v",
config, path, availableConfigs,
)
}
return fmt.Errorf("cannot stat %s: %w", path, err)
}

return nil
}

// availableClickHouseConfigs lists config names that are present in the dir
func availableClickHouseConfigs(dir string) ([]string, error) {
var configs []string

matches, err := filepath.Glob(filepath.Join(dir, "*-config.xml"))
if err != nil {
return nil, err
}
for _, m := range matches {
name := strings.TrimSuffix(filepath.Base(m), "-config.xml")
configs = append(configs, name)
}

sort.Strings(configs)
return configs, nil
}
Loading
Loading