ludicrousdb icon indicating copy to clipboard operation
ludicrousdb copied to clipboard

DB Connections are out of control, running a process jumped to over 2000 connections

Open jpSimkins opened this issue 4 years ago • 6 comments

I used HyperDB and had no issues. I wanted to use this plugin as word around Google is it's more "up-to-date".

I switched to this plugin and within 30 minutes our DB connections went from an average of 100 connections to 2700. I could see the connection spike happening. This naturally caused a max_connections issue and I had to quickly revert this update and go back to HyperDB.

Traffic is not a cause here. This was on minimal traffic. We were performing an import which does many numerous DB calls reads and writes.

Also note, that I ran the same import with HyperDB and the DB connections went to a max of 175 connections. Still higher than I expect but I am not sure how PHP and MySQL work under the hood.

Please let me know if I can provide you with more details.

I am using AWS RDS (Aurora MySQL 5.7.12 with 2 db.r5.2xlarge instances, 1 Writer, 1 Reader).

The server cluster is Amazon Linux 2 AMI running PHP-FPM 7.2 with Apache 2.4.

Using ludicrousdb version: 5.0.0

I cannot provide logs as reverting back spun up new instances and destroyed the older ones (I know, centralized logs are important). When I checked the logs, I didn't see any errors other than connection timeouts or MySQL has gone away.

DB Constants in wp-config.php

define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', 'utf8mb4_general_ci');

My db-config.php:

<?php
/**
 * LudicrousDB configuration file
 *
 * This file should be copied to ABSPATH/db-config.php and modified to suit your
 * database environment. This file comes with a basic configuration by default.
 *
 * See README.md for documentation.
 */

// Exit if accessed directly
defined('ABSPATH') || exit;

/**
 * charset (string)
 * This sets the default character set. Since WordPress 4.2, the suggested
 * setting is "utf8mb4". We strongly recommend not downgrading to utf8,
 * using latin1, or sticking to the default: utf8mb4.
 *
 * Default: utf8mb4
 */
$wpdb->charset = DB_CHARSET;

/**
 * collate (string)
 * This sets the default column collation. For best results, investigate which
 * collation is recommended for your specific character set.
 *
 * Default: utf8mb4_unicode_520_ci
 */
$wpdb->collate = DB_COLLATE;

/**
 * save_queries (bool)
 * This is useful for debugging. Queries are saved in $wpdb->queries. It is not
 * a constant because you might want to use it momentarily.
 * Default: false
 */
$wpdb->save_queries = false;

/**
 * recheck_timeout (float)
 * The amount of time to wait before trying again to ping mysql server.
 *
 * Default: 0.1 (Seconds)
 */
$wpdb->recheck_timeout = 0.1;

/**
 * persistent (bool)
 * This determines whether to use mysql_connect or mysql_pconnect. The effects
 * of this setting may vary and should be carefully tested.
 * Default: false
 */
$wpdb->persistent = false;

/**
 * allow_bail (bool)
 * This determines whether to use mysql connect or mysql connect has failed and to bail loading the rest of WordPress
 * Default: false
 */
$wpdb->allow_bail = false;

/**
 * max_connections (int)
 * This is the number of mysql connections to keep open. Increase if you expect
 * to reuse a lot of connections to different servers. This is ignored if you
 * enable persistent connections.
 * Default: 10
 */
$wpdb->max_connections = 10;

/**
 * check_tcp_responsiveness
 * Enables checking TCP responsiveness by fsockopen prior to mysql_connect or
 * mysql_pconnect. This was added because PHP's mysql functions do not provide
 * a variable timeout setting. Disabling it may improve average performance by
 * a very tiny margin but lose protection against connections failing slowly.
 * Default: true
 */
$wpdb->check_tcp_responsiveness = true;

/**
 * The cache group that is used to store TCP responsiveness.
 * Default: ludicrousdb
 */
$wpdb->cache_group = 'ludicrousdb';

/**
 * This is the most basic way to add a server to LudicrousDB using only the
 * required parameters: host, user, password, name.
 * This adds the DB defined in wp-config.php as a read/write server for
 * the 'global' dataset. (Every table is in 'global' by default.)
 */

$wpdb->add_database(array(
    'host'     => DB_HOST,     // If port is other than 3306, use host:port.
    'user'     => DB_USER,
    'password' => DB_PASSWORD,
    'name'     => DB_NAME,
    'write'    => 1,
    'read'     => 2,
));

// use reader only for frontend
if (defined('DB_READ_HOST') && !is_admin()) {
    $wpdb->add_database(array(
        'host'     => DB_READ_HOST,     // If port is other than 3306, use host:port.
        'user'     => DB_USER,
        'password' => DB_PASSWORD,
        'name'     => DB_NAME,
        'write'    => 0,
        'read'     => 1,
        'dataset'  => 'global',
        'timeout'  => 0.3,
    ));
}

