Mysql-Tabelle crashed immer wieder

Mordor

Registered User
Hallo zusammen

Seit zwei Wochen habe ich testweise auf einer Seite ein PHP-Script am laufen, was die Sessionverwaltung regelt. In dieser Zeit habe ich zweimal Mails von OSSEC bekommen, dass eine Tabelle gecrashed ist. Das Problem konnte zwar jedes mal mit mysamchk -r wieder gelöst werden, nur frage ich mich schon die ganze Zeit, warum die Tabelle crashed. Es muss wohl am PHP-Skript liegen. nur komme ich selbst nicht hinter den Fehler.

Hier mal ein par Daten:

Meldung in den Logfiles von Mysql:
Code:
Oct  1 08:46:09 meinserver mysqld[2353]: 081001  8:46:09 [ERROR] /usr/sbin/mysqld: Table './domain/session' is marked as crashed and should be repaired
Ausgabe von myisamchk -e /pfad/zur/table
Code:
Checking MyISAM file: /var/lib/mysql/domain/session.MYI
Data records:       1   Deleted blocks:       9
myisamchk: warning: Table is marked as crashed
- check file-size
myisamchk: error: Size of datafile is: 20                Should be: 1592
- check record delete-chain
myisamchk: error: record delete-link-chain corrupted
- check key delete-chain
- check index reference
- check data record references index: 1
myisamchk: error: Found key at page 1024 that points to record outside datafile
- check records and index references
myisamchk: warning: Found 0 deleted space.   Should be 1568
myisamchk: warning: Found          0 deleted blocks       Should be: 9
myisamchk: warning: Found          1 parts                Should be: 10 parts
MyISAM-table '/var/lib/mysql/domain/session.MYI' is corrupted
Fix it using switch "-r" or "-o"

Das PHP-Skript sieht so aus:
PHP:
    class sessionmanager
{
	const SESSIONNAME = 'SESSION';
	const DBDEVINITION = "
	CREATE TABLE  `session` (
 	`sessionid` VARCHAR( 32 ) NOT NULL ,
 	`userid` BIGINT( 20 ) NOT NULL ,
 	`variables` TEXT NOT NULL ,
        'browser' TEXT NOT NULL ,
 	`lacces` INT( 14 ) NULL ,
	PRIMARY KEY (  `sessionid` ),
	KEY `userid`(`userid`)
	) TYPE = MYISAM ;";
	
	private static $DB;
	private $dbhost;
	private $dbpass;
	private $dbuser;
        private $datab;
	
	public function __construct() {
		global $host;
		global $dbpass;
		global $dbuser;
		global $db;
		
		$this->datab = $db;
		$this->dbuser = $dbuser;
		$this->dbhost = $host;
		$this->dbpass = $dbpass;
		
		$this->setmysql();
		ini_set('session.use_trans_sid',1);
		ini_set('session.use_coockies',0);
		ini_set('session.gc_probability',1);
		session_module_name("user");
		session_set_save_handler(array('sessionmanager',
										'ms_open'),
								array('sessionmanager',
										'ms_close'),
								array('sessionmanager',
										'ms_read'),
								array('sessionmanager',
										'ms_write'),
								array('sessionmanager',
										'ms_destroy'),
								array('sessionmanager',
										'ms_gc'));								
		session_name(self::SESSIONNAME);
		session_start();
	}
	
	private function settable(){
		$tbl = mysql_list_tables($this->datab, self::$DB);
		while ($t = mysql_fetch_assoc($tbl))
		{
			if($t['Tables_in_'.$this->datab]=='session')
			{
				return;
			}
		}
		mysql_query(self::DBDEVINITION, self::$DB);
	}
	
	private function setmysql()
	{
		self::$DB = @mysql_connect($this->dbhost, $this->dbuser, $this->dbpass);
		if (self::$DB !==FALSE)
		{
			$dbs = mysql_list_dbs(self::$DB);
			while ($db = mysql_fetch_assoc($dbs))
			{
				if ($db['Database']==$this->datab)
				{
					mysql_select_db($this->datab, self::$DB);
					$this->settable();
					return;
				}
			}
		}
		die ("Es konnte keine Session initalisiert werde. Bitte mit dem 
				Systemadmin in Verbindung setzen");
	}

	function ms_open($sesspath, $sessname)
	{
		$time = time();
		$sessid = session_id();
                $browser = self::get_browser();
		$query = "SELECT * FROM session WHERE sessionid = '$sessid' && browser = '$browser'";
		$RS = mysql_query($query, self::$DB);
		if(mysql_num_rows($RS) == 0)
		{
			$query = "INSERT INTO`session`(`sessionid` , `browser` ,  `lacces` ) VALUES ('$sessid', '$browser', '$time');";
		}
		else 
		{
			$query = "UPDATE session SET lacces = '$time' WHERE sessionid='$sessid' && browser = '$browser'";
		}
		$RS = mysql_query($query, self::$DB);
		return $RS;
	}
	
	function ms_read($sessid)
	{
                $browser = self::get_browser();
		$query = "SELECT * FROM session WHERE sessionid = '$sessid' && browser = '$browser'";
		$RS = mysql_query($query, self::$DB);
		$arrRS = mysql_fetch_assoc($RS);
		if (is_array($arrRS))
		{
			return $arrRS[variables];
		}
		else
		{
			return FALES;
		}
	}
	
	function ms_write($sessid, $varis)
	{
                $browser = self::get_browser();
		$query = "UPDATE session SET variables = '$varis' WHERE sessionid = '$sessid' && browser = '$browser'";
		$RS = mysql_query($query, self::$DB);
		return (bool)$RS;
	}
	
	function ms_destroy($sessid)
	{
		$query = "DELETE FROM session WHERE sessionid = '$sessid'";
		$RS = mysql_query($query, self::$DB);
		return (bool) $RS;
	}
	
	function ms_gc($sesslt)
	{	
		$tstamp = time() - $sesslt;
		$query = "DELETE FROM session WHERE lacces < '$tstamp'";
		$RS = mysql_query($query, self::$DB);
		return (bool) $RS;
	}
	
	function ms_close()
	{
		mysql_close(self::$DB);
	}
        
        private function get_browser()
        {
            $browser = $_SERVER[HTTP_USER_AGENT];
            $browser = quotemeta($browser);
            return $browser;
        }
}
new sessionmanager();

?>
Das ganze läuft auf einem Debian Etch mit Mysql 5.0 und PHP 5.2. Die Pakete sind alle aus den Debianquellen und Aktuell

In den Apache Logs ist zum Zeitraum des Crashes kein Aufruf zu finden. Nur acht Stunden vor dem Problem wurde die Seite anscheinend von einem Robot geöffnet.

Ich sag schon mal danke

Gruß Mordor
 
Back
Top