-
Notifications
You must be signed in to change notification settings - Fork 84
4. Replication Lag
LudicrousDB can avoid a replica whose lag exceeds its configured threshold. If no threshold is set, lag is ignored.
A replica is considered lagged when its measured lag is greater than its per-database lag_threshold, or the default in $wpdb->database_defaults['lag_threshold']. A dataset callback may also return a server override containing lag_threshold.
LudicrousDB does not impose a replication monitor. Register two callbacks to supply lag data:
$wpdb->add_callback( 'ludicrousdb_get_lag_cache', 'get_lag_cache' );
$wpdb->add_callback( 'ludicrousdb_get_lag', 'get_lag' );The cache callback runs before a connection is made and should return lag in seconds, or false when unknown. $wpdb->lag_cache_key identifies the replica endpoint. The live callback runs after connection and can use $wpdb->dbhs[ $wpdb->dbhname ].
Percona Toolkit's pt-heartbeat can maintain a timestamp that replicates from the primary. Change heartbeat.heartbeat below to your qualified database and table. The LudicrousDB user needs SELECT access to it.
The qualified table name is deliberate: it avoids changing the selected database before WordPress's query runs. A persistent WordPress object-cache drop-in can share the cached value across requests; without one, the live check remains authoritative.
if ( ! defined( 'LUDICROUSDB_LAG_CACHE_TTL' ) ) {
define( 'LUDICROUSDB_LAG_CACHE_TTL', 30 );
}
$wpdb->add_callback( 'ludicrousdb_get_lag_cache', 'get_lag_cache' );
$wpdb->add_callback( 'ludicrousdb_get_lag', 'get_lag' );
function ludicrousdb_get_lag_cache( $wpdb ) {
if ( ! function_exists( 'wp_cache_get' ) || empty( $GLOBALS['wp_object_cache'] ) ) {
return false;
}
$lag = wp_cache_get( $wpdb->lag_cache_key, 'ludicrousdb-lag' );
return is_numeric( $lag ) ? (float) $lag : false;
}
function ludicrousdb_get_lag( $wpdb ) {
if ( empty( $wpdb->dbhs[ $wpdb->dbhname ] ) ) {
return false;
}
$dbh = $wpdb->dbhs[ $wpdb->dbhname ];
$result = mysqli_query(
$dbh,
'SELECT GREATEST( 0, UNIX_TIMESTAMP() - UNIX_TIMESTAMP( ts ) ) AS lag
FROM heartbeat.heartbeat
ORDER BY ts DESC
LIMIT 1'
);
if ( false === $result ) {
return false;
}
$row = mysqli_fetch_assoc( $result );
mysqli_free_result( $result );
if ( ! is_array( $row ) || ! isset( $row['lag'] ) || ! is_numeric( $row['lag'] ) ) {
return false;
}
$lag = (float) $row['lag'];
if ( function_exists( 'wp_cache_set' ) && ! empty( $GLOBALS['wp_object_cache'] ) ) {
wp_cache_set( $wpdb->lag_cache_key, $lag, 'ludicrousdb-lag', LUDICROUSDB_LAG_CACHE_TTL );
}
return $lag;
}Treat an unknown measurement deliberately. Returning false means LudicrousDB has no lag value; it does not prove that a replica is current. Your monitoring and failover design still need to cover stale, stopped, and divergent replicas.
LudicrousDB documentation · Repository · Support