Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement db slow query analysis changes #1155

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
4 changes: 2 additions & 2 deletions docs/error-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ Please note, some error code values may be generated by other downstream process
| 16 | | For darwin, `brew` is not installed and required to install |
| 17 | | For linux and darwin, `curl` is not installed and required to install |
| 18 | | Attempt to install within a docker container. The user should instead run the install on the host, not in the container |
| 19 | | Attempt to install within a Microsoft Subsytem Linux container. This is not supported |
| 19 | | Attempt to install within a Microsoft Subsystem Linux container. This is not supported |
| 20 | | For linux, systemctl is not available on the host (either nor present or not running) |
| 21 | | There is no newrelic infrastructure agent available for the host |
| 22 | | Recipe depedency not met |
| 22 | | Recipe dependency not met |
| 23 | | User declined to accept recipe terms |
| 24 | | There was an unknown issue trying to download a required component for installation |
| 25 | | There was a web issue trying to download a required component for installation |
Expand Down
132 changes: 130 additions & 2 deletions recipes/newrelic/infrastructure/ohi/mysql/debian.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ install:
if [[ "$NEW_RELIC_MYSQL_PASSWORD" == "" ]]; then
NEW_RELIC_MYSQL_PASSWORD=$(echo -n $(date +%s | sha256sum | base64 | head -c 16); echo "oO0$")
fi

if [[ "$NR_CLI_SLOW_QUERY" == "true" ]]; then
CONFIG_FILES=(
"/etc/mysql/mysql.conf.d/mysqld.cnf"
"/etc/my.cnf"
"/etc/mysql/my.cnf"
)

# Iterate through each configuration file path and update if it exists
FILE_FOUND=0
for config in "${CONFIG_FILES[@]}"; do
# Check if the file exists
if [[ -f "$config" ]]; then
echo "Found MySQL configuration file at $config."
FILE_FOUND=1
break
fi
done
fi

# Check to see if default port works, or prompt if non-interactive
CAN_CONNECT=$(curl $NEW_RELIC_MYSQL_HOSTNAME:$NEW_RELIC_MYSQL_PORT 2>&1 1>/dev/null -s -S | awk -F'[()]' '{print $2}')
Expand Down Expand Up @@ -188,6 +207,11 @@ install:
GRANT REPLICATION CLIENT ON *.* TO 'newrelic'@'localhost';
GRANT SELECT ON *.* TO 'newrelic'@'localhost';
EOT

# Conditionally append the GRANT PROCESS command if NR_CLI_SLOW_QUERY is true
if [[ "$NR_CLI_SLOW_QUERY" == "true" && $FILE_FOUND -eq 1 ]]; then
echo "GRANT PROCESS ON *.* TO 'newrelic'@'localhost';" | sudo tee -a /tmp/sql-create-user.sql > /dev/null
fi

sudo sed -i 's/NEW_RELIC_MYSQL_USERNAME/'$NEW_RELIC_MYSQL_USERNAME'/g' /tmp/sql-drop-user.sql
sudo sed -i 's/NEW_RELIC_MYSQL_USERNAME/'$NEW_RELIC_MYSQL_USERNAME'/g' /tmp/sql-create-user.sql
Expand All @@ -205,6 +229,11 @@ install:
printf "\nPlease enter your username for MySql (default: root): "
read -r USERNAME
USERNAME=${USERNAME:-root}

printf "\nEnter password: "
stty -echo
read -r NEW_RELIC_MYSQL_ROOT_PASSWORD
stty echo

sudo mysql -u $USERNAME --port $NEW_RELIC_MYSQL_PORT -p$NEW_RELIC_MYSQL_ROOT_PASSWORD < /tmp/sql-drop-user.sql &> /dev/null ||:
EXEC_OUTPUT=$(eval sudo mysql -u $USERNAME --port $NEW_RELIC_MYSQL_PORT -p$NEW_RELIC_MYSQL_ROOT_PASSWORD < /tmp/sql-create-user.sql 2>&1)
Expand Down Expand Up @@ -256,6 +285,7 @@ install:
fi

sudo cp /etc/newrelic-infra/integrations.d/mysql-config.yml.sample /etc/newrelic-infra/integrations.d/mysql-config.yml;
if [[ "$NR_CLI_SLOW_QUERY" == "true" && $FILE_FOUND -eq 1 ]]; then
sudo tee /etc/newrelic-infra/integrations.d/mysql-config.yml > /dev/null <<EOT
integrations:
- name: nri-mysql
Expand All @@ -269,9 +299,107 @@ install:
EXTENDED_INNODB_METRICS: true
EXTENDED_MYISAM_METRICS: true
REMOTE_MONITORING: true
ENABLE_QUERY_MONITORING: true
inventory_source: config/mysql
interval: 30s
EOT
else
sudo tee /etc/newrelic-infra/integrations.d/mysql-config.yml > /dev/null <<EOT
integrations:
- name: nri-mysql
env:
HOSTNAME: $NEW_RELIC_MYSQL_HOSTNAME
PORT: $NEW_RELIC_MYSQL_PORT
USERNAME: $NEW_RELIC_MYSQL_USERNAME
PASSWORD: '$NEW_RELIC_MYSQL_PASSWORD'
DATABASE:
EXTENDED_METRICS: true
EXTENDED_INNODB_METRICS: true
EXTENDED_MYISAM_METRICS: true
REMOTE_MONITORING: true
inventory_source: config/mysql
interval: 30s
EOT
fi

