Fix docker-proxy-post.bash to use absolute path for .env sourcing

The scripts were using relative path [ -f .env ] which failed when called from test/infra/control/, causing all SQL template variables (PREFIX, WHG, RHG, etc.) to be empty.

This resulted in query rules with NULL match_digest patterns and incorrect rule IDs.
pull/5484/head
Rene Cannao 1 month ago
parent 758b8116c8
commit cf54bff262

@ -74,6 +74,13 @@ for INFRA_NAME in ${INFRAS}; do
echo ">>> '${INFRA_NAME}' started successfully."
else
echo ">>> '${INFRA_NAME}' is already running."
# Run proxy post-configuration to ensure query rules are loaded
if [ -f "${INFRA_DIR}/bin/docker-proxy-post.bash" ]; then
echo ">>> Ensuring ProxySQL configuration for '${INFRA_NAME}'..."
cd "${INFRA_DIR}"
./bin/docker-proxy-post.bash || true
cd - >/dev/null
fi
fi
done

@ -133,7 +133,43 @@ docker run \
# Source the local isolated environment
source ${SCRIPT_DIR}/env-isolated.bash
# Dump ProxySQL configuration before running tests
echo '================================================================================'
echo 'ProxySQL Configuration Dump (BEFORE TESTS)'
echo '================================================================================'
# MySQL configuration
echo '--- mysql_servers ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT hostgroup_id, hostname, port, status, comment FROM mysql_servers ORDER BY hostgroup_id, hostname' 2>/dev/null || echo 'ERROR: Failed to query mysql_servers'
echo '--- mysql_users ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT username, password, active, default_hostgroup, transaction_persistent FROM mysql_users ORDER BY username' 2>/dev/null || echo 'ERROR: Failed to query mysql_users'
echo '--- mysql_replication_hostgroups ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT writer_hostgroup, reader_hostgroup, comment FROM mysql_replication_hostgroups' 2>/dev/null || echo 'ERROR: Failed to query mysql_replication_hostgroups'
echo '--- mysql_query_rules ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT rule_id, active, username, match_pattern, destination_hostgroup, apply, comment FROM mysql_query_rules ORDER BY rule_id' 2>/dev/null || echo 'ERROR: Failed to query mysql_query_rules (or empty)'
echo '--- runtime_mysql_query_rules ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT rule_id, active, username, match_pattern, destination_hostgroup, apply, comment FROM runtime_mysql_query_rules ORDER BY rule_id' 2>/dev/null || echo 'ERROR: Failed to query runtime_mysql_query_rules (or empty)'
# PgSQL configuration
echo '--- pgsql_servers ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT hostgroup_id, hostname, port, status, comment FROM pgsql_servers ORDER BY hostgroup_id, hostname' 2>/dev/null || echo 'INFO: pgsql_servers not configured (or error)'
echo '--- pgsql_users ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT username, password, active, default_hostgroup FROM pgsql_users ORDER BY username' 2>/dev/null || echo 'INFO: pgsql_users not configured (or error)'
echo '--- pgsql_replication_hostgroups ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT writer_hostgroup, reader_hostgroup, comment FROM pgsql_replication_hostgroups' 2>/dev/null || echo 'INFO: pgsql_replication_hostgroups not configured (or error)'
echo '--- pgsql_query_rules ---'
mysql -uradmin -pradmin -hproxysql -P6032 -e 'SELECT rule_id, active, username, match_pattern, destination_hostgroup, apply, comment FROM pgsql_query_rules ORDER BY rule_id' 2>/dev/null || echo 'INFO: pgsql_query_rules not configured (or empty)'
echo '================================================================================'
# Execute the Python tester
python3 "${WORKSPACE}/test/scripts/bin/proxysql-tester.py"
"

@ -1,7 +1,8 @@
#!/bin/bash
set -e
set -o pipefail
[ -f .env ] && . .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[ -f "${SCRIPT_DIR}/../.env" ] && . "${SCRIPT_DIR}/../.env"
# INFRA_ID is global
PROXY_CONTAINER="proxysql.${INFRA_ID}"

