refactor: DB Updates will now file level lock to stop duplicate updates (#6469)

* refactor: DB Updates will now file level lock to stop duplicate updates

* scrut fixes

* renamed function from clear_lock() to release_lock()
This commit is contained in:
Neil Lathwood
2017-05-03 14:48:23 +01:00
committed by GitHub
parent 0dcc1d18c5
commit 41e7689c77
10 changed files with 82 additions and 27 deletions

View File

@@ -30,21 +30,7 @@ require __DIR__ . '/includes/init.php';
$options = getopt('d::'); $options = getopt('d::');
$lock = false; set_lock('alerts');
if (file_exists($config['install_dir'].'/.alerts.lock')) {
$pids = explode("\n", trim(`ps -e | grep php | awk '{print $1}'`));
$lpid = trim(file_get_contents($config['install_dir'].'/.alerts.lock'));
if (in_array($lpid, $pids)) {
$lock = true;
}
}
if ($lock === true) {
exit(1);
} else {
file_put_contents($config['install_dir'].'/.alerts.lock', getmypid());
}
if (isset($options['d'])) { if (isset($options['d'])) {
echo "DEBUG!\n"; echo "DEBUG!\n";
@@ -74,7 +60,7 @@ if (!defined('TEST') && $config['alert']['disable'] != 'true') {
echo 'End : '.date('r')."\r\n"; echo 'End : '.date('r')."\r\n";
} }
unlink($config['install_dir'].'/.alerts.lock'); release_lock('alerts');
function ClearStaleAlerts() function ClearStaleAlerts()
{ {

View File

@@ -113,7 +113,9 @@ if (!$where) {
exit; exit;
} }
if (get_lock('schema') === false) {
require 'includes/sql-schema/update.php'; require 'includes/sql-schema/update.php';
}
$discovered_devices = 0; $discovered_devices = 0;

View File

@@ -9,16 +9,32 @@ then you can do this by running the following command as the **librenms** user:
This will update both the core LibreNMS files but also update the database This will update both the core LibreNMS files but also update the database
structure if updates are available. structure if updates are available.
#### Advanced users
If you absolutely must update manually then you can do so by running the following commands:
```bash
cd /opt/librenms
git pull
php includes/sql-schema/update.php
```
## Configuring the update channel ## ## Configuring the update channel ##
LibreNMS follows the master branch on github for daily updates. LibreNMS follows the master branch on github for daily updates.
You can change to the monthly releases by setting:
#### Stable branch
You can change to the stable monthly branch by setting:
`$config['update_channel'] = 'release';` `$config['update_channel'] = 'release';`
> Choose this branch if you want to have a stable release
#### Development branch
You can change to the development branch by setting:
`$config['update_channel'] = 'master';`
> Choose this branch if you want the latest features at the cost that sometimes bugs are inadvertently introduced.
## Disabling automatic updates ## ## Disabling automatic updates ##
LibreNMS by default performs updates on a daily basis. This can be disabled LibreNMS by default performs updates on a daily basis. This can be disabled by setting:
by ensuring:
`$config['update'] = 0;` `$config['update'] = 0;`
is no longer commented out.

View File

@@ -57,7 +57,7 @@ $msg_box = array();
// Check for install.inc.php // Check for install.inc.php
if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') { if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {
// no config.php does so let's redirect to the install // no config.php does so let's redirect to the install
header('Location: install.php'); header("Location: {$config['base_url']}/install.php");
exit; exit;
} }

View File

@@ -22,7 +22,7 @@ if ($stage > 3) {
require realpath(__DIR__ . '/..') . '/includes/init.php'; require realpath(__DIR__ . '/..') . '/includes/init.php';
// List of php modules we expect to see // List of php modules we expect to see
$modules = array('gd','mysqli','snmp','mcrypt'); $modules = array('gd','mysqli','mcrypt');
$dbhost = @$_POST['dbhost'] ?: 'localhost'; $dbhost = @$_POST['dbhost'] ?: 'localhost';
$dbuser = @$_POST['dbuser'] ?: 'librenms'; $dbuser = @$_POST['dbuser'] ?: 'librenms';

View File

@@ -2327,6 +2327,53 @@ function db_schema_is_current()
return $current >= $latest; return $current >= $latest;
} }
/**
* Get the lock status for a given name
* @param $name
* @return bool
*/
function get_lock($name)
{
global $config;
$lock_file = $config['install_dir']."/.$name.lock";
if (file_exists($lock_file)) {
$pids = explode("\n", trim(`ps -e | grep php | awk '{print $1}'`));
$lpid = trim(file_get_contents($lock_file));
if (in_array($lpid, $pids)) {
return true;
}
}
return false;
}
/**
* Set the lock status for a given name
* @param $name
*/
function set_lock($name)
{
global $config;
$lock_file = $config['install_dir']."/.$name.lock";
$lock = get_lock($name);
if ($lock === true) {
echo "$lock_file exists, exiting\n";
exit(1);
} else {
file_put_contents($lock_file, getmypid());
}
}
/**
* Release lock file for a given name
* @param $name
*/
function release_lock($name)
{
global $config;
unlink($config['install_dir']."/.$name.lock");
}
/** /**
* @param $device * @param $device
* @return int|null * @return int|null

View File

@@ -15,6 +15,8 @@
* See COPYING for more details. * See COPYING for more details.
*/ */
set_lock('schema');
if (!isset($debug) && php_sapi_name() == 'cli') { if (!isset($debug) && php_sapi_name() == 'cli') {
// Not called from within discovery, let's load up the necessary stuff. // Not called from within discovery, let's load up the necessary stuff.
$init_modules = array(); $init_modules = array();
@@ -24,8 +26,11 @@ if (!isset($debug) && php_sapi_name() == 'cli') {
$debug = isset($options['d']); $debug = isset($options['d']);
} }
d_echo("DB Schema update started....\n");
if (db_schema_is_current()) { if (db_schema_is_current()) {
d_echo("DB Schema already up to date.\n"); d_echo("DB Schema already up to date.\n");
release_lock('schema');
return; return;
} }
@@ -91,3 +96,5 @@ if ($updating) {
$_SESSION['build-ok'] = true; $_SESSION['build-ok'] = true;
} }
} }
release_lock('schema');