# Function to update or append the performance_schema and init-file properties
update_mysql_config() {
local config_file="$1"

# Check if the [mysqld] section is present
if ! grep -qE '^\[mysqld\]' "$config_file"; then
# Append the [mysqld] section with the properties if not present
cp "$config_file" "$config_file.bak"
echo -e "\n[mysqld]\nperformance_schema=ON\ninit-file=/etc/mysql/init.sql" >> "$config_file"
echo "Successfully added the [mysqld] section with performance_schema=ON and init-file=/etc/mysql/init.sql to $config_file."
else
# Handle performance_schema property
if grep -qE '^\s*performance_schema\s*=\s*ON\s*$' "$config_file"; then
echo "The performance_schema is already set to ON in $config_file. No changes made."
elif grep -qE '^\s*performance_schema\s*=' "$config_file"; then
# Update any other value to ON
sed -i.bak 's/^\s*performance_schema\s*=.*$/performance_schema=ON/' "$config_file"
echo "Updated performance_schema to ON in $config_file."
else
# Append the property below the [mysqld] section if not present
sed -i.bak '/\[mysqld\]/a\performance_schema=ON' "$config_file"
echo "Appended performance_schema=ON to $config_file."
fi
# Handle init-file property
if grep -qE '^\s*init-file\s*=\s*/etc/mysql/init.sql\s*$' "$config_file"; then
echo "The init-file is already set to /etc/mysql/init.sql in $config_file. No changes made."
elif grep -qE '^\s*init-file\s*=' "$config_file"; then
# Update any other value to /etc/mysql/init.sql
sed -i 's|^\s*init-file\s*=.*$|init-file=/etc/mysql/init.sql|' "$config_file"
echo "Updated init-file to /etc/mysql/init.sql in $config_file."
else
# Append the property below the [mysqld] section if not present
sed -i '/\[mysqld\]/a\init-file=/etc/mysql/init.sql' "$config_file"
echo "Appended init-file=/etc/mysql/init.sql to $config_file."
fi
fi
}

create_init_sql() {
# Create init.sql file with required SQL commands
local INIT_FILE="/etc/mysql/init.sql"

cat <<EOF | sudo tee "$INIT_FILE" > /dev/null
-- Enable required Performance Schema instruments
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'wait/%';
-- Enable CPU Instruments
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'statement/%';
-- Enable Collection of Current Data Lock Waits
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%lock%';
-- Enable required Performance Schema consumers
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_waits_current', 'events_waits_history_long', 'events_waits_history', 'events_statements_history_long');
-- Enable required Performance Schema consumers for CPU metrics
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME IN ('events_statements_history', 'events_statements_current', 'events_statements_cpu');
UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE 'events_waits_current%' OR NAME LIKE 'events_statements_current%';
SET GLOBAL innodb_lock_wait_timeout = 120; -- Increase to 2 minutes
EOF

echo "Created $INIT_FILE with necessary SQL commands."

printf "Restart the MySQL server after the agent installation? Selecting 'y' will automatically restart the mysql server that is detected. Selecting 'n' will require you to manually restart the process to reflect the slow query configuration changes. (y/n): "
read -r APPLICATION_RESTART
APPLICATION_RESTART=${APPLICATION_RESTART:-y}

if [ "$APPLICATION_RESTART" = "y" ]; then
# Restart MySQL service using systemd
sudo systemctl restart mysqld
echo "MySQL server restarted to apply changes."
else
echo "Warning: Slow query configuration changes will be applied the next time you restart your MySQL server."
fi
}

if [[ "$NR_CLI_SLOW_QUERY" == "true" && $FILE_FOUND -eq 1 ]]; then
update_mysql_config "$config"
create_init_sql
else
echo "Error: No MySQL configuration file found in ${CONFIG_FILES[@]}. Slow query configuration changes will not be applied."
fi

collect_meta:
cmds:
Expand All @@ -280,7 +408,7 @@ install:
version=$(type mysqld &>/dev/null && mysqld --version)
echo {\"Metadata\": {\"user\":\"$user\", \"version\":\"$version\"}} | tee {{.NR_CLI_OUTPUT}} > /dev/null

info: |2
info: |2
⚙️ The MySQL configuration file can be found in /etc/newrelic-infra/integrations.d/mysql-config.yml
Edit this file to make changes or configure advanced features for this integration. See the docs for options:
https://docs.newrelic.com/docs/integrations/host-integrations/host-integrations-list/mysql-monitoring-integration#config
https://docs.newrelic.com/docs/integrations/host-integrations/host-integrations-list/mysql-monitoring-integration#config
Loading
Loading