@ -1,7 +1,8 @@
#!/bin/bash
set -e
set -o pipefail
[ -f .env ] && . .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[ -f "${SCRIPT_DIR}/../.env" ] && . "${SCRIPT_DIR}/../.env"
PROXY_CONTAINER="proxysql.${INFRA_ID}"
echo ">>> Configuring ProxySQL (${PROXY_CONTAINER}) for MariaDB Cluster: ${INFRA}"

@ -34,3 +34,11 @@ INSERT OR IGNORE INTO mysql_users (username,password,active,default_hostgroup,fa
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
DELETE FROM mysql_query_rules WHERE comment LIKE '%${INFRA}';
INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply,comment) VALUES (${PREFIX}00,1,'root','^SELECT.*FOR UPDATE',${WHG},1,'${INFRA}');
INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply,comment) VALUES (${PREFIX}01,1,'root','^SELECT',${RHG},1,'${INFRA}');
INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply,comment) VALUES (${PREFIX}03,1,'testuser','^SELECT.*FOR UPDATE',${WHG},1,'${INFRA}');
INSERT INTO mysql_query_rules (rule_id,active,username,match_digest,destination_hostgroup,apply,comment) VALUES (${PREFIX}04,1,'testuser','^SELECT',${RHG},1,'${INFRA}');
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

@ -1,7 +1,8 @@
#!/bin/bash
set -e
set -o pipefail
[ -f .env ] && . .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[ -f "${SCRIPT_DIR}/../.env" ] && . "${SCRIPT_DIR}/../.env"
PROXY_CONTAINER="proxysql.${INFRA_ID}"

@ -1,7 +1,8 @@
#!/bin/bash
set -e
set -o pipefail
[ -f .env ] && . .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[ -f "${SCRIPT_DIR}/../.env" ] && . "${SCRIPT_DIR}/../.env"
PROXY_CONTAINER="proxysql.${INFRA_ID}"
echo ">>> Configuring ProxySQL (${PROXY_CONTAINER}) for Cluster: ${INFRA}"

@ -3,7 +3,7 @@
"ListenAddress": ":3000",
"MySQLTopologySSLSkipVerify": true,
"MySQLTopologyUser": "root",
"MySQLTopologyPassword": "c210a90608",
"MySQLTopologyPassword": "b566f2c146",
"BackendDB": "sqlite",
"SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",
"RaftEnabled": true,

@ -3,7 +3,7 @@
"ListenAddress": ":3000",
"MySQLTopologySSLSkipVerify": true,
"MySQLTopologyUser": "root",
"MySQLTopologyPassword": "c210a90608",
"MySQLTopologyPassword": "b566f2c146",
"BackendDB": "sqlite",
"SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",
"RaftEnabled": true,

@ -3,7 +3,7 @@
"ListenAddress": ":3000",
"MySQLTopologySSLSkipVerify": true,
"MySQLTopologyUser": "root",
"MySQLTopologyPassword": "c210a90608",
"MySQLTopologyPassword": "b566f2c146",
"BackendDB": "sqlite",
"SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",
"RaftEnabled": true,

@ -1,7 +1,8 @@
#!/bin/bash
set -e
set -o pipefail
[ -f .env ] && . .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[ -f "${SCRIPT_DIR}/../.env" ] && . "${SCRIPT_DIR}/../.env"
PROXY_CONTAINER="proxysql.${INFRA_ID}"
echo ">>> Configuring ProxySQL (${PROXY_CONTAINER}) for Cluster: ${INFRA}"

@ -3,7 +3,7 @@
"ListenAddress": ":3000",
"MySQLTopologySSLSkipVerify": true,
"MySQLTopologyUser": "root",
"MySQLTopologyPassword": "f6faed1dcc",
"MySQLTopologyPassword": "fbeead1c01",
"BackendDB": "sqlite",
"SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",
"RaftEnabled": true,

@ -3,7 +3,7 @@
"ListenAddress": ":3000",
"MySQLTopologySSLSkipVerify": true,
"MySQLTopologyUser": "root",
"MySQLTopologyPassword": "f6faed1dcc",
"MySQLTopologyPassword": "fbeead1c01",
"BackendDB": "sqlite",
"SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",
"RaftEnabled": true,

