mirror of https://github.com/sysown/proxysql
v3.0_fix_ci-mysqlx-fetch-depth
v3.0
feature/ci-codecov-tap-all-groups-callers
fix/run-tests-backtick-leak
GH-Actions
ci/zstd-level-15
feature/ci-codecov-tap-all-groups-callees
v3.0_partition-fairness
feature/ci-codecov-tap-legacy-g2
fix/jemalloc-page-size-auto-detect
v3.0_partition-gate
fix/ci-cache-restore-path
docs/passthrough-auth-spec
v3.0_fix-stale-pause-until
feature/perf-improvements-test2
v3.0_fix_pgsql-set_statement_test_5788
v3.0_pgsql_options_5801
feature/ci-codecov-unit-tests
fix/kill-proxysqlgenai-build-flag-v2
fix/kill-proxysqlgenai-build-flag
v3.0-260523
feat/passthrough-auth
ci-trigger-tolerate-cleanup-401
fix/5790-mariadb-collation-255
fix/parsersql-1.0.3-pg-set-fixes
issue_5639
pgsql_dns_cache
fix/5755-followup-typecast-digest-fixtures
fix/5708-followup-multiline-for
fix/ci-asan-zombie-checks
v3.0_merge-5776-5784
genai_5534
aws-rds-bg
feature/perf-improvements-rene
v3.0_latency_consistency_improvement
fix/5796-ci-mysqlx-build-cache
fix/remove-skip-all
test/cluster-simulator
fix/galera-g5-cluster-start
integration/v3.0-batch-2026-05-13
fix/ghcr-pull-retry
fix/issue-5620-fast-routing-qr-leak
fix/issue-5684-tsdb-dashboard-same-origin
fix/5770-gcc16-jemalloc
fix/issue-5766-libconfig-escape-passthrough
v3.0_cap_violation_5767
fix/issue-5755-pgsql-digest-truncation
fix/issue-5580-deb-xz-compression
ci-mariadb10-galera-v3.0
ci-mariadb10-galera-GH-Actions
ci/fix-gr-g1-hostgroups
ci/fix-gr-g5-cluster-start
issue-5686-galera-vars
ci-mysql84-gr-g1-g9-GH-Actions
ci-mysql84-gr-g1-g9-v3.0
perf/pull-ci-base-from-ghcr
fix/rename-set-parser-group-and-bench-complexity
fix/split-test-groups
fix/rename-set-parser-workflow
perf/scram-cached-hmac
feature/parsersql-integration
gh-actions/add-set-parser-algorithm-3-g1
issue-5729-stats-projection-abi
fix/4760-lenenc-auth-v3.0
fix/tsan-unit-tests-build-failure
fix/4530-mysql-server-selection-prng
fix/4760-advertise-lenenc-auth-capability
fix/unit-test-asan-double-link
fix-auth-lock-order
v3.0-genai-plugin
feature/mysqlx-stack-consolidated
feature/mysqlx-asan-coverage-docker-isolation
fix/ci-unit-tests-tsan-project-name
feature/mysqlx-tsan-v3-companion
feature/ci-builds-add-tsan-matrix
ci-reduce-polling-interval
feature/mysqlx-tsan-workflow-only
feature/mysqlx-ci-validation-workflows
feature/mysqlx-test-leak-cleanup
feature/mysqlx-behavioural-tap
feature/mysqlx-parity-cleanup
ci-g5-enable-cluster
ci-g5-debug-clean
feature/mysqlx-tls-passthrough
feature/mysqlx-asymmetric-tls
feature/mysqlx-state-machines
feature/build-tsan-plumbing
feature/mysqlx-observability-p0
plugin-chassis
fix/mysqlx-review-findings
fix/test-mysqlx-plugin-load-phase-b
docs/plugin-chassis-abi3-update
fix/mysqlx-runtime-views-separation
v3.0-ci-asan-libprotobuf-dev
ProtocolX
ProtocolX-rebased
v3.0-fix-macos-release-upload
v3.0-test-ci
v3.0-fix-init-release-race
v3.0-cleanup-stale-plans
v3.0-ci-pkg-workflows
fix/macos-build-deps
feat/arm64-on-demand-package-builds
fix/3.0.8-review-items
fix/pgsql-active-tx-on-broken-conn
feat/pgsql-tx-poisoned-recovery
pull-5659
session-track-system-variable
feat/cla-assistant-setup
v3.0-slim-dbdeployer-images
ci/fix-mysql-apt-key-expired-v2
ci/fix-mysql-apt-key-expired
fix/mysqlx-check-connect-poll
fix/mysqlx-stale-row-sync
feature/mysqlx-route-identity
fix/mysqlx-listener-lifecycle
fix/mysqlx-backend-tls-post-auth
chore/retire-dead-mysqlx-worker
v3.0-issue5621
v3.0_new_zstd
fix/lint-groups-json-format
v3.0-dbdeployer-mysql84-gr
lint-tap-tests-static-analysis
fix/groups-json-orphaned-entries
mariadb-rpl-helper
feature/gtid-range-update
fix-fc-parsing
v3.0-pgsql-monitor-reschedule-on-interval-change
v3.0-remove-sqlite-rembed
v3.0-fix-read-only-actions-hostgroup
v3.0-fix-pgsql-ssl-keylog-path
v3.0-fix-flake-test-flush-logs
v3.0-doc-test-readme
v3.0-doc-gh-actions-vocabulary
ci/fix-upload-artifact-eacces
v3.0_pgsql-copy-matcher-5568
ci/fix-cache-prune-permissions
ci/disable-unittests-caller
ci/shrink-test-cache
ci/proxysql-tester-zero-test-safety-net
ci/fix-tap-build-target
ci/gh-actions-readme-pointer
ci/rewire-group-callers-and-docs
ci/fix-mysql84-infradb-label
ci/add-missing-group-reusables
v3.0-lint
fix/ci-workflow-run-chain-pr-sha
fix/postgresql-cluster-sync_2
v3.0_ci_min_proxysql_version_5561
mysqlx-plugin-impl
infra-mysql57-binlog
v3.0-ci0405
feature/pgbouncer-compat
v3.0_pgsql_sslkeylog_5281
v3.0-issue5556
fix/5554-resolution-family-limitation
v3.0-CodeCov0325
v3.0-ci260323
fix/3p-ci-error-handling
feat/ffto-error-recording
v3.0-5493
v3.0-ci260322
v3.0-ci260322_cluster
v3.0-5516
v3.0-5517
copilot/feature-load-restapi-routes-config
copilot/add-ssl-tls-certificate-stats-table
unit-tests-skip-proxysql
private/multi-group-runner
v3.0-5473
v3.0-5499
copilot/extract-server-selection-algorithm
copilot/extract-health-state-logic
copilot/extract-query-rule-matching-logic
copilot/extract-connection-pool-logic
v3.0-set_parser_v3
feature/arm-builds
release-notes-3.0.6-4.0.6-draft
v3.0.6-add-tap-test_stats_table_check
v2.7.3-test260221
v4.0-mcp-stats
copilot/uninstall-amazon-linux-2023
fix-prometheus-labels-test
tap-mcp-client
agent-skill-tap-test
v4.0-tsdb1
v3.0-fix_5256
gh-pages
feature/modern-docs
v4.0
v4.0-fix-vec-search
v4.0_rag_sys_prompt
v4.0-mcp_rules_test
v4.0_rag_mcp
v4.0-tsdb
feature/v4-docs-init
otel_system_libs
otel_clean
v3.0-5288
otel
otel_2
fix/postgresql-cluster-sync
v3.0-releate_notes_scripts_fixes
test_gh-actions_triggers
postgresql-digest-testing-improvement
v3.0_select_auto_commit
v3.0-5218
fix-5221
fix/5186-proxysql-stop-admin-crash
v3.0-4951
add-claude-github-actions-1763877527835
fix-rpm
v3.0-DS_crash
add-claude-github-actions-1763663272333
add-claude-github-actions-1763663091346
add-claude-github-actions-1763663091411
add-claude-github-actions-1763476725261
add-claude-github-actions-1763476725489
v3.0_optimizations_and_stability
v2.7.3.1
v3.0.3-upgrade_json
v3.0.sonar-cli
v3.0.sonar-config
otel-tracepoint
v3.0.2-merge-upgrade_deps-add_new_distros
v3.0.2-upgrade_deps
v3.0.2-add_new_distros
v3.0-add_more_testing_groups
v3.0-upgrade_prometheus-cpp
v3.0-upgrade_json
v3.0-upgrade_sqlite3
v3.0-upgrade_libmicrohttpd
v3.0-upgrade_curl
v3.0-add_centos10_builds
v3.0-add_fedora42_builds
v3.0_PG_PrepStmt
v3.0-sliced_groups
v3.0_auth_negotiation
v2.7
v2.7-fix_run_name
v3.0_4799_4827
v3.0-3687
v2.7-pmm_runtime_servers_metrics
v2.7-4839
v2.7-4841
v2.7-bump_version_to_2.7.3
2.6.6-4841
v2.x_pg_PrepStmtBase_240714
v3.0-4803-4817
v3.0-4803
v2.7-minorBugs
v3.0-privates
v2.x-logging_mem_2
v2.7_fix
v2.7_amd64_build_fix
v2.7-fix_aux_threads_ssl_leaks
v2.7-fix_ssl_params_leak
v2.7-rm_malloc_conf_on_version
v2.7_compression
v2.7-actions-add-3p-tests-parameter
none
v2.7-fix_hang_on_resume
v2.x-logging_mem
v2.7_servers_defaults
v2.7-mariadb_column_metadata_integrity_check
ssl_optimization
v2.7_reg_test_4716_single_semicolon
v2.7_issue_4707_threshold_resultset_size
v2.7_reg_test_4723_query_cache_stores_empty_result
2.7_randomized_cache_ttl
v3.0_fix_multiple_builds
v3.0_servers_defaults
v2.7-update_actions_triggers_v2
v2.7-update_actions_triggers
v2.6
v2.6.x-update_triggers
v2.6-4646
v2.7.1-update_actions
v2.x
v2.6.x-testing-global-multiplexing-disabled
use-wrlock-in-dns-cache-empty
v2.6.x-fix-darwin
v2.x-admin_list_ciphers
v2.x-sqlite3_pass_exts
v2.x-tap_tests_opt_ssl
v2.6.0-update_to_libhttpserver_v0.19
v2.x_router_2ports
v2.6.0-update_to_openssl_v3.1.5
v2.x-2411025
v2.x-profiling_poc1
v2.x_sha2pass_draft2
v2.x-webui_fixes
v2.6.0-more-makefile-fixes
v2.x-20230914_test
v2.x-20230913_test
v2.5.5-branch
v2.5.5-branch_255_patches
v2.x-aurora_autodiscovery-refactor_cluster_mysql_servers-gr_bootstrap_mode_2
v2.x_mysql_connector_j_fixes
v2.6-deprecate_old_clickhouse
v2.x_refactor_cluster_mysql_servers
v2.x-aurora_autodiscovery
v2.x-zd70545
v2.x-aurora_autodiscovery_shunned_promotion
v2.x-tap20230609
v2.x-test20230530
v2.x_sha2pass_draft2-TEST
v2.x-session_track_system_variables_v2
v2.x-status-variables-for-set-stmts
v2.x-enable_session_state_trackers
v2.x-increase-logging-eof_fast_forward-t
v2.x-3863-special-query
v2.x-session_track_system_variables
v2.x_refactor_read_only_action
v2.x_sha2pass_draft1
v2.2.0-sqliteserver_read_only
v2.x-digest_umap_aux-comparison
v2.4.8
v2.x-4105_4114
v2.x-3583-server_closed_conn
v2.x-group_replication_rework-SHUNNED_promotion
v2.1.0-var-global-multiplex
v2.x-CI-hostname-tap-test-fixes
v2.x-limit-version-check
v2.x-fix_deprecate_eof_warning
v2.x-3698
v2.x_tidb_replica_read
v2.x-HostGroups_attributes
v2.0.18.221009
v2.x-ci_reg_test_3273_ssl_con
TAP_test_restapi
v2.x-tap_tests_groups
v2.x-tap_test_sqlite3_server-t
PRS_3888_3903_2
PRS_3888_3903
v2.x_code_refactor_2206
v2.x-multipacket_poc_1
v2.x-impr_hg_latency_obsv
v2.x-gcc-warnings
v2.x-hg_lock_session_id
v2.x-3768
v2.x-3371
v2.x-ci_verifications
v2.x-thread_local_qps_limit
v2.x-parser_table
v2.1.1-3207
v2.x-qps_limits
v2.x-3711
v2.x-3642
v2.x-3674
v2.x-ssl3_warnings
V2
v2.3.2
v2.3.2_3646_3647
v2.x-client_err_limit_conn_timeout
v2.x-keep_multiplexing_regression_fix
v2.3.2-3628
v2.2.2-to-v2.3.0-7
v2.2.2-to-v2.3.0-7_merge
v2.2.2-to-v2.3.0-6
v2.2.2-to-v2.3.0-6_merge
v2.2.2-to-v2.3.0-5
v2.2.2-to-v2.3.0-4
v2.2.2-to-v2.3.0-3
v2.2.2-to-v2.3.0-2
v2.2.2-to-v2.3.0-1
v2.3.1
v2.0.14-70226
v2.3.0
v2.x-client_err_limit-gr_replication_lag_action
v2.2.2
v2.2.1-3603
v2.2.1-centos7-ASAN
v2.2.1
v2.2.1-3601
v2.2.1-3599
v2.2.1-3597
v2.2.1-3595
v2.2.0-restapi_server_exc_log
v2.x-3574
v2.x-3558
v2.2.0-3546-centos-7-gcc-8
v2.x-3549
v2.x-cluster_large_mysql_users
v2.x-cov_ci_verification
v2.0.14-tb1
v2.0.14-tb1-3494
v2.0.14-tb1-3488
v2.0.14-tb1-3117
v2.0.14-tb1-2762
v2.0.14-2762
v1.4.13-arm
v2.1.1-3296
v2.2.0
v2.0.18
v2.1.1
v2.0.18-3342
v2.0.18-3182
v2.1.1-3184
v2.1.0-revert-da7fdfe14
v2.0.18-revert-da7fdfe14
v1.4.13-70160
v2.0.18-3354
v2.0.18-3350
v2.0.14-3339
1.4.13-70160
v2.0.18-3339
v2.1.1-3317
v2.1.1-3319
v2.0.18-3317
v2.1.2-LBalgo
v2.0.18-1574
v2.1.2-hgman
v2.0.17
v2.1.0
v2.0.17-3288
v2.0.17-3276
v2.0.17-3273
v2.0.16
v2.0.16-3267
v2.0.16-3265
v2.0.16-3262
v2.0.16-3261
v2.1.1-3252
v2.1.1-collation
v2.0.16-3252
v2.0.16-collation
v2.1.0-parser
v2.0.16-3219
v2.0.16-3216
v2.0.16-3201
v2.0.16-2330
revert-3191-v2.0.16-3190
v2.0.16-3204
v2.0.16-3177
v2.0.16-2619
v2.0.16-3190
v2.0.16-3187
v2.1.0-70118
v2.0.16-3133
v2.0.16-3133_ci_verification
v2.0.16-3150
v2.0.16-change_user
v2.0.15
v2.0.15_amd64_fix
v2.0.15_arm64_packages
v1.4.14-ssl
v2.0.15_arm64
v2.1.0-2820
v2.0.15-sslbug
v2.0.15-KillTrx
v2.0.14
v2.0.14-ch_build_fix
v2.0.14-focal
v2.0.14-valgrind20200904
v2.1.0-3042
v2.0.14-3035
v2.0.14-3036
v2.0.14-2955
v2.0.14-vars
v2.0.14-3005
v2.0.14-3003
v2.0.14_2970_2979
v2.0.14-NOTSOCK
v2.1.0'
v2.0.14-2958
v1.4.10-zd
v2.0.13
v2.0.13-autocommit_fix
v2.1.0-2892
v2.0.13-2711
v2.0.13-duplicated_variables
v2.0.13-duplicated_variables_for_2.1.0
v2.0.12-deprecate_eof
v2.1.0-1377
v2.1.0-admin_queries
v2.0.12-var-global-multiplex
v2.1.0-var-foreign-key
v2.0.12
v2.0.12-tab-small-log
v2.0.12-var-foreign-key
v2.0.12-var-long-query-time
v2.0.12-galera-shunned
v2.1.0-admin_queries_2
v2.1.0-tap-rm-config
v2.0.12-tap-rm-config-test
v2.1.0-QP_stmt_3
v2.0.11-fix-multi-2-ci
v2.0.11-fix-multi
v2.0.11-266_0-3
2.1.0
v2.0.11
v2.1.0-track-vars
v2.1.0-track-variables
v2.0.11-track-variables
v2.0.11-2526
v2.0.11-tap-tests
v2.0.13-2698-commit1
v2.0.10-galera-pxc-maint-mode
v2.0.11-track-vars
v2.0.10-2647
v2.0.11-track
v2.0.11-track-session-vars
v2.0.9-var-array-review
v2.0.11-stats
v2.0.10
v2.0.10-centos67
v1.4.14.2
1.4.14.2
v1.4.14-show-warnings
v2.0.9
v2.0.9-var-array_2
v2.0.9-var-array
v1.4.16
v2.0.8
val214-changing_charset
v2.0.6
v1.4.16-1922_2
v1.4.13.2
v2.0.4-charset248
v2.0.5
v1.4.10-67841
v2.0.4
v2.0.4-sqlite327
v2.0.3
v2.0.2
v1.4.15
v2.0.1
v1.4.14
v2.0.0
v1.4.14-ping_shun
v1.4.14-1828
v1.4.14-latency_awareness
v1.4.12
v1.4.13-admin_deadlock
v2.0.0-improve_speed
v1.4.13
v1.4.13-autocommit_revert
v1.4.11.2
v1.4.13-ps
v2.0.0_bionic_deb_fix
v2_962
v1.4.12-1640
v1.4.11-names_tz
v1.4.12-1693
master
v1.4.11
v1.4.10
v1.4.6
v1.3.10
jenkins_test
v2.0.0-cachegrind
v1.4.9
v2.0-lab
v149_1511
v149_1382
v1.4.7-f2
v1.4.7-f1
v149_1491
v1.4.5-kub
v1.4.8
v2.0-web2
v1.4.3
v1.4.7
bsd_install_update
v1.4.2
v1.4.1-ch2
v1.4.1
v1.3.9
v1.4.1-ch
v1.3.8
v1.3.8-dev
v1.3.7
v1.3.7-dev
v1.3.6-dev
v1.4.0-clickhouse
v1.4.0
v1.3.6
v1.3.5
v1.3.5-dev
v1.4.0-955
v1.3.4
v1.3.4-dev
v1.3.3
v1.3.3-dev
v1.3.2
v1.3.2-dev
v1.3.2-766
v1.3.0h
v1.3.1-utf8mb4
1.4.0-840
v1.3.1
v1.2.6
v1.3.0
v1.4.0-797
v1.2.5-715
v1.2.5
v1.2.4-lowmem
v1.3.1-dev-mem
v1.2.0
connleak
lab-1.2.0
v1.1.2
T107_add_proxysql_consul_requirements
T89_write_consul_integration_doc
T98_consul_multi_table_config
mongoose
evhttp
SQLiteServer
1.0
3.0.9
3.0.8
3.0.7
3.0.6
3.0.5
3.0.4
3.0.3
3.0.2
2.7.3
2.6.6.1
3.0.1
2.7.2
3.0.0
2.6.6
2.7.1
2.7.0
2.6.5
2.6.4
2.6.3
2.6.2
2.6.1
2.5.5
2.6.0
2.5.4
2.5.3
2.5.2
2.5.1
2.4.8
2.5.0
2.4.7
2.4.6
2.4.5
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.2
2.3.1
2.3.0
2.2.2
2.2.1
2.2.0
2.0.18
2.1.1
2.0.17
2.0.16
2.0.15
2.0.14
2.0.13
2.0.12
2.0.11
2.1.0
2.0.10
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
1.4.16
1.4.15
2.0.1
1.4.14
1.4.13
1.4.12
1.4.11
1.4.10
1.3.10
1.4.9
2.0.0
1.4.8
1.4.7
1.4.6
1.4.4
1.4.3
1.4.2
1.3.9
1.3.8
1.4.1
1.3.7
1.4.0
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0h
1.3.0g
1.3.0f
1.3.0e
1.3.0d
1.3.0c
v1.3.0b
1.4.5
v1.1.0
v1.1.0-rc
v1.1.1-beta
v1.1.1-beta.1
v1.1.1-beta.2
v1.1.1-beta.3
v1.1.1-beta.4
v1.1.1-beta.5
v1.1.1-beta.6
v1.1.2
v1.2.0a
v1.2.0b
v1.2.0c
v1.2.0d
v1.2.0e
v1.2.0f
v1.2.0g
v1.2.0h
v1.2.0i
v1.2.0j
v1.2.0k
v1.2.1
v1.2.2
v1.2.3
v1.2.4
v1.2.4.0923
v1.2.5
v1.2.6
v1.3.0
v1.3.0a
v1.3.0g
v1.3.0h
v1.3.1
v1.3.10
v1.3.2
v1.3.2-1
v1.3.3
v1.3.4
v1.3.5
v1.3.6
v1.3.7
v1.3.8
v1.3.9
v1.3.9-prev.1
v1.4.0
v1.4.1
v1.4.10
v1.4.11
v1.4.12
v1.4.13
v1.4.14
v1.4.15
v1.4.16
v1.4.2
v1.4.3
v1.4.4
v1.4.5
v1.4.6
v1.4.7
v1.4.8
v1.4.9
v2.0.0-beta.1
v2.0.0-rc1
v2.0.0-rc2
v2.0.1
v2.0.10
v2.0.11
v2.0.12
v2.0.13
v2.0.14
v2.0.15
v2.0.16
v2.0.17
v2.0.18
v2.0.2
v2.0.3
v2.0.4
v2.0.5
v2.0.6
v2.0.7
v2.0.8
v2.0.9
v2.1.0
v2.1.1
v2.2.0
v2.2.1
v2.2.2
v2.3.0
v2.3.1
v2.3.2
v2.4.0
v2.4.1
v2.4.2
v2.4.3
v2.4.4
v2.4.5
v2.4.6
v2.4.7
v2.4.8
v2.5.0
v2.5.1
v2.5.2
v2.5.3
v2.5.4
v2.5.5
v2.6.0
v2.6.1
v2.6.2
v2.6.3
v2.6.4
v2.6.5
v2.6.6
v2.7.0
v2.7.1
v2.7.2
v2.7.3
v3.0.0-alpha
v3.0.1
v3.0.2
v3.0.3
v3.0.4
v3.0.5
v3.0.6
v3.0.7
v3.0.8
v3.1.6
v3.1.7
v3.1.8
v4.0.6
v4.0.7
v4.0.8
${ noResults }
56 Commits (e462bb0cb447cb8074ced100e5b87734f9343ff6)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
e462bb0cb4 |
fix: address PR review feedback
Resolves in-scope review items on PR #5651. Items deemed out of scope for this PR (O(N) admin dispatch lookup, per-plugin mutex, worker backpressure, runtime-reload DDL semantics, E2E tests going through ProxySQL rather than directly to MySQL) are tracked elsewhere; items that were already fixed in earlier commits on this branch (Admin_Handler MYSQLX alias vectors, Admin_Bootstrap PROXYSQL40 gating) are acknowledged as stale. Changes: * .github/workflows/CI-mysqlx.yml: add `include/` and `src/proxysql_global.cpp` to both `sparse-checkout` blocks. The plugin Makefile discovers the repo root via `src/proxysql_global.cpp` and includes headers from `include/`; without these, `make` inside `plugins/mysqlx` climbs up to `/` or fails on missing includes. (coderabbit: "Checkout the files required by the plugin Makefile.") * .github/workflows/CI-mysqlx.yml: `fail-on-cache-miss` now depends on `github.event_name == 'workflow_run'`. Strict behavior is retained for the cache-driven pipeline that CI-trigger populates; manual `workflow_dispatch` runs no longer fail when the SHA-specific cache doesn't exist yet. (coderabbit: "Don't make manual runs depend on a pre-existing build cache.") * plugins/mysqlx/Makefile: replace the unbounded `while [ ! -f ./src/proxysql_global.cpp ]; do cd ..; done` with a bounded upward walk (up to 12 levels) that fails fast with a clear error message when the marker file is missing — e.g. on a sparse checkout that omits `src/proxysql_global.cpp`. Build output no longer appears to hang indefinitely. (coderabbit: "Prevent root discovery from hanging on sparse or invalid checkouts.") * doc/PLUGIN_API.md: update startup sequence from the old three-phase (load → init → start) description to the four-phase chassis lifecycle (load → register_schemas → admin materialize → init → start). Document the `register_schemas` descriptor field and the `abi_version` / `PROXYSQL_PLUGIN_ABI_VERSION` contract. Clarify that `stop()` pairs with `init()` (not `start()`) for teardown symmetry. (coderabbit: "Update plugin lifecycle documentation to reflect four-phase model and ABI versioning.") * plugins/mysqlx/include/mysqlx_session.h: default-initialize every field in `MysqlxCredentials`. `bool x_enabled` was indeterminate for a default-constructed instance, which would let a lookup miss produce a value that silently authenticates. In-class initializers give every field a deterministic default. (coderabbit: "Default- initialize credential fields used by auth decisions.") * plugins/mysqlx/src/mysqlx_backend_session.cpp: close `backend_fd_` when `authenticate_backend()` returns false. Previously `connect()` stored the newly-opened fd in `backend_fd_` and returned the auth result; a retry on the same `MysqlxBackendSession` would then overwrite `backend_fd_` and leak the previous socket. (coderabbit: "Close/reset `backend_fd_` when authentication fails.") * lib/Admin_Bootstrap.cpp: `materialize_plugin_tables()` now runs DDL only for the subset of plugin-declared tables that were freshly inserted into `tables_defs_*` (the rest are already materialized). DDL failures are startup-fatal: on `execute()` returning false, log the plugin kind + table name + SQL and `exit(EXIT_FAILURE)`. A partially materialized schema produces opaque runtime errors from the plugin later on, so aborting startup is the right default. (gemini + coderabbit: "Execute DDL only for newly materialized plugin tables" / "add error checking".) Not changed in this commit (deferred / out of scope / stale): * CI-mysqlx E2E tests going through ProxySQL (requires plumbing listener + admin config in the CI workflow). * O(N) admin dispatch scan → hash map. * Descriptor build-id hash for libstdc++ compat detection. * Per-plugin mutex on mutable plugin context. * Worker client-fd enqueue backpressure. * Stale plan-doc feedback on docs/superpowers/plans/*.md. Verification (clean tree): * `unset PROXYSQL*; make cleanall && make debug -j$(nproc) && make build_tap_test_debug -j$(nproc)` -- 0 errors. * `PROXYSQLGENAI=1 make cleanall && PROXYSQLGENAI=1 make debug -j$(nproc) && PROXYSQLGENAI=1 make build_tap_test_debug -j$(nproc)` -- 0 errors. * Plugin unit tests (PROXYSQL40): 48 + 52 + 26 + 46 + 10 = 182 pass. |
1 month ago |
|
|
3ba92815f8 |
fix(plugin-chassis): make chassis fully invisible in v3.x builds
Review feedback identified that the chassis was leaking into the v3.0
stable build via unfenced references in core code:
* Admin_Bootstrap.cpp had `if (auto* m = proxysql_get_plugin_manager())`
and a full materialize_plugin_tables() implementation outside any
PROXYSQL40 fence
* proxysql_admin.h declared materialize_plugin_tables()
* proxysql_glovars.hpp held GloVars.plugin_modules and
proxysql_load_plugin_modules_from_config()
* ProxySQL_GloVars.cpp had three unfenced .clear()/use sites
* ProxySQL_Admin.cpp::dispatch_plugin_admin_command (template + two
instantiations) was unfenced
* src/main.cpp's GloPluginManager, LoadConfiguredPlugins,
InitConfiguredPlugins, StartConfiguredPlugins, StopConfiguredPlugins,
UnloadPlugins teardown, the four-phase orchestration block, and the
proxysql_load_plugin_modules_from_config call were all unfenced
Separately, Admin_Handler.cpp held 16 hardcoded MYSQLX alias vectors
(LOAD_MYSQLX_USERS_FROM_MEMORY, etc.) and a 16-deep if-ladder that
called resolve_admin_alias_to_canonical(). This embedded plugin-specific
knowledge in core code -- core should know nothing about any specific
plugin's commands.
The agreed architecture: v3.0/v3.1 builds have NO plugin loader at all;
the entire plugin chassis (including its public manager surface, its
loader, and its dispatch helpers) only exists under PROXYSQL40. v3.0
core code therefore holds zero plugin-related code paths.
Changes:
* include/ProxySQL_Plugin.h, include/ProxySQL_PluginManager.h,
lib/ProxySQL_PluginManager.cpp: wrap entire file body in
`#ifdef PROXYSQL40 ... #endif`. Including the header from a v3.x
translation unit yields nothing; the .cpp compiles to an empty object
file. Removed redundant inner PROXYSQL40 fences inside the now-empty
v3.x body of Plugin.h (kept the few that are inside the file-wide
outer for clarity). PROXYSQL_PLUGIN_ABI_VERSION is now unconditionally
2 (the macro is no longer reachable from a v3.x compile, so the
PROXYSQL40-vs-1 split is moot).
* include/proxysql_glovars.hpp, lib/ProxySQL_GloVars.cpp: gate
GloVars.plugin_modules field, all .clear() sites, the
proxysql_load_plugin_modules_from_config declaration + definition.
* include/proxysql_admin.h: gate materialize_plugin_tables and
dispatch_plugin_admin_command<S> declarations.
* lib/Admin_Bootstrap.cpp: gate `#include "ProxySQL_PluginManager.h"`,
the `if (auto* m = proxysql_get_plugin_manager())` merge block, and
the materialize_plugin_tables definition.
* lib/Admin_Handler.cpp: delete the 16 LOAD_/SAVE_MYSQLX_* const
std::vector<std::string> declarations entirely. Delete the helper
resolve_admin_alias_to_canonical(). Delete the 16-deep if-ladder
+ the !PROXYSQL40 fallback dispatch branch. The remaining plugin
dispatch is one generic call to
proxysql_resolve_configured_plugin_admin_alias() inside an
#ifdef PROXYSQL40 block; v3.x compiles it out entirely. Core now
holds no plugin-specific knowledge of any kind.
* lib/ProxySQL_Admin.cpp: gate dispatch_plugin_admin_command template
body + both explicit instantiations.
* src/main.cpp: gate `#include "ProxySQL_PluginManager.h"`,
GloPluginManager declaration, all four wrapper functions
(LoadConfiguredPlugins / InitConfiguredPlugins /
StartConfiguredPlugins / StopConfiguredPlugins), the
StopConfiguredPlugins call inside UnloadPlugins, the four-phase
orchestration in ProxySQL_Main_init_phase2___not_started, the
GloVars.plugin_modules.clear() and the
proxysql_load_plugin_modules_from_config call in
ProxySQL_Main_process_global_variables. v3.x builds reduce that
whole block to a single ProxySQL_Main_init_Admin_module call.
* plugins/mysqlx/src/mysqlx_plugin.cpp,
plugins/mysqlx/src/mysqlx_admin_schema.cpp: drop the !PROXYSQL40
fallback paths. The plugin only loads under PROXYSQL40 now (no
loader exists in v3.x), so the legacy combined-init code path and
the 16 fallback register_command() calls were dead code. The
descriptor unconditionally wires register_schemas; mysqlx_init holds
only context setup.
* Makefile (top-level): the four build_src_* recipes that recurse into
plugins/mysqlx are wrapped in `$(if $(filter 1,$(PROXYSQL40)),...)`.
v3.x builds emit "[skip] mysqlx plugin (PROXYSQL40 not set)" instead
of building the .so. Clean targets stay unconditional.
* test/tap/tests/unit/mysqlx_admin_alias_resolution_unit-t.cpp:
delete the test (it covered resolve_admin_alias_to_canonical, which
is itself deleted). Remove from unit Makefile UNIT_TESTS list.
Verification:
* v3.0 stable build (`make`, no flags):
- Produces 147 MB src/proxysql binary
- `nm src/proxysql | grep -cE 'invoke_register_schemas_phase|GloPluginManager|materialize_plugin_tables'` -> 0
- mysqlx plugin .so is correctly skipped: "[skip] mysqlx plugin (PROXYSQL40 not set)"
* PROXYSQLGENAI=1 build (cascades PROXYSQL40/31/FFTO/TSDB):
- Produces 200 MB src/proxysql binary with chassis symbols
- mysqlx plugin .so built (9.2 MB), contains mysqlx_register_schemas
* All 5 plugin unit tests pass under PROXYSQL40:
plugin_config_unit-t 48/48
plugin_dispatch_unit-t 52/52
plugin_lifecycle_unit-t 26/26
plugin_query_hook_unit-t 46/46
plugin_prometheus_unit-t 10/10
|
1 month ago |
|
|
ab9d5a1036 |
fix(plugin-chassis): address deep-review findings
Follow-up to
|
1 month ago |
|
|
cd48c5613e |
feat(plugin-chassis): gate chassis ABI additions behind PROXYSQL40
The four-phase plugin lifecycle (Step 2.2), pre-execution query-hook ABI
(Step 2.1), shared Prometheus registry access (Step 2.3), and generic
admin-command alias dispatch (Step 2.5) introduce new plugin ABI surface
area — a new descriptor field (register_schemas), new services-struct
entries (register_query_hook, get_prometheus_registry,
register_command_alias), new public manager methods
(invoke_register_schemas_phase, dispatch_query_hook, etc.), and a new
startup ordering in main().
These changes should not appear in the v3.x stable/innovative tiers.
Wrap every chassis-only declaration, definition, and dispatch path in
`#ifdef PROXYSQL40` so the v3.0/v3.1 builds retain the pre-chassis
behavior: a single init()-only descriptor layout, two-phase load+init
lifecycle, and the hardcoded MYSQLX alias ladder in Admin_Handler.cpp.
Changes:
* Top-level Makefile: introduce PROXYSQL40 as a distinct tier above
PROXYSQL31. Cascade rule: PROXYSQLGENAI=1 implies PROXYSQL40=1
implies PROXYSQL31=1. Bump major version number on PROXYSQL40=1
(previously tied to PROXYSQLGENAI). Export PROXYSQL40 for recursive
submakes.
* lib/Makefile, src/Makefile: add -DPROXYSQL40 via $(PSQL40) so the
compile commands match the top-level tier selection.
* include/ProxySQL_Plugin.h: gate the register_schemas descriptor
field, query-hook types/enums/typedefs, the alias-registration
callback, and the trailing services-struct fields
(register_query_hook, get_prometheus_registry,
register_command_alias). The pre-chassis descriptor remains six
fields (name, abi_version, init, start, stop, status_json) so
plugins built against v3.x headers still link and load.
* include/ProxySQL_PluginManager.h: gate the chassis-exclusive public
methods and private members (schemas_registered, aliases,
services_phase_b_, query hook pointers). Provide two declarations
of proxysql_load_configured_plugins — the four-phase variant (paired
with proxysql_init_configured_plugins) under PROXYSQL40, the legacy
single-call variant otherwise.
* lib/ProxySQL_PluginManager.cpp: gate every method that belongs to
the chassis (invoke_register_schemas_phase, register_command_alias,
resolve_alias_to_canonical, register_query_hook, has_query_hook,
dispatch_query_hook), plus the services_phase_b_ initialization
(nullptr DB handle stubs), the proxysql_dispatch_configured_plugin_
query_hook entry point, and the alternate four-phase body of
proxysql_load_configured_plugins / proxysql_init_configured_plugins.
The legacy two-phase loader is restored under !PROXYSQL40.
get_admindb_service / get_configdb_service / get_statsdb_service
stay ungated because they back the unconditional services_ member.
* lib/Admin_Handler.cpp: gate the `#include \"ProxySQL_PluginManager.h\"`
and restore under !PROXYSQL40 the 16 hardcoded MYSQLX alias vectors
plus the 16-deep if-ladder in admin_handler_command_*(). Under
PROXYSQL40 the ladder is replaced by a single call to
proxysql_resolve_configured_plugin_admin_alias(), which is
plugin-agnostic.
* src/main.cpp: gate InitConfiguredPlugins and branch the startup
sequence in ProxySQL_Main_init_phase2___not_started:
- PROXYSQL40: LoadConfiguredPlugins (Phase A+B) -> admin init (C) ->
materialize_plugin_tables -> InitConfiguredPlugins (D) ->
StartConfiguredPlugins (E).
- !PROXYSQL40: admin init -> LoadConfiguredPlugins (combined
load+init) -> materialize_plugin_tables -> StartConfiguredPlugins,
matching the pre-chassis ordering.
* plugins/mysqlx/src/mysqlx_plugin.cpp: split init under PROXYSQL40
into mysqlx_register_schemas (schema + commands) and a minimal
mysqlx_init (context only). Under !PROXYSQL40 the original single
mysqlx_init remains. Descriptor conditionally wires
register_schemas.
* plugins/mysqlx/src/mysqlx_admin_schema.cpp: under PROXYSQL40 use
the reg() helper to register canonical+aliases via the new ABI;
under !PROXYSQL40 fall back to 16 direct register_command() calls
(aliases handled by Admin_Handler's hardcoded ladder).
* test/tap/test_helpers/fake_plugin.cpp: gate fake_query_hook,
fake_register_schemas, fake_descriptor_with_phase_b, the
REGISTER_QUERY_HOOK block in fake_init, and the ENABLE_PHASE_B
descriptor selection. The pre-chassis descriptor-returning stub is
the sole return path under !PROXYSQL40.
* test/tap/tests/unit/Makefile: autodetect PROXYSQL40 via
invoke_register_schemas_phase (the chassis-exclusive symbol) in the
library archive; add -DPROXYSQL40 to fake_plugin .so compilation so
the descriptor layout matches the loader's expectations; append the
three chassis-only tests (plugin_lifecycle, plugin_prometheus,
plugin_query_hook) to UNIT_TESTS only when PROXYSQL40=1.
* test/tap/tests/unit/plugin_config_unit-t.cpp,
test/tap/tests/unit/plugin_dispatch_unit-t.cpp: compile-time-gate
the chassis-only subtests, adjust plan() counts per mode
(48/50 with PROXYSQL40, 47/32 without), and provide a
proxysql_init_configured_plugins_compat() helper that is a no-op
returning true under !PROXYSQL40 so shared test helpers work in
both modes.
Verification — all plugin unit tests pass in both modes:
PROXYSQL40=1 build (chassis enabled):
plugin_config_unit-t: 48/48
plugin_dispatch_unit-t: 50/50
plugin_lifecycle_unit-t: 14/14
plugin_query_hook_unit-t: 41/41
PROXYSQL40=0 build (v3.x behavior):
plugin_config_unit-t: 47/47
plugin_dispatch_unit-t: 32/32
(plugin_lifecycle, plugin_query_hook not built)
|
1 month ago |
|
|
51535aaeca |
feat(plugin-abi): Step 2.5 — generic admin-command alias dispatch
Replaces the hardcoded 16-deep MYSQLX alias ladder in
lib/Admin_Handler.cpp with a table-driven lookup against
ProxySQL_PluginManager::registered_commands. New plugins register their
own canonical + alias spellings and admin dispatches them without any
core change.
ABI (include/ProxySQL_Plugin.h):
* New callback typedef proxysql_plugin_register_command_alias_cb.
* Appended register_command_alias field to ProxySQL_PluginServices.
Additive, backward-compatible; plugins built against the previous
layout don't read past the older tail (same tail-extension rule
used in Step 2.2 for register_schemas).
Manager (lib/ProxySQL_PluginManager.cpp):
* registered_command_t grows an `aliases` vector of normalized
alternate spellings.
* ProxySQL_PluginManager::register_command_alias(canonical, alias)
— rejects collision with any other command's canonical or alias;
idempotent for duplicate (canonical, alias) pairs.
* ProxySQL_PluginManager::resolve_alias_to_canonical(sql) — returns
the canonical c_str() if the normalized `sql` matches a registered
command's canonical or any of its aliases; nullptr otherwise.
* dispatch_admin_command extended to match aliases too, and now
passes the canonical form (not the incoming spelling) to the
plugin callback — plugins match their own canonical strings only.
* register_command_alias_service trampoline wires the callback into
the active manager during init. Phase-B services expose this as
well, consistent with register_command availability.
Core dispatch (lib/Admin_Handler.cpp):
* Deleted the 16 hardcoded MYSQLX alias vectors (LOAD/SAVE MYSQLX
{USERS,ROUTES,BACKEND ENDPOINTS,VARIABLES} {FROM MEMORY,TO DISK},
...) — ~65 lines.
* Replaced the 16-deep if-ladder of resolve_admin_alias_to_canonical
calls with a single proxysql_resolve_configured_plugin_admin_alias
call. No MYSQLX-specific code left in Admin_Handler; the
dispatcher is now plugin-agnostic.
mysqlx plugin (plugins/mysqlx/src/mysqlx_admin_schema.cpp):
* mysqlx_register_admin_schema now calls register_command_alias for
every user-friendly alternate spelling that previously lived in
Admin_Handler's hardcoded vectors:
LOAD MYSQLX * TO RUNTIME: "FROM MEMORY", "FROM MEM", "TO RUN"
SAVE MYSQLX * TO MEMORY: "TO MEM", "FROM RUNTIME", "FROM RUN"
(disk commands: no aliases, as before)
Tests:
* plugin_dispatch_unit-t gets one new case covering the spec's
requirement — two plugins registering non-conflicting commands,
each with its own alias set. Asserts: canonical dispatch routes
correctly; alias dispatch routes to the owning plugin's callback;
resolve_alias_to_canonical returns the canonical regardless of
which spelling was used to probe it; whitespace/case normalization;
cross-plugin alias shadowing is rejected; duplicate (canonical,
alias) registration is idempotent. plan(32) -> plan(50).
No behavior change for users: the exact same set of LOAD/SAVE MYSQLX
spellings continues to work; the routing now goes through the plugin
manager rather than through Admin_Handler-embedded tables. A future
plugin that wants to add admin commands can do so entirely from its
own source — no core touch required.
|
1 month ago |
|
|
f13463d334 |
feat(plugin-abi): Step 2.2 — four-phase plugin lifecycle
Adds the register_schemas() callback to the plugin descriptor and
wires the loader + main.cpp so that a plugin's schema is declared
BEFORE the admin module bootstraps, and the plugin's init() runs
AFTER the schema has been materialized.
Phase sequence (previously two-phase: load+init):
A. load() — dlopen each .so, read the descriptor.
B. register_schemas() — NEW, optional; plugin calls services->register_table
with its admin/config/stats table defs. Services
hand has register_table live but all DB-handle
getters stubbed to nullptr.
C. ProxySQL_Main_init_Admin_module + GloAdmin->materialize_plugin_tables
— admin bootstrap drains the pending-tables list
via merge_plugin_tables (first-boot == reload).
D. init() — plugin's startup logic with full services
(live DB handles pointing at a schema that
already contains its own tables).
E. start() — plugin launches threads / accept loops.
ABI (include/ProxySQL_Plugin.h):
* New callback typedef proxysql_plugin_register_schemas_cb.
* New descriptor field register_schemas — appended at the end of
ProxySQL_PluginDescriptor so existing 6-field initializers leave
it null (aggregate init value-initializes the trailing slot).
Plugins that left register_schemas null keep the pre-existing
two-phase behavior: Phase B is skipped and their init() is
responsible for both schema registration and startup work.
* Phase-by-phase services availability matrix documented next to
ProxySQL_PluginServices.
Manager (lib/ProxySQL_PluginManager.cpp):
* invoke_register_schemas_phase(err) — public method that runs
Phase B for every plugin whose descriptor sets the callback.
Uses a "services_phase_b_" variant where DB-handle getters are
nullptr stubs; register_query_hook returns false with a warning
(hooks cannot register this early).
* proxysql_load_configured_plugins() — now stops at Phase B. On
success, installs the built manager as the active one so that
ProxySQL_Admin::materialize_plugin_tables (which reads from the
active manager's pending-tables list) sees the registered
tables.
* proxysql_init_configured_plugins() — new entry point, calls
init_all() for Phase D. Separated from load so admin bootstrap
can run between the two.
Main (src/main.cpp):
* Reorder in ProxySQL_Main_init_phase2___not_started:
LoadConfiguredPlugins(); // Phase A + B
ProxySQL_Main_init_Admin_module(...); // Phase C
GloAdmin->materialize_plugin_tables(); // Phase C (materialize)
InitConfiguredPlugins(); // Phase D — NEW
StartConfiguredPlugins(); // Phase E
* Error messages updated to name the phase that failed.
mysqlx plugin:
* mysqlx_init split into:
- mysqlx_register_schemas() — calls mysqlx_register_admin_schema
(pure services->register_table use, no DB access);
- mysqlx_init() — wires the plugin context (services, config
store, started flag) and returns true.
* Descriptor wires the new callback, exercising the full four-
phase path end-to-end.
Tests:
* plugin_lifecycle_unit-t (new) — four cases: both callbacks fire in
order; register_schemas-null skips Phase B; Phase-B DB handles
return nullptr; Phase-B failure aborts init.
* plugin_config_unit-t, plugin_dispatch_unit-t, plugin_query_hook_unit-t
— existing tests updated to also call proxysql_init_configured_plugins
after proxysql_load_configured_plugins where init side-effects are
asserted. test_init_registration_failure_aborts_load reworked: the
fake plugin's invalid-table registration happens in init (not
register_schemas), so load now succeeds and the failure surfaces at
init time.
* test_mysqlx_admin_tables / test_mysqlx_listener_smoke — add an
explicit invoke_register_schemas_phase() call before init_all()
so the mysqlx plugin's schema gets registered under its new
split.
No behavior change for plugins that didn't opt into Phase B: they
still see the same services_ layout and the same {load, init, start,
stop} ordering. Opt-in plugins gain DB access from init() against a
schema that already contains their tables, eliminating the chicken-
and-egg that required ProtocolX's
|
1 month ago |
|
|
3d107c3bed |
chore: commit pre-existing plugin manager improvements
Improvements left uncommitted at the end of Step 0: - atomic g_active_plugin_manager pointer - reject plugin descriptors with null/empty name - assert single-threaded init phase - debug-log dispatched plugin commands - propagate mysqlx_register_admin_schema failure into init - additional plugin manager unit tests (init/start/stop fail, double load) - updated ABI doc/comments for table copy semantics, command context lifetime, services availability, and status_json storage |
1 month ago |
|
|
923cbfeadc |
fix(mysqlx): resolve critical authentication, TLS, and data integrity bugs
- Wire credential_lookup to sessions via config store so frontend auth verification actually runs (was silently bypassed for all users) - Use backend_password (cleartext) instead of password_hash (double-SHA1) for backend MYSQL41 scramble computation - Replace cumulative BIO counter comparison with BIO_ctrl_pending() to fix permanent POLLOUT busy-loop with TLS connections - Add poll(POLLOUT) before getsockopt(SO_ERROR) in check_connect() to correctly detect non-blocking connect completion on Linux - Wrap DELETE+INSERT with BEGIN/COMMIT in sync_disk_to_memory and copy_to_runtime to prevent data loss on crash |
2 months ago |
|
|
04f09d6535 |
fix(mysqlx): address SonarCloud quality gate failures
- Replace void* thread_ptr_ with typed Mysqlx_Thread* for type safety - Use RAII (unique_ptr) for SQLite3 result and error cleanup in plugin - Extract handle_auth_mysql41/handle_auth_plain from handler_auth_start to reduce cognitive complexity (37 -> ~10 per method) - Extract step_auth sub-states into individual methods to reduce cognitive complexity in mysqlx_connection.cpp (55 -> ~8 per method) - Add forward_frame_to_client helper to eliminate repeated frame forwarding code - Replace hardcoded password strings in credential verify test with named test constants - Add NOSONAR annotations for const_cast (required by SQLite3DB API) and SSL_VERIFY_NONE (test-only self-signed certs) - Fix Makefile whitespace issue with mysqlx unit test entries |
2 months ago |
|
|
04c0303ee9 |
fix(mysqlx): address critical code review feedback from PR #5593
- PluginManager: don't mark plugin stopped when stop() fails - PluginManager: add mutex to proxysql_get_plugin_manager() access - PluginManager: reject duplicate plugin paths in load() - mysqlx_thread: add listener_mutex_ for listener_fds_ synchronization - mysqlx_config_store: return tls_mode by value, not by reference - Makefile: propagate PROXYSQLGENAI/31/FFTO/TSDB flags to mysqlx builds |
2 months ago |
|
|
7957720326 |
feat(mysqlx): auto-load persisted config from disk on plugin startup
Add sync_disk_to_memory() and copy_to_runtime() to mysqlx_start() so the MYSQLX plugin automatically restores its configuration from the persisted config DB when ProxySQL restarts. Startup sequence in mysqlx_start(): 1. sync_disk_to_memory() — copies rows from disk.mysqlx_* tables (config DB, ATTACHed as 'disk') into the admin DB's mysqlx_* tables, but only if the disk tables have data. 2. copy_to_runtime() — copies admin DB mysqlx_* tables into runtime_mysqlx_* tables, mirroring what LOAD MYSQLX * TO RUNTIME does manually. 3. load_from_runtime() — existing code reads runtime tables into the in-memory config store. This ensures routes, users, backend endpoints, and variables survive ProxySQL restarts without requiring manual LOAD commands after reboot. Note: dynamic listener addition (starting X Protocol listeners after the thread event loop is running) is not yet implemented. The listener is only created during start() based on the loaded config. A future change will add hot-reload capability for routes. |
2 months ago |
|
|
976d7c2310 |
feat(mysqlx): add LOAD/SAVE MYSQLX * TO/FROM DISK commands
ProxySQL uses a three-tier configuration model: DISK ↔ MEMORY ↔ RUNTIME. The MYSQLX plugin previously only supported the MEMORY ↔ RUNTIME tier (LOAD MYSQLX USERS TO RUNTIME, SAVE MYSQLX USERS TO MEMORY, etc.). Configuration was lost on restart because there was no way to persist it to disk. Add the missing DISK ↔ MEMORY tier commands for all four MYSQLX object types: LOAD MYSQLX USERS FROM DISK (disk → memory) SAVE MYSQLX USERS TO DISK (memory → disk) LOAD MYSQLX ROUTES FROM DISK SAVE MYSQLX ROUTES TO DISK LOAD MYSQLX BACKEND ENDPOINTS FROM DISK SAVE MYSQLX BACKEND ENDPOINTS TO DISK LOAD MYSQLX VARIABLES FROM DISK SAVE MYSQLX VARIABLES TO DISK Implementation: - Add disk_to_memory() and memory_to_disk() helpers in mysqlx_admin_schema.cpp that use qualified SQLite table names (main.<table> and disk.<table>) to copy between the in-memory admin database and the on-disk config database - Register 8 new command handlers in mysqlx_register_admin_schema() - Add alias vectors for all disk commands in Admin_Handler.cpp - Add resolve_admin_alias_to_canonical() calls for disk commands in the MYSQLX dispatch block Tested: Insert → SAVE TO DISK → DELETE → LOAD FROM DISK round-trip confirms data persistence works for all four object types. |
2 months ago |
|
|
8c9b7f9d4b |
fix(mysqlx): add missing include paths to plugin Makefile
Add prometheus-cpp, libconfig, jemalloc, mariadb, and re2 include paths to the plugin build. Without these, mysqlx_thread.cpp fails to compile because it includes proxysql_structs.h which pulls in the full ProxySQL header chain. This was masked previously because the plugin was only built during full releases. Integration testing now requires building the .so independently. |
2 months ago |
|
|
30dc111b1d |
feat(mysqlx): add TLS passthrough mode for raw TLS forwarding
Adds MysqlxTlsMode enum and passthrough mode support: - TLS_OFF: No TLS (default, existing behavior) - TLS_TERMINATE: ProxySQL terminates TLS, decrypts, re-encrypts to backend (existing behavior when TLS is negotiated) - TLS_PASSTHROUGH: Raw encrypted bytes forwarded between client and backend without TLS termination Passthrough behavior: - handler_tls_accept_init(): skips SSL init and handshake entirely, returns to CONNECTING_CLIENT state immediately - handler_connecting_server(): skips backend TLS setup when in passthrough mode (backend_tls_required_ is not set) - X Protocol frames are still parsed at the framing layer since the proxy needs to route and multiplex connections Use cases for passthrough mode: - TLS terminated at an external load balancer - ProxySQL should not have access to TLS certificates - Compliance requirements that forbid TLS inspection set_tls_mode() / get_tls_mode() accessors on MysqlxSession allow runtime configuration of the TLS mode per session. |
2 months ago |
|
|
afffad0356 |
feat(mysqlx): implement backend TLS via CapabilitiesSet negotiation
Adds TLS support for backend X Protocol connections. When the client session is encrypted, the backend connection also negotiates TLS with the MySQL X Protocol server. Backend auth state machine changes: - New BACKEND_AUTH_TLS_HANDSHAKE state between CapSet and AuthStart - CapabilitiesSet now includes tls=true when backend_tls_required_ and an SSL_CTX is available - After CapSet Ok, if TLS required: init_ssl_connect() → handshake → send_authenticate_start() → continue normal auth - send_authenticate_start() extracted as a helper method to avoid goto-based flow control MysqlxConnection new members: - backend_tls_required_ flag (set by session when client is on TLS) - backend_ssl_ctx_ pointer (shared global SSL_CTX) - set_backend_tls_required() / is_backend_tls_required() accessors - set_ssl_ctx() to provide the SSL context TLS handshake in step_auth(): - BACKEND_AUTH_TLS_HANDSHAKE state calls backend_ds_.read_from_net() to feed encrypted bytes into the BIO pair - do_ssl_handshake() performs SSL_connect via memory BIOs - flush_ssl_write_buf() sends pending encrypted output - On failure: ssl_handshake_failed() check, returns BACKEND_AUTH_ERROR Session wiring in handler_connecting_server(): - When client_ds_.is_encrypted(), sets backend_tls_required_=true and provides SSL_CTX from Mysqlx_Thread - Backend auth failure detection distinguishes TLS failures (error 3152) from authentication failures (error 1045) |
2 months ago |
|
|
da75e13841 |
feat(mysqlx): per-message response state machines for terminal frame detection
Replace the single is_terminal_server_frame() catch-all with per-message-type response tracking. Each client message type now has its own terminal frame set, matching MySQL Router's approach. New MysqlxResponseState enum: - RESP_IDLE: no pending response - RESP_WAITING_STMT_EXECUTE: SQL_STMT_EXECUTE_OK, ERROR, FETCH_DONE - RESP_WAITING_CRUD: OK, ERROR, FETCH_DONE, FETCH_SUSPENDED - RESP_WAITING_PREPARE: OK, ERROR - RESP_WAITING_CURSOR: FETCH_DONE, FETCH_SUSPENDED, ERROR - RESP_WAITING_EXPECT: OK, ERROR - RESP_WAITING_SESS_RESET: OK, ERROR Changes: - dispatch_client_message() sets response_state_ before forward_to_backend() based on message type - handler_waiting_server_msg() uses is_terminal_for_state() instead of is_terminal_server_frame() for terminal detection - is_terminal_for_state() checks the response state to determine which frames are terminal - response_state_ resets to RESP_IDLE when terminal frame received - Generic fallback preserved via is_terminal_server_frame_generic() for unknown response states This is more robust than the single catch-all list and correctly handles cases where OK is terminal for Prepare but not for StmtExecute (which needs SQL_STMT_EXECUTE_OK). |
2 months ago |
|
|
d50e48a971 |
feat(mysqlx): add descriptive TLS error messages with failure detection
Adds SSL handshake failure detection and descriptive error messages
for both client-side and backend TLS failures.
Changes to MysqlxDataStream:
- Added ssl_failed_ flag to distinguish WANT_IO (in progress) from
actual SSL failure
- ssl_handshake_failed() accessor for session to check failure state
- ssl_failed_ is set to true in do_ssl_handshake() when
get_ssl_status() returns MYSQLX_SSL_FAIL
- ssl_failed_ is initialized to false in constructor, init_ssl(),
and init_ssl_connect()
Changes to MysqlxSession handler_tls_accept_init():
- After do_ssl_handshake() returns false, checks ssl_handshake_failed()
- On failure: sends error 3151 ("TLS handshake failed") to client
with OpenSSL error details retrieved via ERR_get_error()/
ERR_error_string_n(), then closes session
- On WANT_IO: continues waiting (existing behavior)
- Error 3150: TLS not configured on server (unchanged)
- Error 3151: TLS handshake failed (new)
- Error 3152: Reserved for backend TLS failures (Task 3)
|
2 months ago |
|
|
dc35119813 |
feat(mysqlx): implement Session Reset passthrough with response tracking
SESS_RESET is now properly forwarded to the backend with dedicated
response tracking via the new X_SESSION_RESET_WAITING state:
1. Client sends SESS_RESET -> forward_to_backend() sends to server
2. Session transitions to X_SESSION_RESET_WAITING
3. handler_session_reset_waiting() reads backend response:
- On NOTICE: forward to client immediately, keep waiting
- On OK: clear prepared statement tracking, clear transaction
flag, return backend to pool, resume WAITING_CLIENT_XMSG
- On ERROR: forward error to client, return backend to pool,
resume WAITING_CLIENT_XMSG
- On backend disconnect: return to WAITING_CLIENT_XMSG
This properly resets session state on both sides, clearing
prepared statement and transaction flags so the backend
connection can be safely reused from the pool.
Previously, SESS_RESET was forwarded but the response was not
tracked, potentially leaving the session in an inconsistent state.
|
2 months ago |
|
|
8fcf8b5808 |
fix(mysqlx): use correct X Protocol error code for compression rejection
Replace generic error code 5001 with the standard MySQL X Protocol error code ER_X_CAPABILITY_COMPRESSION_INVALID_ALGORITHM (5008) when rejecting compression capability requests. Error 5008 is the standard MySQL X Protocol error for invalid compression algorithm negotiation, matching the error code used by MySQL Router and the MySQL X Plugin. |
2 months ago |
|
|
85b8d8678c |
feat(mysqlx): explicit NOTICE frame forwarding awareness
Server NOTICE frames are now explicitly handled in the response forwarding loop in handler_waiting_server_msg(). Notices are forwarded immediately to the client with a continue statement, skipping terminal frame detection. Previously, NOTICE frames fell through to the is_terminal_server_frame() check which correctly returned false for them. The explicit handling makes the intent clear and ensures notices are never accidentally included in terminal frame logic: - Warnings, session state changes, and other server-side notifications are always delivered to the client - NOTICE forwarding does not affect response state or terminal detection - NOTICE frames are still forwarded even while waiting for a terminal response (e.g., during a long-running query result set) |
2 months ago |
|
|
437072cf28 |
feat(mysqlx): add backend connect timeout with configurable threshold
Adds a configurable connect timeout (default 10 seconds) for backend X Protocol connections. If the TCP connection does not complete within the timeout, the connection attempt fails with error 2003. Changes to MysqlxConnection: - Added connect_timeout_ms_ (default 10000ms) and connect_start_time_ private members - start_connect() records connect_start_time_ using steady_clock - check_connect() measures elapsed time since start_connect() and returns -1 if timeout exceeded, setting state to ERROR_STATE - Added set_connect_timeout()/get_connect_timeout() accessors Changes to MysqlxSession: - handler_connecting_server() sets connect timeout to 10s before calling start_connect() on new backend connections The timeout is checked on every check_connect() invocation from the event loop, ensuring non-blocking timeout detection without additional timers. |
2 months ago |
|
|
e86cfe237f |
feat(mysqlx): implement client-side TLS negotiation via CapabilitiesSet
Wires TLS into the session state machine following ProxySQL MySQL protocol pattern. When a client sends CapabilitiesSet with tls=true capability, the session initiates SSL_accept on the client data stream. Changes to Mysqlx_Thread: - Added get_ssl_ctx() that returns GloVars.get_SSL_ctx() - Updated rebuild_poll_set() to check has_ssl_pending_write() for POLLOUT on both client and backend data streams Changes to MysqlxSession::handler_capabilities_set(): - Parses CapabilitiesSet protobuf to detect tls capability - If TLS requested and SSL_CTX available: sends Ok, transitions to X_TLS_ACCEPT_INIT state - If SSL_CTX not configured: sends error 3150 and closes session - Without TLS: existing behavior unchanged Changes to MysqlxSession::handler_tls_accept_init(): - Replaced stub with real implementation - Gets SSL_CTX from Mysqlx_Thread - Calls client_ds_.init_ssl(ctx) to create per-session SSL object - Calls do_ssl_handshake() on each handler invocation - When handshake completes, transitions to CONNECTING_CLIENT Changes to MysqlxSession::send_capabilities(): - Advertises tls capability (V_BOOL true) when SSL_CTX is configured - Existing auth capability advertisement unchanged All 10 test suites pass with no regressions. |
2 months ago |
|
|
0b555d3899 |
feat(mysqlx): add TLS infrastructure to MysqlxDataStream
Adds SSL support following ProxySQL BIO-based pattern used in MySQL_Data_Stream and PgSQL_Data_Stream. New members in MysqlxDataStream: - ssl_: per-session SSL object from shared SSL_CTX - rbio_ssl_/wbio_ssl_: memory BIO pair for encrypted I/O - ssl_write_buf_/ssl_write_offset_: pending encrypted output - ssl_handshake_done_: handshake completion tracking New public methods: - init_ssl(SSL_CTX*): creates SSL object with SSL_set_accept_state - init_ssl_connect(SSL_CTX*): creates SSL object with SSL_set_connect_state - do_ssl_handshake(): performs TLS handshake, drains app data on completion - flush_ssl_write_buf(): sends pending encrypted bytes to network - has_ssl_pending_write(): checks BIO pending counts for poll integration - get_ssl()/get_rbio_ssl(): accessors for testing Modified read_from_net(): - SSL handshake phase: recv→BIO_write→do_ssl_handshake - Encrypted phase: recv→BIO_write→SSL_read loop→feed_bytes - Non-TLS path unchanged when ssl_ is null Modified write_to_net(): - SSL handshake phase: flush pending handshake data only - Encrypted phase: SSL_write→BIO_read→flush_ssl_write_buf - write_raw() also uses SSL_write when encrypted - Non-TLS path unchanged when ssl_ is null do_ssl_handshake() drains application data from the SSL object immediately after handshake completes, handling the case where the client sends data in the same TLS record as the Finished message. mysqlx_ssl_status enum maps OpenSSL errors: - MYSQLX_SSL_OK (SSL_ERROR_NONE) - MYSQLX_SSL_WANT_IO (SSL_ERROR_WANT_READ/WRITE) - MYSQLX_SSL_FAIL (all other errors) Tests: 18 assertions covering: - init_ssl with null ctx (no crash, no-op) - Non-TLS read/write unchanged - Full SSL handshake between client and server - Encrypted X Protocol frame read/write - has_ssl_pending_write before SSL init - init_ssl_connect for backend TLS |
2 months ago |
|
|
79783a63d7 |
fix(mysqlx): apply 12 critical/high fixes from four-way review + robustness test suite
Addresses all 6 critical and 6 high issues identified by the four-way
architecture/protocol/testing/security review.
Critical fixes:
- C1: Credential verification — MYSQL41 uses mysqlx_mysql41_verify_hash()
against stored SHA1(SHA1(password)), PLAIN uses mysqlx_mysql41_hash()
+ CRYPTO_memcmp for constant-time comparison
- C2: Backend X Protocol handshake — 6-state state machine in
MysqlxConnection::step_auth() (CapGet→CapSet→AuthStart→AuthContinue→AuthDone)
- C3: Backend FD added to poll set in rebuild_poll_set() — checks
sds->get_fd() >= 0 && sds->get_status() == XDS_READY
- C4: Double frame-pop fixed — removed redundant pop_frame() calls in
dispatch_client_message() for handlers that already pop
- C5: Backend kept until terminal frame — is_terminal_server_frame()
checks 7 terminal types (OK, ERROR, SQL_STMT_EXECUTE_OK, FETCH_DONE,
FETCH_SUSPENDED, DONE_MORE_RESULTSETS, DONE_MORE_OUT_PARAMS)
- C6: Error severity defaults to ERROR (not FATAL) — added fatal
parameter to send_error()
High fixes:
- H1: Parse errors detected — checks client_ds_.has_parse_error()
after read_from_net()
- H2: EINTR retry — do { r = recv/send(...) } while (r < 0 && errno == EINTR)
- H3: Connection limit — max_sessions_ per thread (default 10000),
accept loop breaks when exceeded
- H4: Timeouts — 10s handshake timeout, 8h idle timeout in
process_all_sessions()
- H5: PLAIN auth rejected without TLS — checks client_ds_.is_encrypted()
- H6: write_to_net errors propagated — checks return < 0 with
errno != EAGAIN
New test suites:
- mysqlx_backend_auth_unit-t: 34 assertions covering full backend
handshake state machine and error paths
- mysqlx_credential_verify_unit-t: 24 assertions covering verify_hash,
hex encode/decode, hash consistency
- mysqlx_robustness_unit-t: 33 assertions covering terminal/non-terminal
frame detection, multi-frame pipeline, backend disconnect, client
disconnect, parse errors, auth edge cases, frame forwarding
Robustness test fixes:
- Replaced blocking read_x_frame with poll()-based version (200ms timeout)
to prevent test hangs when no more data is available
- Fixed double-close bug in test cleanup — session destructor and manual
close() both closed same fds, causing next test socketpairs to be
prematurely closed. Added detach_session_fds() helper to invalidate
session fds before manual cleanup
- Fixed drain loop ordering — close write end before draining read end
to prevent blocking
- Re-enabled test_backend_disconnect_during_query (previously crashed
due to double-close fd corruption, not protobuf FATAL)
- Fixed test_mysql41_no_credential_lookup_accepts_any to use valid
20-byte scramble format (40 hex chars)
- Fixed test_forward_empty_frame to use SQL_STMT_EXECUTE message type
instead of unrecognized 0x11
All 9 test suites pass (218+ assertions across backend_auth,
credential_verify, data_stream, message_dispatch, session, thread,
connection, concurrent, robustness).
|
2 months ago |
|
|
70e908b9b6 |
feat(mysqlx): wire event-driven v2 into plugin lifecycle
The mysqlx plugin now creates a configurable thread pool (mysqlx_thread_pool_size, default 4, max 64). Each thread runs its own poll() event loop, accepts connections from listeners, manages sessions cooperatively, and maintains a per-thread connection cache. New admin variables in mysqlx_variables: - mysqlx_thread_pool_size (default 4) - mysqlx_connect_timeout (default 10000ms) - mysqlx_tls_mode (default DISABLED) - mysqlx_max_cached_connections_per_thread (default 100) Plugin version bumped to 2.0.0 to reflect the architectural rewrite. |
2 months ago |
|
|
eb958585a6 |
feat(mysqlx): add protocol-aware dispatch, TLS stubs, connection pool, and async connect
Implements four tightly-coupled v2 components: Task 5 - Protocol-aware frame forwarding: - dispatch_client_message() handles all 23 X Protocol client message types - CRUD operations (Find/Insert/Update/Delete) forwarded to backend - SQL statement execution forwarded to backend - Prepared statements, cursors, views, expect blocks forwarded - Compression rejected with ER_X_CAPABILITY_COMPRESSION_INVALID_ALGORITHM - Unknown messages get ER_X_BAD_MESSAGE error - forward_to_backend() and handler_waiting_server_msg() for bidirectional frame forwarding between client and server data streams Task 6 - TLS stubs: - MysqlxDataStream gains encrypted_ flag for future TLS support - MysqlxSession gains TLS state machine states (accept/connect init/cont/done) - Stub handlers skip TLS states for now (Phase 3 will add OpenSSL) Task 7 - Connection pool integration: - MysqlxSession has back-pointer to Mysqlx_Thread for pool access - handler_connecting_server() checks thread-local cache first - Connections returned to cache after query completion - Pool matching by hostgroup, user, schema Task 8 - Async backend connect: - MysqlxConnection::start_connect() uses SOCK_NONBLOCK + EINPROGRESS - check_connect() polls SO_ERROR for completion - MysqlxSession::handler_connecting_server() manages async state - Graceful error handling with proper X Protocol error frames |
2 months ago |
|
|
ff0070f782 |
feat(mysqlx): add Mysqlx_Thread event loop with poll()
|
2 months ago |
|
|
7f8719c8d1 |
feat(mysqlx): add X Protocol session state machine
MysqlxSession implements the X Protocol handshake and authentication as a cooperative state machine compatible with ProxySQL's poll()-based event loop. States: CONNECTING_CLIENT → X_CAPABILITIES_GET → X_CAPABILITIES_SET → X_AUTH_START → X_AUTH_CHALLENGE_SENT → X_AUTH_OK_SENT → WAITING_CLIENT_XMSG → X_SESSION_CLOSING Uses MysqlxDataStream for non-blocking frame I/O. Handler returns immediately when no data is available, allowing poll() to multiplex thousands of sessions per thread. |
2 months ago |
|
|
c67705ba8b |
feat(mysqlx): add pooled backend connection object
MysqlxConnection tracks the state of a backend X Protocol connection for connection pooling. Tracks hostgroup, user, schema, address, and multiplexing eligibility (transactions, prepared statements disable reuse). Will be used by Mysqlx_Thread's per-thread connection cache and the global connection pool. |
2 months ago |
|
|
6034a3fba6 |
fix(mysqlx): replace raw pointer MysqlxFrame with std::vector<uint8_t>
Code quality fixes from review: - Replace std::pair<uint8_t*,size_t> with std::vector<uint8_t> for MysqlxFrame, eliminating use-after-free risk and Rule of Five violations - Add read buffer compaction when consumed prefix exceeds 4KB - Return -1 from write_to_net() for invalid fd (was returning 0) - Add parse_error_ flag instead of silently closing on malformed input - Add bounds check in enqueue_frame for oversized payloads |
2 months ago |
|
|
401a527186 |
feat(mysqlx): add non-blocking X Protocol frame I/O data stream
Implements MysqlxDataStream with: - Non-blocking frame parsing from raw TCP byte streams - Partial frame buffering (header-first, then body accumulation) - Frame enqueue for writes with proper X Protocol wire format - read_from_net() / write_to_net() using recv()/send() on non-blocking FDs - O_NONBLOCK set automatically on init Foundation for the event-driven v2 rewrite. All future session and thread classes will use MysqlxDataStream for I/O instead of the blocking read()/write() calls from Phase 1. Tests: frame header parsing, partial frames, multiple concatenated frames, write buffer format verification. |
2 months ago |
|
|
3d7ebacaf9 |
fix: call record_conn_used in worker and log config reload errors
I6: Add record_conn_used() call in MysqlxWorker::run() after record_conn_ok() so that the ConnUsed stats counter is actually incremented when sessions are established. Log errors from reload_config_store() via the plugin log_message service instead of silently swallowing them. The admin command still returns success (SQLite tables were updated) but the operator can see if the in-memory reload failed. |
2 months ago |
|
|
ac7bafc75d |
fix: make topology_generation_ atomic to prevent data race UB
Replace plain uint64_t read/write with std::atomic<uint64_t> operations for topology_generation_. The field is written by bump_topology_generation() and read concurrently by worker threads in topology_generation(). Plain read/write on a non-atomic is C++ undefined behavior in the presence of concurrent access. Use load() for reads and fetch_add(1) for the increment to ensure well-defined behavior across threads. |
2 months ago |
|
|
acb6be4178 |
fix: load config store into memory on plugin start and after LOAD commands
C1: Call config_store->load_from_runtime() in mysqlx_start() so that the in-memory store is populated before listeners begin accepting connections. Without this, resolve_identity() always returned nullopt and no client could authenticate. I8: Add reload_config_store() call at the end of each LOAD admin command callback (load_users_to_runtime, load_routes_to_runtime, load_backend_endpoints_to_runtime) so that the in-memory config store is refreshed immediately after runtime tables are updated. |
2 months ago |
|
|
cd94ac2b12 |
fix: populate destination_hostgroup in route stats and add conn_used counter
I5: Pass destination_hostgroup through record_conn_ok and record_conn_err so that MysqlxRouteStats.destination_hostgroup is populated from the actual route configuration instead of remaining 0. I6: Add record_conn_used() method to MysqlxStatsStore that increments the conn_used atomic counter for a route. This counter tracks active session usage of a route and is flushed to stats_mysqlx_routes. |
2 months ago |
|
|
8ff8a038b5 |
fix: add DNS resolution and IPv6 support for backend and listener sockets
I2: Replace inet_pton with getaddrinfo in mysqlx_backend_session to support hostname-based backend endpoints (not just dotted-quad IPv4). getaddrinfo handles DNS lookup, numeric IPv4, and IPv6 transparently. I3: Replace AF_INET/sockaddr_in with getaddrinfo in mysqlx_worker listener creation. Parse [IPv6]:port bracket notation in bind addresses. Set AI_PASSIVE flag for listener sockets. Support dual-stack (AF_UNSPEC) so a single listener can accept both IPv4 and IPv6 connections. Also set TCP_NODELAY on both listener-accepted client sockets and backend connection sockets to reduce latency for small X Protocol messages. |
2 months ago |
|
|
0143f8a4fb |
fix: document plugin ABI constraint and harden PLAIN auth comparison
I11: Add a comment to ProxySQL_Plugin.h documenting that ProxySQL_PluginCommandResult contains std::string and that plugins must be compiled with the same C++ standard library as the core. Minor: Simplify PLAIN auth comparison in mysqlx_frontend_session to ensure CRYPTO_memcmp is always called when password sizes match, avoiding a timing distinguisher on password length mismatch. |
2 months ago |
|
|
11aca24274 |
fix: add -pthread to plugin Makefile and error on MYSQLX commands without plugin
I9: Add -pthread to CXXFLAGS and LDFLAGS in plugins/mysqlx/Makefile. The plugin uses std::thread, std::mutex, and std::shared_mutex which require -pthread on Linux. Without it, linking fails or causes runtime issues. I10: When a MYSQLX admin command is recognized but no plugin is loaded to handle it, send a clear "MYSQLX plugin is not loaded" error to the client instead of falling through to SQLite query execution which would produce a confusing syntax error. |
2 months ago |
|
|
386d4be4b7 |
fix: address crypto, timing, and signal issues in mysqlx protocol
C2: Check sha1_digest/sha1_digest_multi return values in all MYSQL41 auth helpers. Return empty vectors or false on OpenSSL failure instead of using uninitialized stack data. I1: Replace std::vector operator== with CRYPTO_memcmp in mysqlx_mysql41_verify to prevent byte-by-byte timing side-channel attacks on the scramble comparison. I7: Handle EINTR in mysqlx_read_exact and mysqlx_write_all loops. Retry read/write when interrupted by a signal instead of treating EINTR as a fatal error. |
2 months ago |
|
|
d880330c17 |
feat: add SAVE MYSQLX handlers and first-class LOAD/SAVE dispatch
Replace the PLUGIN MYSQLX command namespace with canonical ProxySQL admin syntax matching the MYSQL/PGSQL convention. Plugin changes (mysqlx_admin_schema.cpp): - Add three SAVE handlers (save_users_from_runtime, save_routes_from_runtime, save_backend_endpoints_from_runtime) that copy runtime tables back to config tables (reverse of LOAD) - Register 6 commands with canonical names: LOAD MYSQLX USERS/ROUTES/BACKEND ENDPOINTS TO RUNTIME SAVE MYSQLX USERS/ROUTES/BACKEND ENDPOINTS TO MEMORY Admin handler changes (Admin_Handler.cpp): - Add 6 MYSQLX alias vector definitions following the existing LOAD_MYSQL_USERS_FROM_MEMORY pattern (4 aliases each: FROM MEMORY, FROM MEM, TO RUNTIME, TO RUN) - Replace the generic plugin fallback dispatch with MYSQLX-specific alias matching using is_admin_command_or_alias(), matching how MYSQL and PGSQL commands are dispatched - Use 'return false' pattern consistent with other admin commands |
2 months ago |
|
|
994d46dfd6 |
fix: use PRIu64 for portable uint64_t formatting in stats flush
|
2 months ago |
|
|
31b9e86b59 |
fix: register mysqlx tests in CI groups and document proto source
Register all plugin and mysqlx unit tests in groups.json under unit-tests-g1 so they run in CI: - plugin_manager_unit-t, plugin_config_unit-t, plugin_registry_unit-t - mysqlx_config_store_unit-t, mysqlx_protocol_unit-t, mysqlx_route_store_unit-t, mysqlx_stats_unit-t - test_mysqlx_plugin_load-t, test_mysqlx_admin_tables-t, test_mysqlx_listener_smoke-t Document protobuf source location and regeneration command in plugins/mysqlx/Makefile. |
2 months ago |
|
|
1900db9e57 |
fix: correct MYSQL41 auth wire format for real MySQL 8.x
The MySQL X Protocol MYSQL41 AuthenticateContinue auth_data must be formatted as schema\0username\0*UPPERCASE_HEX(scramble), not raw binary. Backend: AuthenticateContinue now sends \0user\0*HEX(scramble) instead of raw 20-byte binary. This matches what MySQL 8.x X Plugin expects. Frontend: handle_authenticate now parses \0user\0*HEX(scramble) from the client's AuthenticateContinue, hex-decodes the scramble, then verifies. This matches what mysqlsh and other conforming clients send. Backend: Add Notice-skipping loops before reading CONN_CAPABILITIES and SESS_AUTHENTICATE_CONTINUE from MySQL 8.x, which may send Notice frames at any point during the handshake sequence. Add mysqlx_hex_encode/mysqlx_hex_decode helpers. |
2 months ago |
|
|
f8f9debbe1 |
fix: address important code review findings
1. Replace select() with poll() in accept loop and relay to avoid FD_SETSIZE undefined behavior with high file descriptors 2. Make g_rr_index atomic for safe concurrent access 3. Add SO_RCVTIMEO/SO_SNDTIMEO (10s backend, 30s frontend) to prevent indefinite blocking from slow peers 4. Reject TLS CapabilitiesSet requests explicitly in Phase 1 5. Enforce require_tls per user — reject if set since Phase 1 does not implement TLS negotiation 6. Enforce allowed_auth_methods per user — check the comma-separated list before proceeding with auth |
2 months ago |
|
|
9a3b399eb0 |
fix: address critical code review findings
1. SQL injection in stats flush: escape route names with sqlite_escape() 2. Timing attack in PLAIN auth: use CRYPTO_memcmp for constant-time password comparison 3. OOM via oversized frame: add MYSQLX_MAX_PAYLOAD_SIZE (16MB) check in mysqlx_read_frame before allocating payload buffer 4. Thread safety: add shared_mutex to MysqlxConfigStore, shared_lock for readers (resolve_identity, pick_endpoint), unique_lock for writer (load_from_runtime), separate rr_mutex_ for round-robin counter mutation |
2 months ago |
|
|
c2e90d3696 |
feat: add mysqlx stats tables and topology invalidation seam
Add MysqlxStatsStore with atomic route counters (conn_ok, conn_err, bytes_sent, bytes_recv) and flush_to_sqlite() for stats_mysqlx_routes. Register stats_mysqlx_routes and stats_mysqlx_processlist tables in the plugin admin schema. Wire stats recording into the worker: record_conn_ok on successful backend connect, record_conn_err on failure. Add topology generation capture at session bind time as the Phase 2 seam for GR notification-driven route invalidation. |
2 months ago |
|
|
e087fdda4c |
feat: add backend X sessions and hostgroup-based routing
Add MysqlxBackendSession with TCP connect, X Protocol MYSQL41 auth to backend, and bidirectional byte-level relay via select(). Implement round_robin and round_robin_with_fallback endpoint selection strategies in MysqlxConfigStore::pick_endpoint(). Workers now connect to the backend after frontend auth and relay traffic until close. Phase 1 is one frontend = one backend, no pooling. |
2 months ago |
|
|
05ca510f2d |
feat: implement frontend X Protocol handshake and auth
Add mysqlx_protocol.h/cpp with frame encode/decode, MYSQL41 scramble auth using EVP SHA1, and protobuf message helpers for X Protocol Error/Ok/Capabilities/Auth frames. Add mysqlx_frontend_session.h/cpp implementing the full handshake state machine: CapabilitiesGet→Capabilities, CapabilitiesSet→Ok, AuthenticateStart→challenge→AuthenticateContinue→AuthenticateOk. Supports MYSQL41 and PLAIN auth methods. Enforces x_enabled flag, rejects pass_through backend auth mode. Workers now run the frontend session instead of immediately closing connections. |
2 months ago |
|
|
2beb621515 |
feat: add protobuf-compiled X Protocol message definitions
Compile mysqlx*.proto files from MySQL Connector-C 8.4.0 into C++ sources. The plugin .so now links -lprotobuf for X Protocol frame/message encoding and decoding needed by Tasks 7-8. |
2 months ago |
|
|
5b5bbfbcaf |
feat: add mysqlx listener sockets and worker threads
Plugin start now opens TCP listeners for each active route in runtime_mysqlx_routes. An accept thread dispatches incoming connections to worker threads round-robin. Phase 1 workers accept-then-close; Tasks 7-8 will add X Protocol handshake and backend relay. |
2 months ago |