Troubleshooting Writes in Galera Cluster

Troubleshooting WRITE Performance Bottlenecks in Galera Cluster Operations



Understanding Galera Cluster Write Performance

Galera Cluster uses synchronous replication, which means every write operation must be committed on all nodes before being acknowledged to the client. This architecture inherently creates potential bottlenecks that differ from traditional master-slave replication.

Common Write Performance Bottlenecks

1. Network Latency and Bandwidth Issues

Symptoms:

  • High wsrep_local_send_queue values
  • Increasing wsrep_local_cert_failures
  • Slow transaction commit times

Diagnostic Commands:

-- Check network-related status variables
SHOW STATUS LIKE 'wsrep_local_send_queue%';
SHOW STATUS LIKE 'wsrep_local_recv_queue%';
SHOW STATUS LIKE 'wsrep_flow_control%';

-- Monitor certification failures
SHOW STATUS LIKE 'wsrep_local_cert_failures';
SHOW STATUS LIKE 'wsrep_local_bf_aborts';

Solutions:

# Optimize network settings
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_rmem = 4096 65536 134217728' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_wmem = 4096 65536 134217728' >> /etc/sysctl.conf
sysctl -p

2. Flow Control Activation

Symptoms:

  • wsrep_flow_control_paused increasing
  • Slow nodes causing cluster-wide performance degradation
  • High wsrep_local_recv_queue on slower nodes

Configuration Tuning:

-- Adjust flow control parameters
SET GLOBAL wsrep_slave_threads = 4;  -- Increase parallel apply threads
SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=256;gcs.fc_factor=0.99';

3. Large Transaction Handling

Symptoms:

  • Timeouts on large transactions
  • High memory usage during commits
  • wsrep_max_ws_size errors

Optimization:

-- Increase transaction size limits
SET GLOBAL wsrep_max_ws_size = 2147483647;  -- 2GB limit
SET GLOBAL wsrep_max_ws_rows = 0;  -- Unlimited rows

-- Break large transactions into smaller chunks
START TRANSACTION;
-- Process data in batches of 1000-10000 rows
INSERT INTO table SELECT * FROM source LIMIT 1000;
COMMIT;

Advanced Troubleshooting Techniques

4. Monitoring Cluster State and Performance

Real-time Monitoring Script:

#!/bin/bash
# galera_monitor.sh
while true; do
    echo "=== $(date) ==="
    mysql -e "
    SELECT 
        VARIABLE_NAME,
        VARIABLE_VALUE 
    FROM INFORMATION_SCHEMA.GLOBAL_STATUS 
    WHERE VARIABLE_NAME IN (
        'wsrep_local_state_comment',
        'wsrep_cluster_size',
        'wsrep_ready',
        'wsrep_local_send_queue',
        'wsrep_local_recv_queue',
        'wsrep_flow_control_paused',
        'wsrep_cert_deps_distance',
        'wsrep_apply_oooe',
        'wsrep_apply_oool'
    );"
    sleep 5
done

5. Write Set Certification Optimization

Check Certification Performance:

-- Monitor certification conflicts
SHOW STATUS LIKE 'wsrep_local_cert_failures';
SHOW STATUS LIKE 'wsrep_local_bf_aborts';

-- Check write set dependencies
SHOW STATUS LIKE 'wsrep_cert_deps_distance';

Reduce Certification Conflicts:

-- Optimize transaction isolation
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

-- Use explicit locking for conflicting operations
SELECT * FROM table WHERE id = 1 FOR UPDATE;

6. Storage Engine Optimization

InnoDB Configuration for Galera:

-- Optimize InnoDB for Galera workloads
SET GLOBAL innodb_buffer_pool_size = '70% of RAM';
SET GLOBAL innodb_log_file_size = '256MB';
SET GLOBAL innodb_log_buffer_size = '64MB';
SET GLOBAL innodb_flush_log_at_trx_commit = 2;  -- Relaxed durability
SET GLOBAL innodb_doublewrite = 0;  -- Disable for better performance
SET GLOBAL innodb_flush_method = 'O_DIRECT';

Node-Specific Performance Issues

7. Identifying Slow Nodes

Performance Comparison Script:

#!/bin/bash
# check_node_performance.sh
for node in node1 node2 node3; do
    echo "=== $node ==="
    mysql -h $node -e "
    SELECT 
        @@hostname as node,
        VARIABLE_VALUE as local_commits
    FROM INFORMATION_SCHEMA.GLOBAL_STATUS 
    WHERE VARIABLE_NAME = 'wsrep_local_commits';

    SELECT 
        VARIABLE_VALUE as avg_commit_time
    FROM INFORMATION_SCHEMA.GLOBAL_STATUS 
    WHERE VARIABLE_NAME = 'wsrep_commit_oooe';"
done

8. Handling Node Recovery

Optimized SST Configuration:

-- Use faster SST method
SET GLOBAL wsrep_sst_method = 'mariabackup';

-- Optimize SST performance
SET GLOBAL wsrep_provider_options = 
'socket.ssl=no;
gcache.size=2G;
gcs.recv_q_hard_limit=2147483647;
gcs.recv_q_soft_limit=1073741823;
gcs.max_throttle=0.25';

Application-Level Optimizations

9. Connection and Query Optimization

Connection Pooling Configuration:

# Python example with connection pooling
import mysql.connector.pooling

config = {
    'user': 'app_user',
    'password': 'password',
    'host': 'galera-proxy',
    'database': 'app_db',
    'pool_name': 'galera_pool',
    'pool_size': 20,
    'pool_reset_session': True,
    'autocommit': True,  # For better Galera performance
    'sql_mode': 'TRADITIONAL'
}