View File

@@ -1,4 +1,3 @@
UPDATE dbSchema SET version = 107;
CREATE TABLE bill_port_counters_tmp(port_id int NOT NULL PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT current_timestamp, in_counter bigint, in_delta bigint NOT NULL DEFAULT 0, out_counter bigint, out_delta bigint NOT NULL DEFAULT 0); CREATE TABLE bill_port_counters_tmp(port_id int NOT NULL PRIMARY KEY, `timestamp` timestamp NOT NULL DEFAULT current_timestamp, in_counter bigint, in_delta bigint NOT NULL DEFAULT 0, out_counter bigint, out_delta bigint NOT NULL DEFAULT 0);
INSERT INTO bill_port_counters_tmp(port_id, timestamp, in_counter, out_counter) SELECT q.port_id, q.max_timestamp, max(i.counter), max(o.counter) FROM (SELECT port_id, MAX(`timestamp`) AS max_timestamp FROM port_in_measurements GROUP BY port_id) q INNER JOIN port_in_measurements i ON q.port_id = i.port_id AND q.max_timestamp = i.timestamp INNER JOIN port_out_measurements o ON q.port_id = o.port_id AND q.max_timestamp = o.timestamp GROUP BY q.port_id, q.max_timestamp; INSERT INTO bill_port_counters_tmp(port_id, timestamp, in_counter, out_counter) SELECT q.port_id, q.max_timestamp, max(i.counter), max(o.counter) FROM (SELECT port_id, MAX(`timestamp`) AS max_timestamp FROM port_in_measurements GROUP BY port_id) q INNER JOIN port_in_measurements i ON q.port_id = i.port_id AND q.max_timestamp = i.timestamp INNER JOIN port_out_measurements o ON q.port_id = o.port_id AND q.max_timestamp = o.timestamp GROUP BY q.port_id, q.max_timestamp;
RENAME TABLE bill_port_counters_tmp TO bill_port_counters; RENAME TABLE bill_port_counters_tmp TO bill_port_counters;

View File

@@ -1,4 +1,3 @@
UPDATE dbSchema SET version = 118;
ALTER TABLE `eventlog` ADD `device_id` INT NOT NULL AFTER `host` ; ALTER TABLE `eventlog` ADD `device_id` INT NOT NULL AFTER `host` ;
ALTER TABLE `eventlog` ADD INDEX ( `device_id` ) ; ALTER TABLE `eventlog` ADD INDEX ( `device_id` ) ;
UPDATE eventlog SET device_id=host WHERE device_id=0; UPDATE eventlog SET device_id=host WHERE device_id=0;

View File

@@ -1,4 +1,3 @@
UPDATE `dbSchema` SET `version` = 171;
ALTER TABLE `access_points` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; ALTER TABLE `access_points` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
ALTER TABLE `alert_map` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; ALTER TABLE `alert_map` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;
ALTER TABLE `alert_rules` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; ALTER TABLE `alert_rules` DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci;