vogelor
2011-03-28 eed6b3c6f189fcb318a38ef70c66d1501123f342
the new rescue-module is now able to rescue (restart) mysql
4 files modified
221 ■■■■■ changed files
server/lib/classes/db_mysql.inc.php 10 ●●●● patch | view | raw | blame | history
server/lib/classes/monitor_tools.inc.php 69 ●●●●● patch | view | raw | blame | history
server/mods-available/rescue_core_module.inc.php 94 ●●●●● patch | view | raw | blame | history
server/server.php 48 ●●●● patch | view | raw | blame | history
server/lib/classes/db_mysql.inc.php
@@ -61,8 +61,8 @@
        function updateError($location)
        {
            global $app;
            $this->errorNumber = mysql_errno($this->linkId);
            $this->errorMessage = mysql_error($this->linkId);
            $this->errorNumber = @mysql_errno($this->linkId);
            $this->errorMessage = @mysql_error($this->linkId);
            $this->errorLocation = $location;
            if($this->errorNumber && $this->show_error_messages && method_exists($app,'log'))
            {
@@ -76,7 +76,7 @@
        {
            if($this->linkId == 0)
            {
                $this->linkId = mysql_connect($this->dbHost, $this->dbUser, $this->dbPass);
                $this->linkId = @mysql_connect($this->dbHost, $this->dbUser, $this->dbPass);
                if(!$this->linkId)
                {
                    $this->updateError('DB::connect()-> mysql_connect');
@@ -463,7 +463,7 @@
       return $this->query($sql);
       }
       
       // gibt Array mit Tabellennamen zurück
       // gibt Array mit Tabellennamen zur�ck
       function getTables($database_name = '') {
           
            if($database_name == '') $database_name = $this->dbName;
@@ -474,7 +474,7 @@
            return $tb_names;       
       }
       
       // gibt Feldinformationen zur Tabelle zurück
       // gibt Feldinformationen zur Tabelle zur�ck
       /*
       $columns = array(action =>   add | alter | drop
                        name =>     Spaltenname
server/lib/classes/monitor_tools.inc.php
@@ -520,6 +520,14 @@
        /** get the "active" Services of the server from the DB */
        $services = $app->dbmaster->queryOneRecord('SELECT * FROM server WHERE server_id = ' . $server_id);
        /*
         * If the DB is down, we have to set the db to "yes".
         * If we don't do this, then the monitor will NOT monitor, that the db is down and so the
         * rescue-module can not try to rescue the db
         */
        if ($services == null) {
            $services['db_server'] = 1;
        }
        /* The type of the Monitor-data */
        $type = 'services';
@@ -1578,6 +1586,67 @@
        }
    }
    /*
     * Set the state to the given level (or higher, but not lesser).
     * * If the actual state is critical and you call the method with ok,
     *   then the state is critical.
     *
     * * If the actual state is critical and you call the method with error,
     *   then the state is error.
     */
    private function _setState($oldState, $newState)
    {
        /*
         * Calculate the weight of the old state
         */
        switch ($oldState) {
            case 'no_state': $oldInt = 0;
                break;
            case 'ok': $oldInt = 1;
                break;
            case 'unknown': $oldInt = 2;
                break;
            case 'info': $oldInt = 3;
                break;
            case 'warning': $oldInt = 4;
                break;
            case 'critical': $oldInt = 5;
                break;
            case 'error': $oldInt = 6;
                break;
        }
        /*
         * Calculate the weight of the new state
         */
        switch ($newState) {
            case 'no_state': $newInt = 0 ;
                break;
            case 'ok': $newInt = 1 ;
                break;
            case 'unknown': $newInt = 2 ;
                break;
            case 'info': $newInt = 3 ;
                break;
            case 'warning': $newInt = 4 ;
                break;
            case 'critical': $newInt = 5 ;
                break;
            case 'error': $newInt = 6 ;
                break;
        }
        /*
         * Set to the higher level
         */
        if ($newInt > $oldInt){
            return $newState;
        }
        else
        {
            return $oldState;
        }
    }
    private function _getIntArray($line) {
        /** The array of float found */
        $res = array();
server/mods-available/rescue_core_module.inc.php
@@ -94,6 +94,11 @@
        $this->_rescueApache();
        
        /*
         * rescue mysql if needed
         */
        $this->_rescueMySql();
        /*
         * The last step is to save the rescue-data
         */
        $this->_saveRescueData();
@@ -263,15 +268,94 @@
        $app->log('Apache is down! Try rescue apache (try:' . $tryCount . ')...', LOGLEVEL_WARN);
//        echo 'Apache is down! Try rescue apache (try:' . $tryCount . ')...';
        /*
         * First we stop the running service "normally"
         */
        $daemon = '';
        if(is_file($conf['init_scripts'] . '/' . 'httpd')) {
            $daemon = 'httpd';
        } else {
            $daemon = 'apache2';
        }
        $this->_rescueDaemon($daemon);
    }
    /**
     * restarts mysql, if needed
     */
    private function _rescueMySql(){
        global $app, $conf;
        /*
         * do nothing, if it is not allowed to rescue mysql
         */
        if ((isset($conf['serverconfig']['rescue']['do_not_try_rescue_mysql']) && ($conf['serverconfig']['rescue']['do_not_try_rescue_mysql']) == 'y')){
            return;
        }
        /*
         * if the service is up and running, or the service is not installed there is nothing to do...
         */
        if ($this->_monitoringData[0][0]['data']['mysqlserver'] != 0){
            /* Clear the try counter, because we do not have to try to rescue the service */
            $this->_rescueData['mysqlserver']['try_counter'] = 0;
            return;
        }
        /*
         * OK, the service is installed and down.
         * Maybe this is because of a restart of the service by the admin.
         * This means, we check the data 1 minute ago
         */
        if ((!isset($this->_monitoringData[1][0]['data']['mysqlserver'])) ||
                ((isset($this->_monitoringData[1][0]['data']['mysqlserver'])) && ($this->_monitoringData[1][0]['data']['mysqlserver'] != 0))){
            /*
             * We do NOT have this data or we have this data, but the webserver was not down 1 minute ago.
             * This means, it could be, that the admin is restarting the server.
             * We wait one more minute...
             */
            return;
        }
        /*#####
         * The service is down and it was down 1 minute ago.
         * We try to rescue it
         *#####*/
        /* Get the try counter */
        $tryCount = (!isset($this->_rescueData['mysqlserver']['try_counter']))? 1 : $this->_rescueData['mysqlserver']['try_counter'] + 1;
        /* Set the new try counter */
        $this->_rescueData['mysqlserver']['try_counter'] = $tryCount;
        /* if 5 times will not work, we have to give up... */
        if ($tryCount > 5){
            $app->log('MySQL is down! Rescue will not help!', LOGLEVEL_ERROR);
            return;
        }
        $app->log('MySQL is down! Try rescue mysql (try:' . $tryCount . ')...', LOGLEVEL_WARN);
//        echo 'MySQL is down! Try rescue mysql (try:' . $tryCount . ')...';
        if(is_file($conf['init_scripts'] . '/' . 'mysqld')) {
            $daemon = 'mysqld';
        } else {
            $daemon = 'mysql';
        }
        $this->_rescueDaemon($daemon);
    }
    /**
     * Tries to stop and then restart the daemon
     *
     * @param type $daemon the name of the daemon
     */
    private function _rescueDaemon($daemon){
        global $conf;
        // if you need to find all restarts search for "['init_scripts']"
        /*
         * First we stop the running service "normally"
         */
        
        /*
         * ATTENTION!
@@ -292,7 +376,5 @@
         */
        exec($conf['init_scripts'] . '/' . $daemon . ' start');
    }
// if you need to find all restarts search for "['init_scripts']"
}
?>
server/server.php
@@ -50,7 +50,9 @@
}
*/
//* Load the server configuration
/*
 * Try to Load the server configuration from the master-db
 */