pool = mysql.connector.pooling.MySQLConnectionPool(**config)

Batch Operations:

-- Use batch inserts instead of individual inserts
INSERT INTO table (col1, col2, col3) VALUES 
    (val1, val2, val3),
    (val4, val5, val6),
    (val7, val8, val9);

-- Use INSERT ... ON DUPLICATE KEY UPDATE for upserts
INSERT INTO table (id, data) VALUES (1, 'new_data')
ON DUPLICATE KEY UPDATE data = VALUES(data);

10. Load Balancing Write Operations

HAProxy Configuration for Write Distribution:

# haproxy.cfg
global
    maxconn 4096

defaults
    mode tcp
    timeout connect 5000ms
    timeout client 50000ms
    timeout server 50000ms

# Write operations - single node
frontend galera_writes
    bind *:3307
    default_backend galera_write_nodes

backend galera_write_nodes
    balance first
    option httpchk
    server node1 10.0.1.10:3306 check port 9200
    server node2 10.0.1.11:3306 check port 9200 backup
    server node3 10.0.1.12:3306 check port 9200 backup

Performance Monitoring and Alerting

11. Key Metrics to Monitor

Critical Performance Indicators:

-- Create monitoring view
CREATE VIEW galera_performance_metrics AS
SELECT 
    'Flow Control Paused' as metric,
    VARIABLE_VALUE as value,
    CASE 
        WHEN CAST(VARIABLE_VALUE AS DECIMAL) > 0.1 THEN 'CRITICAL'
        WHEN CAST(VARIABLE_VALUE AS DECIMAL) > 0.05 THEN 'WARNING'
        ELSE 'OK'
    END as status
FROM INFORMATION_SCHEMA.GLOBAL_STATUS 
WHERE VARIABLE_NAME = 'wsrep_flow_control_paused'

UNION ALL

SELECT 
    'Local Send Queue' as metric,
    VARIABLE_VALUE as value,
    CASE 
        WHEN CAST(VARIABLE_VALUE AS DECIMAL) > 100 THEN 'CRITICAL'
        WHEN CAST(VARIABLE_VALUE AS DECIMAL) > 50 THEN 'WARNING'
        ELSE 'OK'
    END as status
FROM INFORMATION_SCHEMA.GLOBAL_STATUS 
WHERE VARIABLE_NAME = 'wsrep_local_send_queue';

12. Automated Performance Tuning

Dynamic Configuration Adjustment:

#!/bin/bash
# auto_tune_galera.sh

# Check current flow control status
FC_PAUSED=$(mysql -e "SHOW STATUS LIKE 'wsrep_flow_control_paused';" | awk 'NR==2 {print $2}')

if (( $(echo "$FC_PAUSED > 0.1" | bc -l) )); then
    echo "High flow control detected, adjusting parameters..."
    mysql -e "SET GLOBAL wsrep_slave_threads = 8;"
    mysql -e "SET GLOBAL innodb_flush_log_at_trx_commit = 0;"
fi

# Check queue sizes
SEND_QUEUE=$(mysql -e "SHOW STATUS LIKE 'wsrep_local_send_queue';" | awk 'NR==2 {print $2}')

if [ "$SEND_QUEUE" -gt 100 ]; then
    echo "High send queue detected, optimizing network settings..."
    mysql -e "SET GLOBAL wsrep_provider_options = 'gcs.fc_limit=512';"
fi

Best Practices for Write Performance

  1. Use smaller, frequent transactions instead of large bulk operations
  2. Implement proper connection pooling to reduce connection overhead
  3. Monitor and tune flow control parameters based on workload patterns
  4. Use appropriate isolation levels (READ COMMITTED for better performance)
  5. Optimize network infrastructure with low latency and high bandwidth
  6. Regular monitoring of cluster health and performance metrics
  7. Implement proper backup strategies that don’t impact write performance

By systematically addressing these areas, you can significantly improve write performance in Galera Cluster operations while maintaining data consistency and cluster stability.

FAQ’s

Q1: Why does Galera Cluster exhibit slower write performance compared to standalone MySQL?
Galera Cluster employs synchronous replication, requiring write operations to be confirmed by all nodes before completion. This ensures data consistency but can introduce latency, especially if any node is slow or network issues are present.

Q2: How can I detect if flow control is impacting write performance?
Monitor the wsrep_flow_control_paused status variable. A high value indicates frequent flow control pauses, which can throttle write operations.

Q3: What are common indicators of network-related write bottlenecks in Galera Cluster?
High values in wsrep_local_send_queue and wsrep_local_recv_queue suggest network latency or bandwidth issues affecting replication and write performance.

Q4: How can large transactions affect Galera Cluster’s write performance?
Large transactions can lead to increased memory usage and potential timeouts. It’s advisable to break large transactions into smaller chunks and adjust wsrep_max_ws_size and wsrep_max_ws_rows settings accordingly.

Related Articles

Further Reading on Galera Cluster Performance:



Troubleshooting Galera Cluster for performance

 

Exploring Thread Contention in Linux: Causes and Solutions

 

How are Global Indexes implemented in PostgreSQL?

About MinervaDB Corporation 80 Articles
Full-stack Database Infrastructure Architecture, Engineering and Operations Consultative Support(24*7) Provider for PostgreSQL, MySQL, MariaDB, MongoDB, ClickHouse, Trino, SQL Server, Cassandra, CockroachDB, Yugabyte, Couchbase, Redis, Valkey, NoSQL, NewSQL, Databricks, Amazon Resdhift, Amazon Aurora, CloudSQL, Snowflake and AzureSQL with core expertize in Performance, Scalability, High Availability, Database Reliability Engineering, Database Upgrades/Migration, and Data Security.

Be the first to comment

Leave a Reply