jpSimkins avatar Apr 16 '20 14:04 jpSimkins

I have faced the same problem having an RDS cluster with read replicas. In my case the problem is that I didn't install ludicrousdb correctly. I have fixed it by following these steps:

1.- Downloading the zip file https://github.com/stuttter/ludicrousdb/archive/master.zip 2.- Unzipping the content in wp-content/plugins/ludicrous 3.- Modifying db-config.php file adding writer and reader endpoints of the RDS cluster 4.- Copying db-config.php file to webroot 5.- Copying db.php and db-error.php to wp-content/

This is my wp-content/plugins/ludicrousdb directory:

wp-content/plugins/ludicrousdb ├── composer.json ├── drop-ins │   ├── db-config.php │   ├── db-error.php │   └── db.php ├── includes │   ├── class-ludicrousdb.php │   └── functions.php ├── LICENSE ├── ludicrousdb │   ├── db-config.php │   ├── drop-ins │   │   ├── db-config.php │   │   ├── db-error.php │   │   └── db.php │   └── includes │   ├── class-ludicrousdb.php │   └── functions.php ├── ludicrousdb.php ├── phpcs.xml ├── README.md └── readme.txt

And this is the content of db-config.php adding RDS cluster reader and writer endpoints:

$wpdb->add_database(array(
        'host'     => 'RDS_HOSTNAME',     // If port is other than 3306, use host:port.
        'user'     => 'RDS_USERNAME',
        'password' => 'RDS_PASSWORD',
        'name'     => 'RDS_DB_NAME',
        'write'    => 1,
        'read'     => 0,
));
// Read replica
$wpdb->add_database(array(
        'host'     => 'RDS_HOSTNAME_READER',     // If port is other than 3306, use host:port.
        'user'     => 'RDS_USERNAME',
        'password' => 'RDS_PASSWORD',
        'name'     => 'RDS_DB_NAME',
        'write'    => 0,
        'read'     => 1,
        'dataset'  => 'global',
        'timeout'  => 0.2,
));

isradelatorre avatar Sep 20 '20 12:09 isradelatorre

Installation guide is not good ;-)

des79 avatar Sep 25 '20 11:09 des79

@des79 could you improve the installation guide text, since you already know how it works now Then we could merge it in, to help out others in the future

kkmuffme avatar Sep 30 '20 09:09 kkmuffme

@isradelatorre Thanks for your information. Unfortunately, I did install this properly. I have since gone back to hyper-db and it is working fine for now. I will not be able to attempt to use this until maybe next year at the earliest and it would have to be on a new system. The system is now averaging over a million users/day and I cannot risk attempting this again.

I personally have no issues with the installation guide, this isn't complex to setup. I have tested 3 times by switching back and forth between hyper-db and this plugin and every time I would use this plugin, what I posted above would happen. I was never able to get this plugin to work as expected. That is unfortunate.

jpSimkins avatar Sep 30 '20 14:09 jpSimkins

Sorry for the trouble @jpSimkins. Without logs it's difficult to know for sure what happened, but obviously your experience isn't one we want people to have with LDB, so it will be important that we get this figured out eventually.

Possibly related to #103?

JJJ avatar Oct 26 '20 11:10 JJJ

I have faced the same problem having an RDS cluster with read replicas. In my case the problem is that I didn't install ludicrousdb correctly. I have fixed it by following these steps:

1.- Downloading the zip file https://github.com/stuttter/ludicrousdb/archive/master.zip 2.- Unzipping the content in wp-content/plugins/ludicrous 3.- Modifying db-config.php file adding writer and reader endpoints of the RDS cluster 4.- Copying db-config.php file to webroot 5.- Copying db.php and db-error.php to wp-content/

This is my wp-content/plugins/ludicrousdb directory:

wp-content/plugins/ludicrousdb ├── composer.json ├── drop-ins │   ├── db-config.php │   ├── db-error.php │   └── db.php ├── includes │   ├── class-ludicrousdb.php │   └── functions.php ├── LICENSE ├── ludicrousdb │   ├── db-config.php │   ├── drop-ins │   │   ├── db-config.php │   │   ├── db-error.php │   │   └── db.php │   └── includes │   ├── class-ludicrousdb.php │   └── functions.php ├── ludicrousdb.php ├── phpcs.xml ├── README.md └── readme.txt

Hmm, as a noob this is even more confusing for me now.

You have 3 copies of db-config.php?

  1. wp-content/plugins/ludicrousdb/drop-ins/
  2. wp-content/plugins/ludicrousdb/ludicrousdb/drop-ins/
  3. root

And 3 copies of db.php and db-error.php each?

  1. wp-content/plugins/ludicrousdb/drop-ins/
  2. wp-content/plugins/ludicrousdb/ludicrousdb/drop-ins/
  3. wp-content/

:(

RocknRoIla avatar May 14 '21 13:05 RocknRoIla