diff --git a/doc/htconfig.md b/doc/htconfig.md index 77e63671ab..2435da2baa 100644 --- a/doc/htconfig.md +++ b/doc/htconfig.md @@ -38,6 +38,8 @@ line to your .htconfig.php: * max_connections_level - The maximum level of connections that are allowed to let the poller start. It is a percentage value. Default value is 75. * max_contact_queue - Default value is 500. * max_batch_queue - Default value is 1000. +* max_processes_backend - Maximum number of concurrent database processes for background tasks. Default value is 5. +* max_processes_frontend - Maximum number of concurrent database processes for foreground tasks. Default value is 20. * no_oembed (Boolean) - Don't use OEmbed to fetch more information about a link. * no_oembed_rich_content (Boolean) - Don't show the rich content (e.g. embedded PDF). * no_smilies (Boolean) - Don't show smilies. diff --git a/include/dbm.php b/include/dbm.php new file mode 100644 index 0000000000..3f936947d8 --- /dev/null +++ b/include/dbm.php @@ -0,0 +1,39 @@ + List of processes, separated in their different states + * 'amount' => Number of concurrent database processes + */ + public static function processlist() { + $r = q("SHOW PROCESSLIST"); + $s = array(); + + $processes = 0; + $states = array(); + foreach ($r AS $process) { + $state = trim($process["State"]); + + // Filter out all idle processes + if (!in_array($state, array("", "init", "statistics"))) { + ++$states[$state]; + ++$processes; + } + } + + $statelist = ""; + foreach ($states AS $state => $usage) { + if ($statelist != "") + $statelist .= ", "; + $statelist .= $state.": ".$usage; + } + return(array("list" => $statelist, "amount" => $processes)); + } +} +?> diff --git a/include/poller.php b/include/poller.php index 3a28b177c3..a391ea8c75 100644 --- a/include/poller.php +++ b/include/poller.php @@ -11,6 +11,7 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) { } require_once("boot.php"); +require_once("dbm.php"); function poller_run(&$argv, &$argc){ global $a, $db; @@ -26,6 +27,20 @@ function poller_run(&$argv, &$argc){ unset($db_host, $db_user, $db_pass, $db_data); }; + $max_processes = get_config('system', 'max_processes_backend'); + if (intval($max_processes) == 0) + $max_processes = 5; + + $processlist = dbm::processlist(); + if ($processlist["list"] != "") { + logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG); + + if ($processlist["amount"] > $max_processes) { + logger("Processcheck: Maximum number of processes for backend tasks (".$max_processes.") reached.", LOGGER_DEBUG); + return; + } + } + if (poller_max_connections_reached()) return; @@ -59,6 +74,17 @@ function poller_run(&$argv, &$argc){ while ($r = q("SELECT * FROM `workerqueue` WHERE `executed` = '0000-00-00 00:00:00' ORDER BY `created` LIMIT 1")) { + // Log the type of database processes + $processlist = dbm::processlist(); + if ($processlist["amount"] != "") { + logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG); + + if ($processlist["amount"] > $max_processes) { + logger("Processcheck: Maximum number of processes for backend tasks (".$max_processes.") reached.", LOGGER_DEBUG); + return; + } + } + // Constantly check the number of available database connections to let the frontend be accessible at any time if (poller_max_connections_reached()) return; diff --git a/index.php b/index.php index 73f46cfbef..17258fd0ab 100644 --- a/index.php +++ b/index.php @@ -41,10 +41,11 @@ $install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false */ require_once("include/dba.php"); +require_once("include/dbm.php"); if(!$install) { $db = new dba($db_host, $db_user, $db_pass, $db_data, $install); - unset($db_host, $db_user, $db_pass, $db_data); + unset($db_host, $db_user, $db_pass, $db_data); /** * Load configs from db. Overwrite configs from .htconfig.php @@ -53,6 +54,21 @@ if(!$install) { load_config('config'); load_config('system'); + $processlist = dbm::processlist(); + if ($processlist["list"] != "") { + + logger("Processcheck: Processes: ".$processlist["amount"]." - Processlist: ".$processlist["list"], LOGGER_DEBUG); + + $max_processes = get_config('system', 'max_processes_frontend'); + if (intval($max_processes) == 0) + $max_processes = 20; + + if ($processlist["amount"] > $max_processes) { + logger("Processcheck: Maximum number of processes for frontend tasks (".$max_processes.") reached.", LOGGER_DEBUG); + return; + } + } + $maxsysload_frontend = intval(get_config('system','maxloadavg_frontend')); if($maxsysload_frontend < 1) $maxsysload_frontend = 50; @@ -442,9 +458,9 @@ if($a->is_mobile || $a->is_tablet) { $link = 'toggle_mobile?off=1&address=' . curPageURL(); } $a->page['footer'] = replace_macros(get_markup_template("toggle_mobile_footer.tpl"), array( - '$toggle_link' => $link, - '$toggle_text' => t('toggle mobile') - )); + '$toggle_link' => $link, + '$toggle_text' => t('toggle mobile') + )); } /**