Skip to content

Commit dacac82

Browse files
authored
chore(mariadb): replace mutating write probe with read-only SHOW GRANTS (#2928)
1 parent 7fd2bd6 commit dacac82

2 files changed

Lines changed: 61 additions & 42 deletions

File tree

addons/mariadb/scripts-ut-spec/replication_switchover_spec.sh

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,8 +2049,8 @@ case "$*" in
20492049
echo "GRANT SELECT, PROCESS, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION MASTER ADMIN ON *.* TO 'root'@'127.0.0.1'"
20502050
exit 0
20512051
;;
2052-
*"-uroot"*"INSERT"*)
2053-
echo "ERROR 1044 (42000): Access denied for user 'root'@'127.0.0.1' to database 'kubeblocks'"
2052+
*"-uroot"*"SHOW GRANTS"*)
2053+
echo "ERROR 1044 (42000): Access denied for user 'root'@'127.0.0.1' to database 'mysql'"
20542054
exit 1
20552055
;;
20562056
esac
@@ -2072,6 +2072,29 @@ EOF
20722072
The output should include "reason_hash=sha256"
20732073
End
20742074

2075+
It "alpha.127 v2: 127.0.0.1 SHOW GRANTS rc=0 with no write grants is accepted as read-only fenced"
2076+
cat > "${MARIADB_CLIENT_BIN}" <<'EOF'
2077+
#!/bin/sh
2078+
case "$*" in
2079+
*"-ukb_internal_root"*"SHOW GRANTS"*)
2080+
echo "GRANT SELECT, PROCESS, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION MASTER ADMIN ON *.* TO 'root'@'127.0.0.1'"
2081+
exit 0
2082+
;;
2083+
*"-uroot"*"SHOW GRANTS"*)
2084+
echo "GRANT SELECT, PROCESS, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION MASTER ADMIN ON *.* TO 'root'@'127.0.0.1'"
2085+
exit 0
2086+
;;
2087+
esac
2088+
exit 0
2089+
EOF
2090+
chmod +x "${MARIADB_CLIENT_BIN}"
2091+
When call _verify_host_is_fenced "127.0.0.1"
2092+
The status should be success
2093+
The output should include "write_probe_rc=0"
2094+
The output should include "write_probe_errno=1290"
2095+
The output should include "reason=ok_by_local_probe:1290"
2096+
End
2097+
20752098
It "alpha.62 v1: localhost host → grants-only path (no socket probe), reason=ok_by_grants_only:localhost_socket_not_attempted"
20762099
cat > "${MARIADB_CLIENT_BIN}" <<'EOF'
20772100
#!/bin/sh
@@ -2135,7 +2158,8 @@ case "$*" in
21352158
echo "GRANT SELECT, PROCESS, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION MASTER ADMIN ON *.* TO 'root'@'127.0.0.1'"
21362159
exit 0
21372160
;;
2138-
*"-uroot"*"INSERT"*)
2161+
*"-uroot"*"SHOW GRANTS"*)
2162+
echo "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION MASTER ADMIN ON *.* TO 'root'@'127.0.0.1'"
21392163
exit 0
21402164
;;
21412165
esac
@@ -2405,17 +2429,17 @@ EOF
24052429
It "alpha.63 v1: 127.0.0.1 with multi-line SQL stderr containing 1044 → __PROBE_ERRNO=1044 correctly extracted (alpha.62 RED root cause closed)"
24062430
cat > "${MARIADB_CLIENT_BIN}" <<'EOF'
24072431
#!/bin/sh
2408-
# Simulate alpha.62 RED scenario: mariadb client INSERT returns multi-line SQL stderr containing 1044.
2432+
# Simulate alpha.62 RED scenario: mariadb client SHOW GRANTS returns multi-line SQL stderr containing 1044.
24092433
case "$*" in
24102434
*"-ukb_internal_root"*"SHOW GRANTS"*)
24112435
echo "GRANT SELECT, PROCESS, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT, REPLICATION MASTER ADMIN ON *.* TO 'root'@'127.0.0.1'"
24122436
echo "GRANT PROXY ON ''@'%' TO 'root'@'127.0.0.1' WITH GRANT OPTION"
24132437
exit 0
24142438
;;
2415-
*"-uroot"*"INSERT"*)
2439+
*"-uroot"*"SHOW GRANTS"*)
24162440
cat <<MULTILINE
2417-
ERROR 1044 (42000) at line 3: Access denied for user 'root'@'127.0.0.1'
2418-
to database 'kubeblocks'
2441+
ERROR 1044 (42000): Access denied for user 'root'@'127.0.0.1'
2442+
to database 'mysql'
24192443
MULTILINE
24202444
exit 1
24212445
;;