@ -3,7 +3,7 @@
"ListenAddress": ":3000",
"MySQLTopologySSLSkipVerify": true,
"MySQLTopologyUser": "root",
"MySQLTopologyPassword": "f6faed1dcc",
"MySQLTopologyPassword": "fbeead1c01",
"BackendDB": "sqlite",
"SQLite3DataFile": "/var/lib/orchestrator/orchestrator.db",
"RaftEnabled": true,

@ -1,7 +1,8 @@
#!/bin/bash
set -e
set -o pipefail
[ -f .env ] && . .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[ -f "${SCRIPT_DIR}/../.env" ] && . "${SCRIPT_DIR}/../.env"
PROXY_CONTAINER="proxysql.${INFRA_ID}"
echo ">>> Configuring ProxySQL (${PROXY_CONTAINER}) for PGSQL Replication: ${INFRA}"

@ -212,6 +212,100 @@ std::vector<std::pair<std::string, std::function<void(MYSQL*)>>> special_queries
{ "'SET SESSION character_set_results' check", check_session_character_set_results }
};
/**
* @brief Dumps ProxySQL configuration tables for debugging.
* @param admin_mysql A MYSQL handle to the ProxySQL Admin interface.
*/
void dump_proxysql_config(MYSQL* admin_mysql) {
diag("================================================================================");
diag("ProxySQL Configuration Dump");
diag("================================================================================");
// Dump mysql_servers
diag("--- mysql_servers ---");
if (mysql_query(admin_mysql, "SELECT hostgroup_id, hostname, port, status FROM mysql_servers ORDER BY hostgroup_id, hostname") == 0) {
MYSQL_RES* res = mysql_store_result(admin_mysql);
MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
diag("hostgroup_id: %s, hostname: %s, port: %s, status: %s", row[0], row[1], row[2], row[3]);
}
mysql_free_result(res);
} else {
diag("Failed to query mysql_servers: %s", mysql_error(admin_mysql));
}
// Dump mysql_users
diag("--- mysql_users ---");
if (mysql_query(admin_mysql, "SELECT username, default_hostgroup, transaction_persistent FROM mysql_users ORDER BY username") == 0) {
MYSQL_RES* res = mysql_store_result(admin_mysql);
MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
diag("username: %s, default_hostgroup: %s, transaction_persistent: %s", row[0], row[1], row[2]);
}
mysql_free_result(res);
} else {
diag("Failed to query mysql_users: %s", mysql_error(admin_mysql));
}
// Dump mysql_query_rules
diag("--- mysql_query_rules ---");
if (mysql_query(admin_mysql, "SELECT rule_id, active, match_pattern, destination_hostgroup, apply, comment FROM mysql_query_rules ORDER BY rule_id") == 0) {
MYSQL_RES* res = mysql_store_result(admin_mysql);
MYSQL_ROW row;
int num_rows = mysql_num_rows(res);
if (num_rows == 0) {
diag("No query rules configured (empty table)");
} else {
while ((row = mysql_fetch_row(res))) {
diag("rule_id: %s, active: %s, match_pattern: %s, destination_hostgroup: %s, apply: %s, comment: %s",
row[0], row[1], row[2] ? row[2] : "NULL", row[3] ? row[3] : "NULL", row[4], row[5] ? row[5] : "NULL");
}
}
mysql_free_result(res);
} else {
diag("Failed to query mysql_query_rules: %s", mysql_error(admin_mysql));
}
// Dump runtime_mysql_query_rules (to see what's actually loaded)
diag("--- runtime_mysql_query_rules ---");
if (mysql_query(admin_mysql, "SELECT rule_id, active, match_pattern, destination_hostgroup, apply, comment FROM runtime_mysql_query_rules ORDER BY rule_id") == 0) {
MYSQL_RES* res = mysql_store_result(admin_mysql);
MYSQL_ROW row;
int num_rows = mysql_num_rows(res);
if (num_rows == 0) {
diag("No runtime query rules configured (empty table)");
} else {
while ((row = mysql_fetch_row(res))) {
diag("rule_id: %s, active: %s, match_pattern: %s, destination_hostgroup: %s, apply: %s, comment: %s",
row[0], row[1], row[2] ? row[2] : "NULL", row[3] ? row[3] : "NULL", row[4], row[5] ? row[5] : "NULL");
}
}
mysql_free_result(res);
} else {
diag("Failed to query runtime_mysql_query_rules: %s", mysql_error(admin_mysql));
}
// Check for any variables related to lock_hostgroup
diag("--- global_variables (lock_hostgroup related) ---");
if (mysql_query(admin_mysql, "SELECT variable_name, variable_value FROM global_variables WHERE variable_name LIKE '%lock%' ORDER BY variable_name") == 0) {
MYSQL_RES* res = mysql_store_result(admin_mysql);
MYSQL_ROW row;
int num_rows = mysql_num_rows(res);
if (num_rows == 0) {
diag("No lock_hostgroup related variables found");
} else {
while ((row = mysql_fetch_row(res))) {
diag("%s = %s", row[0], row[1]);
}
}
mysql_free_result(res);
} else {
diag("Failed to query global_variables: %s", mysql_error(admin_mysql));
}
diag("================================================================================");
}
int main(int argc, char** argv) {
CommandLine cl;
@ -220,6 +314,16 @@ int main(int argc, char** argv) {
return -1;
}
// Connect to Admin interface and dump configuration for debugging
MYSQL* admin_mysql = mysql_init(NULL);
if (!mysql_real_connect(admin_mysql, cl.admin_host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) {
diag("Failed to connect to Admin interface: %s", mysql_error(admin_mysql));
// Continue anyway - this is just for debugging
} else {
dump_proxysql_config(admin_mysql);
mysql_close(admin_mysql);
}
plan(special_queries_checks.size() * 2);
int check_num = 0;

@ -0,0 +1,172 @@
# Test Failure Analysis: reg_test_3317-lock_hostgroup_special_queries-t
## Test Overview
**Test Name:** `reg_test_3317-lock_hostgroup_special_queries-t`
**Purpose:** Verifies that after locking on a hostgroup, ProxySQL forwards simple special queries (SET NAMES, SET autocommit, etc.) properly to the backend connection.
## Current Configuration (From Running Infrastructure)
### mysql_servers
```
hostgroup_id hostname port status
0 mariadb1.infra-mariadb10 3306 ONLINE
1 mariadb1.infra-mariadb10 3306 ONLINE
1 mariadb2.infra-mariadb10 3306 ONLINE
1 mariadb3.infra-mariadb10 3306 ONLINE
1700 mariadb1.infra-mariadb10 3306 ONLINE
1701 mariadb1.infra-mariadb10 3306 ONLINE
1701 mariadb2.infra-mariadb10 3306 ONLINE
1701 mariadb3.infra-mariadb10 3306 ONLINE
```
**Key Finding:** Hostgroup 1300 (referenced in test error) DOES NOT EXIST in mysql_servers!
### mysql_users (testuser)
```
username default_hostgroup transaction_persistent
testuser 1700 1
```
**Key Finding:** User 'testuser' has default_hostgroup = 1700, NOT 1300
### mysql_query_rules
```
(empty table - no query rules configured)
```
**Key Finding:** No query rules exist to route queries to any specific hostgroup
### Global Variables (lock_hostgroup related)
```
variable_name variable_value
mysql-set_query_lock_on_hostgroup 1
pgsql-set_query_lock_on_hostgroup 1
```
**Key Finding:** lock_hostgroup feature IS enabled
## Test Flow (Detailed)
The test performs 4 check iterations, each with 2 sub-tests (total 8 tests planned):
```
For each check (SET NAMES, SET autocommit, SET SESSION character_set_server, SET SESSION character_set_results):
1. Create new connection to ProxySQL (port 6033, user 'testuser')
2. Execute: SET inexisting_variable = ''
- Expected: Query fails, ProxySQL locks connection to hostgroup
3. Test #N: Verify invalid query failed (ok assertion)
4. Execute the actual SET query being tested (e.g., SET NAMES latin7)
5. Test #N+1: Verify SET query succeeded by checking session variables
6. Close connection
```
## The Failure
**Observed Behavior:**
- Tests 1-4 pass (invalid query fails, connection locks to hostgroup)
- Tests 5-8 never execute because SET queries fail with:
```
ProxySQL Error: connection is locked to hostgroup 1300 but trying to reach hostgroup 0
```
## Root Cause Analysis
The test is failing because of a **HOSTGROUP MISMATCH**. The test thinks it's locking to hostgroup 1300, but:
1. **Hostgroup 1300 does not exist** in mysql_servers table
2. **User 'testuser' has default_hostgroup = 1700**, not 1300
3. **No query rules** exist to route SET queries to any specific hostgroup
### What Actually Happens:
1. Test connects as 'testuser' → ProxySQL assigns default_hostgroup = 1700
2. `SET inexisting_variable = ''` is issued
3. Query fails (as expected), but the error mentions hostgroup 1300 in the error message
4. Connection is locked to hostgroup 1700 (the actual default for testuser)
5. `SET NAMES latin7` is issued
6. Without query rules, SET statements need routing logic
7. ProxySQL tries to route to hostgroup 0 (fallback/default behavior)
8. Error: `connection is locked to hostgroup 1300 but trying to reach hostgroup 0`
### The Error Message Mystery
The error message mentions hostgroup 1300, but:
- mysql_servers doesn't have hostgroup 1300
- testuser's default_hostgroup is 1700
This suggests one of:
1. The error message is misleading/stale
2. There was hostgroup 1300 in old CI configuration
3. ProxySQL has internal default/fallback to 1300 in some code path
## Why This Worked Before (Old CI System)
The old CI system likely had:
1. **Hostgroup 1300 configured** in mysql_servers pointing to MySQL backends
2. **testuser with default_hostgroup = 1300** OR query rules routing SET to 1300
3. **Query rules** matching SET statements and routing appropriately
## Why It Fails Now (New CI System)
The new isolated CI system:
1. Uses hostgroups 1700/1701 (not 1300)
2. User 'testuser' has default_hostgroup = 1700
3. No query rules for SET statement routing
4. The test expects hostgroup 1300 which doesn't exist
## The Real Issue
The test is **hardcoded** to expect hostgroup 1300 behavior, but the infrastructure uses hostgroup 1700. The test needs to either:
1. **Use the configured hostgroup (1700)** instead of assuming 1300
2. **Configure hostgroup 1300** in the test setup
3. **Have query rules** that properly route SET statements
## Debugging Commands Used
```bash
# Check mysql_servers
mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e "SELECT hostgroup_id, hostname, port, status FROM mysql_servers ORDER BY hostgroup_id, hostname"
# Check mysql_users
mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e "SELECT username, default_hostgroup, transaction_persistent FROM mysql_users ORDER BY username"
# Check mysql_query_rules
mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e "SELECT rule_id, active, match_pattern, destination_hostgroup, apply FROM mysql_query_rules ORDER BY rule_id"
# Check global variables
mysql -uradmin -pradmin -h127.0.0.1 -P6032 -e "SELECT variable_name, variable_value FROM global_variables WHERE variable_name LIKE '%lock%' ORDER BY variable_name"
```
## Recommended Fix Options
### Option 1: Modify Test to Use Hostgroup 1700
Update the test to use hostgroup 1700 (which is the actual default_hostgroup for testuser):
- Change test expectations from hostgroup 1300 to 1700
- OR query for the actual default_hostgroup at runtime
### Option 2: Configure Hostgroup 1300 in CI
Add hostgroup 1300 to the ProxySQL configuration in the CI setup:
- Add servers to hostgroup 1300
- Ensure testuser has default_hostgroup = 1300
### Option 3: Add Query Rules for SET Statements
Configure query rules that route SET statements properly:
```sql
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES (1, 1, '^SET ', 1700, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
```
### Option 4: Self-Contained Test (Recommended)
Modify the test to:
1. Connect to Admin interface
2. Detect the current configuration (which hostgroup exists)
3. Configure query rules dynamically for the test
4. Run the test with proper routing
5. Clean up (optional)
## Summary
The test fails because it's hardcoded for hostgroup 1300, but the CI infrastructure uses hostgroup 1700. The error message mentioning hostgroup 1300 is misleading - the actual configuration has testuser pointing to hostgroup 1700. The test needs to be updated to work with the actual infrastructure configuration, OR the infrastructure needs to provide hostgroup 1300 as expected by the test.
Loading…
Cancel
Save