[Slim-Checkins] r10552 - in /trunk/server: MySQL/my.tt Slim/Schema/Storage.pm Slim/Utils/MySQLHelper.pm

dsully at svn.slimdevices.com dsully at svn.slimdevices.com
Wed Nov 1 17:57:38 PST 2006


Author: dsully
Date: Wed Nov  1 17:57:37 2006
New Revision: 10552

URL: http://svn.slimdevices.com?rev=10552&view=rev
Log:
Bug: Many
Description: Experimental fixes for MySQL issues - mostly for Windows:

* Always log to an error log file for MySQL

* If we can't connect to the database during the ->dbh call, try and bring it up.

* On Windows, try to install & start MySQL as a service.

Modified:
    trunk/server/MySQL/my.tt
    trunk/server/Slim/Schema/Storage.pm
    trunk/server/Slim/Utils/MySQLHelper.pm

Modified: trunk/server/MySQL/my.tt
URL: http://svn.slimdevices.com/trunk/server/MySQL/my.tt?rev=10552&r1=10551&r2=10552&view=diff
==============================================================================
--- trunk/server/MySQL/my.tt (original)
+++ trunk/server/MySQL/my.tt Wed Nov  1 17:57:37 2006
@@ -15,6 +15,8 @@
 language              = [% language %]
 port                  = [% port || 9092 %]
 socket                = [% socket %]
+pid-file              = [% pidFile %]
+log-error             = [% errorLog %]
 innodb_fast_shutdown  = 1
 max_connections       = 4
 thread_concurrency    = 4

Modified: trunk/server/Slim/Schema/Storage.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Schema/Storage.pm?rev=10552&r1=10551&r2=10552&view=diff
==============================================================================
--- trunk/server/Slim/Schema/Storage.pm (original)
+++ trunk/server/Slim/Schema/Storage.pm Wed Nov  1 17:57:37 2006
@@ -13,11 +13,51 @@
 use base qw(DBIx::Class::Storage::DBI::mysql);
 
 use Carp::Clan qw/DBIx::Class/;
+use File::Slurp;
+use File::Spec;
 
 use Slim::Utils::Log;
 use Slim::Utils::Misc;
+use Slim::Utils::MySQLHelper;
+use Slim::Utils::Prefs;
 
 our $dbAccess = Slim::Utils::PerfMon->new('Database Access', [0.002, 0.005, 0.01, 0.015, 0.025, 0.05, 0.1, 0.5, 1, 5], 1);
+
+sub dbh {
+	my $self = shift;
+
+	eval { $self->ensure_connected };
+
+	# Try and bring up the database if we can't connect.
+	if ($@ && $@ =~ /Connection failed/) {
+
+		my $lockFile = File::Spec->catdir(Slim::Utils::Prefs::get('cachedir'), 'mysql.startup');
+
+		if (!-f $lockFile) {
+
+			write_file($lockFile, 'starting');
+
+			logWarning("Unable to connect to the database - trying to bring it up!");
+
+			$@ = '';
+
+			if (Slim::Utils::MySQLHelper->init) {
+
+				eval { $self->ensure_connected };
+
+				if ($@) {
+					logError("Unable to connect to the database - even tried restarting it twice!");
+					logError("Check the event log for errors on Windows. Fatal. Exiting.");
+					exit;
+				}
+			}
+
+			unlink($lockFile);
+		}
+	}
+
+	return $self->_dbh;
+}
 
 sub throw_exception {
 	my ($self, $msg) = @_;

Modified: trunk/server/Slim/Utils/MySQLHelper.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Utils/MySQLHelper.pm?rev=10552&r1=10551&r2=10552&view=diff
==============================================================================
--- trunk/server/Slim/Utils/MySQLHelper.pm (original)
+++ trunk/server/Slim/Utils/MySQLHelper.pm Wed Nov  1 17:57:37 2006
@@ -45,6 +45,9 @@
 }
 
 my $log = logger('database.mysql');
+my $OS  = Slim::Utils::OSDetect::OS();
+
+my $serviceName = 'SlimServerMySQL';
 
 =head2 init()
 
@@ -61,7 +64,7 @@
 
 		$log->info("Not starting MySQL - looks to be user configured.");
 