addons/mariadb/scripts/replication-switchover.sh

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -489,28 +489,27 @@ _local_root_write_probe_127() {
489489
# one of the 5 valid values (1044/1290/1142/0/other) — fail-closed
490490
# `probe_result_malformed` / `probe_result_malformed_errno` otherwise
491491
# (Jack 05:24 instrumentation 1).
492+
#
493+
# alpha.127+ fix: replaced mutating INSERT/DELETE probe with read-only
494+
# SHOW GRANTS check to eliminate orphan GTID writes on the demoted primary.
495+
# Mirrors the pattern used by verify_post_dcs_local_root_write_fenced().
492496
__PROBE_OUT=$("${MARIADB_CLIENT_BIN}" "-u${MARIADB_ROOT_USER}" "-p${MARIADB_ROOT_PASSWORD}" \
493497
--connect-timeout="${MARIADB_CONNECT_TIMEOUT_SECONDS}" \
494-
-P3306 -h127.0.0.1 -N -s -e "
495-
CREATE DATABASE IF NOT EXISTS kubeblocks;
496-
CREATE TABLE IF NOT EXISTS ${SWITCHOVER_REMOTE_ROOT_PROBE_TABLE}(probe_id VARCHAR(128) PRIMARY KEY, check_ts BIGINT);
497-
INSERT INTO ${SWITCHOVER_REMOTE_ROOT_PROBE_TABLE}(probe_id, check_ts)
498-
VALUES ('switchover_local_root_probe', UNIX_TIMESTAMP());
499-
DELETE FROM ${SWITCHOVER_REMOTE_ROOT_PROBE_TABLE} WHERE probe_id='switchover_local_root_probe';
500-
" 2>&1)
498+
-P3306 -h127.0.0.1 -N -s -e "SHOW GRANTS FOR '${MARIADB_ROOT_USER}'@'127.0.0.1';" 2>&1)
501499
__PROBE_RC=$?
502-
case "${__PROBE_OUT}" in
503-
*1044*) __PROBE_ERRNO=1044 ;;
504-
*1290*) __PROBE_ERRNO=1290 ;;
505-
*1142*) __PROBE_ERRNO=1142 ;; # Permission for table itself; accepted as fenced
506-
*)
507-
if [ "${__PROBE_RC}" -eq 0 ]; then
508-
__PROBE_ERRNO=0
509-
else
510-
__PROBE_ERRNO=other
511-
fi
512-
;;
513-
esac
500+
if [ "${__PROBE_RC}" -ne 0 ]; then
501+
case "${__PROBE_OUT}" in
502+
*1044*) __PROBE_ERRNO=1044 ;;
503+
*1141*) __PROBE_ERRNO=1044 ;;
504+
*) __PROBE_ERRNO=other ;;
505+
esac
506+
return
507+
fi
508+
if echo "${__PROBE_OUT}" | grep -qiE 'ALL PRIVILEGES|INSERT|UPDATE|DELETE|CREATE'; then
509+
__PROBE_ERRNO=0
510+
else
511+
__PROBE_ERRNO=1290
512+
fi
514513
}
515514

516515
_filter_grants_keep_unmatched() {
@@ -686,7 +685,12 @@ _verify_host_is_fenced() {
686685
esac
687686
write_rc="${__PROBE_RC}"
688687
write_errno="${__PROBE_ERRNO}"
689-
case "${write_rc}" in
688+
case "${write_errno}" in
689+
1044|1290|1142)
690+
reason="ok_by_local_probe:${write_errno}"
691+
log_switchover_info "remote_root_fence_verify host=${host} verified_host=${host} probe_host=${probe_host} grants_query_rc=0 ${grants_sha_field} grants_bypass=none grants_ignored_count=${__GRANTS_IGNORED_COUNT} write_probe_attempted=true write_probe_rc=${write_rc} write_probe_errno=${write_errno} reason=${reason}"
692+
return 0
693+
;;
690694
0)
691695
reason="writable_unexpected"
692696
log_switchover_error "remote_root_fence_verify host=${host} verified_host=${host} probe_host=${probe_host} grants_query_rc=0 ${grants_sha_field} grants_bypass=none grants_ignored_count=${__GRANTS_IGNORED_COUNT} write_probe_attempted=true write_probe_rc=${write_rc} write_probe_errno=${write_errno} reason=${reason}"
@@ -696,21 +700,12 @@ _verify_host_is_fenced() {
696700
return 1
697701
;;
698702
*)
699-
case "${write_errno}" in
700-
1044|1290|1142)
701-
reason="ok_by_local_probe:${write_errno}"
702-
log_switchover_info "remote_root_fence_verify host=${host} verified_host=${host} probe_host=${probe_host} grants_query_rc=0 ${grants_sha_field} grants_bypass=none grants_ignored_count=${__GRANTS_IGNORED_COUNT} write_probe_attempted=true write_probe_rc=${write_rc} write_probe_errno=${write_errno} reason=${reason}"
703-
return 0
704-
;;
705-
*)
706-
reason="probe_account_mismatch"
707-
log_switchover_error "remote_root_fence_verify host=${host} verified_host=${host} probe_host=${probe_host} grants_query_rc=0 ${grants_sha_field} grants_bypass=none grants_ignored_count=${__GRANTS_IGNORED_COUNT} write_probe_attempted=true write_probe_rc=${write_rc} write_probe_errno=${write_errno} reason=${reason}"
708-
log_switchover_error "remote_root_fence_verify host=${host} probe_dump_begin"
709-
log_switchover_error "${__PROBE_OUT}"
710-
log_switchover_error "remote_root_fence_verify host=${host} probe_dump_end"
711-
return 1
712-
;;
713-
esac
703+
reason="probe_account_mismatch"
704+
log_switchover_error "remote_root_fence_verify host=${host} verified_host=${host} probe_host=${probe_host} grants_query_rc=0 ${grants_sha_field} grants_bypass=none grants_ignored_count=${__GRANTS_IGNORED_COUNT} write_probe_attempted=true write_probe_rc=${write_rc} write_probe_errno=${write_errno} reason=${reason}"
705+
log_switchover_error "remote_root_fence_verify host=${host} probe_dump_begin"
706+
log_switchover_error "${__PROBE_OUT}"
707+
log_switchover_error "remote_root_fence_verify host=${host} probe_dump_end"
708+
return 1
714709
;;
715710
esac
716711
;;

0 commit comments

Comments
 (0)