<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dan Cryer - Leeds Web Developer &#187; servers</title>
	<atom:link href="http://www.dancryer.com/tag/servers/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dancryer.com</link>
	<description>Dan Cryer - Leeds Web Developer</description>
	<lastBuildDate>Mon, 06 Sep 2010 22:05:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>VPS.NET Auto Recovery Monitor</title>
		<link>http://www.dancryer.com/2010/06/vps-net-auto-recovery-monitor</link>
		<comments>http://www.dancryer.com/2010/06/vps-net-auto-recovery-monitor#comments</comments>
		<pubDate>Tue, 29 Jun 2010 18:26:47 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Other Things]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[vps.net]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=539</guid>
		<description><![CDATA[I&#8217;ve been using VPS.NET for months now, both for myself and for Media Wow. Whilst their platform is incredibly stable, and their automated failover is great, there are still occasionally times when a server will go down and not come back up by itself. The nicely integrated Server Density monitoring does a great job of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using VPS.NET for months now, both for myself and for Media Wow. Whilst their platform is incredibly stable, and their automated failover is great, there are still occasionally times when a server will go down and not come back up by itself. </p>
<p>The nicely integrated Server Density monitoring does a great job of informing you if a server is down, but it can&#8217;t do anything about it. So I&#8217;ve created a script that I run on an external server to check all of the servers are up (via HTTP) and reboot those that are not. It&#8217;s fairly simple, the process is as follows:</p>
<ul>
<li>Get a list of VMs from VPS.NET.</li>
<li>For each VM, send a GET request to http://{hostname}.{domainname}/ and give it (by default) 5 seconds to respond.</li>
<li>If the server does not respond, it will check if it is marked as &#8220;running&#8221; on VPS.NET &#8211; by default it will then assume that there is simply a routing issue.</li>
<li>If it is not, it will check if the server is already in a power change state (i.e. startup, reboot).</li>
<li>Finally, if neither of the above are true, it will send a power on request to VPS.NET.</li>
<li>After all of that, it&#8217;ll (optionally) send you an email to let you know.</li>
</ul>
<p>The code is below. You can also <a href="/files/monitor.php.zip">download it here</a>. Let me know if you find it useful!</p>
<p><strong>Notes:</strong></p>
<ul>
<li>This script needs setting up as a cron job, on an off-site server / computer. I recommend running it every 5 minutes or so.</li>
<li>I don&#8217;t use the VPS.NET API PHP classes because they seem to be out of date.</li>
<li>This script *will* spam you to oblivion if there is a cloud issue and you set it up to email in all cases.</li>
</ul>
<div style="height: 300px; width: 100%; overflow: auto;">
<pre class="php" name="code">< ?php

//----
// Set up the monitoring script:
//----

define('MONITOR_MAIL_TO', '');     // Email address to send alerts to.
define('MONITOR_API_EMAIL', ''); // Email address associated with VPS.NET API account.
define('MONITOR_API_KEY', '');     // VPS.NET API key.
define('MONITOR_SEND_EMAILS', true);               // Whether or not to send emails if a server is flagged as down.
define('MONITOR_SEND_EMAILS_ON_NO_ACTION', true);  // Whether or not to send emails if no action is taken.
define('MONITOR_REBOOT_IF_RUNNING', true);         // If HTTP check fails, but VPS.NET says the server is up, reboot?
define('MONITOR_HTTP_TIMEOUT', 5);                 // Number of seconds to allow for a server response. 

//----
// Initialise API Class and get VMs:
//----
$api = new SimpleVpsApi();
$api->setApiEmail(MONITOR_API_EMAIL);
$api->setApiKey(MONITOR_API_KEY);
$vms = $api->getVMs();

//----
// Loop through all the VMs and check their status:
//----
$out     = '';
foreach($vms as $vm)
{
	$server = $vm['virtual_machine']['hostname'] . '.' . $vm['virtual_machine']['domain_name'];
	$id     = $vm['virtual_machine']['id'];

	$get = false;
	$get = @file_get_contents('http://'.$server.'/', false, stream_context_create(array('http' => array('timeout' => MONITOR_HTTP_TIMEOUT))));

	if(!$get)
	{
		$_out .= 'Server ' . $server . ' appears to be DOWN!'.PHP_EOL;

		$vm = $api->getVM($id);

		if($vm['power_action_pending'])
		{
			$_out .= '- VPS.NET is reporting that the server is rebooting already. Taking no action.'.PHP_EOL;

			if(!MONITOR_SEND_EMAILS_ON_NO_ACTION)
			{
				$_out = '';
			}
		}
		elseif($vm['running'] &#038;&#038; !MONITOR_REBOOT_IF_RUNNING)
		{
			$_out .= '- VPS.NET is reporting the server as running. Taking no action.'.PHP_EOL;

			if(!MONITOR_SEND_EMAILS_ON_NO_ACTION)
			{
				$_out = '';
			}
		}
		elseif($vm['running'] &#038;&#038; MONITOR_REBOOT_IF_RUNNING)
		{
			$api->rebootVM($id);
			$_out .= '- VPS.NET is reporting the server as running. Rebooting.'.PHP_EOL;
		}
		else
		{
			$api->bootVM($id);
			$_out .= '- Submitted an automated power on request to VPS.NET.'.PHP_EOL;
		}

		// If we've logged anything for this VM, append it to the log:
		if($_out)
		{
			if($out != '')
			{
				$out .= PHP_EOL;
			}

			$out .= $_out;
			$_out = '';
		}
	}
}

//----
// Emailing functionality, for notification of server downtime:
//----

$email = '<html>
	<body>
<div style="background: #ddd; font-family: arial, verdana, sans-serif; font-size: 13px; padding: 15px;">
		<strong style="font-size: 20px; margin-bottom: 15px">Server Monitoring Notice</strong>
<div style="background: #fff; border: 1px solid #ccc; color: #333; margin: 15px 0; padding: 15px">
			<!--content-->
		</div>
</div>

	</body>
</html>';

if($out != '' &#038;&#038; MONITOR_SEND_EMAILS)
{
	$email = str_replace('<!--content-->', nl2br($out), $email);
	mail(MONITOR_MAIL_TO, 'Server Monitoring Notice', $email, 'Content-Type: text/html'."\r\n");
}

//----
// Custom class for interacting with the VPS.NET API:
//----

class SimpleVpsApi
{
	const TYPE_GET  = 1;
	const TYPE_POST = 2;

	protected $apiUrl   = 'api.vps.net/';
	protected $apiEmail = null;
	protected $apiKey   = null;

	/**
	* Set the email address to use in requests:
	*/
	public function setApiEmail($email)
	{
		$this->apiEmail = $email;
	}

	/**
	* Set the API key to use in requests:
	*/
	public function setApiKey($key)
	{
		$this->apiKey = $key;
	}

	/**
	* Get a list of all VMs:
	*/
	public function getVMs()
	{
		$vm = $this->sendApiRequest('virtual_machines', 'GET');

		if($vm)
		{
			return $vm;
		}
		else
		{
			return array();
		}
	}

	/**
	* Sends a request to VPS.NET to load details about a VM:
	*/
	public function getVM($id)
	{
		$vm = $this->sendApiRequest('virtual_machines/'.$id, 'GET');

		if($vm)
		{
			return $vm['virtual_machine'];
		}
		else
		{
			return null;
		}
	}

	/**
	* Sends a request to VPS.NET to reboot a VM:
	*/
	public function rebootVM($id)
	{
		return $this->sendApiRequest('virtual_machines/'.$id.'/reboot', 'POST');
	}

	/**
	* Sends a request to VPS.NET to boot a VM:
	*/
	public function bootVM($id)
	{
		return $this->sendApiRequest('virtual_machines/'.$id.'/power_on', 'POST');
	}

	/**
	* Send an API request to VPS.NET
	*/
	protected function sendApiRequest($uri, $type = 'GET')
	{
		if(!$this->apiEmail || !$this->apiKey)
		{
			throw new Exception('You must set an API key and email address first.');
		}

		$opts = array(
		  'http'=>array(
		    'method'  => $type,
		    'header'  => 'Accept: application/json' . "\r\n" .
		                 'Content-Type: application/json' . "\r\n" .
						 'Authorization: Basic ' . base64_encode($this->apiEmail.':'.$this->apiKey) . "\r\n",

			'timeout' => 3,
		  )
		);

		$url      = 'https://'.$this->apiUrl.$uri.'.api10json';
		$context  = stream_context_create($opts);
		$response = @file_get_contents($url, false, $context);
		return json_decode($response, true);
	}
}</pre>
</div>
<p> edc17388fb0743a4910e77ba4c1b8171</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/06/vps-net-auto-recovery-monitor/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Load-Balanced Cluster Guide – Part 3</title>
		<link>http://www.dancryer.com/2010/01/load-balancing-mysql-with-ha-proxy</link>
		<comments>http://www.dancryer.com/2010/01/load-balancing-mysql-with-ha-proxy#comments</comments>
		<pubDate>Thu, 28 Jan 2010 17:14:00 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=434</guid>
		<description><![CDATA[This article is the last in my MySQL Load-Balanced Cluster Guide series, following on from my earlier post today on setting up MySQL Monitoring on the cluster nodes, this article is a guide to setting up the load balancer with HAProxy, using the monitoring scripts we&#8217;ve created to check the node status. HAProxy is a [...]]]></description>
			<content:encoded><![CDATA[<p>This article is the last in my MySQL Load-Balanced Cluster Guide series, following on from my earlier post today on <a href="http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd">setting up MySQL Monitoring on the cluster nodes</a>, this article is a guide to setting up the load balancer with HAProxy, using the monitoring scripts we&#8217;ve created to check the node status.</p>
<p>HAProxy is a well known, powerful load balancer. Best known for use with HTTP servers, but it can work with any kind of TCP traffic, including MySQL. Upcoming versions will support native MySQL monitoring, so we&#8217;ll be able to retire the custom scripts we created in the previous step, when they&#8217;re available in apt-get.</p>
<p><strong>1. Install HAProxy using the following apt-get command: </strong>apt-get install haproxy</p>
<p><strong>2. Delete the file /etc/haproxy/haproxy.cfg and create a new one with the following contents:</strong></p>
<p><code>global<br />
log 127.0.0.1   local0<br />
maxconn 4096<br />
user haproxy<br />
group haproxy<br />
daemon</code></p>
<p><code> </code></p>
<p><code>defaults<br />
log     global<br />
mode    tcp<br />
option  tcplog<br />
option  dontlognull<br />
retries 3<br />
option redispatch<br />
maxconn 2000<br />
contimeout      4000<br />
clitimeout      50000<br />
srvtimeout      30000<br />
stats enable<br />
stats scope	.</code></p>
<p><code>frontend mysql_cluster<br />
bind {load-balancer-ip}:3306<br />
default_backend	mysql_cluster</code></p>
<p><code>backend mysql_cluster<br />
mode tcp<br />
balance roundrobin<br />
stats enable<br />
option tcpka<br />
option httpchk<br />
server {node-name} {ip-address}:3306 weight 1 check port 9200 inter 5s rise 2 fall 2<br />
server {node-name} {ip-address}:3306 weight 1 check port 9200 inter 5s rise 2 fall 2</p>
<p></code></p>
<p><code>listen stats {load-balancer-ip}:80<br />
mode http<br />
option httpclose<br />
balance roundrobin<br />
stats uri     /<br />
stats realm   Haproxy\ Statistics<br />
stats auth    {username}:{password}<br />
</code></p>
<p>Once you&#8217;ve modified this file with settings appropriate to your environment, you&#8217;ll have a ready to go load balancer for MySQL. It&#8217;ll open port 3306 on the load balancer and forward those connections using round-robin load balancing to your two cluster servers. If either server goes down, it&#8217;ll be removed from the pool and no connections will be sent to it until it comes back up.</p>
<p>Additionally, it&#8217;ll create a statistics interface similar to the following, which you can access by going to your load balancing server&#8217;s address in your browser.</p>
<p><a href="http://www.dancryer.com/wp/wp-content/uploads/2010/01/haproxy.png"><img class="aligncenter size-large wp-image-437" title="HA Proxy" src="http://www.dancryer.com/wp/wp-content/uploads/2010/01/haproxy-1024x566.png" alt="HA Proxy Web Interface" width="450" height="248" /></a></p>
<p>Each cluster node should be listed under the first &#8220;mysql_cluster&#8221; section. They should all appear in green, as they should all be live. If a server is down, it&#8217;ll appear red, as explained in the key at the top of the page. From this interface you can also see how long the load balancer has been up, how long each server has been up, how much downtime each have had, as well as the individual number of downtime incidents. As you can see in the image above, our &#8216;cluster-1&#8242; server has had 21 separate downtime incidents, totalling just over 9 minutes of downtime.</p>
<p>So what do you need to change in your haproxy.cfg file? Here&#8217;s a quick rundown:</p>
<ul>
<li>Firstly, you&#8217;ll need to change the line starting &#8216;bind&#8217; to use your load balancer&#8217;s public IP address.</li>
<li>Secondly, make the same change on the line starting &#8216;listen stats&#8217;. You may also choose to put this service on a different port than port 80.</li>
<li>Next, change the {username} and {password} section of the &#8216;stats auth&#8217; line to ones of your choosing. This provides password protection to your web interface.</li>
<li>Finally, for each of your MySQL cluster nodes, you&#8217;ll need an appropriate &#8216;server&#8217; line in the &#8216;mysql_cluster&#8217; backend group. The things you need to change are {node-name}, to the name of the cluster node you defined earlier (e.g. cluster-1, cluster-2) and {ip-address} to the cluster node&#8217;s internal IP address.</li>
</ul>
<p>You may also wish to change the interval at which the load balancer will poll the MySQL servers, by changing &#8216;inter 5&#8242; to a different number. For more information on HAProxy configuration, their detailed &#8211; if a little unfriendly &#8211; documentation is available <a rel="nofollow" href="http://haproxy.1wt.eu/download/1.3/doc/configuration.txt">here</a>.</p>
<p>The final step to get this running, is to restart haproxy: /etc/init.d/haproxy restart - You should now be able to access both your web interface on port 80 and your brand new MySQL cluster on port 3306!</p>
<p>If you&#8217;ve got any questions about these guides or setting up a similar cluster, please leave a comment below and I&#8217;ll do my best to answer it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/load-balancing-mysql-with-ha-proxy/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MySQL Load-Balanced Cluster Guide – Part 2</title>
		<link>http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd</link>
		<comments>http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd#comments</comments>
		<pubDate>Thu, 28 Jan 2010 16:28:35 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=425</guid>
		<description><![CDATA[Following on from yesterday&#8217;s guide to setting up MySQL master-master replication, the first of today&#8217;s guides is how to set up a script to monitor the status of your MySQL cluster nodes, which we&#8217;ll use in the next guide to set up our proxy. On every one of your MySQL cluster nodes, follow the steps [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from yesterday&#8217;s guide to <a href="/2010/01/mysql-circular-replication">setting up MySQL master-master replication</a>, the first of today&#8217;s guides is how to set up a script to monitor the status of your MySQL cluster nodes, which we&#8217;ll use in the next guide to set up our proxy.</p>
<p>On every one of your MySQL cluster nodes, follow the steps below to get it ready for status reporting:</p>
<p><strong>1. Run the following apt-get command: <em>apt-get install xinetd php5-cli php5-mysql</em></strong> &#8211; We need xinetd to host our status server, and php5 for the status checking script.</p>
<p><strong>2. Put the following code into a new file: /etc/xinetd.d/mysqlchk</strong> &#8211; This creates an xinetd &#8220;server&#8221; on port 9200, using the /opt/mysql-status.php file to generate the response. Our proxy will connect to this server to check the status of the node.</p>
<p><code>#<br />
# /etc/xinetd.d/mysqlchk<br />
#<br />
service mysqlchk<br />
{<br />
flags           = REUSE<br />
socket_type     = stream<br />
protocol        = tcp<br />
port            = 9200<br />
wait            = no<br />
user            = mysql<br />
server          = /opt/mysql-status.php<br />
log_on_failure  += USERID<br />
disable         = no<br />
}</code></p>
<p><strong>3. Add the following line at the bottom of /etc/services</strong> &#8211; This registers your newly created xinetd service with the system to allow it to function.<br />
<code>mysqlchk	9200/tcp	# MySQL Monitoring</code></p>
<p><strong>4. Create the PHP file /opt/mysql-status.php with the code below.</strong><br />
This script tries to connect to your MySQL server, and if it succeeds, checks the &#8216;Seconds_Behind_Master&#8217; value of the slave status to make sure it is not too far behind it&#8217;s master. If either of these checks fail, it will return a 503 error to the client, telling it that the server is down.<br />
<code>#!/usr/bin/php<br />
&lt; ?php<br />
/**<br />
*	MySQL Replication Monitor<br />
*/</code></p>
<p><code>// Connection details:<br />
$_host     = 'localhost';<br />
$_username = '{username}';<br />
$_password = '{password}';<br />
$_timeout  = 60; // Number of seconds behind master this node can fall before being marked as "down".</p>
<p>try<br />
{<br />
$pdo = new PDO('mysql:host='.$_host, $_username, $_password);<br />
$pdo-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);</p>
<p>$stmt   = $pdo-&gt;query('SHOW SLAVE STATUS');<br />
$status = $stmt-&gt;fetch(PDO::FETCH_ASSOC);</p>
<p>if($status == false)<br />
{<br />
serverIsDown('Querying slave status failed.');<br />
}</p>
<p>if(intval($status['Seconds_Behind_Master']) &gt; $_timeout)<br />
{<br />
serverIsDown('Slave is behind.');<br />
}<br />
}<br />
catch(Exception $ex)<br />
{<br />
if(!is_null($pdo))<br />
unset($pdo);</p>
<p>serverIsDown('Failed to connect to MySQL.');<br />
}</p>
<p>unset($pdo);</p>
<p>serverIsUp();</p>
<p>function serverIsDown($message)<br />
{<br />
$output = 'Server is currently down. Message:' . $message;<br />
print "HTTP/1.1 503 Service Unavailable\r\n";<br />
print "Date: " . date('r') . "\r\n";<br />
print "Server: MySQL Monitor/1.0\r\n";<br />
print "Connection: close\r\n";<br />
print "Content-Type: text/plain\r\n";<br />
print "Content-Length: " . strlen($output) . "\r\n";<br />
print "\r\n";<br />
print $output;<br />
die;<br />
}</p>
<p></code></p>
<p><code>function serverIsUp()<br />
{<br />
$output = 'Server is up. All is okay.';<br />
print "HTTP/1.1 200 OK\r\n";<br />
print "Date: " . date('r') . "\r\n";<br />
print "Server: MySQL Monitor/1.0\r\n";<br />
print "Connection: close\r\n";<br />
print "Content-Type: text/plain\r\n";<br />
print "Content-Length: " . strlen($output) . "\r\n";<br />
print "\r\n";<br />
print $output;<br />
die;<br />
}</code></p>
<p><strong>5. chown -fv mysql:mysql /opt/mysql-status.php</strong> &#8211; Give ownership of the status checking script to mysql.<br />
<strong>6. chmod -fv +x /opt/mysql-status.php</strong> &#8211; Give execute permissions on the script.<br />
<strong>7. /etc/init.d/xinetd restart</strong> &#8211; Restart xinetd, to make all of the changes we&#8217;ve just made live.</p>
<p>Having completed the steps above, you will now have a script that checks the current status of your MySQL server, responding to connections on port 9200 of your server. In the next article, I&#8217;ll describe how to set up your load balancing server with HAProxy, and utilise the server we&#8217;ve just created to check which nodes are live at any given time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Load-Balanced Cluster Guide &#8211; Part 1</title>
		<link>http://www.dancryer.com/2010/01/mysql-circular-replication</link>
		<comments>http://www.dancryer.com/2010/01/mysql-circular-replication#comments</comments>
		<pubDate>Wed, 27 Jan 2010 17:35:21 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=409</guid>
		<description><![CDATA[I&#8217;m currently working on setting up a load-balanced many-master MySQL cluster at work, without using MySQL Cluster as it&#8217;s incompatible with our needs. Finding good guides on how to do this has proven incredibly difficult, so I thought I would document the process here. This first post is going to cover setting up the servers [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on setting up a load-balanced many-master MySQL cluster at work, without using MySQL Cluster as it&#8217;s incompatible with our needs. Finding good guides on how to do this has proven incredibly difficult, so I thought I would document the process here.</p>
<p>This first post is going to cover setting up the servers themselves and configuring MySQL replication.</p>
<p><strong>1. Set up the following three servers:<br />
</strong></p>
<ul>
<li><strong>Cluster Load Balancer</strong> &#8211; One Public IP, One Internal IP &#8211; Ubuntu Jaunty Basic installation</li>
<li><strong>Cluster MySQL 1</strong> &#8211; One Public IP, One Internal IP &#8211; Ubuntu Jaunty Basic + MySQL Server 5.x</li>
<li><strong>Cluster MySQL 2</strong> &#8211; One Public IP, One Internal IP &#8211; Ubuntu Jaunty Basic + MySQL Server 5.x</li>
</ul>
<p>We&#8217;re using <a rel="nofollow" href="http://manage.aff.biz/z/146/CD2815/">VPS.NET</a>. If you&#8217;re going to do the same, use the &#8216;Ubuntu 8.04 LTS 64-bit Basic Installation&#8217; template for the Load Balancer and &#8216;Ubuntu 8.04 x64 MySQL&#8217; for the MySQL nodes. You&#8217;ll then need to do the following to upgrade to Jaunty:</p>
<ul>
<li>Edit the file &#8216;<em>/etc/update-manager/release-upgrades</em>&#8216; and change the line &#8216;<em>Prompt=lts</em>&#8216; to &#8216;<em>Prompt=normal</em>&#8216;.</li>
<li>Run the command &#8216;<em>do-release-upgrade</em>&#8216;. Let it go through the entire process of installing Intrepid, then reboot.</li>
<li>Repeat the step above again to install of Jaunty.</li>
</ul>
<p><strong>2. On the two MySQL servers, edit /etc/mysql/my.cnf and comment out the line &#8216;<em>bind-address 127.0.0.1</em>&#8216; &#8211; the servers need to allow remote TCP/IP connections.<br />
</strong><br />
<strong>3. On each server, add the following to the /etc/mysql/my.cnf file:<br />
</strong><br />
<code>server-id = 1                         # Increment this number by one for each server, so 1 for cluster-1, 2 for cluster-2<br />
auto_increment_increment = 2          # Set to the number of nodes you have (or are likely to have)<br />
auto_increment_offset = 1             # Set to the same as the server-id<br />
replicate-same-server-id = 0          # To ensure the slave thread doesn't try to write updates that this node has produced.<br />
log-bin                               # Turn on binary logging (neccessary for replication)<br />
log-slave-updates                     # Neccessary for chain or circular replication<br />
relay-log                             # As above<br />
relay-log-index                       # As above</code></p>
<p><strong>Note:</strong> On our servers, we&#8217;ve used an <em>auto_increment_increment </em>of 4, to allow us to add two more nodes to our cluster at a later date, without hitting auto-increment problems.</p>
<p><strong>4. Restart MySQL on both servers.<br />
</strong><br />
<strong>5. On Cluster 1, log into the MySQL Console and run the following queries:<br />
</strong><br />
<code>STOP SLAVE;<br />
CHANGE master TO master_host="cluster-2.yourdomain.com", master_user="{username}", master_password="{password}", master_log_file="mysqld-bin.000001", master_log_pos=98;<br />
START SLAVE;</code></p>
<p><strong>Note:</strong> To verify the master_log_pos value, execute the query: &#8220;SHOW MASTER STATUS;&#8221; and check the Position column. Also, you may wish to use your internal IP addresses for the master_host option.</p>
<p><strong>6. On Cluster 2, log into the MySQL Console and run the following queries:<br />
</strong><br />
<code>STOP SLAVE;<br />
CHANGE master TO master_host="cluster-1.yourdomain.com", master_user="{username}", master_password="{password}", master_log_file="mysqld-bin.000001", master_log_pos=98;<br />
START SLAVE;</code></p>
<p><strong>Note:</strong> If on either server you get an error message at this point, verify that:</p>
<ul>
<li>a) the master_log_file name in the query above matches the ones your servers are generating</li>
<li>b) your username and password for the other server are correct</li>
<li>c) that your servers can communicate with each other using the host names you specified.</li>
<li>Additionally, you may wish to remove AppArmor, as that can interfere with MySQL replication and cause all kinds of miscellaneous problems. To do so, run &#8216;<em>apt-get remove apparmor</em>&#8216; followed by &#8216;<em>apt-get purge apparmor</em>&#8216;.</li>
</ul>
<p>You should now have master to master replication set up and running across your two MySQL servers. To test, create a database on cluster-1, then create a table within that database and insert some data into it. Next, log on to cluster-2 and you should be able to see that newly created table, complete with data.</p>
<p>If you want to ensure that it works both ways, insert some data on cluster-2 and you should see it on cluster-1. You will also want to test that your auto-increment settings are working correctly.</p>
<p>If you&#8217;ve got any questions about this article, or have any problems setting up the replication, please leave a comment below and I&#8217;ll do my best to help. The next article in this guide will cover setting up a proxy on the load balancer and hopefully, implementing failover.</p>
<ul>
<li>Next Step: <a href="http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd">Setting up MySQL Monitoring on the cluster nodes</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/mysql-circular-replication/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free VPS.NET Server Setup</title>
		<link>http://www.dancryer.com/2010/01/free-vps-net-server-setup</link>
		<comments>http://www.dancryer.com/2010/01/free-vps-net-server-setup#comments</comments>
		<pubDate>Mon, 18 Jan 2010 17:40:31 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[vps.net]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=372</guid>
		<description><![CDATA[I&#8217;ve been getting a lot of traffic lately from people looking for information about VPS.NET and it&#8217;s cloud platform, and I get the impression that people might think it&#8217;s difficult to get started. It&#8217;s not. As such, I&#8217;ve decided to make an offer to people wanting to use it for their web sites. I&#8217;ll set [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been getting a lot of traffic lately from people looking for information about VPS.NET and it&#8217;s cloud platform, and I get the impression that people might think it&#8217;s difficult to get started. It&#8217;s not. As such, I&#8217;ve decided to make an offer to people wanting to use it for their web sites.</p>
<p>I&#8217;ll set your web server up for you, for free, after you sign up to VPS.NET. I&#8217;ll get it up and running with Ubuntu Linux, Apache 2.2, PHP 5.2 and MySQL 5.1. I&#8217;ll also set up FTP (if desired) and create up to five user accounts and Apache virtual hosts for domains you already have.</p>
<p>All you have to do to take advantage of this is the following:</p>
<ol>
<li>Sign up to VPS.NET using <a rel="nofollow" href="http://manage.aff.biz/z/155/CD2815/">this link</a> (see note 1) - but don&#8217;t create a VPS</li>
<li>Forward the account details link you get from VPS.NET (including your account username and password) to <a href="mailto:vps@dancryer.com">vps@dancryer.com</a></li>
<li>In the email, include the number of VPS.NET &#8220;nodes&#8221; you want me to allocate to your VPS, a list of up to five domains you would like to be set up, the server name you want to use (if you have a preference), and whether or not you would like to be able to access it via FTP.</li>
</ol>
<p>I&#8217;ll set up the server as soon as I can and email you back with a list of Ubuntu user names and passwords, MySQL usernames and passwords, and various other server details.</p>
<div style="font-size: 0.9em;">
<p><strong>Notes:</strong></p>
<ol>
<li>In order to qualify for the free set up, you must use the link I provided to sign up. VPS.NET offers a generous affiliate program that covers the cost for my time to set up the server, which allows me to offer it to you for no cost.</li>
<li>If demand is high, I cannot guarantee to be able to set your server up for you. I&#8217;ll email you back at the earliest possible time to let you know.</li>
<li>Your account details will be deleted from my email account as soon as the work is completed, you are of course welcome to change all passwords after completion of the work.</li>
<li>I cannot offer ongoing server support for free, such requests will be met with a request for payment.</li>
<li>I will not install any web applications as part of this offer, nor migrate data from existing hosting accounts, simply install the server software itself, further configuration is up to you.</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/free-vps-net-server-setup/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
