From 4bd4ad4fc57580df98e7f061d7e5714ab157dc27 Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Tue, 7 Apr 2026 03:29:38 +0000 Subject: [PATCH 1/9] Use MariaDB replication helper for binlog TAP tests - Replace the external binlog reader with a helper function which uses mariadb replication functions. - The helper opens replication sessions, sends `COM_REGISTER_SLAVE`, and fetches heartbeats to verify the stream is active. - It runs the same two-session flow required for TAP tests: - `test_com_register_slave_enables_fast_forward-t` - `test_binlog_reader_uses_previous_hostgroup-t` Signed-off-by: Wazir Ahmed --- test/infra/control/run-tests-isolated.bash | 3 - test/tap/tests/Makefile | 3 + test/tap/tests/binlog_rpl.h | 192 ++++++++++++++++++ ...inlog_reader_uses_previous_hostgroup-t.cpp | 18 +- ..._register_slave_enables_fast_forward-t.cpp | 45 ++-- 5 files changed, 226 insertions(+), 35 deletions(-) create mode 100644 test/tap/tests/binlog_rpl.h diff --git a/test/infra/control/run-tests-isolated.bash b/test/infra/control/run-tests-isolated.bash index c87a11e3e6..43f5c5397d 100755 --- a/test/infra/control/run-tests-isolated.bash +++ b/test/infra/control/run-tests-isolated.bash @@ -229,7 +229,6 @@ chmod 777 "${TESTS_LOGS_PATH_HOST}" # Find binaries MYSQL_BINLOG_BIN=$(find "${WORKSPACE}" -path "${WORKSPACE}/ci_infra_logs" -prune -o -path "${WORKSPACE}/.git" -prune -o -name "mysqlbinlog" -type f -executable -print | head -n 1) -BINLOG_READER_BIN=$(find "${WORKSPACE}" -path "${WORKSPACE}/ci_infra_logs" -prune -o -path "${WORKSPACE}/.git" -prune -o -name "test_binlog_reader-t" -type f -executable -print | head -n 1) # Execution: run the container docker run \ @@ -255,7 +254,6 @@ docker run \ -e COVERAGE_REPORT_DIR="${COVERAGE_REPORT_DIR}" \ -e SCRIPT_DIR="${SCRIPT_DIR}" \ -e MYSQL_BINLOG_BIN="${MYSQL_BINLOG_BIN}" \ - -e BINLOG_READER_BIN="${BINLOG_READER_BIN}" \ -e TAP_USE_NOISE="${TAP_USE_NOISE:-0}" \ -e TAP_PGSQL_SYNC_REPLICA_PORT="${TAP_PGSQL_SYNC_REPLICA_PORT:-}" \ -e MULTI_GROUP="${MULTI_GROUP:-0}" \ @@ -354,7 +352,6 @@ docker run \ mkdir -p \"${WORKSPACE}/test-scripts/deps\" [ -n \"${MYSQL_BINLOG_BIN}\" ] && ln -sf \"${MYSQL_BINLOG_BIN}\" \"${WORKSPACE}/test-scripts/deps/mysqlbinlog\" - [ -n \"${BINLOG_READER_BIN}\" ] && ln -sf \"${BINLOG_READER_BIN}\" \"${WORKSPACE}/test-scripts/deps/test_binlog_reader-t\" # Source group environment first (sets TEST_PY_* flags etc.) if [ -n \"${TAP_GROUP}\" ]; then diff --git a/test/tap/tests/Makefile b/test/tap/tests/Makefile index f9d2947437..6e645964e9 100644 --- a/test/tap/tests/Makefile +++ b/test/tap/tests/Makefile @@ -185,6 +185,9 @@ else $(CXX) -DEXCLUDE_TRACKING_VARIABLES $< ../tap/SQLite3_Server.cpp -I$(CLICKHOUSE_CPP_IDIR) $(IDIRS) $(LDIRS) -L$(CLICKHOUSE_CPP_LDIR) -L$(LZ4_LDIR) $(OPT) $(OBJ) $(MYLIBSJEMALLOC) $(MYLIBS) $(STATIC_LIBS) $(CLICKHOUSE_CPP_LDIR)/libclickhouse-cpp-lib.a $(CLICKHOUSE_CPP_PATH)/contrib/zstd/zstd/libzstdstatic.a $(LZ4_LDIR)/liblz4.a -lscram -lusual -Wl,--allow-multiple-definition -o $@ endif +test_binlog_reader_uses_previous_hostgroup-t: binlog_rpl.h +test_com_register_slave_enables_fast_forward-t: binlog_rpl.h + %-t: %-t.cpp $(TAP_LDIR)/libtap.so $(CXX) $< $(IDIRS) $(LDIRS) $(OPT) $(MYLIBS) $(STATIC_LIBS) -o $@ diff --git a/test/tap/tests/binlog_rpl.h b/test/tap/tests/binlog_rpl.h new file mode 100644 index 0000000000..d1ecd0b9ce --- /dev/null +++ b/test/tap/tests/binlog_rpl.h @@ -0,0 +1,192 @@ +/** + * @file binlog_rpl.h + * @brief Runs binlog replication sessions via MARIADB_RPL with COM_REGISTER_SLAVE. + * @details Uses the MariaDB client replication API to exercise binlog streaming + * functionality. Setting rpl->host before mariadb_rpl_open() triggers + * COM_REGISTER_SLAVE registration. + * + * The helper runs two replication sessions. Each session: + * 1. Opens a fresh connection to ProxySQL + * 2. Issues a lightweight pre-replication query + * 3. Configures replication session variables (checksum, heartbeat) + * 4. Initializes MARIADB_RPL with rpl->host set (triggers COM_REGISTER_SLAVE) + * 5. Opens replication and fetches events to verify the stream is active + * 6. Closes the replication session cleanly + * + * Returns EXIT_SUCCESS only if both sessions succeed. + */ + +#ifndef BINLOG_RPL_H +#define BINLOG_RPL_H + +#include +#include +#include +#include + +#include "mysql.h" +#include "mariadb_rpl.h" +#include "command_line.h" +#include "tap.h" +#include "utils.h" + +// Number of heartbeats to wait per replication session to confirm stream is active +#define BINLOG_RPL_NHB 3 + +/** + * @brief Run a replication session against ProxySQL. + * @details Opens a connection, issues a pre-query, configures replication + * variables, then uses MARIADB_RPL with rpl->host set to send + * COM_REGISTER_SLAVE. Fetches events until BINLOG_RPL_NHB heartbeats + * are received, verifying the binlog stream is active. + * + * @param cl CommandLine with connection parameters. + * @param session_id A label for diagnostic output (e.g. 1 or 2). + * @param server_id Unique server_id for the replication registration. + * @return EXIT_SUCCESS if the session completes successfully, EXIT_FAILURE otherwise. + */ +static int run_replication_session(const CommandLine& cl, int session_id, int server_id) { + int rc = EXIT_FAILURE; + MYSQL* mysql = NULL; + MYSQL_RES* res = NULL; + MARIADB_RPL* rpl = NULL; + MARIADB_RPL_EVENT* event = NULL; + int num_heartbeats = 0; + int num_events = 0; + + diag("Session %d: Connecting to ProxySQL at %s:%d as %s", + session_id, cl.host, cl.port, cl.username); + + mysql = mysql_init(NULL); + if (!mysql) { + diag("Session %d: mysql_init failed", session_id); + goto cleanup; + } + + // Force CLIENT_DEPRECATE_EOF to match backend capabilities for fast-forward + mysql->options.client_flag |= CLIENT_DEPRECATE_EOF; + + if (!mysql_real_connect(mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + diag("Session %d: Connection failed: %s", session_id, mysql_error(mysql)); + goto cleanup; + } + + // Issue a pre-replication query that disables multiplexing. This ensures the + // backend connection stays pinned to the session so that when COM_REGISTER_SLAVE + // triggers fast_forward, the existing backend is reused instead of requiring a + // new connection. + if (run_q(mysql, "SELECT @@hostname")) { + goto cleanup; + } + res = mysql_store_result(mysql); + mysql_free_result(res); + + // Configure replication session variables + if (run_q(mysql, "SET @master_binlog_checksum = 'NONE'")) { + goto cleanup; + } + if (run_q(mysql, "SET @master_heartbeat_period = 2000000000")) { + goto cleanup; + } + + // Initialize replication handle + rpl = mariadb_rpl_init(mysql); + if (!rpl) { + diag("Session %d: mariadb_rpl_init failed", session_id); + goto cleanup; + } + + rpl->server_id = server_id; + rpl->start_position = 4; + rpl->flags = MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS; + + // KEY: Setting rpl->host causes mariadb_rpl_open() to send COM_REGISTER_SLAVE + // before proceeding with the binlog dump. This is the core mechanism under test. + rpl->host = strdup("127.0.0.1"); + rpl->port = cl.port; + + diag("Session %d: Opening replication with server_id=%d (COM_REGISTER_SLAVE will be sent)", + session_id, server_id); + + if (mariadb_rpl_open(rpl)) { + diag("Session %d: mariadb_rpl_open failed: [%d] %s", + session_id, mysql_errno(rpl->mysql), mysql_error(rpl->mysql)); + goto cleanup; + } + + // Fetch events until we receive enough heartbeats to confirm the stream is active + diag("Session %d: Fetching binlog events, waiting for %d heartbeats...", + session_id, BINLOG_RPL_NHB); + + while (num_heartbeats < BINLOG_RPL_NHB && + (event = mariadb_rpl_fetch(rpl, event))) { + num_events++; + if (event->event_type == HEARTBEAT_LOG_EVENT_V2 || + event->event_type == HEARTBEAT_LOG_EVENT) { + num_heartbeats++; + diag("Session %d: Heartbeat %d/%d received (total events: %d)", + session_id, num_heartbeats, BINLOG_RPL_NHB, num_events); + } + } + + if (num_heartbeats < BINLOG_RPL_NHB && event == NULL) { + diag("Session %d: Replication stream ended prematurely: %s", + session_id, mysql_error(mysql)); + } + + if (num_heartbeats < BINLOG_RPL_NHB) { + diag("Session %d: FAILED - received only %d/%d heartbeats", + session_id, num_heartbeats, BINLOG_RPL_NHB); + goto cleanup; + } + + diag("Session %d: SUCCESS - received %d heartbeats across %d events", + session_id, num_heartbeats, num_events); + rc = EXIT_SUCCESS; + +cleanup: + mariadb_free_rpl_event(event); + if (rpl) { + mariadb_rpl_close(rpl); + } + if (mysql) { + mysql_close(mysql); + } + return rc; +} + +/** + * @brief Run two binlog replication sessions via MARIADB_RPL. + * @details Executes two independent replication sessions, each sending + * COM_REGISTER_SLAVE. Used by TAP tests: + * - test_com_register_slave_enables_fast_forward-t: verifies COM_REGISTER_SLAVE + * enables fast-forward mode and binlog streaming works + * - test_binlog_reader_uses_previous_hostgroup-t: verifies fast-forward + * connections use the hostgroup from prior COM_QUERY + * + * @param cl CommandLine with connection parameters. + * @return EXIT_SUCCESS if both sessions succeed, EXIT_FAILURE otherwise. + */ +static int run_binlog_rpl(const CommandLine& cl) { + diag("=== Binlog RPL test: Starting ==="); + diag("Running two replication sessions to exercise COM_REGISTER_SLAVE"); + + // Session 1 + int rc = run_replication_session(cl, 1, 100001); + if (rc != EXIT_SUCCESS) { + diag("=== Binlog RPL test: FAILED (session 1) ==="); + return EXIT_FAILURE; + } + + // Session 2 + rc = run_replication_session(cl, 2, 100002); + if (rc != EXIT_SUCCESS) { + diag("=== Binlog RPL test: FAILED (session 2) ==="); + return EXIT_FAILURE; + } + + diag("=== Binlog RPL test: SUCCESS (both sessions completed) ==="); + return EXIT_SUCCESS; +} + +#endif // BINLOG_RPL_H \ No newline at end of file diff --git a/test/tap/tests/test_binlog_reader_uses_previous_hostgroup-t.cpp b/test/tap/tests/test_binlog_reader_uses_previous_hostgroup-t.cpp index b37de627be..850e329498 100644 --- a/test/tap/tests/test_binlog_reader_uses_previous_hostgroup-t.cpp +++ b/test/tap/tests/test_binlog_reader_uses_previous_hostgroup-t.cpp @@ -2,11 +2,11 @@ * @file test_binlog_reader_uses_previous_hostgroup-t.cpp * @brief Test binlog reader uses the hostgroup of the previous COM_QUERY. * @details When a COM_REGISTER_SLAVE command is received, test that ProxySQL - * will automatically switch from not fast_forward mode to fast_forward mode. - * It also test that the destination hostgroup assigned from previous COM_QUERY - * commands is the one used to establish the fast_forward connection. To test - * this we look at how many connections are closed in the hostgroup that should - * have been used for the fast_forward connections. + * will automatically switch from not fast_forward mode to fast_forward mode. + * It also tests that the destination hostgroup assigned from previous + * COM_QUERY commands is the one used to establish the fast_forward connection. + * To test this we look at how many connections are closed in the hostgroup + * that should have been used for the fast_forward connections. */ #include @@ -18,6 +18,7 @@ #include "command_line.h" #include "utils.h" #include "tap.h" +#include "binlog_rpl.h" using std::vector; using std::string; @@ -105,10 +106,9 @@ int main(int argc, char** argv) { } const long conn_closed_before = std::stol(hg_stats_row[0]); - const char * tdp = getenv("TEST_DEPS"); - const std::string test_binlog_reader = ( tdp == nullptr || *tdp == '\0' ) ? "./test_binlog_reader-t" : std::string(tdp) + "/test_binlog_reader-t"; - const int test_binlog_reader_res = system(test_binlog_reader.c_str()); - if (test_binlog_reader_res) { + const int res = run_binlog_rpl(cl); + if (res) { + diag("Binlog RPL test failed with exit code: %d", res); mysql_close(proxy_admin); return EXIT_FAILURE; } diff --git a/test/tap/tests/test_com_register_slave_enables_fast_forward-t.cpp b/test/tap/tests/test_com_register_slave_enables_fast_forward-t.cpp index 16acaa95b8..7426ff770e 100644 --- a/test/tap/tests/test_com_register_slave_enables_fast_forward-t.cpp +++ b/test/tap/tests/test_com_register_slave_enables_fast_forward-t.cpp @@ -1,40 +1,39 @@ /** - * @file test_com_register_slave_enables_fast_forward-t.cpp @brief Test - * COM_REGISTER_SLAVE enables fast forward. @details Test checks if - * test_binlog_reader is executed successfully using a user with fast forward - * flag set to false. test_binlog_reader sends command COM_REGISTER_SLAVE, then - * ProxySQL enables fast forward. test_binlog_reader then uses libslave to - * listen binlog events. It listen two times, one after sending a query that do - * not disable multiplexing and the other after sending a query that disables - * multiplexing. - * - * The repository for test_binlog_reader-t is: - * https://github.com/ProxySQL/proxysql_binlog_test + * @file test_com_register_slave_enables_fast_forward-t.cpp + * @brief Test COM_REGISTER_SLAVE enables fast forward. + * @details Verifies that ProxySQL correctly enables fast forward for a user + * when it receives COM_REGISTER_SLAVE, even if fast_forward was initially + * disabled. Uses MARIADB_RPL to send COM_REGISTER_SLAVE commands. */ -#include #include #include "tap.h" +#include "command_line.h" +#include "binlog_rpl.h" int main(int argc, char** argv) { + CommandLine cl; + plan(1); diag("Testing COM_REGISTER_SLAVE enables fast forward"); - diag("This test verifies that ProxySQL correctly enables fast forward for a user when it receives COM_REGISTER_SLAVE, even if it was initially disabled."); + diag("This test verifies that ProxySQL correctly enables fast forward for a" + " user when it receives COM_REGISTER_SLAVE, even if it was initially disabled."); + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return EXIT_FAILURE; + } - const char * tdp = getenv("TEST_DEPS"); - const std::string test_binlog_reader = ( tdp == nullptr || *tdp == '\0' ) ? "./test_binlog_reader-t" : std::string(tdp) + "/test_binlog_reader-t"; + const int res = run_binlog_rpl(cl); - diag("Executing test_binlog_reader-t from: %s", test_binlog_reader.c_str()); - const int test_binlog_reader_res = system(test_binlog_reader.c_str()); - - if (test_binlog_reader_res != 0) { - diag("test_binlog_reader-t failed with exit code: %d", test_binlog_reader_res); + if (res != 0) { + diag("Binlog RPL test failed with exit code: %d", res); } ok( - test_binlog_reader_res == 0, - "'test_binlog_reader-t' should be correctly executed. Err code was: %d", - test_binlog_reader_res + res == 0, + "Binlog RPL test should complete successfully. Err code was: %d", + res ); diag("Test completed"); From 235b08af79bf0b23a954055b2aee0d44b0c015c4 Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Thu, 9 Apr 2026 01:21:16 +0530 Subject: [PATCH 2/9] infra-mysql57-binlog: Use binlog-reader in MySQL container, avoid sidecars Issue --- - Currently binlog-reader is deployed as a sidecar in `infra-mysql57-binlog` alongside with MySQL container, but the sidecar is not configured to share the same IP. - This results in unreliable DNS resolution and causes ProxySQL to connect with the binlog-reader for new backend connections. - In `infra-mysql57-binlog`, MySQL containers already have an binlog-reader installed, but they are misconfigured, making the sidecar approach redundant. Fix --- - Remove binlog-reader sidecar, use the binlog-reader installed in MySQL container. - Pass correct environment variables to the binlog-reader process. - Introduce a configurable delay in the CI to ensure that binlog-readers are up and running before running the test. Signed-off-by: Wazir Ahmed --- test/infra/SKILL.md | 14 +-- test/infra/control/ensure-infras.bash | 14 ++- test/infra/control/run-tests-isolated.bash | 16 ++++ test/infra/infra-mysql57-binlog/.env | 1 + .../conf/proxysql/infra-config.sql | 3 +- .../docker-compose-init.bash | 1 + .../infra-mysql57-binlog/docker-compose.yml | 93 +++++++------------ 7 files changed, 75 insertions(+), 67 deletions(-) diff --git a/test/infra/SKILL.md b/test/infra/SKILL.md index 15332a663c..4ae35348b1 100644 --- a/test/infra/SKILL.md +++ b/test/infra/SKILL.md @@ -138,18 +138,18 @@ docker network inspect ${INFRA_ID}_backend ### Issue: "GTID: failed to connect to ProxySQL binlog reader on port 6020" -**Cause:** Reader containers not running or gtid_port misconfigured. +**Cause:** Binlog reader on the mysqlN containers is not listening on 6020, or `gtid_port` is misconfigured. **Solution:** -1. Verify reader containers are running: - ```bash - docker ps | grep reader - ``` -2. Check mysql_servers has gtid_port set: +1. Check mysql_servers has gtid_port set: ```bash docker exec proxysql.${INFRA_ID} mysql -uradmin -pradmin -h127.0.0.1 -P6032 \ -e "SELECT hostname, gtid_port FROM mysql_servers;" ``` +2. Verify the mysqlN container is listening on 6020: + ```bash + docker exec ${COMPOSE_PROJECT}-mysql1-1 bash -lc 'timeout 3 bash -lc ">> Checking if ProxySQL (${PROXY_CONTAINER}) is running..." @@ -148,4 +160,4 @@ if [ -f "${SETUP_HOOK}" ]; then "${SETUP_HOOK}" fi -# ensure-infras.bash completed successfully \ No newline at end of file +# ensure-infras.bash completed successfully diff --git a/test/infra/control/run-tests-isolated.bash b/test/infra/control/run-tests-isolated.bash index 43f5c5397d..3f579dbfca 100755 --- a/test/infra/control/run-tests-isolated.bash +++ b/test/infra/control/run-tests-isolated.bash @@ -75,6 +75,18 @@ if [ -z "${INFRAS_TO_CHECK}" ]; then INFRAS_TO_CHECK="${INFRA_TYPE}" fi +export BINLOG_READER_START_DELAY="${BINLOG_READER_START_DELAY:-30}" +BINLOG_INFRA_FOUND=0 +for INFRA in ${INFRAS_TO_CHECK}; do + if [[ "${INFRA}" == *-binlog ]]; then + BINLOG_INFRA_FOUND=1 + break + fi +done +if [ "${BINLOG_INFRA_FOUND}" -eq 0 ]; then + export BINLOG_READER_START_DELAY=0 +fi + # 2. Automatically derive DEFAULT_MYSQL_INFRA and DEFAULT_PGSQL_INFRA # We take the first compatible infrastructure found in the list. if [ -n "${INFRAS_TO_CHECK}" ]; then @@ -257,6 +269,7 @@ docker run \ -e TAP_USE_NOISE="${TAP_USE_NOISE:-0}" \ -e TAP_PGSQL_SYNC_REPLICA_PORT="${TAP_PGSQL_SYNC_REPLICA_PORT:-}" \ -e MULTI_GROUP="${MULTI_GROUP:-0}" \ + -e BINLOG_READER_START_DELAY="${BINLOG_READER_START_DELAY:-}" \ -e GCOV_PREFIX="/gcov/tap" \ -e GCOV_PREFIX_STRIP="3" \ proxysql-ci-base:latest \ @@ -388,6 +401,9 @@ docker run \ exit 1 fi + echo '>>> Waiting for binlog readers to be ready...' + sleep "\${BINLOG_READER_START_DELAY}" + # Dump ProxySQL configuration before running tests echo '================================================================================' echo 'ProxySQL Configuration Dump (BEFORE TESTS)' diff --git a/test/infra/infra-mysql57-binlog/.env b/test/infra/infra-mysql57-binlog/.env index bdd6f1fd65..feb4268cbc 100644 --- a/test/infra/infra-mysql57-binlog/.env +++ b/test/infra/infra-mysql57-binlog/.env @@ -24,3 +24,4 @@ INFRA_LOGS_PATH=${INFRA_LOGS_PATH:-./logs} # Dynamic password derived from INFRA_ID (used for root user across MySQL and ProxySQL) ROOT_PASSWORD=${ROOT_PASSWORD:-$(echo -n "${INFRA_ID:-dev}" | sha256sum | head -c 10)} +BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY:-30} diff --git a/test/infra/infra-mysql57-binlog/conf/proxysql/infra-config.sql b/test/infra/infra-mysql57-binlog/conf/proxysql/infra-config.sql index 887e211493..54803cba8c 100644 --- a/test/infra/infra-mysql57-binlog/conf/proxysql/infra-config.sql +++ b/test/infra/infra-mysql57-binlog/conf/proxysql/infra-config.sql @@ -3,8 +3,7 @@ LOAD ADMIN VARIABLES TO RUNTIME; SAVE ADMIN VARIABLES TO DISK; DELETE FROM mysql_servers WHERE comment LIKE '%${INFRA}'; --- MySQL servers with gtid_port pointing to proxysql_mysqlbinlog readers --- Note: reader1/2/3 hostnames resolve to the reader containers via Docker network aliases +-- In *-binlog infra, binlog readers are embedded into all mysqlN containers and serve gtid_port 6020. INSERT INTO mysql_servers (hostgroup_id,hostname,gtid_port,port,max_replication_lag,comment) VALUES (${WHG},'mysql1.${INFRA}',6020,3306,10,'mysql1.${INFRA}'); INSERT INTO mysql_servers (hostgroup_id,hostname,gtid_port,port,max_replication_lag,comment) VALUES (${RHG},'mysql2.${INFRA}',6020,3306,10,'mysql2.${INFRA}'); INSERT INTO mysql_servers (hostgroup_id,hostname,gtid_port,port,max_replication_lag,comment) VALUES (${RHG},'mysql3.${INFRA}',6020,3306,10,'mysql3.${INFRA}'); diff --git a/test/infra/infra-mysql57-binlog/docker-compose-init.bash b/test/infra/infra-mysql57-binlog/docker-compose-init.bash index 53d60397ca..24f2e81453 100755 --- a/test/infra/infra-mysql57-binlog/docker-compose-init.bash +++ b/test/infra/infra-mysql57-binlog/docker-compose-init.bash @@ -99,6 +99,7 @@ ROOT_PASSWORD=${ROOT_PASSWORD} INFRA=${INFRA} COMPOSE_PROJECT=${COMPOSE_PROJECT} INFRA_LOGS_PATH=${INFRA_LOGS_PATH} +BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} ENVEOF # 5. START CONTAINERS diff --git a/test/infra/infra-mysql57-binlog/docker-compose.yml b/test/infra/infra-mysql57-binlog/docker-compose.yml index ffd82d8365..dcd92689f7 100644 --- a/test/infra/infra-mysql57-binlog/docker-compose.yml +++ b/test/infra/infra-mysql57-binlog/docker-compose.yml @@ -11,6 +11,18 @@ services: - mysql1.infra-mysql57-binlog environment: - MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} + - MYSQL_HOST=127.0.0.1 + - MYSQL_USER=binlog + - MYSQL_PASSWORD=binlog + - LISTEN_PORT=6020 + - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} + command: > + bash -c "(docker-entrypoint.sh mysqld &); + sleep ${BINLOG_READER_START_DELAY}; + while true; do + sleep 5; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${MYSQL_USER:=root}\" -p \"$${MYSQL_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; + done" volumes: - ./conf/mysql/mysql1:/etc/mysql/conf.d - ./conf/mysql/ssl:/docker-entrypoint-initdb.d @@ -34,6 +46,18 @@ services: - mysql2.infra-mysql57-binlog environment: - MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} + - MYSQL_HOST=127.0.0.1 + - MYSQL_USER=binlog + - MYSQL_PASSWORD=binlog + - LISTEN_PORT=6020 + - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} + command: > + bash -c "(docker-entrypoint.sh mysqld &); + sleep ${BINLOG_READER_START_DELAY}; + while true; do + sleep 5; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${MYSQL_USER:=root}\" -p \"$${MYSQL_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; + done" volumes: - ./conf/mysql/mysql2:/etc/mysql/conf.d - ./conf/mysql/ssl:/docker-entrypoint-initdb.d @@ -59,6 +83,18 @@ services: - mysql3.infra-mysql57-binlog environment: - MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} + - MYSQL_HOST=127.0.0.1 + - MYSQL_USER=binlog + - MYSQL_PASSWORD=binlog + - LISTEN_PORT=6020 + - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} + command: > + bash -c "(docker-entrypoint.sh mysqld &); + sleep ${BINLOG_READER_START_DELAY}; + while true; do + sleep 5; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${MYSQL_USER:=root}\" -p \"$${MYSQL_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; + done" volumes: - ./conf/mysql/mysql3:/etc/mysql/conf.d - ./conf/mysql/ssl:/docker-entrypoint-initdb.d @@ -73,63 +109,6 @@ services: soft: 1048576 hard: 1048576 - reader1: - image: proxysql/ci-infra:proxysql-mysqlbinlog - hostname: reader1.${INFRA} - container_name: ${COMPOSE_PROJECT}-reader1-1 - environment: - - MYSQL_HOST=mysql1.${INFRA} - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog - - GTID_PORT=6020 - volumes: - - ${INFRA_LOGS_PATH}/${COMPOSE_PROJECT}/reader1:/var/log/mysqlbinlog - networks: - backend: - aliases: - - reader1.${INFRA} - - mysql1.${INFRA} - depends_on: - - mysql1 - - reader2: - image: proxysql/ci-infra:proxysql-mysqlbinlog - hostname: reader2.${INFRA} - container_name: ${COMPOSE_PROJECT}-reader2-1 - environment: - - MYSQL_HOST=mysql2.${INFRA} - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog - - GTID_PORT=6020 - volumes: - - ${INFRA_LOGS_PATH}/${COMPOSE_PROJECT}/reader2:/var/log/mysqlbinlog - networks: - backend: - aliases: - - reader2.${INFRA} - - mysql2.${INFRA} - depends_on: - - mysql2 - - reader3: - image: proxysql/ci-infra:proxysql-mysqlbinlog - hostname: reader3.${INFRA} - container_name: ${COMPOSE_PROJECT}-reader3-1 - environment: - - MYSQL_HOST=mysql3.${INFRA} - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog - - GTID_PORT=6020 - volumes: - - ${INFRA_LOGS_PATH}/${COMPOSE_PROJECT}/reader3:/var/log/mysqlbinlog - networks: - backend: - aliases: - - reader3.${INFRA} - - mysql3.${INFRA} - depends_on: - - mysql3 - orc1: hostname: orc1.${INFRA} image: proxysql/ci-infra:openark-orchestrator From 4a9c968171fb62eec89f5299151f55c5c1621199 Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Thu, 9 Apr 2026 01:20:53 +0530 Subject: [PATCH 3/9] CI: Remove `sudo` dependency from isolated CI startup Signed-off-by: Wazir Ahmed --- test/infra/control/docker-fs-helper.bash | 23 +++++++++++++++++++ .../control/start-proxysql-isolated.bash | 12 ++++------ .../infra/control/stop-proxysql-isolated.bash | 5 +++- .../docker-compose-init.bash | 10 ++++---- 4 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 test/infra/control/docker-fs-helper.bash diff --git a/test/infra/control/docker-fs-helper.bash b/test/infra/control/docker-fs-helper.bash new file mode 100644 index 0000000000..f89d83af64 --- /dev/null +++ b/test/infra/control/docker-fs-helper.bash @@ -0,0 +1,23 @@ +#!/bin/bash + +# docker_fs_exec +# Run a command against a host path through a temporary container. +# Use this for host-mounted files/directories whose ownership was set by container users and +# cannot be reliably modified from the host user context. +# Example: docker_fs_exec "rm -f proxysql/proxysql.db" "${INFRA_LOGS_PATH}/${INFRA_ID}" +docker_fs_exec() { + local fs_command="$1" + local target_path="$2" + + if [ -z "${fs_command}" ] || [ -z "${target_path}" ]; then + echo "docker_fs_exec requires a command and a path" >&2 + return 1 + fi + + # Work around host-mounted paths owned by container users different from the host user. + # Alpine/busybox would also work here, but proxysql-ci-base:latest is already pulled in this workflow. + docker run --rm \ + -v "${target_path}:/target" \ + proxysql-ci-base:latest \ + /bin/sh -ec "cd /target && ${fs_command}" +} diff --git a/test/infra/control/start-proxysql-isolated.bash b/test/infra/control/start-proxysql-isolated.bash index 7132e29074..6d67fcf91b 100755 --- a/test/infra/control/start-proxysql-isolated.bash +++ b/test/infra/control/start-proxysql-isolated.bash @@ -2,15 +2,13 @@ set -e set -o pipefail -# SUDO helper: empty if root -SUDO="" -if [ "$(id -u)" != "0" ]; then SUDO="sudo"; fi - # Derive Workspace relative to script SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" export WORKSPACE="${REPO_ROOT}" +source "${SCRIPT_DIR}/docker-fs-helper.bash" + if [ -z "${INFRA_ID}" ]; then echo "Error: INFRA_ID is not set."; exit 1; fi export ROOT_PASSWORD=$(echo -n "${INFRA_ID}" | sha256sum | head -c 10) @@ -35,9 +33,9 @@ echo ">>> Setting up isolated network: ${NETWORK_NAME}" docker network inspect ${NETWORK_NAME} >/dev/null 2>&1 || docker network create ${NETWORK_NAME} echo ">>> Preparing ProxySQL data directory: ${PROXY_DATA_DIR}" -$SUDO mkdir -p "${PROXY_DATA_DIR}" -$SUDO chmod -R 777 "${INFRA_LOGS_PATH}/${INFRA_ID}" -$SUDO rm -f "${PROXY_DATA_DIR}/proxysql.db" "${PROXY_DATA_DIR}"/*.pem +mkdir -p "${PROXY_DATA_DIR}" +docker_fs_exec "chmod -R 777 ." "${INFRA_LOGS_PATH}/${INFRA_ID}" +docker_fs_exec "rm -f proxysql/proxysql.db proxysql/*.pem" "${INFRA_LOGS_PATH}/${INFRA_ID}" docker rm -f "${PROXY_CONTAINER}" >/dev/null 2>&1 || true diff --git a/test/infra/control/stop-proxysql-isolated.bash b/test/infra/control/stop-proxysql-isolated.bash index 5d36433a03..bc404e3ca3 100755 --- a/test/infra/control/stop-proxysql-isolated.bash +++ b/test/infra/control/stop-proxysql-isolated.bash @@ -7,6 +7,8 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" export WORKSPACE="${REPO_ROOT}" +source "${SCRIPT_DIR}/docker-fs-helper.bash" + # Default INFRA_ID if not provided export INFRA_ID="${INFRA_ID:-dev-$USER}" @@ -34,5 +36,6 @@ done echo ">>> Log permissions cleanup" INFRA_LOGS_PATH="${WORKSPACE}/ci_infra_logs" if [ -d "${INFRA_LOGS_PATH}/${INFRA_ID}" ]; then - sudo chmod -R 777 "${INFRA_LOGS_PATH}/${INFRA_ID}" 2>/dev/null || true + chmod -R 777 "${INFRA_LOGS_PATH}/${INFRA_ID}" 2>/dev/null || \ + docker_fs_exec "chmod -R 777 ." "${INFRA_LOGS_PATH}/${INFRA_ID}" >/dev/null 2>&1 || true fi diff --git a/test/infra/infra-mysql57-binlog/docker-compose-init.bash b/test/infra/infra-mysql57-binlog/docker-compose-init.bash index 24f2e81453..3568297dab 100755 --- a/test/infra/infra-mysql57-binlog/docker-compose-init.bash +++ b/test/infra/infra-mysql57-binlog/docker-compose-init.bash @@ -13,13 +13,11 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" export WORKSPACE="${REPO_ROOT}" +source "${REPO_ROOT}/test/infra/control/docker-fs-helper.bash" + set -e set -o pipefail -# SUDO helper: empty if root -SUDO="" -if [ "$(id -u)" != "0" ]; then SUDO="sudo"; fi - # relaunch self with timeout [[ $(ps -o command= $(ps -o ppid= $$)) =~ timeout ]] || exec timeout -v -s 9 ${TIMEOUT:-600} "${BASH_SOURCE}" "$@" @@ -80,8 +78,8 @@ for RAW_PATH in ${MOUNTED_PATHS}; do fi echo "Preparing directory: ${ACTUAL_PATH}" - $SUDO mkdir -p "${ACTUAL_PATH}" - $SUDO chmod -R 777 "${ACTUAL_PATH}" + mkdir -p "${ACTUAL_PATH}" + docker_fs_exec "chmod -R 777 ." "${ACTUAL_PATH}" done # 3. Inject dynamic variables into Orchestrator configs From b66d6225abfae3959a7cb12c9032904562c792dc Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Thu, 9 Apr 2026 13:59:33 +0530 Subject: [PATCH 4/9] infra-mysql57-binlog: fix replica GTID bootstrap Signed-off-by: Wazir Ahmed --- .../bin/docker-mysql-post.bash | 4 ++-- .../infra-mysql57-binlog/docker-compose.yml | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/test/infra/infra-mysql57-binlog/bin/docker-mysql-post.bash b/test/infra/infra-mysql57-binlog/bin/docker-mysql-post.bash index afb451f165..d103dd443f 100755 --- a/test/infra/infra-mysql57-binlog/bin/docker-mysql-post.bash +++ b/test/infra/infra-mysql57-binlog/bin/docker-mysql-post.bash @@ -80,6 +80,8 @@ SQL else echo "Configuring slave (mysql${i})..." docker exec -i "${CONTAINER}" mysql -h127.0.0.1 -uroot ${PASS_OPT} < @@ -21,7 +21,7 @@ services: sleep ${BINLOG_READER_START_DELAY}; while true; do sleep 5; - proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${MYSQL_USER:=root}\" -p \"$${MYSQL_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; done" volumes: - ./conf/mysql/mysql1:/etc/mysql/conf.d @@ -47,8 +47,8 @@ services: environment: - MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} - MYSQL_HOST=127.0.0.1 - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog + - BINLOG_READER_USER=root + - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > @@ -56,7 +56,7 @@ services: sleep ${BINLOG_READER_START_DELAY}; while true; do sleep 5; - proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${MYSQL_USER:=root}\" -p \"$${MYSQL_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; done" volumes: - ./conf/mysql/mysql2:/etc/mysql/conf.d @@ -84,8 +84,8 @@ services: environment: - MYSQL_ROOT_PASSWORD=${ROOT_PASSWORD} - MYSQL_HOST=127.0.0.1 - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog + - BINLOG_READER_USER=root + - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > @@ -93,7 +93,7 @@ services: sleep ${BINLOG_READER_START_DELAY}; while true; do sleep 5; - proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${MYSQL_USER:=root}\" -p \"$${MYSQL_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; done" volumes: - ./conf/mysql/mysql3:/etc/mysql/conf.d From 4a231bbc13748789ad24b09d5e276347c3cdb8da Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Mon, 13 Apr 2026 00:42:56 +0530 Subject: [PATCH 5/9] CI: fix typo in skill.md --- test/infra/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/infra/SKILL.md b/test/infra/SKILL.md index 4ae35348b1..ec7ddd02d7 100644 --- a/test/infra/SKILL.md +++ b/test/infra/SKILL.md @@ -148,7 +148,7 @@ docker network inspect ${INFRA_ID}_backend ``` 2. Verify the mysqlN container is listening on 6020: ```bash - docker exec ${COMPOSE_PROJECT}-mysql1-1 bash -lc 'timeout 3 bash -lc " Date: Mon, 13 Apr 2026 08:54:43 +0530 Subject: [PATCH 6/9] CI: Port mysql57-binlog changes to mysql84-binlog - Align infra-mysql84-binlog with the mysql57-binlog infra behavior - Fix mysql84-binlog-reader wiring to use shared mysql service networking on port 6020 - Add binlog-reader startup delay plumbing for mysql84 infra - Update mysql84 replica bootstrap flow and ProxySQL test user setup Signed-off-by: Wazir Ahmed --- test/infra/infra-mysql84-binlog/.env | 2 + .../bin/docker-mysql-post.bash | 4 +- .../conf/proxysql/infra-config.sql | 4 +- .../docker-compose-init.bash | 11 ++-- .../infra-mysql84-binlog/docker-compose.yml | 66 ++++++++++--------- 5 files changed, 47 insertions(+), 40 deletions(-) diff --git a/test/infra/infra-mysql84-binlog/.env b/test/infra/infra-mysql84-binlog/.env index 3c6686c7e2..d36a44f12d 100644 --- a/test/infra/infra-mysql84-binlog/.env +++ b/test/infra/infra-mysql84-binlog/.env @@ -24,6 +24,8 @@ ORC3_PORT=${PREFIX}103 INFRA=${INFRA:-infra-mysql84-binlog} +BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY:-30} + # Export hostgroup for TAP tests that need it export TAP_REG_TEST_3549_AUTOCOMMIT_TRACKING___MYSQL_SERVER_HOSTGROUP=${WHG} export TAP_MYSQL8_BACKEND_HG=${WHG} diff --git a/test/infra/infra-mysql84-binlog/bin/docker-mysql-post.bash b/test/infra/infra-mysql84-binlog/bin/docker-mysql-post.bash index 579e486e54..d9b4125d9e 100755 --- a/test/infra/infra-mysql84-binlog/bin/docker-mysql-post.bash +++ b/test/infra/infra-mysql84-binlog/bin/docker-mysql-post.bash @@ -80,14 +80,14 @@ SQL else echo "Configuring replica (mysql${i})..." docker exec -i "${CONTAINER}" mysql -h127.0.0.1 -uroot ${PASS_OPT} < + bash -c "sleep ${BINLOG_READER_START_DELAY}; + while true; do + sleep 5; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysqlbinlog/error.log; + done" volumes: - ${INFRA_LOGS_PATH}/${COMPOSE_PROJECT}/reader1:/var/log/mysqlbinlog - networks: - backend: - aliases: - - reader1.${INFRA} - - mysql1.${INFRA} + network_mode: service:mysql1 depends_on: - mysql1 reader2: image: proxysql/ci-infra:proxysql-mysqlbinlog-v2.3 - hostname: reader2.${INFRA} container_name: ${COMPOSE_PROJECT}-reader2-1 environment: - - MYSQL_HOST=mysql2.${INFRA} - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog - - GTID_PORT=6020 + - MYSQL_HOST=127.0.0.1 + - BINLOG_READER_USER=root + - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} + - LISTEN_PORT=6020 + - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} + command: > + bash -c "sleep ${BINLOG_READER_START_DELAY}; + while true; do + sleep 5; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysqlbinlog/error.log; + done" volumes: - ${INFRA_LOGS_PATH}/${COMPOSE_PROJECT}/reader2:/var/log/mysqlbinlog - networks: - backend: - aliases: - - reader2.${INFRA} - - mysql2.${INFRA} + network_mode: service:mysql2 depends_on: - mysql2 reader3: image: proxysql/ci-infra:proxysql-mysqlbinlog-v2.3 - hostname: reader3.${INFRA} container_name: ${COMPOSE_PROJECT}-reader3-1 environment: - - MYSQL_HOST=mysql3.${INFRA} - - MYSQL_USER=binlog - - MYSQL_PASSWORD=binlog - - GTID_PORT=6020 + - MYSQL_HOST=127.0.0.1 + - BINLOG_READER_USER=root + - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} + - LISTEN_PORT=6020 + - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} + command: > + bash -c "sleep ${BINLOG_READER_START_DELAY}; + while true; do + sleep 5; + proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysqlbinlog/error.log; + done" volumes: - ${INFRA_LOGS_PATH}/${COMPOSE_PROJECT}/reader3:/var/log/mysqlbinlog - networks: - backend: - aliases: - - reader3.${INFRA} - - mysql3.${INFRA} + network_mode: service:mysql3 depends_on: - mysql3 From b1192473ba243fa16be5a72824c63d6cef6f0bfe Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Mon, 13 Apr 2026 08:58:21 +0530 Subject: [PATCH 7/9] CI: Remove redundant `docker-compose-destroy.bash` helper for mysql57-binlog infra --- .../docker-compose-destroy.bash | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100755 test/infra/infra-mysql57-binlog/docker-compose-destroy.bash diff --git a/test/infra/infra-mysql57-binlog/docker-compose-destroy.bash b/test/infra/infra-mysql57-binlog/docker-compose-destroy.bash deleted file mode 100755 index 6a70edbff9..0000000000 --- a/test/infra/infra-mysql57-binlog/docker-compose-destroy.bash +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -# RELIABLY CAPTURE INFRA_ID FROM ENVIRONMENT OR DIRECTORY NAME -if [ -z "${INFRA_ID}" ]; then - export INFRA_ID=$(basename $(dirname $(pwd)) | sed 's/infra-//; s/docker-//') -fi -# Final safety: if INFRA_ID is still empty or ".", use a default -if [ -z "${INFRA_ID}" ] || [ "${INFRA_ID}" = "." ]; then - export INFRA_ID="dev-$USER" -fi - -# Derive Workspace relative to script -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "${SCRIPT_DIR}/../../.." && pwd)" -export WORKSPACE="${REPO_ROOT}" - -set -e -set -o pipefail - -# make sure we have correct cwd -pushd $(dirname $0) &>/dev/null -trap 'popd &>/dev/null' EXIT - -# Load .env but ensure INFRA_ID is preserved -if [ ! -f .env ]; then echo "Error: .env not found"; exit 1; fi -SAVED_INFRA_ID="${INFRA_ID}" -set -a; . .env; set +a -export INFRA_ID="${SAVED_INFRA_ID}" - -# Docker Compose version helper - prefer plugin (v2) -COMPOSE_CMD="docker compose" -if ! $COMPOSE_CMD version &>/dev/null; then - COMPOSE_CMD="docker-compose" - if ! $COMPOSE_CMD version &>/dev/null; then - echo "ERROR: Neither 'docker compose' nor 'docker-compose' found!" - exit 1 - fi -fi - -if [ -z "${INFRA_ID}" ]; then echo "Error: INFRA_ID must be set"; exit 1; fi - -export ROOT_PASSWORD=$(echo -n "${INFRA_ID}" | sha256sum | head -c 10) -export INFRA=${PWD##*/} -export COMPOSE_PROJECT="${INFRA}-${INFRA_ID}" -export INFRA_LOGS_PATH=${INFRA_LOGS_PATH:-${WORKSPACE}/ci_infra_logs} - -echo "=================================================================================" -echo "Destroying CI Infra '${INFRA}' (Project: ${COMPOSE_PROJECT}) ..." -echo "=================================================================================" - -# Create temp env file -ENV_FILE=".env.isolated.${INFRA_ID}" -cat < "${ENV_FILE}" -INFRA_ID=${INFRA_ID} -ROOT_PASSWORD=${ROOT_PASSWORD} -INFRA=${INFRA} -COMPOSE_PROJECT=${COMPOSE_PROJECT} -INFRA_LOGS_PATH=${INFRA_LOGS_PATH} -ENVEOF - -$COMPOSE_CMD --env-file .env --env-file "${ENV_FILE}" -p "${COMPOSE_PROJECT}" down -v -rm -f "${ENV_FILE}" - -echo "=================================================================================" -echo "Done." -echo "=================================================================================" From 8796364b7eff32edcc1b50d7baf27a1d88e8bfba Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Mon, 13 Apr 2026 09:24:21 +0530 Subject: [PATCH 8/9] CI: Remove binlog-reader fixed start-delay - Take a different approach from 235b08af7, which introduced `BINLOG_READER_START_DELAY` - Remove start-delay plumbing from ensure/run-test/binlog infra paths - Wait for each binlog reader to open port 6020 during infra startup - Keep reader retry loops simple with a fixed 5-second pre-start backoff - Fail ensure-infras early with logs if a reader never comes up Signed-off-by: Wazir Ahmed --- test/infra/control/ensure-infras.bash | 12 -------- test/infra/control/run-tests-isolated.bash | 16 ---------- test/infra/infra-mysql57-binlog/.env | 2 -- .../docker-compose-init.bash | 29 ++++++++++++++++++- .../infra-mysql57-binlog/docker-compose.yml | 6 ---- test/infra/infra-mysql84-binlog/.env | 2 -- .../docker-compose-init.bash | 29 ++++++++++++++++++- .../infra-mysql84-binlog/docker-compose.yml | 12 ++------ 8 files changed, 59 insertions(+), 49 deletions(-) diff --git a/test/infra/control/ensure-infras.bash b/test/infra/control/ensure-infras.bash index 7435989ef0..b7f9383962 100755 --- a/test/infra/control/ensure-infras.bash +++ b/test/infra/control/ensure-infras.bash @@ -64,18 +64,6 @@ else fi fi -export BINLOG_READER_START_DELAY="${BINLOG_READER_START_DELAY:-30}" -BINLOG_INFRA_FOUND=0 -for INFRA_NAME in ${INFRAS}; do - if [[ "${INFRA_NAME}" == *-binlog ]]; then - BINLOG_INFRA_FOUND=1 - break - fi -done -if [ "${BINLOG_INFRA_FOUND}" -eq 0 ]; then - export BINLOG_READER_START_DELAY=0 -fi - # 2. Ensure ProxySQL Control Plane is running first PROXY_CONTAINER="proxysql.${INFRA_ID}" echo ">>> Checking if ProxySQL (${PROXY_CONTAINER}) is running..." diff --git a/test/infra/control/run-tests-isolated.bash b/test/infra/control/run-tests-isolated.bash index 3ae9cc2e23..1bebcb7fb6 100755 --- a/test/infra/control/run-tests-isolated.bash +++ b/test/infra/control/run-tests-isolated.bash @@ -75,18 +75,6 @@ if [ -z "${INFRAS_TO_CHECK}" ]; then INFRAS_TO_CHECK="${INFRA_TYPE}" fi -export BINLOG_READER_START_DELAY="${BINLOG_READER_START_DELAY:-30}" -BINLOG_INFRA_FOUND=0 -for INFRA in ${INFRAS_TO_CHECK}; do - if [[ "${INFRA}" == *-binlog ]]; then - BINLOG_INFRA_FOUND=1 - break - fi -done -if [ "${BINLOG_INFRA_FOUND}" -eq 0 ]; then - export BINLOG_READER_START_DELAY=0 -fi - # Derive INFRA_TYPE from TAP_GROUP if not set # This is simple and deterministic - matches group naming convention if [ -z "${INFRA_TYPE}" ]; then @@ -309,7 +297,6 @@ docker run \ -e TAP_USE_NOISE="${TAP_USE_NOISE:-0}" \ -e TAP_PGSQL_SYNC_REPLICA_PORT="${TAP_PGSQL_SYNC_REPLICA_PORT:-}" \ -e MULTI_GROUP="${MULTI_GROUP:-0}" \ - -e BINLOG_READER_START_DELAY="${BINLOG_READER_START_DELAY:-}" \ -e GCOV_PREFIX="/gcov/tap" \ -e GCOV_PREFIX_STRIP="3" \ proxysql-ci-base:latest \ @@ -441,9 +428,6 @@ docker run \ exit 1 fi - echo '>>> Waiting for binlog readers to be ready...' - sleep "\${BINLOG_READER_START_DELAY}" - # Dump ProxySQL configuration before running tests echo '================================================================================' echo 'ProxySQL Configuration Dump (BEFORE TESTS)' diff --git a/test/infra/infra-mysql57-binlog/.env b/test/infra/infra-mysql57-binlog/.env index aeadddfef2..671f530f21 100644 --- a/test/infra/infra-mysql57-binlog/.env +++ b/test/infra/infra-mysql57-binlog/.env @@ -27,5 +27,3 @@ ROOT_PASSWORD=${ROOT_PASSWORD:-$(echo -n "${INFRA_ID:-dev}" | sha256sum | head - # Export hostgroup for TAP tests that need it export TAP_REG_TEST_3549_AUTOCOMMIT_TRACKING___MYSQL_SERVER_HOSTGROUP=${WHG} - -BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY:-30} diff --git a/test/infra/infra-mysql57-binlog/docker-compose-init.bash b/test/infra/infra-mysql57-binlog/docker-compose-init.bash index 3568297dab..2c6b964e26 100755 --- a/test/infra/infra-mysql57-binlog/docker-compose-init.bash +++ b/test/infra/infra-mysql57-binlog/docker-compose-init.bash @@ -97,7 +97,6 @@ ROOT_PASSWORD=${ROOT_PASSWORD} INFRA=${INFRA} COMPOSE_PROJECT=${COMPOSE_PROJECT} INFRA_LOGS_PATH=${INFRA_LOGS_PATH} -BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} ENVEOF # 5. START CONTAINERS @@ -127,6 +126,34 @@ fi # 7. Run post-scripts if they exist sleep 2 # wait a bit for engines to start [ -f ./bin/docker-mysql-post.bash ] && ./bin/docker-mysql-post.bash + +if [[ "${INFRA}" == *-binlog ]]; then + echo ">>> Waiting for binlog readers on port 6020..." + for i in 1 2 3; do + MYSQL_CONTAINER="${COMPOSE_PROJECT}-mysql${i}-1" + READER_CONTAINER="${COMPOSE_PROJECT}-reader${i}-1" + echo -n "Waiting for mysql${i} binlog reader ..." + MAX_WAIT=60 + COUNT=0 + while ! docker exec "${MYSQL_CONTAINER}" bash -lc 'exec 3<>/dev/tcp/127.0.0.1/6020; exec 3>&-; exec 3<&-' >/dev/null 2>&1; do + echo -n "." + sleep 2 + COUNT=$((COUNT+2)) + if [ ${COUNT} -ge ${MAX_WAIT} ]; then + echo " FAILED" + echo ">>> ${MYSQL_CONTAINER} logs:" + docker logs "${MYSQL_CONTAINER}" | tail -n 50 || true + if docker inspect "${READER_CONTAINER}" >/dev/null 2>&1; then + echo ">>> ${READER_CONTAINER} logs:" + docker logs "${READER_CONTAINER}" | tail -n 50 || true + fi + exit 1 + fi + done + echo " OK." + done +fi + [ -f ./bin/docker-orchestrator-post.bash ] && ./bin/docker-orchestrator-post.bash [ -f ./bin/docker-proxy-post.bash ] && ./bin/docker-proxy-post.bash "$1" diff --git a/test/infra/infra-mysql57-binlog/docker-compose.yml b/test/infra/infra-mysql57-binlog/docker-compose.yml index d9debc7d51..47770c7cec 100644 --- a/test/infra/infra-mysql57-binlog/docker-compose.yml +++ b/test/infra/infra-mysql57-binlog/docker-compose.yml @@ -15,10 +15,8 @@ services: - BINLOG_READER_USER=root - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > bash -c "(docker-entrypoint.sh mysqld &); - sleep ${BINLOG_READER_START_DELAY}; while true; do sleep 5; proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; @@ -50,10 +48,8 @@ services: - BINLOG_READER_USER=root - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > bash -c "(docker-entrypoint.sh mysqld &); - sleep ${BINLOG_READER_START_DELAY}; while true; do sleep 5; proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; @@ -87,10 +83,8 @@ services: - BINLOG_READER_USER=root - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > bash -c "(docker-entrypoint.sh mysqld &); - sleep ${BINLOG_READER_START_DELAY}; while true; do sleep 5; proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysql/binlogreader-error.log; diff --git a/test/infra/infra-mysql84-binlog/.env b/test/infra/infra-mysql84-binlog/.env index d36a44f12d..3c6686c7e2 100644 --- a/test/infra/infra-mysql84-binlog/.env +++ b/test/infra/infra-mysql84-binlog/.env @@ -24,8 +24,6 @@ ORC3_PORT=${PREFIX}103 INFRA=${INFRA:-infra-mysql84-binlog} -BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY:-30} - # Export hostgroup for TAP tests that need it export TAP_REG_TEST_3549_AUTOCOMMIT_TRACKING___MYSQL_SERVER_HOSTGROUP=${WHG} export TAP_MYSQL8_BACKEND_HG=${WHG} diff --git a/test/infra/infra-mysql84-binlog/docker-compose-init.bash b/test/infra/infra-mysql84-binlog/docker-compose-init.bash index 3568297dab..2c6b964e26 100755 --- a/test/infra/infra-mysql84-binlog/docker-compose-init.bash +++ b/test/infra/infra-mysql84-binlog/docker-compose-init.bash @@ -97,7 +97,6 @@ ROOT_PASSWORD=${ROOT_PASSWORD} INFRA=${INFRA} COMPOSE_PROJECT=${COMPOSE_PROJECT} INFRA_LOGS_PATH=${INFRA_LOGS_PATH} -BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} ENVEOF # 5. START CONTAINERS @@ -127,6 +126,34 @@ fi # 7. Run post-scripts if they exist sleep 2 # wait a bit for engines to start [ -f ./bin/docker-mysql-post.bash ] && ./bin/docker-mysql-post.bash + +if [[ "${INFRA}" == *-binlog ]]; then + echo ">>> Waiting for binlog readers on port 6020..." + for i in 1 2 3; do + MYSQL_CONTAINER="${COMPOSE_PROJECT}-mysql${i}-1" + READER_CONTAINER="${COMPOSE_PROJECT}-reader${i}-1" + echo -n "Waiting for mysql${i} binlog reader ..." + MAX_WAIT=60 + COUNT=0 + while ! docker exec "${MYSQL_CONTAINER}" bash -lc 'exec 3<>/dev/tcp/127.0.0.1/6020; exec 3>&-; exec 3<&-' >/dev/null 2>&1; do + echo -n "." + sleep 2 + COUNT=$((COUNT+2)) + if [ ${COUNT} -ge ${MAX_WAIT} ]; then + echo " FAILED" + echo ">>> ${MYSQL_CONTAINER} logs:" + docker logs "${MYSQL_CONTAINER}" | tail -n 50 || true + if docker inspect "${READER_CONTAINER}" >/dev/null 2>&1; then + echo ">>> ${READER_CONTAINER} logs:" + docker logs "${READER_CONTAINER}" | tail -n 50 || true + fi + exit 1 + fi + done + echo " OK." + done +fi + [ -f ./bin/docker-orchestrator-post.bash ] && ./bin/docker-orchestrator-post.bash [ -f ./bin/docker-proxy-post.bash ] && ./bin/docker-proxy-post.bash "$1" diff --git a/test/infra/infra-mysql84-binlog/docker-compose.yml b/test/infra/infra-mysql84-binlog/docker-compose.yml index 9eb5a1d048..b7840a29f3 100644 --- a/test/infra/infra-mysql84-binlog/docker-compose.yml +++ b/test/infra/infra-mysql84-binlog/docker-compose.yml @@ -75,10 +75,8 @@ services: - BINLOG_READER_USER=root - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > - bash -c "sleep ${BINLOG_READER_START_DELAY}; - while true; do + bash -c "while true; do sleep 5; proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysqlbinlog/error.log; done" @@ -96,10 +94,8 @@ services: - BINLOG_READER_USER=root - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > - bash -c "sleep ${BINLOG_READER_START_DELAY}; - while true; do + bash -c "while true; do sleep 5; proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysqlbinlog/error.log; done" @@ -117,10 +113,8 @@ services: - BINLOG_READER_USER=root - BINLOG_READER_PASSWORD=${ROOT_PASSWORD} - LISTEN_PORT=6020 - - BINLOG_READER_START_DELAY=${BINLOG_READER_START_DELAY} command: > - bash -c "sleep ${BINLOG_READER_START_DELAY}; - while true; do + bash -c "while true; do sleep 5; proxysql_binlog_reader -h \"$${MYSQL_HOST:-127.0.0.1}\" -u \"$${BINLOG_READER_USER:=root}\" -p \"$${BINLOG_READER_PASSWORD:-root}\" -P \"$${MYSQL_PORT:-3306}\" -l \"$${LISTEN_PORT:-6020}\" -f 2>&1 | tee -a /var/log/mysqlbinlog/error.log; done" From 8494ccc234e7f27997871b39e837d92e2cd828d0 Mon Sep 17 00:00:00 2001 From: Wazir Ahmed Date: Mon, 13 Apr 2026 13:51:36 +0530 Subject: [PATCH 9/9] CI: Update docker image for binlog-reader --- test/infra/infra-mysql84-binlog/docker-compose.yml | 6 +++--- test/tap/groups/groups.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/infra/infra-mysql84-binlog/docker-compose.yml b/test/infra/infra-mysql84-binlog/docker-compose.yml index b7840a29f3..b03fb14066 100644 --- a/test/infra/infra-mysql84-binlog/docker-compose.yml +++ b/test/infra/infra-mysql84-binlog/docker-compose.yml @@ -68,7 +68,7 @@ services: hard: 1048576 reader1: - image: proxysql/ci-infra:proxysql-mysqlbinlog-v2.3 + image: proxysql/proxysql-mysqlbinlog container_name: ${COMPOSE_PROJECT}-reader1-1 environment: - MYSQL_HOST=127.0.0.1 @@ -87,7 +87,7 @@ services: - mysql1 reader2: - image: proxysql/ci-infra:proxysql-mysqlbinlog-v2.3 + image: proxysql/proxysql-mysqlbinlog container_name: ${COMPOSE_PROJECT}-reader2-1 environment: - MYSQL_HOST=127.0.0.1 @@ -106,7 +106,7 @@ services: - mysql2 reader3: - image: proxysql/ci-infra:proxysql-mysqlbinlog-v2.3 + image: proxysql/proxysql-mysqlbinlog container_name: ${COMPOSE_PROJECT}-reader3-1 environment: - MYSQL_HOST=127.0.0.1 diff --git a/test/tap/groups/groups.json b/test/tap/groups/groups.json index 119d99c8fb..8fddd92645 100644 --- a/test/tap/groups/groups.json +++ b/test/tap/groups/groups.json @@ -261,10 +261,10 @@ "test_auth_methods-t" : [ "mysql84-g2","mysql-auto_increment_delay_multiplex=0-g2","mysql-multiplexing=false-g2","mysql-query_digests=0-g2","mysql-query_digests_keep_comment=1-g2" ], "test_auto_increment_delay_multiplex-t" : [ "legacy-g2","mysql84-g2","mysql-auto_increment_delay_multiplex=0-g2","mysql-multiplexing=false-g2","mysql-query_digests=0-g2","mysql-query_digests_keep_comment=1-g2" ], "test_backend_conn_ping-t" : [ "legacy-g2","mysql84-g2","mysql-auto_increment_delay_multiplex=0-g2","mysql-multiplexing=false-g2","mysql-query_digests=0-g2","mysql-query_digests_keep_comment=1-g2" ], - "test_binlog_dump_multi_backend_crash-t" : [ "legacy-binlog-g1" ], - "test_binlog_fast_forward-t" : [ "legacy-binlog-g1","mysql84-binlog-g2" ], + "test_binlog_dump_multi_backend_crash-t" : [ "legacy-binlog-g1", "mysql84-binlog-g1" ], + "test_binlog_fast_forward-t" : [ "legacy-binlog-g1","mysql84-binlog-g1" ], "test_binlog_reader-t" : [ "legacy-binlog-g1","mysql84-binlog-g1" ], - "test_binlog_reader_uses_previous_hostgroup-t" : [ "legacy-binlog-g1","mysql84-g5" ], + "test_binlog_reader_uses_previous_hostgroup-t" : [ "legacy-binlog-g1", "mysql84-binlog-g1", "mysql84-g5" ], "test_cacert_load_and_verify_duration-t" : [ "legacy-g3","mysql84-g3","mysql-auto_increment_delay_multiplex=0-g3","mysql-multiplexing=false-g3","mysql-query_digests=0-g3","mysql-query_digests_keep_comment=1-g3" ], "test_change_user-t" : [ "legacy-g3","mysql84-g3","mysql-auto_increment_delay_multiplex=0-g3","mysql-multiplexing=false-g3","mysql-query_digests=0-g3","mysql-query_digests_keep_comment=1-g3" ], "test_clickhouse_server-t" : [ "legacy-clickhouse-g1","mysql-auto_increment_delay_multiplex=0-g3","mysql-multiplexing=false-g3","mysql-query_digests=0-g3","mysql-query_digests_keep_comment=1-g3" ],