if($app->dbmaster->connect()) {
    // get the dalaog_id of the last performed record
    $server_db_record = $app->dbmaster->queryOneRecord("SELECT * FROM server WHERE server_id = ".$conf['server_id']);
@@ -64,6 +66,21 @@
    $conf['log_priority'] = intval($conf['serverconfig']['server']['loglevel']);
    
    unset($server_db_record);
} else {
    /*
     * The master-db is not available.
     * Problem: because we need to start the rescue-module (to rescue the DB if this IS the
     * server, the master-db is running at) we have to initialize some config...
     */
    $conf['last_datalog_id'] = intval('9223372036854775807'); // maxint at 32 and 64 bit systems
    $conf['mirror_server_id'] = 0; // no mirror
    // Set the loglevel to warning
    $conf['log_priority'] = LOGLEVEL_WARN;
    /*
     * Set the configuration to rescue the database
     */
    $conf['serverconfig']['rescue']['try_rescue'] = 'y';
    $conf['serverconfig']['rescue']['do_not_try_rescue_mysql'] = 'n';
}
@@ -88,7 +105,12 @@
@touch($conf['temppath'].$conf['fs_div'].'.ispconfig_lock');
$app->log('Set Lock: '.$conf['temppath'].$conf['fs_div'].'.ispconfig_lock', LOGLEVEL_DEBUG);
/** Do we need to start the core-modules */
$needStartCore = true;
/*
 * Next we try to process the datalog
 */
if($app->db->connect() && $app->dbmaster->connect()) {
    // Check if there is anything to update
@@ -118,10 +140,24 @@
        $app->modules->processDatalog();
        // Restart services that need to after configuration
        $app->services->processDelayedActions();
        // All modules are already loaded and processed, so there is NO NEED to load the core once again...
        $needStartCore = false;
    }
    } else {
    if (!$app->db->connect()) {
        $app->log('Unable to connect to local server.' . $app->db->errorMessage, LOGLEVEL_WARN);
    } else {
        $app->log('Unable to connect to master server.' . $app->dbmaster->errorMessage, LOGLEVEL_WARN);
    }
}
        /*
         There is no trigger inside the database -> load only the core, maybe they have to do something
 * Under normal circumstances the system was loaded and all updates are done.
 * but if we do not have to update anything or if the database is not accessible, then we
 * have to start the core-system (if the database is accessible, we need the core because of the
 * monitoring. If the databse is NOT accessible, we need the core because of rescue the db...
        */
if ($needStartCore) {
        // Write the log
        $app->log('No Updated records found, starting only the core.', LOGLEVEL_DEBUG);
        // Load required base-classes
@@ -131,13 +167,7 @@
        // Load the plugins that are in the plugins-core folder
        $app->plugins->loadPlugins('core');
    }
} else {
    if(!$app->db->connect()) {
        $app->log('Unable to connect to local server.'.$app->db->errorMessage,LOGLEVEL_WARN);
    } else {
        $app->log('Unable to connect to master server.'.$app->dbmaster->errorMessage,LOGLEVEL_WARN);
    }
}
// Remove lock
@unlink($conf['temppath'].$conf['fs_div'].'.ispconfig_lock');