<?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"
	>

<channel>
	<title>MCslp Coalface</title>
	<atom:link href="http://coalface.mcslp.com/wp-rss2.php" rel="self" type="application/rss+xml" />
	<link>http://coalface.mcslp.com</link>
	<description>Thoughts from the bleeding edge of the MCslp keyboards</description>
	<pubDate>Sat, 22 Nov 2008 11:27:05 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language></language>
			<item>
		<title>Multiple VCS Updates and Cleanups</title>
		<link>http://coalface.mcslp.com/2008/11/22/multiple-vcs-updates-and-cleanups/</link>
		<comments>http://coalface.mcslp.com/2008/11/22/multiple-vcs-updates-and-cleanups/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 11:27:05 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Development Environments]]></category>

		<category><![CDATA[Scripting]]></category>

		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=182</guid>
		<description><![CDATA[I spend a lot of time updating a variety of different repositories of different varieties and denominations, and I hate having to do that all by hand - I&#8217;d rather just go up into a top-level directory and say update-all and let a script work out what to do, no matter what different repos are [...]]]></description>
			<content:encoded><![CDATA[<p>I spend a lot of time updating a variety of different repositories of different varieties and denominations, and I hate having to do that all by hand - I&#8217;d rather just go up into a top-level directory and say <code>update-all</code> and let a script work out what to do, no matter what different repos are there. </p>
<p>I do it with a function defined within my bash profile/rc scripts, and it covers git, bzr, svn, bk, and cvs. The trick is to identify what type of directory we are updating. I do this, lazily, for each type individually, rather than for each directory, but I&#8217;ve found this method to be more reliable.</p>
<blockquote><p><code>update-all ()<br />
{<br />
    for file in `ls -d */.svn 2>/dev/null`;<br />
    do<br />
        realdir=`echo $file|cut -d/ -f1`;<br />
        echo Updating in $realdir;<br />
        ( cd $realdir;<br />
        svn update );<br />
    done;<br />
    for file in `ls -d */.bzr 2>/dev/null`;<br />
    do<br />
        realdir=`echo $file|cut -d/ -f1`;<br />
        echo Updating in $realdir;<br />
        ( cd $realdir;<br />
        bzr pull );<br />
    done;<br />
    for file in `ls -d */.git 2>/dev/null`;<br />
    do<br />
        realdir=`echo $file|cut -d/ -f1`;<br />
        echo Updating in $realdir;<br />
        ( cd $realdir;<br />
        git pull );<br />
    done;<br />
    for file in `ls -d */CVS 2>/dev/null`;<br />
    do<br />
        realdir=`echo $file|cut -d/ -f1`;<br />
        echo Updating in $realdir;<br />
        ( cd $realdir;<br />
        cvs up );<br />
    done;<br />
    for file in `ls -d */BitKeeper 2>/dev/null`;<br />
    do<br />
        realdir=`echo $file|cut -d/ -f1`;<br />
        echo Updating in $realdir;<br />
        ( cd $realdir;<br />
        bk pull );<br />
    done;<br />
    unset realdir<br />
}<br />
</code></p></blockquote>
<p>That&#8217;s it - a quick way to update any directory of repos.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/22/multiple-vcs-updates-and-cleanups/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Feeding Query Analyzer from DTrace</title>
		<link>http://coalface.mcslp.com/2008/11/15/feeding-query-analyzer-from-dtrace/</link>
		<comments>http://coalface.mcslp.com/2008/11/15/feeding-query-analyzer-from-dtrace/#comments</comments>
		<pubDate>Sat, 15 Nov 2008 09:02:54 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Databases]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Solaris]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=178</guid>
		<description><![CDATA[One of the new features in the new release of MySQL Enterprise Monitor is Query Analyzer. As the name suggests, the Query Analyzer provides information about the queries that are running on your server, the response times and row and byte statistics. The information provided is great, and it doesn&#8217;t take very long to see [...]]]></description>
			<content:encoded><![CDATA[<p>One of the new features in the new release of MySQL Enterprise Monitor is Query Analyzer. As the name suggests, the Query Analyzer provides information about the queries that are running on your server, the response times and row and byte statistics. The information provided is great, and it doesn&#8217;t take very long to see from the query data supplied that there are places where you could improve the the query, or even reduce the number of queries that you submit. </p>
<p>The system works by using the functionality of the MySQL Proxy to monitor the queries being executed and then provide that information up to the MySQL Enterprise Service Manager so that the information can be displayed within the Query Analyzer page. To get the queries monitored, you have to send the queries through the agent which both monitors their execution and sends the information on up to the Manager, along with all the other data being monitored. </p>
<p>The team, though, have been a bit clever and opened up the system to allow information to be sent to the Manager using a REST interface. This means that any system capable of providing information that you want to monitor can be sent up to the Manager. Of course, you can’t just send anything, the Manager needs to know how to handle it, but it shows the flexibility of the design and the potential for the future. </p>
<p>So how does this help us? </p>
<p>Well, one of the new features in MySQL 6.0 that I’ve been working on (with Mikael Ronstrom and Alexey Kopytov) is DTrace probes. We’ve added a bunch of static DTrace probes into MySQL 6.0 (the full set will appear in MySQL 6.0.8, I think) designed to let you  monitor the execution of queries within the server. The probes will allow you to see both the top-level information, such as overall execution time, but also deeper so that you can get information about individual row operations, whether the query used the query cache, and whether it used a filesort operation. </p>
<p>I haven’t finished the DTrace probes documentation yet, but I have been demonstrating the probes at conferences and talks (including my MySQL on OpenSolaris university session this week). Trust me, you’ll be pleased. I’ve got a separate blog post detailing some of the specifics in the works at the moment. </p>
<p>For obvious reasons, there’s a synergy here that should be obvious. Why don’t we feed up data extracted using DTrace and provide that up to the Enterprise Manager?</p>
<p>To do this, there are two parts to the process, the DTrace probes and the script hat passes that information up in a suitable format to the manager. </p>
<p>The D script is quite straightforward, we initialize the structures, populate the core information that we need (query string, bytes, rows and the time), and the use the remainder of the probes to finalize that information. Let&#8217;s have look at the script and then go through the detail: </p>
<blockquote><pre>#!/usr/sbin/dtrace -s

#pragma D option quiet

mysql*:::query-start
{
   self->query = copyinstr(arg0);
   self->db    = copyinstr(arg2);
   self->rows  = 0;
   self->querystart = timestamp;
   self->bytes = 0;
}

mysql*:::select-done
{
        self->rows = arg1;
}

mysql*:::insert-done
{
        self->rows = arg1;
}

mysql*:::update-done
{
        self->rows = arg2;
}

mysql*:::multi-delete-done
{
        self->rows = arg1;
}

mysql*:::delete-done
{
        self->rows = arg1;
}

mysql*:::multi-update-done
{
        self->rows = arg2;
}

mysql*:::net-write-start
{
        self->bytes = self->bytes + arg0;
}

mysql*:::query-done
/self->query != NULL/
{
        printf("%s:%s:%d:%d:%d\n",
        self->query,
        self->db,
        ((timestamp - self->querystart)/1000),
        self->rows,self->bytes);
}</pre>
</blockquote>
<p>First, we set a pragma to quieten down the output so that the DTrace script only reports what we explicitly write out: </p>
<blockquote><pre>#pragma D option quiet</pre>
</blockquote>
<p>In DTrace, the individual execution points are called probes, and probes are triggered each time that point in the code is reached. To specify the probes we want to watch for, you use a special format, <code>provider:module:function:name</code> that identifies the probe by the name of the provider (the application), the module, the function, and the probe, each separated by a colon. We can just specify the provider and probe name, like <code>mysql*:::query-start</code>.</p>
<p>It should also be noted that probes are often provided in pairs at the start and end of an operation, so you can identify the start and end of a query by looking for the <code>query-start</code> and <code>query-done</code> probes.</p>
<p>The DTrace probes in the server are set-up in a sort of nested structure, going deeper into the query process as needed. Although not at the very top of the execution cycle, the start of the main query processing is identified by the <code>query-start</code> probe. Each time a query is submitted to MySQL, this probe will get triggered, so for us, it is the start of the process. The probe has a number of arguments, but for our purposes we only need the first (<code>arg0</code>), which contains the full query string, and the third (<code>arg2</code>) which contains the name of the database that the query was executed against.</p>
<p>We also initialize the row and byte counts, and the time when the query was executed using the built-in <code>timestamp</code> value. All of this information is placed into the special <code>self</code> structure, which is a persistent structure used to share information between the individual probes that get fired during execution. </p>
<blockquote><pre>mysql*:::query-start
{
   self->query = copyinstr(arg0);
   self->db    = copyinstr(arg2);
   self->rows  = 0;
   self->querystart = timestamp;
   self->bytes = 0;
}</pre>
</blockquote>
<p>To get the counts of the number of rows, we can&#8217;t get the information from the <code>query-done</code> probe. This is because different operations actually provide different levels of information. For example, the <code>select-done</code> and <code>insert-done</code> just provide a count of the rows. But the <code>update-done</code> probe provides information both about the number of rows that matched the original <code>WHERE</code> clause, and the count of the number rows actually modified. </p>
<p>To record the number of the rows modified by the query, we therefore need to pull out each piece of information individually: </p>
<blockquote><pre>mysql*:::select-done
{
        self->rows = arg1;
}
mysql*:::insert-done
{
        self->rows = arg1;
}

mysql*:::update-done
{
        self->rows = arg2;
}

mysql*:::multi-delete-done
{
        self->rows = arg1;
}

mysql*:::delete-done
{
        self->rows = arg1;
}

mysql*:::multi-update-done
{
        self->rows = arg2;
}</pre>
</blockquote>
<p>For the bytes retrieved by each query, the information is a bit more difficult to identify. I&#8217;m going to cheat a bit and use the bytes sent by <code>mysqld</code> during a net write to the client. There is a limitation here I&#8217;ve skipped, which is that we could report data sent to any client, since I haven&#8217;t bothered to track connection IDs. I could do this, but it would make the script a little more complicated. Since the <code>net-write-start</code> might be called multiple times for a long query, we calculate a cumulative byte count.</p>
<blockquote><pre>mysql*:::net-write-start
{
        self->bytes = self->bytes + arg0;
}</pre>
</blockquote>
<p>That&#8217;s all of the information collection; now we just need to print out the information when the query completes. We do this by writing out a colon separated list of the information that we&#8217;ve collected. One additional point here though is that to calculate the duration of the query, you take the timestamp recorded when <code>query-start</code> was called away from the current <code>timestamp</code>. </p>
<p>Timestamp information is recorded in nanoseconds (yes, you read that right, nanoseconds), so we divide it by a thousand to get it in microseconds, which is what the Enterprise Manager will expected. </p>
<pre>
<blockquote>mysql*:::query-done
/self->query != NULL/
{
        printf("%s:%s:%d:%d:%d\n",
        self->query,
        self->db,
        ((timestamp - self->querystart)/1000),
        self->rows,self->bytes);
}</blockquote>
</pre>
<p>If you run this script on it&#8217;s own (against a MySQL running on Solaris/OpenSolaris, with probes, of course), then you&#8217;ll get output like this: </p>
<blockquote><pre>SELECT DATABASE()::391:1:44
show databases:test:947:2:84
show tables:test:2018:3:74
select * from t limit 5:test:595:5:51</pre>
</blockquote>
<p>To provide the information up to the Enterprise Manager we cannot use D scripts. Instead, a wrapper around the D script will read the raw information produced and then pass that up to the Enterprise Manager. </p>
<p>Before we look at that process, it is worth looking at the REST API that has been built in to v2 of the Enterprise Monitor. The interface is available through the standard URL for the Enterprise service, typically your hostname and the port 18080 if you&#8217;ve used the default settings. Therefore we can access the interface using the url <code>http://nautilus:18080/v2/rest/</code>, assuming our host is <code>nautilus</code>. </p>
<p>From the base URL, you can start to get information, or put information, about the different entries in the repository using the path in the URL to signifiy what it is we are looking for. Information about instances is within the <code>instance</code>, with the provider as <code>mysql</code>, and the MySQL server as <code>server</code>. Or better put, the base URL would be <code>http://nautilus:18080/v2/rest/instance/mysql/server/</code>.</p>
<p>The last fragment of information we need is the UUID. All objects within the repository have a unique ID, and these are split at different levels. For example, an agent has a UUID, and so does the server it is monitoring. In our example, we want the UUID of the MySQL server, which is conveniently stored within the server itself in the <code>mysql.inventory</code> table. </p>
<p>Finally, we need the username and password of the agent user. Through the REST API we use basic HTTP authentication, to make the process easy. </p>
<p>Putting all of this together, we can get the core information about an instance using wget:</p>
<blockquote><pre>$ wget -qO mysql.server --http-user=agent --http-password=password \
    'http://nautilus:18080/v2/rest/instance/mysql/server/2b86b277-fb2b-492d-b946-3a2acaec0869'
</pre>
</blockquote>
<p>If we now look at the output file, <code>mysql.server</code>:</p>
<blockquote><pre>{
    "name": "2b86b277-fb2b-492d-b946-3a2acaec0869",
    "parent": "/instance/os/Host/ssh:{88:e1:fc:6d:99:69:e4:5f:b4:0a:ec:5a:09:c0:6a:24}",
    "values":     {
        "blackout": "false",
        "displayname": null,
        "registration-complete": "true",
        "repl.groupName": null,
        "server.connected": 1,
        "server.last_error": null,
        "server.reachable": 1,
        "transport": "a3113263-4993-4890-8235-cadef9617c4b",
        "visible.displayname": "bear:3306"
    }
}
</pre>
</blockquote>
<p>I wont go into detail about what is here, most of it should be self explanatory. However, there are a few things of note. First, the information is in JSON format. This makes it easy to read and more importantly create. </p>
<p>Second, note the notation. The item is identified by its name, and also by it&#8217;s parent. This is an important construct because it helps identify the different elements with each other. In this case, the MySQL server is associated with a physical host (<code>/instance/os/Host</code>) and the individual host is identified by a SSH key, which is one of the alternative UUID formats support by the Enterprise Server to identify individual entities.</p>
<p>When submitting information, we need to flip the process around. We don&#8217;t use a GET request to obtain the information, we use a PUT to send up a JSON packet containing the information we want. The URL for sending the information depends on what we are uploading. The main element for the statements used for Query Analyzer is the <code>statementsummary</code>. </p>
<p>The URL for this is <code>http://nautilus:18080/v2/rest/instance/mysql/statementsummary/</code>. For the identifier at the end of the URL, you use a period-separated list that includes the UUID of the MySQL server, the name of the MySQL database the SQL statement relates to, and an MD5 hash of the SQL statement text. </p>
<p>For the actual packet, we use the following format, taken here from the Perl script: </p>
<blockquote><pre>{
    "name": "$server_uuid.$quanbase->{dbname}.$md5",
    "parent": "/instance/mysql/server/$server_uuid",
    "values" : {
	"count": "$quanbase->{count}",
	"text": "$quanbase->{query}",
	"query_type": "$quanbase->{qtype}",
	"text_hash": "$md5",
	"max_exec_time": "$quanbase->{max_exec_time}",
	"min_exec_time": "$quanbase->{min_exec_time}",
	"exec_time": "$quanbase->{exec_time}",
	"rows": "$quanbase->{rows}",
	"max_rows": "$quanbase->{max_rows}",
	"min_rows": "$quanbase->{min_rows}",
	"database": "$quanbase->{dbname}",
	"bytes": "$quanbase->{bytes}",
	"max_bytes": "$quanbase->{max_bytes}",
	"min_bytes": "$quanbase->{min_bytes}",
    }
}</pre>
</blockquote>
<p>Most of this should be self-explanatory. Remember that this is a statement <strong>summary</strong>, which means that we can send up information about multiple invocations of the same statement in one packet. Thus, within the statementsummary packet we have information about the count of invocations of the statement, execution, row and byte counts and maximum/minimum of each of them, and then the core information like the actual query text, database name, and query type (SELECT, INSERT, etc). </p>
<p>Once again, note the <code>name</code> and <code>parent</code>. Here the name is the same tuple as used in the URL, the UUID of the MySQL server, the database, and the hash of the query. This is used as the identifier for this query within the repository and allows us to uniquely identify the query, and the query execution on this server. The parent is the location of, and UUID of, the MySQL server. </p>
<p>Now, the Perl script that collates the information from our D script has to do two things, first read the raw output that we create with the D script, and second, supply this up as a PUT request to the Enterprise Server. </p>
<p>Dealing with the latter part first, I&#8217;ve used Perl and LWP (libwww-perl) module to construct a suitable request object with the HTTP authorization attached: </p>
<blockquote><pre>my $header = HTTP::Headers->new;
$header->content_type('text/text');
$header->authorization_basic('agent','password');
my $res = LWP::UserAgent->new();
</pre>
<p>Once we&#8217;ve constructed a packet, sending it is a case of specifying the URL, the header, and the content: </p>
<blockquote><pre>$header->content_length(length $bio);
my $req = HTTP::Request->new(PUT => $url, $header, $bio);

$res->request($req);
</pre>
</blockquote>
<p>The bulk of the rest of the script is devoted to reading the information from the D script output, and assembling the packet and min/max values per query. </p>
<p>Within the Query Analyzer, the SQL statements are normalized, or canonicalized so that variables are replaced with a question mark. This ensures that we are tracking the <strong>query</strong> and not the individual values. The significance here is that we want to compare the raw SQL statement, of which there may only be a few hundred in a typical application, not each individual query with it&#8217;s <code>WHERE</code> and other clauses. </p>
<p>Hence, the statement: </p>
<blockquote><pre>SELECT photoid,title from media_photos where photoid > 23785 limit 15</pre>
</blockquote>
<p>Would be normalized to:</p>
<blockquote><pre>SELECT photoid,title from media_photos where photoid > ? limit ?</pre>
</blockquote>
<p>For the Perl script, I do just one type of normalization, removing the value from a
<literal>LIMIT</literal> clause.</p>
<blockquote><pre>#!/usr/bin/perl
use Data::Dumper;
use LWP;
use HTTP::Request;
use Digest::MD5 qw/md5_hex/;

my $server_uuid = '2b86b277-fb2b-492d-b946-3a2acaec0869';

my $header = HTTP::Headers->new;
$header->content_type('text/text');
$header->authorization_basic('agent','password');
my $res = LWP::UserAgent->new();

my $interval = shift || 20;

print "Sending queries every $interval statement(s)\n";

open(DTRACE,"./merlin.d|") or die "Couldn't open DTRACE\n";

my $counter = 1;
my $querybase = {};

while(
<dtrace>)
{
    chomp;
    my ($origquery,$dbname,$time,$rows,$bytes) = split m{:};

    my $query = $origquery;
    $query =~ s/limit \d+/limit ?/g;

    $querybase->{$query}->{dbname} = $dbname;
    $querybase->{$query}->{query} = $query;
    $querybase->{$query}->{count}++;
    $querybase->{$query}->{rows} += $rows;
    $querybase->{$query}->{bytes} += $bytes;
    $querybase->{$query}->{exec_time} += $time;

    if (exists($querybase->{$query}))
    {
	$querybase->{$query}->{max_rows} = $rows if ($rows > $querybase->{$query}->{max_rows});
	$querybase->{$query}->{min_rows} = $rows if ($rows < $querybase->{$query}->{min_rows});
	$querybase->{$query}->{max_bytes} = $bytes if ($bytes > $querybase->{$query}->{max_bytes});
	$querybase->{$query}->{min_bytes} = $bytes if ($bytes < $querybase->{$query}->{min_bytes});
	$querybase->{$query}->{max_exec_time} = $time if ($time > $querybase->{$query}->{max_exec_time});
	$querybase->{$query}->{min_exec_time} = $time if ($time < $querybase->{$query}->{min_exec_time});
    }
    else
    {
	$querybase->{$query}->{max_rows} = $rows;
	$querybase->{$query}->{min_rows} = $rows;
	$querybase->{$query}->{max_bytes} = $bytes;
	$querybase->{$query}->{min_bytes} = $bytes;
	$querybase->{$query}->{max_exec_time} = $time;
	$querybase->{$query}->{min_exec_time} = $time;
    }	

    if (($counter % $interval) == 0)
    {
	print STDERR "Writing quan packets ($counter queries sent)\n";
        foreach my $query (keys %{$querybase})
        {
            send_quandata($querybase->{$query});
	    delete($querybase->{$query});
        }
    }
    $counter++;
}

sub send_quandata
{
    my ($quanbase) = @_;

    my $urlbase = 'http://nautilus:18080/v2/rest/instance/mysql/statementsummary/%s.%s.%s';

    my $md5 = md5_hex($quanbase->{query});
    my $url = sprintf($urlbase,$server_uuid,$quanbase->{dbname},$md5);

my $bio = < <EOF;
{
    "name": "$server_uuid.$quanbase->{dbname}.$md5",
    "parent": "/instance/mysql/server/$server_uuid",
    "values" : {
        "count": "$quanbase->{count}",
        "text": "$quanbase->{query}",
        "query_type": "$quanbase->{qtype}",
        "text_hash": "$md5",
        "max_exec_time": "$quanbase->{max_exec_time}",
        "min_exec_time": "$quanbase->{min_exec_time}",
        "exec_time": "$quanbase->{exec_time}",
        "rows": "$quanbase->{rows}",
        "max_rows": "$quanbase->{max_rows}",
        "min_rows": "$quanbase->{min_rows}",
        "database": "$quanbase->{dbname}",
        "bytes": "$quanbase->{bytes}",
        "max_bytes": "$quanbase->{max_bytes}",
        "min_bytes": "$quanbase->{min_bytes}",
    }
}
EOF

$header->content_length(length $bio);
my $req = HTTP::Request->new(PUT => $url, $header, $bio);

$res->request($req);
}</dtrace></pre>
</blockquote>
<p>The basic structure is: </p>
<ol>
<li>Open the DTrace script</li>
<li>Read a line</li>
<li>Add that to the temporary list of queries I know about, adding stats</li>
<li>When I&#8217;ve read N queries, send up the stats about each query as a JSON packet to the Enterprise Manager</li>
<li>Repeat</li>
</ol>
<p>Depending on how busy your server is, you may want to adjust the interval when the stats data is uploaded. The default is every 20 queries, but when running on a really busy server, or when running benchmarks, you might want to up that to prevent the script spending too much time sending fairly small packets of stats up. </p>
<p>If you run the script, it should just work in the background: </p>
<blockquote><pre>$ ./dtrace_merlin.pl
Sending queries every 20 statement(s)
Writing quan packets (20 queries sent)
Writing quan packets (40 queries sent)
Writing quan packets (60 queries sent)
</pre>
</blockquote>
<p>That&#8217;s it!</p>
<p>I set this up and then sent some random queries to the server. The following graphic shows the query data only from the DTrace sourced information. </p>
<p><a href="http://coalface.mcslp.com/wp-content/uploads/2008/11/picture-5.png"><img src="http://coalface.mcslp.com/wp-content/uploads/2008/11/picture-5-300x74.png" alt="" title="Quan data from DTrace" width="300" height="74" class="alignnone size-medium wp-image-179" /></a></p>
<p>There are some limitations to the current script. I don&#8217;t do full normalization, for example, and I dont send the detailed information about individual statements up at the moment. There is also an <code>EXPLAIN</code> packet that you can send that contains the output from an <code>EXPLAIN</code> on a long running query. I could do that by opening a connection to the server and picking out the information. </p>
<p>But what I&#8217;d really like to do is use the DTrace-based output to show the detail of each part of the query process <em>and</em> the <code>EXPLAIN</code> output. I&#8217;m sure I can work on that with the Enterprise team. </p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/15/feeding-query-analyzer-from-dtrace/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL on OpenSolaris Presentation/Transcript Now Available</title>
		<link>http://coalface.mcslp.com/2008/11/13/mysql-on-opensolaris-presentationtranscript-now-available/</link>
		<comments>http://coalface.mcslp.com/2008/11/13/mysql-on-opensolaris-presentationtranscript-now-available/#comments</comments>
		<pubDate>Thu, 13 Nov 2008 16:18:15 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Solaris]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=175</guid>
		<description><![CDATA[As I mentioned earlier this week, I did a presentation on MySQL in OpenSolaris today. 
The presentation (audio and slides) is now viewable online (and downloadable), and you can also get hold of the transcript of the questions: here (or download). The original presentation is here. 
One minor difference from the presentation is that we [...]]]></description>
			<content:encoded><![CDATA[<p>As I mentioned earlier <a href="http://coalface.mcslp.com/2008/11/10/mysql-university-mysql-and-opensolaris/">this week</a>, I did a presentation on MySQL in OpenSolaris today. </p>
<p>The presentation (audio and slides) is now <a href="http://recordings.dimdim.com/view/c2a86fb2-02da-102c-a126-003048944478">viewable online</a> (and <a href="http://recordings.dimdim.com/saveflv/c2a86fb2-02da-102c-a126-003048944478">downloadable</a>), and you can also get hold of the transcript of the questions: <a href="http://recordings.dimdim.com/chat/c2a86fb2-02da-102c-a126-003048944478">here</a> (or <a href="http://recordings.dimdim.com/chat/c2a86fb2-02da-102c-a126-003048944478">download</a>). The original presentation is <a href="http://forge.mysql.com/w/images/d/de/MySQLonOpenSolarisv1.pdf">here</a>. </p>
<p>One minor difference from the presentation is that we have upgraded MySQL to 5.0.67 in 2008.11. I had forgotten we&#8217;d agreed to do this after the 5.1 pushback. Thanks to Matt Lord for the heads up.</p>
<p>And thanks to everybody for attending. Up next week, memcached!</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/13/mysql-on-opensolaris-presentationtranscript-now-available/feed/</wfw:commentRss>
<enclosure url="http://recordings.dimdim.com/saveflv/c2a86fb2-02da-102c-a126-003048944478" length="9768196" type="video/flv" />
		</item>
		<item>
		<title>MySQL University: MySQL and OpenSolaris</title>
		<link>http://coalface.mcslp.com/2008/11/10/mysql-university-mysql-and-opensolaris/</link>
		<comments>http://coalface.mcslp.com/2008/11/10/mysql-university-mysql-and-opensolaris/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 11:07:09 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[Solaris]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=172</guid>
		<description><![CDATA[On Thursday, November 13, 2008 (14:00 UTC / 14:00 BST / 15:00 CET), I&#8217;ll be presenting a MySQL University session on MySQL and OpenSolaris. 
The presentation will be similar to the presentation I did at the London OpenSolaris Users Group in July, you can see that presentation by visiting the LOSUG: July 2008 page.
The presentation [...]]]></description>
			<content:encoded><![CDATA[<p>On Thursday, November 13, 2008 (14:00 UTC / 14:00 BST / 15:00 CET), I&#8217;ll be presenting a MySQL University session on MySQL and OpenSolaris. </p>
<p>The presentation will be similar to the presentation I did at the London OpenSolaris Users Group in July, you can see that presentation by visiting the <a href="http://opensolaris.org/os/project/losug/files/July2008">LOSUG: July 2008</a> page.</p>
<p>The presentation on thursday will be slightly different - I&#8217;ll be providing a bit more hands-on information about how to install MySQL, how to configure and change the configuration and some more detail on solutions like the Webstack and Coolstack distributions. </p>
<p>I&#8217;ll also cover our plans for the inclusion of MySQL 5.1 in OpenSolaris, which will happen next year, and provide some examples on the new DTrace probes that we have been adding to MySQL generally. </p>
<p>Of course, if there&#8217;s anything specific you want me to talk about, comment here and I&#8217;ll see if I can squeeze it into the presentation before thursday.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/10/mysql-university-mysql-and-opensolaris/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Compiling MySQL Workbench on Gentoo</title>
		<link>http://coalface.mcslp.com/2008/11/10/compiling-mysql-workbench-on-gentoo/</link>
		<comments>http://coalface.mcslp.com/2008/11/10/compiling-mysql-workbench-on-gentoo/#comments</comments>
		<pubDate>Mon, 10 Nov 2008 11:01:16 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=166</guid>
		<description><![CDATA[The Workbench team have just announced the release of Workbench for Linux, including binary packages and source packages with instructions on how to build. 
I&#8217;m a Gentoo Linux user, so I prefer building from source, and you&#8217;ll need to emerge the following packages (and note the USE) requirement as part of the source build process:
# [...]]]></description>
			<content:encoded><![CDATA[<p>The Workbench team have just announced the release of <a href="http://dev.mysql.com/workbench/?page_id=152">Workbench for Linux</a>, including binary packages and source packages with instructions on how to build. </p>
<p>I&#8217;m a Gentoo Linux user, so I prefer building from source, and you&#8217;ll need to <code>emerge</code> the following packages (and note the <code>USE</code>) requirement as part of the source build process:</p>
<blockquote><pre># USE="svg" emerge libzip libxml2 libsigc++ libglade libgtksourceviewmm media-libs/glut mysql lua ossp-uuid libpcre libgnome gtk+ pango cairo
</pre>
</blockquote>
<p>Depending on your config and platform, you may need to bypass some package masking by adding the packages to your <code>/etc/portage/package.keywords</code> file. </p>
<p>Then download and install the <code>ctemplate</code> library from <a href="http://code.google.com/p/google-ctemplate/">google code page</a>. The current Gentoo version is 0.90, and you really should install the 0.91 version. </p>
<p>With the required packages and libraries in place, download the Workbench sources and then build:</p>
<blockquote><pre># cd mysql-workbench-5.1.4alpha
# ./autogen.sh
# make
# make install</pre>
</blockquote>
<p>That should build and install MySQL Workbench for you. </p>
<p>Just to confirm, here&#8217;s a screenshot of the built Workbench running on Gentoo Linux and displaying to my Mac OS X-based desktop.<br />
<a href="http://coalface.mcslp.com/wp-content/uploads/2008/11/picture-2.png"><img src="http://coalface.mcslp.com/wp-content/uploads/2008/11/picture-2-300x213.png" alt="" title="MySQL Workbench on Gentoo" width="300" height="213" class="alignnone size-medium wp-image-168" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/10/compiling-mysql-workbench-on-gentoo/feed/</wfw:commentRss>
		</item>
		<item>
		<title>ZFS Replication for MySQL data</title>
		<link>http://coalface.mcslp.com/2008/11/09/zfs-replication-for-mysql-data/</link>
		<comments>http://coalface.mcslp.com/2008/11/09/zfs-replication-for-mysql-data/#comments</comments>
		<pubDate>Sun, 09 Nov 2008 17:15:11 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Backups]]></category>

		<category><![CDATA[Databases]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[Mac OS X]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Solaris]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=154</guid>
		<description><![CDATA[At the European Customer Conference a couple of weeks back, one of the topics was the use of DRBD. DRBD is a kernel-based block device that replicates the data blocks of a device from one machine to another. The documentation I developed for that and MySQL is available here. 
Fundamentally, with DRBD, you set up [...]]]></description>
			<content:encoded><![CDATA[<p>At the European Customer Conference a couple of weeks back, one of the topics was the use of DRBD. DRBD is a kernel-based block device that replicates the data blocks of a device from one machine to another. The documentation I developed for that and MySQL is available <a href="http://dev.mysql.com/doc/refman/5.1/en/ha-drbd.html">here</a>. </p>
<p>Fundamentally, with DRBD, you set up a physical device, configure DRBD on top of that, and write to the DRBD device. In the background, on the primary, the DRBD device writes the data to the physical disk and replicates those changed blocks to the seconday, which in turn writes the data to it&#8217;s physical device. The result is a block level copy of the source data. In an HA solution, which means that you can switch over from your primary host to your secondary host in the event of system failure and be sure pretty certain that the data on the primary and seconday are the same. </p>
<p>In short, DRBD simplifies one of the more complex aspects of the typical HA solution by copying the data needed during the switch. Because DRBD is a Linux Kernel module you can&#8217;t use it on other platforms, like Mac OS X or Solaris. But there is another solution: ZFS. </p>
<p>ZFS supports filesystem snapshots. You can create a snapshot at any time, and you can create as many snapshots as you like.</p>
<p>Let&#8217;s take a look at a typical example. Below I have a simple OpenSolaris system running with two pools, the root pool and another pool I&#8217;ve mount at <code>/opt</code>:</p>
<blockquote><pre>Filesystem             size   used  avail capacity  Mounted on
rpool/ROOT/opensolaris-1
                       7.3G   3.6G   508M    88%    /
/devices                 0K     0K     0K     0%    /devices
/dev                     0K     0K     0K     0%    /dev
ctfs                     0K     0K     0K     0%    /system/contract
proc                     0K     0K     0K     0%    /proc
mnttab                   0K     0K     0K     0%    /etc/mnttab
swap                   465M   312K   465M     1%    /etc/svc/volatile
objfs                    0K     0K     0K     0%    /system/object
sharefs                  0K     0K     0K     0%    /etc/dfs/sharetab
/usr/lib/libc/libc_hwcap1.so.1
                       4.1G   3.6G   508M    88%    /lib/libc.so.1
fd                       0K     0K     0K     0%    /dev/fd
swap                   466M   744K   465M     1%    /tmp
swap                   465M    40K   465M     1%    /var/run
rpool/export           7.3G    19K   508M     1%    /export
rpool/export/home      7.3G   1.5G   508M    75%    /export/home
rpool                  7.3G    60K   508M     1%    /rpool
rpool/ROOT             7.3G    18K   508M     1%    /rpool/ROOT
opt                    7.8G   1.0G   6.8G    14%    /opt
</pre>
</blockquote>
<p>I&#8217;ll store my data in a directory on <code>/opt</code>. To help demonstrate some of the basic replication stuff, I have other things stored in <code>/opt</code> as well:</p>
<blockquote><pre>
total 17
drwxr-xr-x  31 root     bin           50 Jul 21 07:32 DTT/
drwxr-xr-x   4 root     bin            5 Jul 21 07:32 SUNWmlib/
drwxr-xr-x  14 root     sys           16 Nov  5 09:56 SUNWspro/
drwxrwxrwx  19 1000     1000          40 Nov  6 19:16 emacs-22.1/
lrwxrwxrwx   1 root     root          48 Nov  5 09:56 uninstall_Sun_Studio_12.class -> SUNWspro/installer/uninstall_Sun_Studio_12.class
</pre>
</blockquote>
<p>To create a snapshot of the filesystem, you use <code>zfs snapshot</code>, and then specify the pool and the snapshot name: </p>
<blockquote><p><code># zfs snapshot opt@snap1</code></p></blockquote>
<p>To get a list of snapshots you&#8217;ve already taken: </p>
<blockquote><pre># zfs list -t snapshot
NAME                                         USED  AVAIL  REFER  MOUNTPOINT
opt@snap1                                       0      -  1.03G  -
rpool@install                               19.5K      -    55K  -
rpool/ROOT@install                            15K      -    18K  -
rpool/ROOT/opensolaris-1@install            59.8M      -  2.22G  -
rpool/ROOT/opensolaris-1@opensolaris-1       100M      -  2.29G  -
rpool/ROOT/opensolaris-1/opt@install            0      -  3.61M  -
rpool/ROOT/opensolaris-1/opt@opensolaris-1      0      -  3.61M  -
rpool/export@install                          15K      -    19K  -
rpool/export/home@install                     20K      -    21K  -
</pre>
</blockquote>
<p>The snapshots themselves are stored within the filesystem metadata, and the space required to keep them will vary as time goes on because of the way the the snapshots are created. The initial creation of a snapshot is really quick, because instead of taking an entire copy of the data and metadata required to hold the entire snapshot, ZFS merely records the point in time and metadata of when the snaphot was created.</p>
<p>As you make more changes to the original filesystem, the size of the snapshot increases because more space is required to keep the record of the old blocks. Furthermore, if you create lots of snapshots, say one per day, and then delete the snapshots from earlier in the week, the size of the newer snapshots may also increase, as the changes that make up the newer state have to be included in the more recent snapshots, rather than being spread over the seven snapshots that make up the week. </p>
<p>The result is that creating snapshots is generally very fast, and storing snapshots is very efficient. As an example, creating a snapshot of a 40GB filesystem takes less than 20ms on my machine. </p>
<p>The only issue, from a backup perspective, is that snaphots exist within the confines of the original filesystem. To get the snapshot out into a format that you can copy to another filesystem, tape, etc. you use the <code>zfs send</code> command to create a stream version of the snapshot. </p>
<p>For example, to write out the snapshot to a file: </p>
<blockquote><pre># zfs send opt@snap1 >/backup/opt-snap1</pre>
</blockquote>
<p>Or tape, if you are still using it:</p>
<blockquote><pre># zfs send opt@snap1 >/dev/rmt/0</pre>
</blockquote>
<p>You can also write out the incremental changes between two snapshots using <code>zfs send</code>:</p>
<blockquote><pre># zfs send opt@snap1 opt@snap2 >/backup/opt-changes</pre>
</blockquote>
<p>To recover a snapshot, you use <code>zfs recv</code> which applies the snapshot information either to a new filesytem, or to an existing one. I&#8217;ll skip the demo of this for the moment, because it will make more sense in the context of what we&#8217;ll do next. </p>
<p>Both <code>zfs send</code> and <code>zfs recv</code> work on streams of the snapshot information, in the same way as <code>cat</code> or <code>sed</code> do. We&#8217;ve already seen some examples of that when we used standard redirection to write the information out to a file. </p>
<p>Because they are stream based, you can use them to replicate information from one system to another by combining <code>zfs send</code>, <code>ssh</code>, and <code>zfs recv</code>. </p>
<p>For example, let&#8217;s say I&#8217;ve created a snapshot of my <code>opt</code> filesystem and want to copy that data to a new system into a pool called <code>slavepool</code>:</p>
<blockquote><pre># zfs send opt@snap1 |ssh mc@slave pfexec zfs recv -F slavepool</pre>
</blockquote>
<p>The first part, <code>zfs send opt@snap1</code>, streams the snapshot, the second, <code>ssh mc@slave</code>, and the third, <code>pfexec zfs recv -F slavepool</code>, receives the streamed snapshot data and writes it to slavepool. In this instance, I&#8217;ve specified the <code>-F</code> option which forces the snapshot data to be applied, and is therefore destructive. This is fine, as I&#8217;m creating the first version of my replicated filesystem. </p>
<p>On the slave machine, if I look at the replicated filesystem: </p>
<blockquote><pre># ls -al /slavepool/
total 23
drwxr-xr-x   6 root     root           7 Nov  8 09:13 ./
drwxr-xr-x  29 root     root          34 Nov  9 07:06 ../
drwxr-xr-x  31 root     bin           50 Jul 21 07:32 DTT/
drwxr-xr-x   4 root     bin            5 Jul 21 07:32 SUNWmlib/
drwxr-xr-x  14 root     sys           16 Nov  5 09:56 SUNWspro/
drwxrwxrwx  19 1000     1000          40 Nov  6 19:16 emacs-22.1/
lrwxrwxrwx   1 root     root          48 Nov  5 09:56 uninstall_Sun_Studio_12.class -> SUNWspro/installer/uninstall_Sun_Studio_12.class
</pre>
</blockquote>
<p>Wow - that looks familiar!</p>
<p>Once you&#8217;ve snapshotted once, to synchronize the filesystem again, I just need to create a new snapshot, and then use the incremental snapshot feature of <code>zfs send</code> to send the changes over to the slave machine again: </p>
<blockquote><pre># zfs send -i opt@snapshot1 opt@snapshot2 |ssh mc@192.168.0.93 pfexec zfs recv slavepool</pre>
</blockquote>
<p>Actually, this operation will fail. The reason is that the filesystem on the slave machine can currently be modified, and you can&#8217;t apply the incremental changes to a destination filesystem that has changed. What&#8217;s changed? The metadata about the filesystem, like the last time it was accessed - in this case, it will have been our <code>ls</code> that caused the problem. </p>
<p>To fix that, set the filesystem on the slave to be read-only:</p>
<blockquote><pre># zfs set readonly=on slavepool</pre>
</blockquote>
<p>Setting <code>readonly</code> means that we can&#8217;t change the filesystem on the slave by normal means - that is, I can&#8217;t change the files or metadata (modification times and so on). It also means that operations that would normally update metadata (like our <code>ls</code>) will silently perform their function without attempting to update the filesystem state. </p>
<p>In essence, our slave filesystem is nothing but a static copy of our original filesystem. However, even when enabled to readonly, a filesystem can have snapshots applied to it. Now it&#8217;s read only, re-run the initial copy: </p>
<blockquote><pre># zfs send opt@snap1 |ssh mc@slave pfexec zfs recv -F slavepool</pre>
</blockquote>
<p>Now we can make changes to the original and replicate them over. Since we&#8217;re dealing with MySQL, let&#8217;s initialize a database on the original pool. I&#8217;ve updated the configuration file to use <code>/opt/mysql-data</code> as the data directory, and now I can initialize the tables: </p>
<blockquote><pre># mysql_install_db --defaults-file=/etc/mysql/5.0/my.cnf --user=mysql</pre>
</blockquote>
<p>Now, we can synchronize the information to our slave machine and filesystem by creating another snapshot and then doing an incremental <code>zfs send</code>:</p>
<blockquote><pre># zfs snapshot opt@snap2</pre>
</blockquote>
<p>Just to demonstrate the efficiency of the snapshots, the size of the data created during initialization is 39K:</p>
<blockquote><pre># du -sh /opt/mysql-data/
  39K	/opt/mysql-data</pre>
</blockquote>
<p>If I check the size used by the snapshots:</p>
<blockquote><pre># zfs list -t snapshot
NAME                                         USED  AVAIL  REFER  MOUNTPOINT
opt@snap1                                     47K      -  1.03G  -
opt@snap2                                       0      -  1.05G  -</pre>
</blockquote>
<p>The size of the snapshot is 47K. Note, by the way, that it is 47K in <code>snap1</code>, because currently <code>snap2</code> should be more or less equal to our current filesystem state.</p>
<p>Now, let&#8217;s synchronize this over:</p>
<blockquote><pre># zfs send -i opt@snap1 opt@snap2|ssh mc@192.168.0.93 pfexec zfs recv slavepool
</pre>
</blockquote>
<p>Note we don&#8217;t have to force the operation this time - we&#8217;re synchronizing the incremental changes from what are identical filesystems, just on different systems. </p>
<p>And double check that the slave has it:</p>
<blockquote><pre># ls -al /slavepool/mysql-data/</pre>
</blockquote>
<p>Now we can start up MySQL, create some data, and then synchronize the information over again, replicating the changes. To do that, you have to create a new snapshot, then do the send/recv to the slave to synchronize the changes. </p>
<p>The rate at which you do it is entirely up to you, but keep in mind that if you have a lot of changes then doing it as frequently as once a minute may lead to your data becoming behind the because of the time taken to transfer the filesystem changes over the network - running snapshot with MySQL running in the background still takes comparatively little time. </p>
<p>To demonstrate that, here&#8217;s the time taken to create a snapshot mid-way through a 4 million row insert into an InnoDB table: </p>
<blockquote><pre># time zfs snapshot opt@snap3

real    0m0.142s
user    0m0.006s
sys     0m0.027s
</pre>
</blockquote>
<p>I told you it was quick <img src='http://coalface.mcslp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>However, the send/recv operation took a few minutes to complete, with about 212MB of data transferred over a very slow network connection, and the machine was busy writing those additional records.</p>
<p>Ideally you want to set up a simple script that will handle that sort of snapshot/replication for you and run it past <code>cron</code> to do the work for you. You might also want to try ready-made tools like Tim Foster&#8217;s zfs replication tool, which you can find out about <a href="http://blogs.sun.com/timf/entry/zfs_automatic_snapshots_now_with">here</a>. Tim&#8217;s system works through SMF to handle the replication and is very configurable. It even handles automatic deletion of old, synchronized, snapshots. </p>
<p>Of course, all of this is useless unless once replicated from one machine to another we can actually use the databases. Let&#8217;s assume that there was a failure and we needed to fail over to the slave machine. To do: </p>
<ol>
<li>Stop the script on the master, if it&#8217;s still up and running.</li>
<li>Set the slave filesystem to be read/write:<br />
<blockquote><pre># zfs set readonly=off slavepool </pre>
</blockquote>
</li>
<li>Start up <code>mysqld</code> on the slave. If you are using InnoDB, Falcon or Maria you should get auto-recovery, if it&#8217;s needed, to make sure the table data is correct, as shown here when I started up from our mid-INSERT snapshot:<br />
<blockquote><pre>InnoDB: The log sequence number in ibdata files does not match
InnoDB: the log sequence number in the ib_logfiles!
081109 15:59:59  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
081109 16:00:03  InnoDB: Started; log sequence number 0 1142807951
081109 16:00:03 [Note] /slavepool/mysql-5.0.67-solaris10-i386/bin/mysqld: ready for connections.
Version: '5.0.67'  socket: '/tmp/mysql.sock'  port: 3306  MySQL Community Server (GPL)
</pre>
</blockquote>
</li>
</ol>
<p>Yay - we&#8217;re back up and running. On MyISAM, or other tables, you need to run <code>REPAIR TABLE</code>, and you might even have lost some information, but it should be minor. </p>
<p>The point is, a mid-INSERT ZFS snapshot, combined with replication, could be a good way of supporting a hot-backup of your system on Mac OS X or Solaris/OpenSolaris. </p>
<p>Probably, the most critical part is finding the sweet spot between the snapshot replication time, and how up to date you want to be in a failure situation. It&#8217;s also worth pointing out that you can replicate to as many different hosts as you like, so if you want wanted to replicate your ZFS data to two or three hosts, you could.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/09/zfs-replication-for-mysql-data/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL on Solaris Best Practices Presentation</title>
		<link>http://coalface.mcslp.com/2008/11/06/mysql-on-solaris-best-practices-presentation/</link>
		<comments>http://coalface.mcslp.com/2008/11/06/mysql-on-solaris-best-practices-presentation/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 12:16:30 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=151</guid>
		<description><![CDATA[A couple of weeks ago I was at the MySQL European Customer Conference in London, where I was presenting my talk on deploying MySQL on Solaris best practices. You can download a copy of the presentation here: MySQL on Solaris Best Practices. 
I cover both choosing the best release version, using tricks like mtmalloc (the [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I was at the MySQL European Customer Conference in London, where I was presenting my talk on deploying MySQL on Solaris best practices. You can download a copy of the presentation here: <a href='http://coalface.mcslp.com/wp-content/uploads/2008/11/mysqlonsolarisbestpracticesmcbv2.pdf'>MySQL on Solaris Best Practices</a>. </p>
<p>I cover both choosing the best release version, using tricks like <code>mtmalloc</code> (the threaded malloc library) before moving on to UFS and ZFS tricks, using DTrace and MySQL Cluster and Sun Cluster. </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/11/06/mysql-on-solaris-best-practices-presentation/feed/</wfw:commentRss>
		</item>
		<item>
		<title>BBC Quiz: Old computers</title>
		<link>http://coalface.mcslp.com/2008/10/29/bbc-quiz-old-computers/</link>
		<comments>http://coalface.mcslp.com/2008/10/29/bbc-quiz-old-computers/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 08:15:18 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=149</guid>
		<description><![CDATA[The BBC has a great quiz on old computers, most of which I&#8217;m happy to admit that I have actually owned. 
Despite this I only 7 out of 10, but I still think that&#8217;s a respectable score.
]]></description>
			<content:encoded><![CDATA[<p>The BBC has a great <a href="http://news.bbc.co.uk/1/hi/magazine/7671677.stm">quiz on old computers</a>, most of which I&#8217;m happy to admit that I have actually owned. </p>
<p>Despite this I only 7 out of 10, but I still think that&#8217;s a respectable score.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/29/bbc-quiz-old-computers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL Documentation Myths</title>
		<link>http://coalface.mcslp.com/2008/10/24/mysql-documentation-myths/</link>
		<comments>http://coalface.mcslp.com/2008/10/24/mysql-documentation-myths/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 08:46:49 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=144</guid>
		<description><![CDATA[There are a few myths surrounding the MySQL documentation and how it works, and I thought I&#8217;d try and dispel some of those myths if I can. If you have any more questions or misunderstandings you want clarified, let me know. 
Myth: 
MySQL Documentation is written by the developers.

Reality
MySQL Documentation is written by a dedicated [...]]]></description>
			<content:encoded><![CDATA[<p>There are a few myths surrounding the MySQL documentation and how it works, and I thought I&#8217;d try and dispel some of those myths if I can. If you have any more questions or misunderstandings you want clarified, let me know. </p>
<p><b>Myth</b>: </p>
<blockquote><p>MySQL Documentation is written by the developers.
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>MySQL Documentation is written by a dedicated team of writers with help and input from the developers. There are four main writers, Paul DuBois, Tony Bedford, Jon Stephens, and MC Brown (me!), plus our Team Lead, Stefan Hinz. </p>
<p>All the documentation staff are employed full time for the sole purpose of writing documentation. Sure, some of us get involved in other things too, but that&#8217;s basically the nature of the job. Some of us simply cannot help ourselves.
</p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>Docs team members are just writers and have no technical expertise.
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>It&#8217;s tempting to come back with a rude response to this one, but it is a comment I heard from someone at a conference. The reality is that all of us have some technical background, unsurprisingly often with MySQL. Some of us have expertise elsewhere too. Speaking only for myself, go look at <a href="http://mcslp.com">MCslp.com</a> for more info. If you want details, feel free to ask, but know that this myth is definitely busted. </p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>The documentation is updated very rarely.
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>Our main tree, mysqldoc, is publicly available, and if you want to go view the commits to that tree, please feel free. It doesn&#8217;t take much to see that we commit to that tree all day, and every time we change something, the documentation gets rebuilt. How frequently? Well, on a typical day we will generate 10-15 new versions of each reference manual. It&#8217;s actually difficult to rebuild more frequently than that due to the sheer size of the documentation. </p>
<p>If you want to check the build date of the documentation, check the intro/preface of each document. The build and build date information is included there. </p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>The MySQL documentation is small and unused.
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>You&#8217;d be amazed how many people need to be told <a href="http://en.wikipedia.org/wiki/RTFM">RTFM</a>, but a surprising number of people who criticize the MySQL documentation have actually never read it, or, they looked at it years ago and haven&#8217;t bothered to look recently because they couldn&#8217;t find what they were looking for before.</p>
<p>The reality is that our documentation is over 2000 pages per reference manual, which means over 10,000 pages now just for MySQL. There are hundreds more pages on the GUI tools, Workbench, Cluster/NDBAPI, and the Enterprise Monitor.</p>
<p>As to the popularity, the hits to the online pages of our manual exceed the hits to every other section of the MySQL website by a significant factor. For the downloadable formats we get an average of 200,000 downloads in all the various formats each month, with occasional spikes up to 800,000. For the online manuals, the documentation pages make up about 45% of <strong>all</strong> the traffic on mysql.com. Or to say it another way, we account for almost half of all the web traffic that MySQL receives, including downloads. </p>
<p>In short, we have no shortage of interested readers.
</p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>Docs team don&#8217;t read comments
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>Actually, we all get an email each time you post a comment and all of us will read it, determine whether it is suitable, useful, or (occasionally) spam, and either ignore it, delete it, or comment on it accordingly. Often that will happen within minutes of your leaving the comment. If there&#8217;s a non-standard reply to your comment, you&#8217;ll get that too. </p>
<p>Now, we are aware that the comments system has it&#8217;s faults. For one, we have one comment system for all the different versions of the manual, which means comments can be confusing and even misleading. We&#8217;re fixing that. We&#8217;re also trying to address the problem that some comments are really tips, while others are just plain comments and observations. </p>
<p>Any other comments or criticisms, let us know. We may not be unaware of the problem, but if we know your pain we can do something about it.
</p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>Docs team don&#8217;t accept bugs or corrections
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>You can report a bug or correction to us using the standard <a href="http://bugs.mysql.com">bugs.mysql.com</a>, or drop us an email to docs@mysql.com.
</p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>Docs are &#8216;closed source&#8217;
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>The docs are not closed source - you can download the DocBook XML and the files and tools required to build them (well, beyond the XML parsers, Perl, and other bits and pieces). You can get hold of the repos (via SVN), on the <a href="http://dev.mysql.com/tech-resources/sources.html">Tech Resources</a> page. </p>
<p>That said, we don&#8217;t allow anybody to commit changes, but see the response above for information on how to provide changes and fixes. Again this is something we are working to improve on.</p></blockquote>
<p><b>Myth</b></p>
<blockquote><p>MySQL Documentation is not distributable
</p></blockquote>
<p><b>Reality</b></p>
<blockquote><p>This mostly comes out of the fuss around Debian dropping the man pages from their MySQL distributions You can see the description why here: <a href="http://coalface.mcslp.com/2008/01/31/mysql-documentation-and-debianubuntu/">MySQL Documentation and Debian/Ubuntu</a>. </p>
<p>The short answer is that it is a mis-understanding in our license for the documentation, which is not released under the same license as MySQL. You can provide documentation if you provide MySQL, but not on it&#8217;s own. The reason for this is that our documentation is updated so regularly that we want to ensure that we only get genuine, up to date, versions of our documentation out there. Trust me, do a search for MySQL and some term and you will find versions of the manual that are months, or even years out of date, which is no help to anybody. </p>
<p>It&#8217;s about trying to make our documentation readable and usable and not misleading.
</p></blockquote>
<hr />
<p>OK that&#8217;s enough myths busted today, but if you hear any more, or just have additional questions, feel free to ask.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/24/mysql-documentation-myths/feed/</wfw:commentRss>
		</item>
		<item>
		<title>DimDim and MySQL University</title>
		<link>http://coalface.mcslp.com/2008/10/20/dimdim-and-mysql-university/</link>
		<comments>http://coalface.mcslp.com/2008/10/20/dimdim-and-mysql-university/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 13:25:34 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=140</guid>
		<description><![CDATA[Stop the press! My boss, Stefan Hinz, has just started blogging, with his first post here: Using NetBeans with MySQL.
So who is he? Well, Stefan is the guy that keeps the rest of us in the docs team in check and makes sure we do what we&#8217;re asked, when we&#8217;re are asked and that all [...]]]></description>
			<content:encoded><![CDATA[<p>Stop the press! My boss, Stefan Hinz, has just started blogging, with his first post here: <a href="http://blogs.sun.com/mysqlf/entry/using_netbeans_with_mysql">Using NetBeans with MySQL</a>.</p>
<p>So who is he? Well, Stefan is the guy that keeps the rest of us in the docs team in check and makes sure we do what we&#8217;re asked, when we&#8217;re are asked and that all of the machinery, legalities and management tasks happen in the background. Without him we really couldn&#8217;t function as effectively as we do. </p>
<p>It&#8217;s wonderful to see some other Docs team members getting in on the act (to be fair to the rest of the team, <a href="http://blog.plasticfish.info/">Jon is also a blogger</a>). We are all writers, you would think the blogging would come as a natural extension. </p>
<p>Behind the tease is the simple fact that the improved system for MySQL University I was talking about is getting a trial run this week. </p>
<p>We&#8217;ve been trying out <a href="http://dimdim.com">Dimdim</a> for web conferencing with <a href="http://davidvancouvering.blogspot.com/">David van Couvering</a> and I have to say I&#8217;m pretty impressed. </p>
<p>We chatted, we tried out screen-sharing, presentations and the whiteboard functionality and it all worked really nicely. </p>
<p>We&#8217;re going to be using it for the MySQL University session this week, <a href="http://forge.mysql.com/wiki/Using_MySQL_With_NetBeans">Using MySQL with NetBeans</a>. Space will be limited, but feel free to join us if you can.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/20/dimdim-and-mysql-university/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using the MySQL Doc source tree</title>
		<link>http://coalface.mcslp.com/2008/10/20/using-the-mysql-doc-source-tree/</link>
		<comments>http://coalface.mcslp.com/2008/10/20/using-the-mysql-doc-source-tree/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 09:07:04 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[DocBook]]></category>

		<category><![CDATA[Documentation]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=136</guid>
		<description><![CDATA[I&#8217;ve mentioned a number of times that the documentation repositories that we use to build the docs are freely available, and so they are, but how do you go about using them? 
More and more people are getting interested in being able to work with the MySQL docs, judging by the queries we get, and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve mentioned a number of times that the documentation repositories that we use to build the docs are freely available, and so they are, but how do you go about using them? </p>
<p>More and more people are getting interested in being able to work with the MySQL docs, judging by the queries we get, and internally we sometimes get specialized requests. </p>
<p>There are some limitations - although you can download and access the docs and generate your own versions in various formats, you are not allowed to distribute or supply that iinformation, it can only be employed for personal use. The reasons and disclaimer for that are available on the main page for each of the docs, such as the one on the <a href="http://dev.mysql.com/doc/refman/5.1/en/index.html">5.1 Manual</a>. </p>
<p>Those issues aside, if you want to use and generate your own docs from the Subversion source tree then you&#8217;ll need the following: </p>
<ul>
<li><a href="http://subversion.tigris.org/">Subversion</a> to download the sources</li>
<li><a href="http://www.xmlsoft.org/">XML processors</a> to convert the DocBook XML into various target formats; we include DocBook XML/XSLT files you&#8217;ll need.</li>
<li>Perl for some of the checking scripts and the ID mapping parts of the build process</li>
<li><a href="http://xmlgraphics.apache.org/fop/">Apache&#8217;s FOP</a> if you want to generate PDFs, if not, you can ignore. </li>
</ul>
<p>To get you started, you must download the DocBook XML source from the public subversion repository. We recently split a single Subversion tree with the English language version into two different repositories, one containing the pure content, and the other the tools that required to build the docs. The reason for that is consistency across all of our repositories, internally and externally, for the reference manual in all its different versions. </p>
<p>Therefore, to get started, you need both repositories. You need check them out into the same directory: </p>
<blockquote><p><code>$ svn checkout http://svn.mysql.com/svnpublic/mysqldoc<br />
$ svn checkout http://svn.mysql.com/svnpublic/mysqldoc-toolset</code></p></blockquote>
<p>Assuming you have the downloaded the XML toolkit already, make sure you have the necessary Perl modules installed. You&#8217;ll need <a href="http://expat.sourceforge.net/">Expat</a> library, and the following Perl modules: </p>
<ul>
<li>Digest::MD5</li>
<li>XML::Parser::PerlSAX</li>
<li>IO::File</li>
<li>IO::String</li>
</ul>
<p>If you have CPAN installed, you can install them automatically using <code>perl -MCPAN -e 'install modulename'</code>, or use your respective package management system to install the modules for you. You&#8217;ll get an error message if there is something missing. </p>
<p>OK, with everything in place you are ready to try building the documentation. You can change into most directories and convert the XML files there into a final document. For example, to build the Workbench documentation, change into the Workbench directory. We use <code>make</code> to build the various files and dependencies. </p>
<p>To build the full Workbench documentation, specify the main file, <code>workbench</code>, as the target, and the file format you want to produce as the extension. For example, to build a single HTML file, the extension is <code>html</code>. I&#8217;ve included the full output here so that you can see the exact output you will get: </p>
<blockquote><p><code>make workbench.html<br />
set -e; \<br />
	../../mysqldoc-toolset/tools/dynxml-parser.pl \<br />
	        --infile=news-workbench-core.xml --outfile=dynxml-local-news-workbench.xml-tmp-$$ --srcdir=../dynamic-docs --srclangdir=../dynamic-docs; \<br />
		mv dynxml-local-news-workbench.xml-tmp-$$ dynxml-local-news-workbench.xml<br />
make -C ../refman-5.1 metadata/introduction.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
../../mysqldoc-toolset/tools/idmap.pl refman/5.1/en introduction.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
make -C ../refman-5.1 metadata/partitioning.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
../../mysqldoc-toolset/tools/idmap.pl refman/5.1/en partitioning.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
make -C ../refman-5.1 metadata/se-merge.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
../../mysqldoc-toolset/tools/idmap.pl refman/5.1/en se-merge.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
make -C ../refman-5.1 metadata/se-myisam-core.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
../../mysqldoc-toolset/tools/idmap.pl refman/5.1/en se-myisam-core.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
make -C ../refman-5.1 metadata/sql-syntax-data-definition.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
../../mysqldoc-toolset/tools/idmap.pl refman/5.1/en sql-syntax-data-definition.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/refman-5.1&#8242;<br />
make -C ../workbench metadata/documenting-database.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en documenting-database.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/foreign-key-relationships.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en foreign-key-relationships.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/forward-engineering.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en forward-engineering.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/grt-shell.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en grt-shell.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/images.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en images.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/installing.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en installing.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/layers.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en layers.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/notes.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en notes.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/plugins.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en plugins.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/printing.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en printing.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/reference.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en reference.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/reverse-engineering.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en reverse-engineering.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/server-connection-wizard.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en server-connection-wizard.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/stored-procedures.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en stored-procedures.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/tables.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en tables.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/text-objects.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en text-objects.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/tutorial.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en tutorial.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/validation-plugins.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en validation-plugins.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
make -C ../workbench metadata/views.idmap<br />
make[1]: Entering directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
../../mysqldoc-toolset/tools/idmap.pl workbench//en views.xml<br />
make[1]: Leaving directory `/nfs/mysql-live/mysqldocs/working/Docs/mysqldoc/workbench&#8217;<br />
XML_CATALOG_FILES=&#8221;../../mysqldoc-toolset//catalog.xml&#8221; xsltproc &#8211;xinclude &#8211;novalid  \<br />
		&#8211;stringparam repository.revision &#8220;`../../mysqldoc-toolset/tools/get-svn-revision`&#8221; \<br />
		&#8211;param map.remark.to.para 0 \<br />
		&#8211;stringparam qandaset.style &#8220;&#8221; \<br />
		../../mysqldoc-toolset/xsl.d/dbk-prep.xsl workbench.xml > workbench-prepped.xml.tmp2<br />
../../mysqldoc-toolset/tools/bug-prep.pl < workbench-prepped.xml.tmp2 > workbench-prepped.xml.tmp<br />
../../mysqldoc-toolset/tools/idremap.pl  &#8211;srcpath=&#8221;../workbench ../gui-common ../refman-5.1 ../refman-common ../refman-5.0&#8243; &#8211;prefix=&#8221;workbench-&#8221; workbench-prepped.xml.tmp > workbench-prepped.xml.tmp2<br />
mv workbench-prepped.xml.tmp2 workbench-prepped.xml<br />
rm -f workbench-prepped.xml.tmp<br />
XML_CATALOG_FILES=&#8221;../../mysqldoc-toolset//catalog.xml&#8221; xsltproc &#8211;xinclude &#8211;novalid  \<br />
		&#8211;stringparam l10n.gentext.default.language en \<br />
		&#8211;output workbench.html-tmp \<br />
		../../mysqldoc-toolset/xsl.d/mysql-html.xsl \<br />
		workbench-prepped.xml<br />
../../mysqldoc-toolset/tools/add-index-navlinks.pl workbench.html-tmp<br />
mv workbench.html-tmp workbench.html<br />
</code></p></blockquote>
<p>There&#8217;s lots in the output above, and I&#8217;ll describe the content as best I can without going in to too much detail in this piece. </p>
<p>First off, the <code>make</code> triggers some dependencies, which are the creation of a number of &#8216;IDMap&#8217; files. These files contain information about the content of the files and are used to help produce valid links in to other parts of the documentation. I&#8217;ll talk about ID mapping more in a later post. </p>
<p>The next stage is to build the &#8216;prepped&#8217; version of the documentation, which combines all of the individual files into one large file and does some pre-processing to ensure that we get the output that we want. </p>
<p>The next is the remapping. This uses the IDMap information built in the first stage and ensures that any links in the documentation that go to a document we know about, like the reference manual, point to the correct online location. It is the ID mapping (and remapping) that allows us to effectively link between documents (such as the Workbench and Refman) without us having to worry about creating a complex URL link. Instead, we just include a link to the correct ID within the other document and let the ID mapping system do the rest. </p>
<p>The final stage takes our prepped, remapped, DocBook XML source and converts it into the final XML using the standard DocBook XSL templates. </p>
<p>One of the benefits of us using <code>make</code> is that because we build different stages in the build process, when we build another target, we dont have to repeat the full process. For example, to build a PDF version of the same document, the prepping, remapping and other stages are fundamentally the same, which is why we keep the file, <code>workbench-prepped.xml</code>. Building the PDF only requires us to build the FO (Formatting Objects) output, and then use <code>fop</code> to turn this into PDF: </p>
<blockquote><p><code>$ make workbench.pdf<br />
XML_CATALOG_FILES="../../mysqldoc-toolset//catalog.xml" xsltproc --xinclude --novalid  \<br />
		--output - ../../mysqldoc-toolset/xsl.d/strip-remarks.xsl workbench-prepped.xml \<br />
	| XML_CATALOG_FILES="../../mysqldoc-toolset//catalog.xml" xsltproc --xinclude --novalid  \<br />
		--stringparam l10n.gentext.default.language en \<br />
		 \<br />
		--output workbench.fo-tmp ../../mysqldoc-toolset/xsl.d/mysql-fo.xsl -<br />
Making portrait pages on USletter paper (8.5inx11in)<br />
mv workbench.fo-tmp workbench.fo<br />
set -e; \<br />
	if [ -f ../../mysqldoc-toolset/xsl.d/userconfig.xml ]; then \<br />
		../../mysqldoc-toolset/tools/fixup-multibyte.pl workbench.fo workbench.fo.multibyte; \<br />
		mv workbench.fo.multibyte workbench.fo; \<br />
		fop -q -c ../../mysqldoc-toolset/xsl.d/userconfig.xml workbench.fo workbench.pdf-tmp > workbench.pdf-err; \<br />
	else \<br />
		fop -q workbench.fo workbench.pdf-tmp > workbench.pdf-err; \<br />
	fi<br />
mv workbench.pdf-tmp workbench.pdf<br />
sed -e &#8216;/hyphenation/d&#8217; < workbench.pdf-err<br />
[ERROR] Areas pending, text probably lost in lineWhen synchronizing the database, table comments were not updated. However, column comments worked as expected.<br />
rm -f workbench.pdf-err<br />
</code></code></p></blockquote>
<p>You can see in this output that the prepping and remapping processes don&#8217;t even take place - the process immediately converts the prepped file into FO and then calls <code>fop</code>. </p>
<p>That completes our whirlwind tour of the basics of building MySQL documentation,  I&#8217;ll look at some more detailed aspects of the process in future blog posts. Until then, you might want to read our metadocs on the internals in <a href="http://dev.mysql.com/doc/mysqldoc-guide/en/index.html">MySQL Guide to MySQL Documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/20/using-the-mysql-doc-source-tree/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL on Solaris at the MySQL European Customer Conference</title>
		<link>http://coalface.mcslp.com/2008/10/18/mysql-on-solaris-at-the-mysql-european-customer-conference/</link>
		<comments>http://coalface.mcslp.com/2008/10/18/mysql-on-solaris-at-the-mysql-european-customer-conference/#comments</comments>
		<pubDate>Sat, 18 Oct 2008 14:09:00 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=133</guid>
		<description><![CDATA[I&#8217;m speaking at the MySQL European Customer Conference this week (Thursday, 23rd), on the topic of the best deployment practices for using MySQL on Solaris. 
I&#8217;ll be covering a number of topics, including: 

Overview of MySQL availability on Solaris
General tips for MySQL on Solaris
MySQL on ZFS
DTrace and the new DTrace Probes
Using MySQL with containers and [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m speaking at the <a href="http://www.mysql.com/news-and-events/european-conferences/2008/">MySQL European Customer Conference</a> this week (Thursday, 23rd), on the topic of the best deployment practices for using MySQL on Solaris. </p>
<p>I&#8217;ll be covering a number of topics, including: </p>
<ul>
<li>Overview of MySQL availability on Solaris</li>
<li>General tips for MySQL on Solaris</li>
<li>MySQL on ZFS</li>
<li>DTrace and the new DTrace Probes</li>
<li>Using MySQL with containers and zones</li>
<li>Using Sun Cluster and MySQL Cluster for HA</li>
</ul>
<p>Some of the material I&#8217;ve already covered before (see <a href="http://www.opensolaris.org/os/project/losug/files/July2008/LOSUGv3.pdf">my presentation</a> at the <a href="http://opensolaris.org/os/project/losug/">London Solaris User&#8217;s Group</a>, but most of the content will be new and more focused than the top level LOSUG presentation.</p>
<p>There are similar presentations being presented at the Paris and Munich conferences by Eric Bezille and Franz Haberhauer, and we&#8217;re all presenting the same basic content as we&#8217;ve been working together on the presentation. </p>
<p>If you are in the region and can make it to the conference, I suggest you come. Not just for my presentation, there are other topics including performance tuning, HA, MySQL Proxy and using MySQL and memcached.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/18/mysql-on-solaris-at-the-mysql-european-customer-conference/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Replicating multiple masters to one slave</title>
		<link>http://coalface.mcslp.com/2008/10/17/replicating-multiple-masters-to-one-slave/</link>
		<comments>http://coalface.mcslp.com/2008/10/17/replicating-multiple-masters-to-one-slave/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 10:43:20 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Databases]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=126</guid>
		<description><![CDATA[As standard, MySQL allows replication from one master to multiple slaves, and that is a common scale-out scenario, but there have been a few comments recently, and some longer standing queries about having a setup that works the other way round, that is, multiple slaves replicating into a single master. 
This a common enough scenario [...]]]></description>
			<content:encoded><![CDATA[<p>As standard, MySQL allows replication from one master to multiple slaves, and that is a common scale-out scenario, but there have been a few comments recently, and some longer standing queries about having a setup that works the other way round, that is, multiple slaves replicating into a single master. </p>
<p>This a common enough scenario in data logging systems, where the data is collected locally and then distributed up to a central database, or in EPOS (Electronic Point of Sale) systems where you want the transactions logs from the tills logged up to the database at head office. There are many other situations where you want that merging of information. </p>
<p>Although MySQL doesn&#8217;t support what is called &#8216;multiple master, single slave&#8217; solution, you can simulate the general approach by using a combination of replication and federated tables. </p>
<p>Replication allows for different table types on the master (the source of the data) and the slave. There are many advantages to this, for example, using InnoDB on the master to take advantage of transactions, while using MyISAM on the slave for read performance. </p>
<p><a href="http://dev.mysql.com/doc/refman/5.1/en/federated-storage-engine.html">Federation</a> allows you to access the tables of a remote server as if it were a local table.  You can set up a federated table to access a remote table from as many machines as you like. That means that you can have two, or more, MySQL instances set up to use the remote table using the federated engine. You can execute any queries you like on the remote table, but you need to take care when using multiple hosts to access the remote table. Particularly when doing INSERT from multiple hosts, using InnoDB, Falcon, Maria or another table that supports multiple writers can be a good idea, although I&#8217;ll cover some workarounds for that later. </p>
<p>Using federated gives us the ability to write to the same table from multiple hosts, but you dont want to read and write from the same remote table all the time, especially if on your local machine (your till, or data collector) you want to be able to run your own queries. </p>
<p>This is where the replication fits in, if you set up replication from the master to another instance of MySQL, let&#8217;s call it &#8216;Fed Slave&#8217; (which works both ways). On the Fed Slave, you configure the table or tables that you want to merge on the final &#8216;Slave&#8217; machine to be federated tables. What happens is that data is replicated from the master to the Fed Slave, and on Fed Slave the queries are sent to the Merge Slave via federation. You can probably see this more clearly in the figure below. </p>
<p><a href="http://coalface.mcslp.com/wp-content/uploads/2008/10/repfed.png"><img src="http://coalface.mcslp.com/wp-content/uploads/2008/10/repfed-183x300.png" alt="" title="Replication/Federation for Multiple Masters to one Slave" width="183" height="300" class="alignnone size-medium wp-image-127" /></a></p>
<p>To re-iterate:</p>
<ol>
<li>INSERT on Master 1 is replicated to Fed Slave 1</li>
<li>Fed Slave 1 executes the INSERT on a Federated table which points to Merge Slave</li>
<li>Merge Slave executes the federated statement on its local table</li>
</ol>
<p>Each Fed Slave is relatively lightweight - all it&#8217;s doing is executing a statement and sending the statement over the network to the Merge Slave, so you could run it on the same machine as Master 1. </p>
<p>There are few problems with this design: </p>
<ol>
<li>Updating the same federated table from multiple hosts can get messy. There are a few ways you can get get round this, one is to stop the query execution on the slaves and only allow them to run during a set period of time. For example, let Fed Slave 1 execute the queries in the log from 1am to 2am, and Fed Slave 2 from 2am to 3am, and so on. </li>
<li>Federation doesn&#8217;t get round the problems of duplicate IDs - if you try to run a statement on a federated table that inserts a duplicate ID it will fail just as will locally. You can get round this by making sure that the tables that hold the merge data on your Merge Slave dont have unique ID constraints, and that your Masters and all the table definitions contain a field to identify the source of the data in each case. </li>
<li>Load can be an issue. One of the reasons I suggested InnoDB/Falcon/Maria is to help get round the multiple-insert and locking that is normally applied, but the very nature of the system means that locks and delays might still occur. You can&#8217;t eliminate it, but you can ease it.</li>
</ol>
<p>I&#8217;ve tried and used this method in a number of situations, actually not for the reasons given above, but for performance logging from multiple hosts onto one. I&#8217;ll be honest and say that I&#8217;ve never seen a problem, but, at the same time, the type of data that I am collecting means that I would have been unlikely to notice a missing data point or two. </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/17/replicating-multiple-masters-to-one-slave/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL University: Checking Threading and Locking With Helgrind</title>
		<link>http://coalface.mcslp.com/2008/10/13/mysql-university-checking-threading-and-locking-with-helgrind/</link>
		<comments>http://coalface.mcslp.com/2008/10/13/mysql-university-checking-threading-and-locking-with-helgrind/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 15:28:26 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=120</guid>
		<description><![CDATA[This Thursday, Stewart Smith will give a MySQL University session:
Checking Threading and Locking With Helgrind
Note that this particular session starts 9:00 BST / 10:00 CET /
18:00 Brisbane/Melbourne
Stewart is always enjoyable to listen to, both because he knows his stuff and because he is a really fun guy (heads up for the MySQL Conference 09, the [...]]]></description>
			<content:encoded><![CDATA[<p>This Thursday, Stewart Smith will give a MySQL University session:</p>
<p><a href="http://forge.mysql.com/wiki/Checking_Threading_and_Locking_With_Helgrind">Checking Threading and Locking With Helgrind</a></p>
<p><em><strong>Note that this particular session starts 9:00 BST / 10:00 CET /<br />
18:00 Brisbane/Melbourne</strong></em></p>
<p>Stewart is always enjoyable to listen to, both because he knows his stuff and because he is a really fun guy (heads up for the MySQL Conference 09, the Monty Taylor/Stewart Smith double act at this years conference was one of the most interesting and information sessions I went to). </p>
<blockquote>
<p>Please register for this session by filling in your name on the session<br />
Wiki page. Registering is not required but appreciated. That Wiki page<br />
also contains a section to post questions. Please use it!</p>
<p>MySQL University sessions normally start at 13:00 UTC (summer) or 14:00<br />
UTC (winter); see: <a href="http://forge.mysql.com/wiki/MySQL_University">MySQL University</a> for more time zone information.</p>
<p>Those planning to attend a MySQL University session for the very first<br />
time should probably read the instructions for attendees,<br />
<a href="http://forge.mysql.com/wiki/Instructions_for_Attendees">Instructions for Attendees</a>.</p>
<p>See <a href="http://forge.mysql.com/wiki/MySQL_University#Upcoming_Sessions">Upcoming Sessions</a> for the complete list of upcoming University sessions.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/13/mysql-university-checking-threading-and-locking-with-helgrind/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to analyze memory leaks on Windows</title>
		<link>http://coalface.mcslp.com/2008/10/13/how-to-analyze-memory-leaks-on-windows/</link>
		<comments>http://coalface.mcslp.com/2008/10/13/how-to-analyze-memory-leaks-on-windows/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 10:13:35 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Windows]]></category>

		<category><![CDATA[debugging]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=113</guid>
		<description><![CDATA[We use valgrind to find memory leaks in MySQL on Linux. The tool is a convenient, and often enlightening way of finding out where the real and potential problems are location. 
On Windows, you dont have valgrind, but Microsoft do provide a free native debugging tool, called the user-mode dump heap (UMDH) tool. This performs [...]]]></description>
			<content:encoded><![CDATA[<p>We use <a href="http://valgrind.org">valgrind</a> to find memory leaks in MySQL on Linux. The tool is a convenient, and often enlightening way of finding out where the real and potential problems are location. </p>
<p>On Windows, you dont have valgrind, but Microsoft do provide a free native debugging tool, called the user-mode dump heap (UMDH) tool. This performs a similar function to valgrind to determine memory leaks.  </p>
<p>Vladislav Vaintroub, who works on the Falcon team and is one of our resident Windows experts provides the following how-to for using UMDH:</p>
<ol>
<li>
<p>Download and install debugging tools for Windows from here<br />
<a href="http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx">MS Debugging Tools</a><br />
Install 64 bit version if you&#8217;re on 64 bit Windows and 32 bit version<br />
otherwise.</p>
</li>
<li>
<p>Change the <code>PATH</code> environment variable to include bin directory of Debugging tools.<br />
On my system, I added<br />
<code>C:\Program Files\Debugging Tools for Windows 64-bit</code> to the <code>PATH</code>.</p>
</li>
<li>
<p>Instruct OS to collect  allocation stack for mysqld with <code>gflags -i<br />
mysqld.exe +ust</code>.<br />
On Vista and later, this should be done in &#8220;elevated&#8221; command prompt,<br />
it requires admin privileges.
</p>
<p>
Now collect the leak information. The mode of operation is that: take the<br />
heap snapshot once, and after some load take it once again. Compare<br />
snapshots and output leak info.</p>
</li>
<li>
<p>Preparation : setup debug symbol path.<br />
In the command prompt window, do</p>
<p><code>set _NT_SYMBOL_PATH= srv*C:\websymbols*http://msdl.microsoft.com/download/symbols;G:\bzr\mysql-6.0\sql\Debug</code></p>
<p>Adjust second path component for your needs, it should include directory<br />
where mysqld.exe is.</p>
</li>
<li>Start mysqld and run it for some minutes</li>
<li>
<p>Take first heap snapshot</p>
<p><code>umdh -p:6768 -f:dump1</code></p>
<p>Where -p:
<pid_of_process> actually, PID of my mysqld was 6768.
</pid_of_process></li>
<li>Let mysqld run for another some minutes</li>
<li>
<p>Take second heap snapshot</p>
<p><code>umdh -p:6768 -f:dump2</code></p>
</li>
<li>
<p>Compare snapshots</p>
<p><code>umdh -v dump1 dump2 > dump.compare.txt</code></p>
</li>
<li>Examine the result output file. It is human readable, but all numbers are<br />
in hex, to scare everyone except  geeks.</li>
<li>
<p><code>gflags -i mysqld.exe -ust</code></p>
<p>Instruct OS  not to collect mysqld user mode stacks for allocations<br />
anymore.</p>
</li>
</ol>
<p>These are 10 steps and it sounds like much work, but in reality it takes 15<br />
minutes first time you do it and 5 minutes next time.</p>
<p>Additional information is given in Microsoft KB article about UMDH<br />
<a href="http://support.microsoft.com/kb/268343">KB 268343</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/13/how-to-analyze-memory-leaks-on-windows/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book: Intellectual Property and Open Source - the solution to IANAL</title>
		<link>http://coalface.mcslp.com/2008/10/12/book-intellectual-property-and-open-source-the-solution-to-ianal/</link>
		<comments>http://coalface.mcslp.com/2008/10/12/book-intellectual-property-and-open-source-the-solution-to-ianal/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 14:26:15 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[FOSS]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=110</guid>
		<description><![CDATA[I&#8217;m reading Intellectual Property and Open Source by Van Lindberg at the moment, and despite being about a relatively dry topic, I must admit that it&#8217;s a fascinating read. 
Van Lindberg introduces the book by talking about the comments that end up on Slashdot.org, almost certainly prefixed by the expression IANAL (I Am Not A [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m reading <a href="http://www.amazon.com/exec/obidos/ASIN/0596517963/mcwords">Intellectual Property and Open Source by Van Lindberg</a> at the moment, and despite being about a relatively dry topic, I must admit that it&#8217;s a fascinating read. </p>
<p>Van Lindberg introduces the book by talking about the comments that end up on <a href="http://slashdot.org">Slashdot.org</a>, almost certainly prefixed by the expression IANAL (I Am Not A Lawyer) where people defend, discuss, and rip people up about the legalities of open source and the various licenses. Van Lindberg also talks about how he spends much of his time translating the contents of various legal documents into engineer speak and back again. </p>
<p>Despite being a proponent and long time user of free software and open source for the best part of my working life, I&#8217;ll admit to being completely ignorant of many of the issues. This isn&#8217;t through lack of interest, but I&#8217;d rather leave those discussions and decisions to people who know, and it&#8217;s clear that Van Lindberg not only knows the subject, but he also knows how to make it interesting to those of us who actually have to work within the confines of rules and regulations.  </p>
<p>I&#8217;m still reading and learning a lot of the ins and outs of copyright, company agreements, and individual licenses and details. There&#8217;s a lot of material and detail included here. </p>
<p> I&#8217;ll have a full review when I&#8217;ve finished. Until then, if you have even a passing interest in the various licensing, legal and IP issues with open source, check out the book for a proper read.  </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/12/book-intellectual-property-and-open-source-the-solution-to-ianal/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL University - quick survey</title>
		<link>http://coalface.mcslp.com/2008/10/09/mysql-university-quick-survey/</link>
		<comments>http://coalface.mcslp.com/2008/10/09/mysql-university-quick-survey/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 10:27:22 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Commentary]]></category>

		<category><![CDATA[Databases]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=108</guid>
		<description><![CDATA[MySQL University has been running for the last 18 months, and we&#8217;ve covered a wide range of topics, from the internals of MySQL right up to Amazon&#8217;s EC2, using MySQL in the Solaris/OpenSolaris Webstack and a description of the forthcoming MySQL Online Backup. 
Personally, I think they&#8217;re great. Obviously many times I am scribe and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://forge.mysql.com/wiki/MySQL_University">MySQL University</a> has been running for the last 18 months, and we&#8217;ve covered a wide range of topics, from the internals of MySQL right up to Amazon&#8217;s EC2, using MySQL in the Solaris/OpenSolaris Webstack and a description of the forthcoming MySQL Online Backup. </p>
<p>Personally, I think they&#8217;re great. Obviously many times I am scribe and am there for the sessions, but I listen to lots of the sessions anyway, and I&#8217;m yet to be disappointed by the content. What&#8217;s really great is that in all the cases the person you are listening to is probably the person that either developed, or helped drive development of the particular function, or, in the case of some of the external tools (EC2, for example), these guys are expert in it. The experience is not quite as thrilling as attending the MySQL User Conference, but the content is just the same. </p>
<p>The problem is that despite all the work we do to get the presenters, interesting topics, and promotion of the upcoming sessions, we don&#8217;t always get as many attendees as we want or expect. </p>
<p>So, I&#8217;m wondering why this should be the case. We know that the current presentation system is not ideal (and we&#8217;re working on that), but I&#8217;m interested to hear people&#8217;s opinions on MySQL University. If you want to help shape the future of MySQL University, then comment here, and either answer the questions below, or make up your own.</p>
<ul>
<li>Have you attended any MySQL University sessions. How many?</li>
<li>How would you rate the sessions generally? A simple good or bad will do</li>
<li>If you haven&#8217;t attended any sessions, or don&#8217;t regularly attend them, why not?</li>
<li>Have you ever looked at/listened to the past sessions that provide on MySQL Forge?</li>
</ul>
<p>Please, I&#8217;m interested to hear.  </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/09/mysql-university-quick-survey/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Podcast Producer Variables</title>
		<link>http://coalface.mcslp.com/2008/10/08/podcast-producer-variables/</link>
		<comments>http://coalface.mcslp.com/2008/10/08/podcast-producer-variables/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 15:56:08 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[Mac OS X]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=104</guid>
		<description><![CDATA[The first of a new series of articles on using and extending the functionality of Apple&#8217;s Podcast Producer has just been published (see  Podcast Producer: Anatomy of a Workflow). 
One of the things that you might find useful when working with Workflows in Podcast Producer are the properties that are defined automatically when a [...]]]></description>
			<content:encoded><![CDATA[<p>The first of a new series of articles on using and extending the functionality of Apple&#8217;s Podcast Producer has just been published (see <a href="http://mcslp.com/?p=304"> Podcast Producer: Anatomy of a Workflow</a>). </p>
<p>One of the things that you might find useful when working with Workflows in Podcast Producer are the properties that are defined automatically when a podcast is submitted for processing. These runtime properties are used to specify information such as the source file name and job name. You need these within the action specification to select the input file, Podcast title, description and other parameters to process the content. </p>
<p>The combination of standard properties, and job specific properties, are combined together into a file called properties.plist that becomes part of the Workflow specification that is submitted for processing. Because global properties can change or be modified, by copying the specification into the properties.plist file during assembly, the system can ensure that the configuration at the time of submission of the podcast is used. This helps to prevent problems if the job gets queued and the configuration changes between submission and processing. </p>
<p>The dynamic properties submitted as part of the job will differ depending on the submission type, but the main properties generated are shown in the table below.</p>
<table border="1">
<tr>
<th width="100px">Property</th>
<th>Description</th>
</tr>
<tr>
<td>Base Directory</td>
<td>The base directory for the Podcast submission. The directory is automatically created within the shared filesystem when a new job is submitted to Podcast Producer. A new universally unique ID (UUID) is created and used as the directory name. All of the resources for the submission are then placed into that directory. This information is required so that actions can<br />
access the raw contents. </td>
</tr>
<tr>
<td>Content File Basename</td>
<td>The basename (filename without extension) of the source content. </td>
</tr>
<tr>
<td>Content File Extensions</td>
<td>The extension of the source content. </td>
</tr>
<tr>
<td>Content File Name</td>
<td>The full filename (basename and extension) of the source content. </td>
</tr>
<tr>
<td>Date_YYYY-MM-DD</td>
<td> The date of submission for the podcast. The property demonstrates the format of the date (year, month, day). </td>
</tr>
<tr>
<td>Global Resource Path</td>
<td>The path to the global resource for this instance of Podcast Producer. The directory holds all of the global resources (such as organization specific videos, preambles, and introductions) that can be used during processing. </td>
</tr>
<tr>
<td>Podcast Producer URL</td>
<td>The URL of the Podcast Producer server. This is used when communicating information back to the Podcast Producer instance. </td>
</tr>
<tr>
<td>Recording Started At</td>
<td>The date/time when the Podcast was started. This information is represented as the number of seconds since the epoch. </td>
</tr>
<tr>
<td>Recording Stopped At</td>
<td>The date/time when the Podcast was stopped. This information is represented as the number of seconds since the epoch.</td>
</tr>
<tr>
<td>Server UUID</td>
<td>The UUID of the server to which the podcast was submitted.</td>
</tr>
<tr>
<td>Shared Filesystem</td>
<td>The base directory that holds all Podcast information. This directory is set within the General Settings portion of the Podcast Producer section of Server Admin. </td>
</tr>
<tr>
<td>Title</td>
<td>The title of the podcast, as set by the user when the job was submitted using Podcast Capture.</td>
</tr>
<tr>
<td>User Full Name</td>
<td>The full name of the user that submitted the job. When a job is submitted by Podcast Capture, the user must login to the Podcast Capture application. It is these credentials that are used to identify the user. </td>
</tr>
<tr>
<td>User Home Directory</td>
<td>The home directory configured for the user. </td>
</tr>
<tr>
<td>User ID</td>
<td>The user ID of the user that submitted the podcast.</td>
</tr>
<tr>
<td>User Short Name</td>
<td>The shortname (login) of the user that submitted the podcast. </td>
</tr>
<tr>
<td>Workflow Bundle Path</td>
<td>The path to the Workflow Bundle that was selected when the job was submitted. This will be one of the Workflows configured in the system and selected at the point of submission from within Podcast Capture. </td>
</tr>
<tr>
<td>Workflow Resource Path</td>
<td>The path to the Resources directory for the Workflow selected when the job was submitted. </td>
</tr>
<tr>
<td>Xgrid Job Name</td>
<td>The Xgrid job name. By default, the job name is a combination of the job title, the user?s full name, and the name of the Workflow that was selected. You can control this within the individual workflow, but often the standard configuration is enough for you to be able to identify the job as it progresses through the Xgrid processing stage. </td>
</tr>
</table>
<p>These dynamic properties are vital to the execution of an individual action as they provide the unique properties required to process an individual podcast processing request. </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/08/podcast-producer-variables/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL on i5/OS</title>
		<link>http://coalface.mcslp.com/2008/10/08/mysql-on-i5os/</link>
		<comments>http://coalface.mcslp.com/2008/10/08/mysql-on-i5os/#comments</comments>
		<pubDate>Wed, 08 Oct 2008 08:36:53 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[Databases]]></category>

		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<category><![CDATA[OS]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=102</guid>
		<description><![CDATA[i5/OS doesn&#8217;t immediately strike you as the most natural environment for running MySQL, but in fact, there some advantages and benefits of making use of the hardware and i5/OS environment. The System i  environment used with i5/OS is scalable, and the i5/OS itself provides lots of benefits over the control and separate of work. [...]]]></description>
			<content:encoded><![CDATA[<p>i5/OS doesn&#8217;t immediately strike you as the most natural environment for running MySQL, but in fact, there some advantages and benefits of making use of the hardware and i5/OS environment. The System i  environment used with i5/OS is scalable, and the i5/OS itself provides lots of benefits over the control and separate of work. </p>
<p>Obviously another key advantage is that if you are already using i5/OS for your application, then being able to plug in MySQL into that equation on the same machine makes a big difference. For those companies and organizations that already have a business application on their server, you can use MySQL in combination with ODBC or more direct interfaces such as PHP to provide a web interface to your business application all in the same box. </p>
<p>MySQL works through PASE  (Portable Application Solutions Environment) which allows AIX applications to run directly on i5/OS through a direct application binary interface. </p>
<p>As a supported platform for MySQL 5.0 we obviously have instructions for <a href="http://dev.mysql.com/doc/refman/5.0/en/installation-i5os.html">installing MySQL into your i5/OS environment</a>. Once installed, MySQL on i5/OS works just like any other MySQL installation. </p>
<p>However, if you want a more complete view of the support, environment, and deployment of MySQL on i5/OS and more detailed instructions for setting PASE and your system to accept MySQL, then check out the IBM Redbook <a href="http://www.redbooks.ibm.com/abstracts/sg247398.html">Discovering MySQL on IBM i5/OS</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/08/mysql-on-i5os/feed/</wfw:commentRss>
		</item>
		<item>
		<title>MySQL Topics now added directly to the reference manual</title>
		<link>http://coalface.mcslp.com/2008/10/07/mysql-topics-now-added-directly-to-the-reference-manual/</link>
		<comments>http://coalface.mcslp.com/2008/10/07/mysql-topics-now-added-directly-to-the-reference-manual/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 14:58:38 +0000</pubDate>
		<dc:creator>Martin MC Brown</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://coalface.mcslp.com/?p=98</guid>
		<description><![CDATA[Last week I mentioned that we had added a topic-based interface to the MySQL documentation to make it easier to go to specific topics, identified either by your needs, user type or technology. 
It occurred to me at the end of the week that the information is just as useful when reading the documentation, so [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I mentioned that we had added a <a href="http://coalface.mcslp.com/2008/09/29/mysql-documentation-by-topic/">topic-based interface to the MySQL documentation</a> to make it easier to go to specific topics, identified either by your needs, user type or technology. </p>
<p>It occurred to me at the end of the week that the information is just as useful when reading the documentation, so you can go direct to a topic within the online reference manual, rather than trying to work out what chapter it is in. </p>
<p>This works in all reference manuals, whether you are viewing the online HTML version: </p>
<div id="attachment_97" class="wp-caption alignnone" style="width: 310px"><a href="http://coalface.mcslp.com/wp-content/uploads/2008/10/refmantopichtml1.png"><img src="http://coalface.mcslp.com/wp-content/uploads/2008/10/refmantopichtml1-300x93.png" alt="Topics embedded in the reference manual, HTML" title="refmantopichtml1" width="300" height="93" class="size-medium wp-image-97" /></a><p class="wp-caption-text">Topics embedded in the reference manual, HTML</p></div>
<p>It also works in all the offline versions, including HTML and PDF, as here: </p>
<div id="attachment_99" class="wp-caption alignnone" style="width: 310px"><a href="http://coalface.mcslp.com/wp-content/uploads/2008/10/refmantopicpdf.png"><img src="http://coalface.mcslp.com/wp-content/uploads/2008/10/refmantopicpdf-300x127.png" alt="Topics in the reference manual, PDF" title="refmantopicpdf" width="300" height="127" class="size-medium wp-image-99" /></a><p class="wp-caption-text">Topics in the reference manual, PDF</p></div>
<p>For those topics that are outside the normal scope of the manual, such as all the standalone guides, the links take you to the online version of those guides directly. </p>
]]></content:encoded>
			<wfw:commentRss>http://coalface.mcslp.com/2008/10/07/mysql-topics-now-added-directly-to-the-reference-manual/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