-		if (Slim::Utils::OSDetect::OS() ne 'win') {
+		if ($OS ne 'win') {
 
 			my $mysql_config = which('mysql_config');
 
@@ -107,7 +110,15 @@
 	# time. That's ok.
 	if (!$class->dbh) {
 
-		$class->startServer;
+		# Bring MySQL up as a service on Windows.
+		if ($OS eq 'win') {
+
+			$class->startServer(1);
+
+		} else {
+
+			$class->startServer;
+		}
 	}
 
 	return 1;
@@ -130,16 +141,13 @@
 		'language' => $class->mysqlDir,
 		'datadir'  => catdir($cacheDir, 'MySQL'),
 		'socket'   => $class->socketFile,
+		'pidFile'  => $class->pidFile,
+		'errorLog' => catdir($cacheDir, 'mysql-error-log.txt'),
 	);
 
 	# Because we use the system MySQL, we need to point to the right
 	# directory for the errmsg. files. Default to english.
-	if (Slim::Utils::OSDetect::isDebian()) {
-
-		$config{'language'} = '/usr/share/mysql/english';
-	}
-
-	if (Slim::Utils::OSDetect::isRHELorFC()) {
+	if (Slim::Utils::OSDetect::isDebian() || Slim::Utils::OSDetect::isRHELorFC()) {
 
 		$config{'language'} = '/usr/share/mysql/english';
 	}
@@ -159,7 +167,7 @@
 	}
 
 	# MySQL on Windows wants forward slashes.
-	if (Slim::Utils::OSDetect::OS() eq 'win') {
+	if ($OS eq 'win') {
 
 		for my $key (keys %config) {
 			$config{$key} =~ s/\\/\//g;
@@ -170,12 +178,12 @@
 
 	my $template = Template->new({ 'ABSOLUTE' => 1 }) or die Template->error(), "\n";
            $template->process($ttConf, \%config, $output) || die $template->error;
-
-	$class->confFile($output);
 
 	# Bug: 3847 possibly - set permissions on the config file.
 	# Breaks all kinds of other things.
 	# chmod(0664, $output);
+
+	return $output;
 }
 
 =head2 startServer()
@@ -187,15 +195,28 @@
 =cut
 
 sub startServer {
-	my $class = shift;
-
-	# Start on Debian - but use the private port/socket.
-	# if (Slim::Utils::OSDetect::isDebian()) {
-	#	$log->info("Not starting MySQL server on Debian..");
-	#	return 1;
-	#}
-
-	if ($class->pidFile && $class->processObj && $class->processObj->alive) {
+	my $class   = shift;
+	my $service = shift || 0;
+
+	my $isRunning = 0;
+
+	if ($service) {
+
+		my %status = ();
+
+        	Win32::Service::GetStatus('', $serviceName, \%status);
+
+		if ($status{'CurrentState'} == 0x04) {
+
+			$isRunning = 1;
+		}
+
+	} elsif ($class->pidFile && $class->processObj && $class->processObj->alive) {
+
+		$isRunning = 1;
+	}
+
+	if ($isRunning) {
 
 		$log->info("MySQL is already running!");
 
@@ -208,26 +229,54 @@
 	};
 
 	my $confFile = $class->confFile;                                                                                                                    
+	my $process  = undef;
 
 	# Bug: 3461
-	if (Slim::Utils::OSDetect::OS() eq 'win') {
+	if ($OS eq 'win') {
+		$mysqld   = Win32::GetShortPathName($mysqld);
 		$confFile = Win32::GetShortPathName($confFile);
 	}
 
-	my @commands = (
-		$mysqld, 
-		sprintf('--defaults-file=%s', $confFile),
-		sprintf('--pid-file=%s', $class->pidFile),
-	);
-
-	# Log MySQL errors to slimserver log file
-	if ($::logfile) {
-		push @commands, sprintf('--log-error=%s', $::logfile);
-	}
-
-	$log->info(sprintf("About to start MySQL with command: [%s]\n", join(' ', @commands)));
-
-	my $proc = Proc::Background->new(@commands);
+	my @commands = ($mysqld, sprintf('--defaults-file=%s', $confFile));
+
+	$log->info(sprintf("About to start MySQL as a %s with command: [%s]\n",
+		($service ? 'service' : 'process'), join(' ', @commands),
+	));
+
+	if ($service && $OS eq 'win') {
+
+		my %status = ();
+
+        	Win32::Service::GetStatus('', $serviceName, \%status);
+
+		# Install the service, if it isn't.
+       		if (scalar keys %status == 0) {
+
+			push @commands, ("--install $serviceName", pop @commands);
+
+			system(join(' ', @commands));
+
+        		Win32::Service::GetStatus('', $serviceName, \%status);
+
+       			if (scalar keys %status == 0) {
+
+				logError("Couldn't install MySQL as a service! Will run as a process!");
+				$service = 0;
+			}
+		}
+
+		if ($service) {
+
+			Win32::Service::StartService('', $serviceName);
+		}
+	}
+
+	# Catch Unix users, and Windows users when we couldn't run as a service.
+	if (!$service) {
+
+		$process = Proc::Background->new(@commands);
+	}
+
 	my $dbh  = undef;
 	my $secs = 30;
 
@@ -248,7 +297,7 @@
 		$log->logdie("FATAL: Server didn't startup in $secs seconds! Exiting!");
 	}
 
-	$class->processObj($proc);
+	$class->processObj($process);
 
 	return 1;
 }
@@ -259,11 +308,27 @@
 
 This is a no-op if you are using a pre-configured copy of MySQL.
 
+Or are running MySQL as a Windows service.
+
 =cut
 
 sub stopServer {
 	my $class = shift;
 	my $dbh   = shift || $class->dbh;
+
+	if ($OS eq 'win') {
+
+		my %status = ();
+
+		Win32::Service::GetStatus('', $serviceName, \%status);
+
+       		if (scalar keys %status != 0) {
+
+			$log->info("Running as Windows service, skipping shutdown.");
+
+			return;
+		}
+	}
 
 	# We have a running server & handle. Shut it down internally.
 	if ($dbh) {
@@ -342,8 +407,7 @@
 sub createSystemTables {
 	my $class = shift;
 
-	# We need to bring up MySQL to set the initial system tables, then
-	# bring it down again.
+	# We need to bring up MySQL to set the initial system tables, then bring it down again.
 	$class->startServer;
 
 	my $sqlFile = catdir($class->mysqlDir, 'system.sql');
@@ -392,7 +456,7 @@
 	my $class = shift;
 	my $dsn   = '';
 
-	if (Slim::Utils::OSDetect::OS() eq 'win') {
+	if ($OS eq 'win') {
 
 		$dsn = Slim::Utils::Prefs::get('dbsource');
 		$dsn =~ s/;database=.+;?//;



More information about the checkins mailing list