diff --git a/include/ProxySQL_Cluster.hpp b/include/ProxySQL_Cluster.hpp index 395328b1a..df895d803 100644 --- a/include/ProxySQL_Cluster.hpp +++ b/include/ProxySQL_Cluster.hpp @@ -12,6 +12,15 @@ #define PROXYSQL_NODE_METRICS_LEN 5 /** + * @file ProxySQL_Cluster.hpp + * @brief ProxySQL Cluster synchronization and management definitions. + * + * This file contains definitions for ProxySQL's clustering functionality, including: + * - Cluster query definitions for MySQL and PostgreSQL module synchronization + * - Node management and metrics collection + * - Checksum computation and comparison algorithms + * - Peer selection and synchronization logic + * * CLUSTER QUERIES DEFINITION * ========================== * @@ -19,11 +28,20 @@ * the queries issued for generating the checksum for each of the target modules, for simpler reasoning, they should * also represent the actual resultset being received when issuing them, since this resultset is used for computing the * 'expected checksum' for the fetched config before loading it to runtime. This is done for the following modules: + * + * MySQL modules: * - 'runtime_mysql_servers': tables 'mysql_servers' * - 'runtime_mysql_users'. * - 'runtime_mysql_query_rules'. * - 'mysql_servers_v2': tables admin 'mysql_servers', 'mysql_replication_hostgroups', 'mysql_group_replication_hostroups', * 'mysql_galera_hostgroups', 'mysql_aws_aurora_hostgroups', 'mysql_hostgroup_attributes'. + * + * PostgreSQL modules: + * - 'runtime_pgsql_servers': runtime PostgreSQL server status and configuration + * - 'runtime_pgsql_users': runtime PostgreSQL user authentication settings + * - 'runtime_pgsql_query_rules': runtime PostgreSQL query routing rules + * - 'pgsql_servers_v2': static PostgreSQL server configuration + * * IMPORTANT: For further clarify this means that it's important that the actual resultset produced by the intercepted * query preserve the filtering and ordering expressed in this queries. */ @@ -61,19 +79,129 @@ /* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_mysql_query_rules_fast_routing'. See top comment for details. */ #define CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING "PROXY_SELECT username, schemaname, flagIN, destination_hostgroup, comment FROM runtime_mysql_query_rules_fast_routing ORDER BY username, schemaname, flagIN" -/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_servers'. See top comment for details. */ +/** + * @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_servers'. + * + * This query retrieves the current operational status and configuration of PostgreSQL servers + * from the runtime_pgsql_servers table. It includes server health metrics, connection settings, + * and current operational status. The query filters out OFFLINE_HARD servers and converts + * numeric status values to human-readable format. + * + * Result columns: + * - hostgroup_id: Logical grouping identifier for PostgreSQL servers + * - hostname: Server hostname or IP address + * - port: PostgreSQL server port number + * - status: Converted status string (ONLINE, OFFLINE_SOFT, OFFLINE_HARD) + * - weight: Load balancing weight for the server + * - compression: Whether compression is enabled + * - max_connections: Maximum allowed connections + * - max_replication_lag: Maximum acceptable replication lag + * - use_ssl: SSL/TLS connection requirement + * - max_latency_ms: Maximum acceptable latency + * - comment: Administrative comments + * + * @see runtime_pgsql_servers + * @see pull_runtime_pgsql_servers_from_peer() + */ #define CLUSTER_QUERY_RUNTIME_PGSQL_SERVERS "PROXY_SELECT hostgroup_id, hostname, port, CASE status WHEN 0 THEN \"ONLINE\" WHEN 1 THEN \"ONLINE\" WHEN 2 THEN \"OFFLINE_SOFT\" WHEN 3 THEN \"OFFLINE_HARD\" WHEN 4 THEN \"ONLINE\" END status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM runtime_pgsql_servers WHERE status<>'OFFLINE_HARD' ORDER BY hostgroup_id, hostname, port" -/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'pgsql_servers_v2'. See top comment for details. */ +/** + * @brief Query to be intercepted by 'ProxySQL_Admin' for 'pgsql_servers_v2'. + * + * This query retrieves the static configuration of PostgreSQL servers from the pgsql_servers_v2 table. + * It includes connection parameters, load balancing settings, and server metadata. The query + * filters out OFFLINE_HARD servers and converts SHUNNED status to ONLINE for cluster synchronization. + * + * Result columns: + * - hostgroup_id: Logical grouping identifier for PostgreSQL servers + * - hostname: Server hostname or IP address + * - port: PostgreSQL server port number + * - status: Server status (SHUNNED converted to ONLINE for sync) + * - weight: Load balancing weight for the server + * - compression: Whether compression is enabled + * - max_connections: Maximum allowed connections + * - max_replication_lag: Maximum acceptable replication lag + * - use_ssl: SSL/TLS connection requirement + * - max_latency_ms: Maximum acceptable latency + * - comment: Administrative comments + * + * @see pgsql_servers_v2 + * @see pull_pgsql_servers_v2_from_peer() + */ #define CLUSTER_QUERY_PGSQL_SERVERS_V2 "PROXY_SELECT hostgroup_id, hostname, port, CASE WHEN status=\"SHUNNED\" THEN \"ONLINE\" ELSE status END AS status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM pgsql_servers_v2 WHERE status<>'OFFLINE_HARD' ORDER BY hostgroup_id, hostname, port" -/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_users'. See top comment for details. */ +/** + * @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_users'. + * + * This query retrieves PostgreSQL user authentication configuration from the runtime_pgsql_users table. + * It includes credentials, connection settings, and user behavior preferences that are used for + * authenticating and managing PostgreSQL client connections. + * + * Result columns: + * - username: PostgreSQL username + * - password: Authentication password/hash + * - use_ssl: SSL/TLS connection requirement + * - default_hostgroup: Default hostgroup for routing + * - transaction_persistent: Whether transactions persist across connections + * - fast_forward: Fast forwarding mode setting + * - backend: Backend connection settings + * - frontend: Frontend connection settings + * - max_connections: Maximum connections per user + * - attributes: Additional user attributes (JSON) + * - comment: Administrative comments + * + * @see runtime_pgsql_users + * @see pull_pgsql_users_from_peer() + */ #define CLUSTER_QUERY_PGSQL_USERS "PROXY_SELECT username, password, use_ssl, default_hostgroup, transaction_persistent, fast_forward, backend, frontend, max_connections, attributes, comment FROM runtime_pgsql_users" -/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_query_rules'. See top comment for details. */ +/** + * @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_query_rules'. + * + * This query retrieves PostgreSQL query routing rules from the runtime_pgsql_query_rules table. + * It includes comprehensive rule definitions for query matching, routing, caching, and behavior + * control. Rules are ordered by rule_id to ensure consistent processing and checksum generation. + * + * Key result columns: + * - rule_id: Unique identifier for the rule + * - username: Filter by PostgreSQL username + * - database: Filter by database name (PostgreSQL-specific, replaces schemaname) + * - flagIN, flagOUT: Rule processing flags + * - match_digest, match_pattern: Query matching criteria + * - destination_hostgroup: Target hostgroup for matching queries + * - cache_ttl, cache_timeout: Query caching settings + * - timeout, retries, delay: Query execution parameters + * - mirror_hostgroup: Query mirroring destination + * - error_msg, ok_msg: Custom response messages + * - sticky_conn, multiplex: Connection pooling behavior + * - log, apply: Logging and application flags + * - attributes: Additional rule attributes (JSON) + * - comment: Administrative comments + * + * @see runtime_pgsql_query_rules + * @see pull_pgsql_query_rules_from_peer() + */ #define CLUSTER_QUERY_PGSQL_QUERY_RULES "PROXY_SELECT rule_id, username, database, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, cache_empty_result, cache_timeout, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, log, apply, attributes, comment FROM runtime_pgsql_query_rules ORDER BY rule_id" -/* @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_query_rules_fast_routing'. See top comment for details. */ +/** + * @brief Query to be intercepted by 'ProxySQL_Admin' for 'runtime_pgsql_query_rules_fast_routing'. + * + * This query retrieves PostgreSQL fast routing rules from the runtime_pgsql_query_rules_fast_routing table. + * Fast routing provides a lightweight mechanism for direct query routing based on username, database, + * and processing flags without complex pattern matching. This enables efficient routing for common + * use cases and reduces processing overhead. + * + * Result columns: + * - username: PostgreSQL username for routing rule + * - database: Database name for routing rule (PostgreSQL-specific) + * - flagIN: Input processing flag for rule matching + * - destination_hostgroup: Target hostgroup for direct routing + * - comment: Administrative comments + * + * @see runtime_pgsql_query_rules_fast_routing + * @see pull_pgsql_query_rules_from_peer() + * @see CLUSTER_QUERY_PGSQL_QUERY_RULES + */ #define CLUSTER_QUERY_PGSQL_QUERY_RULES_FAST_ROUTING "PROXY_SELECT username, database, flagIN, destination_hostgroup, comment FROM runtime_pgsql_query_rules_fast_routing ORDER BY username, database, flagIN" class ProxySQL_Checksum_Value_2: public ProxySQL_Checksum_Value { diff --git a/lib/ProxySQL_Cluster.cpp b/lib/ProxySQL_Cluster.cpp index 12f24991a..3907e3ef2 100644 --- a/lib/ProxySQL_Cluster.cpp +++ b/lib/ProxySQL_Cluster.cpp @@ -404,6 +404,53 @@ ProxySQL_Node_Metrics * ProxySQL_Node_Entry::get_metrics_prev() { return m; } +/** + * @brief Processes checksum updates from a cluster peer and triggers synchronization when needed. + * + * This function is the core of ProxySQL's cluster monitoring and synchronization system. It processes + * checksum data received from peer nodes, compares it with local checksums, and initiates synchronization + * when differences are detected and thresholds are met. + * + * The function processes checksums for the following modules: + * MySQL modules: + * - admin_variables: ProxySQL admin configuration + * - mysql_query_rules: MySQL query routing rules + * - mysql_servers_v2: MySQL server configuration + * - runtime_mysql_servers: Runtime MySQL server status + * - mysql_users: MySQL user credentials + * - mysql_variables: MySQL server variables + * - ldap_variables: LDAP authentication settings + * - proxysql_servers: ProxySQL cluster node configuration + * + * PostgreSQL modules: + * - pgsql_query_rules: PostgreSQL query routing rules + * - pgsql_servers_v2: PostgreSQL server configuration + * - runtime_pgsql_servers: Runtime PostgreSQL server status + * - pgsql_users: PostgreSQL user credentials + * + * Synchronization Logic: + * 1. For each module, it compares local and peer checksums + * 2. If checksums differ, it checks the epoch timestamp to determine recency + * 3. If the peer is more recent and diff_check exceeds configured thresholds, sync is triggered + * 4. Conflict resolution handles cases where multiple nodes have the same epoch + * 5. Appropriate pull functions are called to fetch updated configuration + * + * Thresholds and Configuration: + * Each module has a corresponding *_diffs_before_sync variable that controls how many + * consecutive differences must be observed before triggering synchronization. This prevents + * excessive network traffic due to transient changes. + * + * @param _r MySQL result set containing checksum data from a peer node + * + * @note This function is thread-safe and requires GloVars.checksum_mutex to be held + * @note The function logs detailed information about checksum changes and synchronization decisions + * @note Metrics are updated to track successful and failed synchronization attempts + * @see ProxySQL_Cluster::pull_mysql_query_rules_from_peer() + * @see ProxySQL_Cluster::pull_pgsql_query_rules_from_peer() + * @see ProxySQL_Cluster::pull_pgsql_users_from_peer() + * @see ProxySQL_Cluster::pull_pgsql_servers_v2_from_peer() + * @see cluster_*_diffs_before_sync variables + */ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) { MYSQL_ROW row; time_t now = time(NULL); @@ -1229,6 +1276,33 @@ uint64_t mysql_raw_checksum(MYSQL_RES* resultset) { return res_hash; } +/** + * @brief Pulls MySQL query rules configuration from a cluster peer node. + * + * This function fetches MySQL query rules from a peer ProxySQL instance when the peer's + * checksum differs from the local checksum and the difference exceeds the configured + * threshold (cluster_mysql_query_rules_diffs_before_sync). It retrieves both regular query + * rules and fast routing rules. + * + * The function performs the following steps: + * 1. Identifies the optimal peer to sync from using get_peer_to_sync_mysql_query_rules() + * 2. Establishes a MySQL connection to the peer's admin interface + * 3. Executes CLUSTER_QUERY_MYSQL_QUERY_RULES and CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING + * 4. Computes checksums for the fetched data + * 5. Validates checksums match the expected values + * 6. Loads the query rules to runtime via load_mysql_query_rules_to_runtime() + * 7. Optionally saves configuration to disk if cluster_mysql_query_rules_save_to_disk is enabled + * + * @param expected_checksum The expected checksum of the query rules on the peer + * @param epoch The epoch timestamp of the query rules on the peer + * + * @note This function is thread-safe and requires the update_mysql_query_rules_mutex to be held + * @note The function will sleep(1) if the fetch operation fails to prevent busy loops + * @see get_peer_to_sync_mysql_query_rules() + * @see CLUSTER_QUERY_MYSQL_QUERY_RULES + * @see CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING + * @see load_mysql_query_rules_to_runtime() + */ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer(const string& expected_checksum, const time_t epoch) { char * hostname = NULL; char * ip_address = NULL; @@ -2782,6 +2856,37 @@ __exit_pull_proxysql_servers_from_peer: if (fetch_failed == true) sleep(1); } +/** + * @brief Pulls PostgreSQL users configuration from a cluster peer node. + * + * This function fetches PostgreSQL users from a peer ProxySQL instance when the peer's + * checksum differs from the local checksum and the difference exceeds the configured + * threshold (cluster_pgsql_users_diffs_before_sync). It retrieves PostgreSQL user credentials + * including usernames, passwords, and connection settings for PostgreSQL authentication. + * + * The function performs the following steps: + * 1. Identifies the optimal peer to sync from using get_peer_to_sync_pgsql_users() + * 2. Establishes a MySQL connection to the peer's admin interface + * 3. Executes CLUSTER_QUERY_PGSQL_USERS to fetch user configuration + * 4. Computes checksums for the fetched data using get_mysql_users_checksum() + * 5. Validates checksums match the expected values + * 6. Loads the users to runtime via init_pgsql_users() + * 7. Optionally saves configuration to disk if cluster_pgsql_users_save_to_disk is enabled + * + * This function provides PostgreSQL-specific cluster synchronization for user credentials, + * ensuring consistent PostgreSQL authentication across all cluster nodes. + * + * @param expected_checksum The expected checksum of the PostgreSQL users on the peer + * @param epoch The epoch timestamp of the PostgreSQL users on the peer + * + * @note This function is thread-safe and reuses the update_mysql_users_mutex + * @note The function will sleep(1) if the fetch operation fails to prevent busy loops + * @note Reuses get_mysql_users_checksum() from MySQL users for consistency + * @see get_peer_to_sync_pgsql_users() + * @see CLUSTER_QUERY_PGSQL_USERS + * @see init_pgsql_users() + * @see get_mysql_users_checksum() + */ void ProxySQL_Cluster::pull_pgsql_users_from_peer(const std::string& expected_checksum, const time_t epoch) { char * hostname = NULL; char * ip_address = NULL; @@ -2889,6 +2994,39 @@ __exit_pull_pgsql_users_from_peer: if (fetch_failed == true) sleep(1); } +/** + * @brief Pulls PostgreSQL query rules configuration from a cluster peer node. + * + * This function fetches PostgreSQL query rules from a peer ProxySQL instance when the peer's + * checksum differs from the local checksum and the difference exceeds the configured + * threshold (cluster_pgsql_query_rules_diffs_before_sync). It retrieves both regular query + * rules and fast routing rules, providing PostgreSQL-specific cluster synchronization. + * + * The function performs the following steps: + * 1. Identifies the optimal peer to sync from using get_peer_to_sync_pgsql_query_rules() + * 2. Establishes a MySQL connection to the peer's admin interface + * 3. Executes CLUSTER_QUERY_PGSQL_QUERY_RULES and CLUSTER_QUERY_PGSQL_QUERY_RULES_FAST_ROUTING + * 4. Computes checksums for the fetched data using mysql_raw_checksum() and SpookyHash + * 5. Validates checksums match the expected values + * 6. Loads the query rules to runtime via load_pgsql_query_rules_to_runtime() + * 7. Optionally saves configuration to disk if cluster_pgsql_query_rules_save_to_disk is enabled + * + * This function implements the same synchronization pattern as MySQL query rules but + * for PostgreSQL-specific tables and query rule processing. + * + * @param expected_checksum The expected checksum of the PostgreSQL query rules on the peer + * @param epoch The epoch timestamp of the PostgreSQL query rules on the peer + * + * @note This function is thread-safe and reuses the update_mysql_query_rules_mutex + * @note The function will sleep(1) if the fetch operation fails to prevent busy loops + * @note Uses the same checksum computation algorithm as MySQL query rules for consistency + * @see get_peer_to_sync_pgsql_query_rules() + * @see CLUSTER_QUERY_PGSQL_QUERY_RULES + * @see CLUSTER_QUERY_PGSQL_QUERY_RULES_FAST_ROUTING + * @see load_pgsql_query_rules_to_runtime() + * @see SpookyHash + * @see mysql_raw_checksum() + */ void ProxySQL_Cluster::pull_pgsql_query_rules_from_peer(const std::string& expected_checksum, const time_t epoch) { char * hostname = NULL; char * ip_address = NULL; @@ -3021,6 +3159,40 @@ __exit_pull_pgsql_query_rules_from_peer: if (fetch_failed == true) sleep(1); } +/** + * @brief Pulls runtime PostgreSQL servers configuration from a cluster peer node. + * + * This function fetches runtime PostgreSQL servers status from a peer ProxySQL instance when the peer's + * checksum differs from the local checksum and the difference exceeds the configured + * threshold. It retrieves the current operational status, health metrics, and runtime statistics + * for PostgreSQL servers in the cluster. + * + * The function performs the following steps: + * 1. Identifies the optimal peer to sync from using get_peer_to_sync_runtime_pgsql_servers() + * 2. Establishes a MySQL connection to the peer's admin interface + * 3. Executes CLUSTER_QUERY_RUNTIME_PGSQL_SERVERS to fetch runtime server status + * 4. Computes checksum for the fetched data using mysql_raw_checksum() + * 5. Validates checksum matches the expected value from peer_runtime_pgsql_server.value + * 6. Loads the runtime PostgreSQL servers status (TODO: integrate with load_pgsql_servers_to_runtime) + * 7. Optionally saves configuration to disk if save settings are enabled + * + * Runtime data includes: + * - Server status (ONLINE, OFFLINE, SHUNNED, etc.) + * - Current connections and load metrics + * - Health check results and response times + * - Error counts and statistics + * + * @param peer_runtime_pgsql_server The checksum structure containing expected checksum value and epoch timestamp for runtime PostgreSQL servers + * + * @note This function is thread-safe and requires the update_runtime_mysql_servers_mutex to be held (reused for pgsql_servers) + * @note The function will sleep(1) if the fetch operation fails to prevent busy loops + * @note The function reuses MySQL servers counters for metrics tracking + * @note Runtime loading integration is pending and marked as TODO + * @see get_peer_to_sync_runtime_pgsql_servers() + * @see CLUSTER_QUERY_RUNTIME_PGSQL_SERVERS + * @see mysql_raw_checksum() + * @see get_checksum_from_hash() + */ void ProxySQL_Cluster::pull_runtime_pgsql_servers_from_peer(const runtime_pgsql_servers_checksum_t& peer_runtime_pgsql_server) { char * hostname = NULL; char * ip_address = NULL; @@ -3128,6 +3300,36 @@ __exit_pull_runtime_pgsql_servers_from_peer: if (fetch_failed == true) sleep(1); } +/** + * @brief Pulls PostgreSQL servers v2 configuration from a cluster peer node. + * + * This function fetches PostgreSQL servers configuration from a peer ProxySQL instance when the peer's + * checksum differs from the local checksum and the difference exceeds the configured + * threshold (cluster_pgsql_servers_diffs_before_sync). It retrieves PostgreSQL server definitions + * including hostgroup mappings, connection parameters, and server status. + * + * The function performs the following steps: + * 1. Identifies the optimal peer to sync from using get_peer_to_sync_pgsql_servers_v2() + * 2. Establishes a MySQL connection to the peer's admin interface + * 3. Executes CLUSTER_QUERY_PGSQL_SERVERS_V2 to fetch server configuration + * 4. Computes checksum for the fetched data using mysql_raw_checksum() + * 5. Validates checksum matches the expected value from peer_pgsql_server_v2.value + * 6. Loads the PostgreSQL servers configuration (TODO: integrate with load_pgsql_servers_to_runtime) + * 7. Optionally saves configuration to disk if cluster_pgsql_servers_save_to_disk is enabled + * + * @param peer_pgsql_server_v2 The checksum structure containing expected checksum value and epoch timestamp for pgsql_servers_v2 + * @param peer_runtime_pgsql_server The checksum structure containing runtime PostgreSQL servers checksum (currently unused but reserved for future use) + * @param fetch_runtime_pgsql_servers Boolean flag indicating whether to fetch runtime PostgreSQL servers data (currently unused but reserved for future implementation) + * + * @note This function is thread-safe and requires the update_mysql_servers_v2_mutex to be held (reused for pgsql_servers_v2) + * @note The function will sleep(1) if the fetch operation fails to prevent busy loops + * @note The function reuses MySQL servers counters for metrics tracking + * @note Runtime loading integration is pending and marked as TODO + * @see get_peer_to_sync_pgsql_servers_v2() + * @see CLUSTER_QUERY_PGSQL_SERVERS_V2 + * @see mysql_raw_checksum() + * @see get_checksum_from_hash() + */ void ProxySQL_Cluster::pull_pgsql_servers_v2_from_peer(const pgsql_servers_v2_checksum_t& peer_pgsql_server_v2, const runtime_pgsql_servers_checksum_t& peer_runtime_pgsql_server, bool fetch_runtime_pgsql_servers) { char * hostname = NULL; @@ -4065,6 +4267,30 @@ void ProxySQL_Cluster_Nodes::get_peer_to_sync_proxysql_servers(char **host, uint } } +/** + * @brief Identifies the optimal cluster peer for PostgreSQL users synchronization. + * + * This function scans all available cluster nodes to find the best peer for synchronizing + * PostgreSQL users configuration. It selects a peer based on the following criteria: + * 1. The peer must have a valid pgsql_users checksum (version > 1) + * 2. The peer should have the latest epoch timestamp + * 3. The peer's diff_check count must exceed cluster_pgsql_users_diffs_before_sync threshold + * + * The algorithm prioritizes nodes with the most recent configuration changes while ensuring + * sufficient differences have accumulated to justify synchronization. This prevents excessive + * network traffic and unnecessary synchronization operations. + * + * @param host Pointer to store the hostname of the selected peer (caller must free) + * @param port Pointer to store the port number of the selected peer + * @param ip_address Pointer to store the IP address of the selected peer (caller must free) + * + * @note If no suitable peer is found, *host will be set to NULL + * @note If a peer has the maximum epoch but insufficient diff_check, a warning is logged and sync is skipped + * @note The function performs memory allocation for hostname and ip_address that must be freed by the caller + * @note This is a PostgreSQL counterpart to get_peer_to_sync_mysql_users() + * @see cluster_pgsql_users_diffs_before_sync + * @see ProxySQL_Checksum_Value_2::pgsql_users + */ void ProxySQL_Cluster_Nodes::get_peer_to_sync_pgsql_users(char **host, uint16_t *port, char** ip_address) { unsigned long long version = 0; unsigned long long epoch = 0; @@ -4120,6 +4346,31 @@ void ProxySQL_Cluster_Nodes::get_peer_to_sync_pgsql_users(char **host, uint16_t } } +/** + * @brief Identifies the optimal cluster peer for PostgreSQL query rules synchronization. + * + * This function scans all available cluster nodes to find the best peer for synchronizing + * PostgreSQL query rules configuration. It selects a peer based on the following criteria: + * 1. The peer must have a valid pgsql_query_rules checksum (version > 1) + * 2. The peer should have the latest epoch timestamp + * 3. The peer's diff_check count must exceed cluster_pgsql_query_rules_diffs_before_sync threshold + * + * The algorithm prioritizes nodes with the most recent query rules changes while ensuring + * sufficient differences have accumulated to justify synchronization. This prevents excessive + * network traffic and unnecessary synchronization operations for query rules that haven't + * changed significantly. + * + * @param host Pointer to store the hostname of the selected peer (caller must free) + * @param port Pointer to store the port number of the selected peer + * @param ip_address Pointer to store the IP address of the selected peer (caller must free) + * + * @note If no suitable peer is found, *host will be set to NULL + * @note If a peer has the maximum epoch but insufficient diff_check, a warning is logged and sync is skipped + * @note The function performs memory allocation for hostname and ip_address that must be freed by the caller + * @note This is a PostgreSQL counterpart to get_peer_to_sync_mysql_query_rules() + * @see cluster_pgsql_query_rules_diffs_before_sync + * @see ProxySQL_Checksum_Value_2::pgsql_query_rules + */ void ProxySQL_Cluster_Nodes::get_peer_to_sync_pgsql_query_rules(char **host, uint16_t *port, char** ip_address) { unsigned long long version = 0; unsigned long long epoch = 0; @@ -4175,6 +4426,31 @@ void ProxySQL_Cluster_Nodes::get_peer_to_sync_pgsql_query_rules(char **host, uin } } +/** + * @brief Identifies the optimal cluster peer for runtime PostgreSQL servers synchronization. + * + * This function scans all available cluster nodes to find the best peer for synchronizing + * runtime PostgreSQL servers status and metrics. It selects a peer based on the following criteria: + * 1. The peer must have a valid pgsql_servers runtime checksum (version > 1) + * 2. The peer should have the latest epoch timestamp + * 3. The peer's diff_check count must exceed cluster_pgsql_servers_diffs_before_sync threshold + * + * The function focuses on runtime data synchronization, which includes server status, + * health metrics, connection counts, and other operational statistics. This enables + * cluster nodes to maintain consistent views of PostgreSQL server operational states. + * + * @param host Pointer to store the hostname of the selected peer (caller must free) + * @param port Pointer to store the port number of the selected peer + * @param peer_checksum Pointer to store the runtime checksum string of the selected peer (caller must free, optional) + * @param ip_address Pointer to store the IP address of the selected peer (caller must free) + * + * @note If no suitable peer is found, *host will be set to NULL + * @note If a peer has the maximum epoch but insufficient diff_check, a warning is logged and sync is skipped + * @note The function performs memory allocation for hostname, ip_address, and checksum that must be freed by the caller + * @note This is a PostgreSQL counterpart to get_peer_to_sync_runtime_mysql_servers() + * @see cluster_pgsql_servers_diffs_before_sync + * @see ProxySQL_Checksum_Value_2::pgsql_servers + */ void ProxySQL_Cluster_Nodes::get_peer_to_sync_runtime_pgsql_servers(char **host, uint16_t *port, char **peer_checksum, char** ip_address) { unsigned long long version = 0; unsigned long long epoch = 0; @@ -4245,6 +4521,35 @@ void ProxySQL_Cluster_Nodes::get_peer_to_sync_runtime_pgsql_servers(char **host, } } +/** + * @brief Identifies the optimal cluster peer for PostgreSQL servers v2 synchronization. + * + * This function scans all available cluster nodes to find the best peer for synchronizing + * PostgreSQL servers configuration. It selects a peer based on the following criteria: + * 1. The peer must have a valid pgsql_servers_v2 checksum (version > 1) + * 2. The peer should have the latest epoch timestamp + * 3. The peer's diff_check count must exceed cluster_pgsql_servers_diffs_before_sync threshold + * + * In addition to connection information, this function also provides checksums for both + * the static configuration (pgsql_servers_v2) and runtime status (pgsql_servers) if requested. + * This enables the caller to perform comprehensive synchronization of both configuration + * and runtime data. + * + * @param host Pointer to store the hostname of the selected peer (caller must free) + * @param port Pointer to store the port number of the selected peer + * @param peer_pgsql_servers_v2_checksum Pointer to store the pgsql_servers_v2 checksum string (caller must free, optional) + * @param peer_runtime_pgsql_servers_checksum Pointer to store the runtime pgsql_servers checksum string (caller must free, optional) + * @param ip_address Pointer to store the IP address of the selected peer (caller must free) + * + * @note If no suitable peer is found, *host will be set to NULL + * @note If a peer has the maximum epoch but insufficient diff_check, a warning is logged and sync is skipped + * @note The function performs memory allocation for all returned strings that must be freed by the caller + * @note Runtime checksum is only provided if the peer has valid runtime data (version > 1) + * @note This is a PostgreSQL counterpart to get_peer_to_sync_mysql_servers_v2() + * @see cluster_pgsql_servers_diffs_before_sync + * @see ProxySQL_Checksum_Value_2::pgsql_servers_v2 + * @see ProxySQL_Checksum_Value_2::pgsql_servers + */ void ProxySQL_Cluster_Nodes::get_peer_to_sync_pgsql_servers_v2(char** host, uint16_t* port, char** peer_pgsql_servers_v2_checksum, char** peer_runtime_pgsql_servers_checksum, char** ip_address) { unsigned long long version = 0;