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

<channel>
	<title>Toru Maesaka</title>
	<atom:link href="http://torum.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://torum.net</link>
	<description>Hackaholic and a Web Addict based in Tokyo</description>
	<lastBuildDate>Tue, 09 Feb 2010 02:23:02 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cross Posting Woes of Micro Blogging Messages</title>
		<link>http://torum.net/2010/02/cross-posting-microblog-annoyance/</link>
		<comments>http://torum.net/2010/02/cross-posting-microblog-annoyance/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 02:13:34 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[webservice]]></category>
		<category><![CDATA[interoperability]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2333</guid>
		<description><![CDATA[The concept of web services to interoperate and broaden the ecosystem is a beautiful thing. I agree to this concept but lately I&#8217;ve found myself being frustrated to a certain subset of this concept. Where does my frustration come from? It comes from cross-posts of micro blogging messages. To be more specific, seeing significant amount [...]]]></description>
			<content:encoded><![CDATA[<p>The concept of web services to interoperate and broaden the ecosystem is a beautiful thing. I agree to this concept but lately I&#8217;ve found myself being frustrated to a certain subset of this concept. Where does my frustration come from? It comes from cross-posts of micro blogging messages. To be more specific, seeing significant amount of Twitter updates on my Facebook news feed.</p>
<p>Living in Tokyo, I usually check social updates and RSS feeds on the train. It often begins from checking unread tweets then firing up whatever I feel like checking next (usually Facebook, Google Reader or Mixi). What disappoints me here is having to rip through tweets that I&#8217;ve already looked at on Facebook. Tokyo is a busy place so it&#8217;s important to gain information efficiently.</p>
<p>On Facebook I have various types of connections from childhood friends to acquaintances. Some of them are on Facebook and not on Twitter (and vice versa). I guess this is to do with user demographics but the important thing here is that I&#8217;m gradually finding it hard to pickup content from my friends outside of IT. I&#8217;m saying IT because it seems from observing my news feed that it&#8217;s mostly my friends in the IT industry that have setup cross posting.</p>
<p>There is probably some sort of content balancing gimick in the news feed code but this seems to not work well against my heavy Japanese twitter user friends. It&#8217;s a shame because my cross posting friends are completely innocent and aren&#8217;t trying to deliberately cause noise. Last thing I want to do is defriend people just because they are innocently causing noise.</p>
<h3>Further Thoughts</h3>
<p>This is what user specified content filters are for! If there&#8217;s a &#8216;block updates from xxx service&#8217; option I would use it. Or perhaps I&#8217;m missing something and there is a way to filter out content from certain web services in the news feed.</p>
<p>If there is such an option, I would love to be enlightened!</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2010/02/cross-posting-microblog-annoyance/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Notes on HEAP/MyISAM Index Key Handling on WRITE</title>
		<link>http://torum.net/2010/01/notes-on-heap-myisam-key-generation/</link>
		<comments>http://torum.net/2010/01/notes-on-heap-myisam-key-generation/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 08:57:05 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[drizzle]]></category>
		<category><![CDATA[knowledge]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2331</guid>
		<description><![CDATA[Disclaimer: This post is based on HEAP/MyISAM&#8217;s sourcecode in Drizzle.
Here are my brief notes on investigating how index keys are generated in HEAP and MyISAM. I lurked through these because I&#8217;ve started preparing for decent index support in BlitzDB. I also wrote this to assist my biological memory for later grepping (I have terrible memory [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Disclaimer: This post is based on HEAP/MyISAM&#8217;s sourcecode in Drizzle.</strong></p>
<p>Here are my brief notes on investigating how index keys are generated in HEAP and MyISAM. I lurked through these because I&#8217;ve started preparing for decent index support in BlitzDB. I also wrote this to assist my biological memory for later grepping (I have terrible memory for names). I&#8217;m only going to cover key generation on write in this post. Otherwise this post is going to be massive.</p>
<h3>HEAP Engine</h3>
<p>The index structure of HEAP can be either BTREE or HASH (in MySQL doc terms). Like other engines HEAP has a structure for keeping Key definition (parts, type, logic and etc). This structure is called HP_KEYDEF and it contains function pointers for write, delete, and getting the length of the key. These function pointers are assigned to at table creation or when the table is opened. The assigned function depends on the data structure of the index and it can be either of the following:</p>
<h4>BTREE</h4>
<ul>
<li>hp_rb_write_key()</li>
<li>hp_rb_delete_key()</li>
</ul>
<h4>HASH</h4>
<ul>
<li>hp_write_key()</li>
<li>hp_delete_key()</li>
</ul>
<p>As for get_key_length(), either of the following functions are used for both data structures.</p>
<ul>
<li>hp_rb_var_key_length()</li>
<li>hp_rb_null_key_length()</li>
<li>hp_rb_key_length()</li>
</ul>
<p>When writing a row to the tree, HEAP writes to the index using a key generated by hp_rb_make_key(). Note that it does not use this for the hash index. The generated key is populated inside &#8216;recbuffer&#8217; in HEAP&#8217;s handler object (HP_INFO structure).</p>
<p>From my understanding, it loops through the key segments (I suspect it is similar the internal  KEY_PART_INFO structure) and appropriately copies each key field value to the output buffer. By meaning &#8220;appropriately&#8221; it respects the characteristics of the data type when packing the buffer. For example, for a variable length field, it will only copy the actual data and not the max possible size of it. The final byte that is copied to the buffer is the address of the chunk where the record lives.</p>
<h3>MyISAM Engine</h3>
<p>The upper layer of key handling in MyISAM looks somewhat similar to HEAP so you can really tell that it was written by the same people. Things are nicely wrapped together by the MYISAM_SHARE structure so it&#8217;s relatively easy to follow. BlitzDB has a class called BlitzShare for the same purpose (This is based off Archive Engine&#8217;s ArchiveShare class).</p>
<p>Like HEAP, MyISAM has a structure for individual key definition called MI_KEYDEF (it&#8217;s defined in myisam.h). There are more function pointers in this structure than HEAP.</p>
<ul>
<li>bin_search()</li>
<li>get_key()</li>
<li>pack_key()</li>
<li>store_key()</li>
<li>ck_insert()</li>
<li>ck_delete()</li>
</ul>
<p>In Drizzle, _mi_ck_write() is assigned to ck_insert() which is the entry point to writing a MyISAM index. The key that MyISAM uses to write to the index is generated by _mi_make_key(). Like HEAP, it will loop through the key segments and pack the relevant fields accordingly to the characteristic of the data type. The output buffer belongs to MyISAM&#8217;s hander (lastkey2).</p>
<h3>From Here</h3>
<p>I&#8217;ve actually written a naive key generator for BlitzDB already based on Drizzle/MySQL&#8217;s internal KEY_PART_INFO array. It seems to be working on EXACT MATCH but I still need to implement an index scanner which looks much harder to pull off than a table scanner. What I&#8217;m really worried about is supporting composite indexes (namely reading/searching on it) but hopefully I&#8217;ll understand how this area of the storage system works soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2010/01/notes-on-heap-myisam-key-generation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Further thoughts on BlitzDB&#8217;s Index Handling</title>
		<link>http://torum.net/2010/01/further-thoughts-on-blitzdb-index/</link>
		<comments>http://torum.net/2010/01/further-thoughts-on-blitzdb-index/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 09:05:30 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[drizzle]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[blitzdb]]></category>
		<category><![CDATA[index]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2328</guid>
		<description><![CDATA[I&#8217;ve been thinking quite a bit about collation handling in BlitzDB for the last couple of days. The more I think about it, the more stuck I&#8217;ve been getting with BlitzDB&#8217;s index design. I&#8217;m actually so frustrated with myself at the moment that I want to hit my head against a wall or something.
So, I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been thinking quite a bit about collation handling in BlitzDB for the last couple of days. The more I think about it, the more stuck I&#8217;ve been getting with BlitzDB&#8217;s index design. I&#8217;m actually so frustrated with myself at the moment that I want to hit my head against a wall or something.</p>
<p>So, I&#8217;m writing this entry to clear up my mind. Heh, my blog is slowly becoming BlitzDB&#8217;s design document draft. This should hopefully be good though since by blogging it, people can tell me whether I&#8217;m moving towards a stupid direction or not.</p>
<h3>Collation Importance</h3>
<p>When writing database software that is intended for International use, it is important to handle textual data by respecting collation order. It is arguable that most people are only interested in English lexicographic ordering but unfortunately the world is not so standard.</p>
<h3>Internal Primary Key Handling</h3>
<p>I want to motivate people to actively define a PRIMARY KEY with BlitzDB. I plan to make this attractive by providing the best performance when PK is defined. In <a href="http://torum.net/2009/12/end-of-year-progress-on-blitzdb/">December 2009</a>, my answer to this was to write the PK value as the key for the data dictionary (where actual rows are stored in BlitzDB). This allows BlitzDB to do a direct lookup on the data dictionary for PK based lookup, instead of consulting the B+Tree index. I&#8217;m still fond of this lookup optimization approach but it introduces problems too. </p>
<p><strong>Problem 1.</strong> Consider the following textual keys: &#8220;key&#8221; and &#8220;KEY&#8221;. They obviously have different binary representations but in certain cases they can be logically equivalent. Because the data dictionary is a hash database, this is a problem. The solution that instantly pops up is to normalize the key before writing or reading it. This however, causes a problem in cases where the two keys are inequivalent. Perhaps Drizzle/MySQL provides an internal normalization function that respects this. I still need to study this area of the storage subsystem.</p>
<p><strong>Problem 2.</strong> Directly writing a PK to the data dictionary means fast lookup but because of the data structure, it&#8217;s not possible to fetch the next &#8220;logical&#8221; key, meaning I can&#8217;t implement index scanning on PK as it is. Quick solution for users is to create an index on the PK column (this would create a separate B+Tree for it) but this is not so friendly because it requires the user to have prior knowledge of all this. So, my plan is to provide the best of both worlds. I&#8217;ll elaborate on how I&#8217;m planning on tackling this problem next.</p>
<h3>Current Primary Key Read/Write Behavior</h3>
<p>In general, keys of BlitzDB&#8217;s data dictionary is a unique 8 byte integer. The idea is that BlitzDB writes this unique ID along with the key to the B+Tree Index so that it can later identify that row. The difference with PK is that, if a PK is present in a table, BlitzDB will not generate an internal unique ID and use PK for the data dictionary&#8217;s key instead. BlitzDB won&#8217;t create a B+Tree index for PK at the time I wrote this blog entry.</p>
<h3>Next Step</h3>
<p>Create a B+Tree index for PK anyway. BlitzDB will still use the PK value as the key for data dictionary if it exists. For PK based lookup requests, BlitzDB will look directly at the data dictionary and for PK based requests that involve index scanning, BlitzDB will look at the B+Tree index.</p>
<p>This approach can consume more space when textual data is used for keys but I think it&#8217;s worth it. At the same time, you can <strong>save space</strong> if you use use types that are smaller than 8 bytes for PK. For example, using a 4 byte integer would reduce BlitzDB&#8217;s key space by 50%.</p>
<p>Hmm, I think my mind has cleared a little.</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2010/01/further-thoughts-on-blitzdb-index/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Drizzle, BlitzDB and HTON_STATS_RECORDS_IS_EXACT</title>
		<link>http://torum.net/2010/01/blitzdb-and-record-counting/</link>
		<comments>http://torum.net/2010/01/blitzdb-and-record-counting/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 13:23:34 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[drizzle]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[blitzdb]]></category>
		<category><![CDATA[engine]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2326</guid>
		<description><![CDATA[Recently I enabled HTON_STATS_RECORDS_IS_EXACT in BlitzDB to let the optimizer know that BlitzDB can instantaneously return the number of rows in a specified table. As a result, the Drizzle kernel can directly call the Cursor::info() function to get the row count. To users, it means that SELECT COUNT statements can be executed in O(1). So [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I enabled HTON_STATS_RECORDS_IS_EXACT in BlitzDB to let the optimizer know that BlitzDB can instantaneously return the number of rows in a specified table. As a result, the Drizzle kernel can directly call the Cursor::info() function to get the row count. To users, it means that SELECT COUNT statements can be executed in O(1). So it&#8217;s a great thing in general.</p>
<h3>Something Broke</h3>
<p>After I enabled HTON_STATS_RECORDS_IS_EXACT, I noticed that issuing SELECT statement on a table with 1 row would no longer return a resultset. Weird indeed! after investigating with GDB, I noticed that rnd_next() is only called once instead of twice on a table with 1 row (second time is to find EOF) when HTON_STATS_RECORDS_IS_EXACT is enabled. This makes sense because the kernel knows that there is only 1 row and therefore it doesn&#8217;t need to keep scanning for EOF. However, this made me scratch my head since this shouldn&#8217;t break BlitzDB&#8217;s table scanner.</p>
<h3>Remedy</h3>
<p>Logically, I was confident that BlitzDB&#8217;s table scanner was functioning properly so I decided to look at what was going on beyond the engine API. Turns out that join_read_system() in sql_select.cc looks at the table->status value and decides that it&#8217;s an error if 0 isn&#8217;t assigned to it. What&#8217;d you know? I realized that I wasn&#8217;t assigning anything to the status variable. It&#8217;s more that I didn&#8217;t know that I was meant to update an internal structure. You&#8217;d think that engine developers aren&#8217;t meant to touch those. It&#8217;s not mentioned in the <a href="http://forge.mysql.com/wiki/MySQL_Internals_Custom_Engine">Engine Documentation</a> at MySQL Forge either. Nevertheless, the important thing is that it works now. Oh and SELECT COUNT is fast now too. </p>
<h3>Eye Opener</h3>
<p>This experience among other occasions where I had to read the kernel&#8217;s source made me think that it would be nice to provide an intensive up to date documentation on how to develop storage engines for Drizzle in the future (when the API becomes stable). Needless to say, this would be co-ordinated within the Drizzle community. I&#8217;m not a license person but it should hopefully be provided with a freely available license too.</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2010/01/blitzdb-and-record-counting/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to Recover a Tokyo Cabinet Database</title>
		<link>http://torum.net/2010/01/how-to-recover-a-tokyo-cabinet-database-file/</link>
		<comments>http://torum.net/2010/01/how-to-recover-a-tokyo-cabinet-database-file/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 07:36:47 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[oss]]></category>
		<category><![CDATA[recovery]]></category>
		<category><![CDATA[tokyocabinet]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2324</guid>
		<description><![CDATA[Recently Mark Callaghan had asked me whether BlitzDB is crash safe since he was aware that Tokyo Cabinet isn&#8217;t crash safe (unless used with transactions). For Tokyo Cabinet and Tyrant&#8217;s defense, I should mention that this is intentional. The idea is to reduce durability in return for higher throughput. The author&#8217;s philosophy is that data [...]]]></description>
			<content:encoded><![CDATA[<p>Recently <a href="http://mysqlha.blogspot.com/">Mark Callaghan</a> had asked me whether BlitzDB is crash safe since he was aware that <a href="http://1978th.net/tokyocabinet/">Tokyo Cabinet</a> isn&#8217;t crash safe (unless used with transactions). For Tokyo Cabinet and Tyrant&#8217;s defense, I should mention that this is intentional. The idea is to reduce durability in return for higher throughput. The author&#8217;s philosophy is that data availability should be secured by replication. This makes sense since the design of TC and TT are influenced by mixi&#8217;s high traffic (we need single instances to handle over 10k requests per sec).</p>
<p>So with that said, let&#8217;s move on to the main topic. The honest answer is that BlitzDB is not crash safe either (transaction support is still a long way to go). If the admin is lucky, she would be able to repair the table(s) using the REPAIR TABLE syntax. BlitzDB&#8217;s crash safety strategy is the same as Tokyo Tyrant &#8211; You should use replication. The question is,  how do you repair a broken Tokyo Cabinet file?</p>
<p>The answer is pretty simple and it&#8217;s documented in the Japanese TC documentation. Unfortunately it&#8217;s not not present in the English documentation. So allow me to go through it with demo code in this post. There are two ways to attempt to recover a Tokyo Cabinet database:</p>
<ol>
<li>By using the Tokyo Cabinet API.</li>
<li>By using Tokyo Cabinet&#8217;s command line tool.</li>
</ol>
<p>Let&#8217;s first go through how to confirm that your database is broken. I&#8217;ve also covered how to comprehend the errors.</p>
<h3>How to confirm that your Database is broken</h3>
<p>Simply use the command line tools installed with Tokyo Cabinet. Look at the &#8220;additional flags&#8221; line on the output of &#8220;tchmgr inform&#8221; or &#8220;tcbmgr inform&#8221; depending on your database type. If it says, &#8220;fetal&#8221; then your file is really broken. If it says &#8220;open&#8221;, it means that your application died or exited without closing the database. A file in the &#8220;open&#8221; state is still usable but your most recent records are most likely unavailable. This is because TC connects the hash chain after it has confirmed that a write operation was successful. If your application died before the record is chained, then it&#8217;s not accessible in the database.</p>
<p>Furthermore, the records that weren&#8217;t sync&#8217;d by the kernel won&#8217;t be present on power failure. If the disaster was a process failure, then the written data will hopefully be in the kernel&#8217;s write buffer so you won&#8217;t lose that data. For pedantic people, TC provides a way to sync the database from your application. Whether to call this function (and how often) is up to your application&#8217;s policy.</p>
<h3>Using the Tokyo Cabinet API</h3>
<p>(1) Open the database file without the lock option. Meaning, supply HDBONOLCK or BDBONOLCK to the open function of the appropriate database type (TCHDB or TCBDB).</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* This is for TCHDB */</span>
TCHDB <span style="color: #339933;">*</span>hdb <span style="color: #339933;">=</span> tchdbnew<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>tchdbopen<span style="color: #009900;">&#40;</span>hdb<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;/path/to/broken_file&quot;</span><span style="color: #339933;">,</span> HDBONOLCK <span style="color: #339933;">|</span> HDBOWRITER<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #808080; font-style: italic;">/* Failed to open. Do the appropriate thing. */</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* This is for TCBDB */</span>
TCBDB <span style="color: #339933;">*</span>btree <span style="color: #339933;">=</span> tcbdbnew<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>tcbdbopen<span style="color: #009900;">&#40;</span>btree<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;/path/to/broken_file&quot;</span><span style="color: #339933;">,</span> BDBONOLCK <span style="color: #339933;">|</span> BDBOWRITER<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #808080; font-style: italic;">/* Failed to open. Do the appropriate thing. */</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(2) Run tchdboptmize() or tcbdboptimize() depending on the database type. You might wonder what you should give as the parameter for the optimize function. Conveniently, TC stores the tuning parameters of the database when you first opened it so you can just provide -1 as an argument _but_ the final one. This is because the final argument is an unsigned integer (uint8_t). What you want to provide instead is UINT8_MAX for this.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* This if for TCHDB */</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>tchdboptimize<span style="color: #009900;">&#40;</span>hdb<span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> UINT8_MAX<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #808080; font-style: italic;">/* We're out of luck. This hash database can't be rescued. */</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* This if for TCBDB */</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>tcbdboptimize<span style="color: #009900;">&#40;</span>btree<span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> UINT8_MAX<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #808080; font-style: italic;">/* We're out of luck. This b+tree database can't be rescued. */</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If you&#8217;re lucky, the above would repair the database that is associated with TC&#8217;s database object.</p>
<h3>Using TC&#8217;s command line tool</h3>
<p>This approach is more towards database admins since I&#8217;m sure the last thing they want to do is write their own program to get their work done. Lazyness is good.</p>
<p>TC provides a utility program called tchmgr (for a hash database) and tcbmgr (for a b+tree database) which allows you to run optimize on a database file. So if you wanted to repair a TC hash database, you would do the following:</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ tchmgr optimize -nl /path/to/broken_file</pre></div></div>

<p>and the following for the B+Tree Database:</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ tcbmgr optimize -nl /path/to/broken_file</pre></div></div>

<p>For those that are interested, the &#8220;-nl&#8221; option means &#8220;No Lock&#8221; which is required to repair a database file.</p>
<p>Well, I guess this sums up this blog post. I hope this post will help you administrate Tokyo Tyrant and/or your Tokyo Cabinet based application!</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2010/01/how-to-recover-a-tokyo-cabinet-database-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Congrats to Kyoto Cabinet&#8217;s Alpha Release</title>
		<link>http://torum.net/2010/01/kyotocabinet-alpha-release/</link>
		<comments>http://torum.net/2010/01/kyotocabinet-alpha-release/#comments</comments>
		<pubDate>Fri, 01 Jan 2010 16:36:30 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[oss]]></category>
		<category><![CDATA[kyotocabinet]]></category>
		<category><![CDATA[tokyocabinet]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2322</guid>
		<description><![CDATA[Writing this blog entry to congratulate Mikio for releasing Kyoto Cabinet (alpha release), which is positioned as a successor project of Tokyo Cabinet.
From development perspective, the big difference is that Kyoto Cabinet is implemented in pure C++03 whereas TC is pure C99. ASFAIK, C++03 was adopted so that KC can run on broader platforms than [...]]]></description>
			<content:encoded><![CDATA[<p>Writing this blog entry to congratulate <a href="http://1978th.net">Mikio</a> for releasing <a href="http://1978th.net/kyotocabinet/">Kyoto Cabinet</a> (alpha release), which is positioned as a successor project of Tokyo Cabinet.</p>
<p>From development perspective, the big difference is that Kyoto Cabinet is implemented in pure C++03 whereas TC is pure C99. ASFAIK, C++03 was adopted so that KC can run on broader platforms than POSIX oriented systems (So, theoretically it can build on Windows). From project perspective, KC is licensed under GPLv3 whereas TC is licensed under LGPL.</p>
<p>For my projects, I currently have no interest in moving to KC from TC since I&#8217;m convinced that TC is better suited for my target platforms (UNIX/Linux). Another reason (VERY personal reason) is that I like C99 more than C++. Although&#8230; I don&#8217;t have the right to say this since I&#8217;m far from proficient at C++. For more details on the project differences, you should take a look at KC&#8217;s project page that Mikio had prepared:</p>
<ul>
<li><a href="http://1978th.net/kyotocabinet/">http://1978th.net/kyotocabinet/</a></li>
</ul>
<p>For those that are interested in KC&#8217;s performance, I&#8217;ll do some benchmarks against TC when I get back from my end of year vacation. Hope everyone is enjoying New Years!</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2010/01/kyotocabinet-alpha-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Last Minute Christmas Shopping</title>
		<link>http://torum.net/2009/12/last-minute-christmas-shopping/</link>
		<comments>http://torum.net/2009/12/last-minute-christmas-shopping/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 11:14:48 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[random]]></category>
		<category><![CDATA[gizmo]]></category>
		<category><![CDATA[monitor]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2320</guid>
		<description><![CDATA[Last minute Christmas Shopping for myself. 23&#8243; Full HD monitor with HDMI input (Mitsubishi RDT231WLM). I&#8217;ve been looking for a reasonable new monitor with HDMI for sometime so I&#8217;m pretty happy with this purchase. This is going to be used for PS3 and watching movies.

Merry Christmas.
]]></description>
			<content:encoded><![CDATA[<p>Last minute Christmas Shopping for myself. 23&#8243; Full HD monitor with HDMI input (Mitsubishi <a href="http://www.engadget.com/2009/10/07/mitsubishi-debuts-power-saving-rdt231wlm-s-23-inch-monitor/">RDT231WLM</a>). I&#8217;ve been looking for a reasonable new monitor with HDMI for sometime so I&#8217;m pretty happy with this purchase. This is going to be used for PS3 and watching movies.</p>
<p align="center"><a href="http://www.flickr.com/photos/tmaesaka/4210171879/" title="Last Minute Purchase by tmaesaka, on Flickr"><img src="http://farm3.static.flickr.com/2654/4210171879_18383d706d.jpg" width="473" height="500" alt="Last Minute Purchase" /></a></p>
<p>Merry Christmas.</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2009/12/last-minute-christmas-shopping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>End of Year Progress on BlitzDB</title>
		<link>http://torum.net/2009/12/end-of-year-progress-on-blitzdb/</link>
		<comments>http://torum.net/2009/12/end-of-year-progress-on-blitzdb/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 09:47:06 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[drizzle]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[blitzdb]]></category>
		<category><![CDATA[storage]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2318</guid>
		<description><![CDATA[FURTHER UPDATE: Further thoughts on BlitzDB’s Index Handling
My open source friends might have noticed that I&#8217;ve been working quite a bit on BlitzDB lately. To tell the truth, I had a hidden goal to get Version-1 done by Christmas. Unfortunately it doesn&#8217;t look like I can reach that goal. However, looking at the brightside I [...]]]></description>
			<content:encoded><![CDATA[<p><strong>FURTHER UPDATE:</strong> <a href="http://torum.net/2010/01/further-thoughts-on-blitzdb-index/">Further thoughts on BlitzDB’s Index Handling</a></p>
<p>My open source friends might have noticed that I&#8217;ve been working quite a bit on BlitzDB lately. To tell the truth, I had a hidden goal to get Version-1 done by Christmas. Unfortunately it doesn&#8217;t look like I can reach that goal. However, looking at the brightside I got a lot done in the past few weeks so allow me to &#8220;journal&#8221; it in this blog post.</p>
<h3>Agony of Knowing</h3>
<p>The more I understood Drizzle&#8217;s storage mechanism and Tokyo Cabinet&#8217;s internals, the more I disliked what I previously had. This led me to spending quite a bit of time rewriting BlitzDB&#8217;s codebase. I was using pthread&#8217;s rwlock for concurrency control but I decided to design and write <a href="http://torum.net/2009/11/blitzdb-and-tc-concurrency-model/">BlitzDB&#8217;s own lock mechanism</a> to get the best out of TC (in terms of concurrency). I also rewrote the entire table scan code which is something you&#8217;d hope won&#8217;t be executed that often (people should use indexes!) but needless to say, it&#8217;s an important component of a relational storage engine so I&#8217;ve put in a lot of effort there.</p>
<h3>Rewriting the Table Scanner</h3>
<p>In the process of rewriting the table scanner, Jay Pipes&#8217; gave me a fantastic advise on using Drizzle&#8217;s internal atomic type (drizzled::atomics). He gave me this advise because he noticed that  my atomic ID generator was securing atomicity with pthread&#8217;s mutex. It is debatable that this mutex was only enabled for only few CPU instructions but the philosophy of using the most efficient method on the platform where BlitzDB is to be run was appealing enough for me to use drizzled::atomics. Mikio did some experiments on this and found that in a competitive/congested environment, using the compiler&#8217;s builtin function can gain you <a href="http://1978th.net/tech/promenade.cgi?id=68">3x throughput</a>.</p>
<h3>Hacking on Index Support</h3>
<p>I&#8217;ve finally started hacking on index support and I just finished supporting basic operations on a primary key. By design, BlitzDB&#8217;s index is a dense <a href="http://en.wikipedia.org/wiki/Index_(database)#Clustered">clustered</a> b+tree but in the first release I am going to limit PK to only be a HASH index. This is because I want BlitzDB to treat all PKs as direct keys inside the data dictionary (hash database where the actual rows are stored). So in other words, I want people to use PK for &#8220;needle in a haystack&#8221; like queries only. An example of a needle in a haystack like query is:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">WHERE</span> primary_key_column <span style="color: #66cc66;">=</span> whatever;</pre></div></div>

<p>Saying that, I don&#8217;t like to force people to do things the way I like so I plan on providing best of both worlds by supporting both data structures for PKs in Version-2:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> t1 <span style="color: #66cc66;">&#40;</span>id int<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">USING</span> btree<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>blitzdb;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> t1 <span style="color: #66cc66;">&#40;</span>id int<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">USING</span> hash<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>blitzdb;</pre></div></div>

<p>BlitzDB&#8217;s default configuration will use PK as a &#8220;direct&#8221; data dictionary index. If you wish to do range queries on PK, the solution is to create a index on the PK column.</p>
<h3>Primary Key lookup Performance</h3>
<p>So, how does my implementation perform? Here&#8217;s a quick benchmark with a test-run that randomly fetches 100 thousand rows from a BlitzDB table with 1 million rows. This is the table I used:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> t1 <span style="color: #66cc66;">&#40;</span>id int <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span> a int<span style="color: #66cc66;">,</span> b int<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>blitzdb;</pre></div></div>

<p>and the query looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> t1 <span style="color: #993333; font-weight: bold;">WHERE</span> id <span style="color: #66cc66;">=</span> random_number_under_one_million;</pre></div></div>

<p>The hardware I used is the following commodity server: Intel Quad Xeon E5345 (2&#215;4MB L2 cache), 8GB Memory, 500GB SATA II. Unfortunately I could not prepare a standalone client server today so both the server and the test program were run on the same machine. Yeah&#8230; this sucks so I can&#8217;t claim that this benchmark is 100% creditable.</p>
<p>Here is the result I obtained from <a href="http://code.google.com/p/skyload">skyload</a>. Please only view it as a guideline to BlitzDB&#8217;s lookup performance. I&#8217;ll do a proper benchmark with the Drizzle Community and publish it after I get Version-1 released.</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">[ READ LOAD EMULATION RESULT ]
  SQL File               : 100k_select.sql
  Concurrent Connections : 1
  Task Completion Time   : 5.88856 secs
  Number of Queries:     : 100000
  Number of Test Runs:   : 1
&nbsp;
[ READ LOAD EMULATION RESULT ]
  SQL File               : 100k_select.sql
  Concurrent Connections : 2
  Task Completion Time   : 6.94474 secs
  Number of Queries:     : 100000
  Number of Test Runs:   : 1
&nbsp;
[ READ LOAD EMULATION RESULT ]
  SQL File               : 100k_select.sql
  Concurrent Connections : 4
  Task Completion Time   : 7.04455 secs
  Number of Queries:     : 100000
  Number of Test Runs:   : 1</pre></div></div>

<p>As you can see, &#8220;needle in a haystack&#8221; queries can be executed pretty efficiently in BlitzDB. Looking at the first result, we can observe that it took an average of 0.058 milliseconds to process a query.</p>
<h3>Future Plans</h3>
<p>Admittedly, primary key support isn&#8217;t completely done so I&#8217;ll continue working on it. After that, I will start hacking on b+tree indexes and write more tests as I go. Once I support at least two indexes, I&#8217;ll ask the Drizzle Community to consider merging BlitzDB into Drizzle&#8217;s trunk. This is my goal for BlitzDB at the moment.</p>
<p>I also happen to own blitzdb.com so I&#8217;m planning on putting user documentation (including tutorial) and architectural notes there. This is currently not so high on my TODO list so I suspect it won&#8217;t happen until I get Version-1 released. All I can say about the release schedule at the moment is, &#8220;before the MySQL conference in april&#8221;.</p>
<p>So, that&#8217;s all I have to summarize for now. Thanks for reading this far. Merry Christmas and have a Happy New Year. Don&#8217;t trip on ice :)</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2009/12/end-of-year-progress-on-blitzdb/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Storage Engine Tests in Drizzle. Organized!</title>
		<link>http://torum.net/2009/12/storage-engine-tests-in-drizzle-organized/</link>
		<comments>http://torum.net/2009/12/storage-engine-tests-in-drizzle-organized/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 15:33:45 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[drizzle]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[tests]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2316</guid>
		<description><![CDATA[Good news to storage engine developers. In Drizzle, you can now place your engine specific test files (.test and .result) in your engine&#8217;s directory. Here&#8217;s an example in BlitzDB:
First, let&#8217;s look inside BlitzDB&#8217;s directory.

$ ls -l blitzdb/
Total 60
-rw-r--r-- 1 maesaka maesaka   649 2009-12-13 20:51 AUTHORS
-rw-r--r-- 1 maesaka maesaka  5878 2009-12-13 20:51 blitzdata.cc
-rw-r--r-- [...]]]></description>
			<content:encoded><![CDATA[<p>Good news to storage engine developers. In Drizzle, you can now place your engine specific test files (.test and .result) in your engine&#8217;s directory. Here&#8217;s an example in BlitzDB:</p>
<p>First, let&#8217;s look inside BlitzDB&#8217;s directory.</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ ls -l blitzdb/
Total 60
-rw-r--r-- 1 maesaka maesaka   649 2009-12-13 20:51 AUTHORS
-rw-r--r-- 1 maesaka maesaka  5878 2009-12-13 20:51 blitzdata.cc
-rw-r--r-- 1 maesaka maesaka  3347 2009-12-13 20:51 blitzlock.cc
-rw-r--r-- 1 maesaka maesaka 18146 2009-12-13 20:51 ha_blitz.cc
-rw-r--r-- 1 maesaka maesaka  8360 2009-12-13 20:51 ha_blitz.h
-rw-r--r-- 1 maesaka maesaka   289 2009-12-13 20:51 plugin.ac
-rw-r--r-- 1 maesaka maesaka   261 2009-12-13 23:51 plugin.ini
drwxr-xr-x 4 maesaka maesaka  4096 2009-12-13 23:51 tests</pre></div></div>

<p>Notice the final line? that&#8217;s where the tests are kept. So, let&#8217;s look inside it.</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ ls -l blitzdb/tests/
Total 8
drwxr-xr-x 2 maesaka maesaka 4096 2009-12-13 23:51 r
drwxr-xr-x 2 maesaka maesaka 4096 2009-12-13 23:51 t</pre></div></div>

<p>As you can see, there are two directories. By now, storage engine developers would have caught on to what&#8217;s going on. The r/ directory is where the .result files are kept and t/ is where the .test files are kept. This is exactly the same layout as what we&#8217;re used to working on (&#8220;src/tests/t/&#8221; and &#8220;src/tests/r/&#8221;).</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ ls -l blitzdb/tests/t/
Total 8
-rw-r--r-- 1 maesaka maesaka   21 2009-12-13 23:51 blitzdb-master.opt
-rw-r--r-- 1 maesaka maesaka 1964 2009-12-13 23:51 blitzdb.test</pre></div></div>

<p>The .opt file is used to make sure that the server is started with your storage engine enabled. You simply write the startup option inside the .opt file. Here&#8217;s what mine looks like at the moment (there&#8217;s only a single line in it).</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ less blitzdb/tests/t/blitzdb-master.opt
--plugin_add=blitzdb
blitzdb/tests/t/blitzdb-master.opt (END)</pre></div></div>

<p>Next step is actually running it. You simply specify your engine name with the &#45;&#45;suite option to dtr and you&#8217;re done! Unfortunately the symlink permission for dtr seems broken on my repository so I&#8217;ll directly call test-run.pl in this example.</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ ./test-run.pl --suite=blitzdb
Logging: ./test-run.pl --suite=blitzdb
MySQL Version 2009.12.1245
Use of uninitialized value in scalar assignment at ./test-run.pl line 1416.
Using MTR_BUILD_THREAD      = -69.4
Using MASTER_MYPORT         = 9306
Using MASTER_MYPORT1        = 9307
Using SLAVE_MYPORT          = 9308
Using SLAVE_MYPORT1         = 9309
Using SLAVE_MYPORT2         = 9310
Using MC_PORT               = 9316
Killing Possible Leftover Processes
Removing Stale Files
Creating Directories
=======================================================
DEFAULT STORAGE ENGINE: innodb
TEST                           RESULT         TIME (ms)
-------------------------------------------------------
&nbsp;
blitzdb.blitzdb                [ pass ]             63
-------------------------------------------------------
Stopping All Servers
All 1 tests were successful.
The servers were restarted 1 times
Spent 0.063 of 2 seconds executing testcases</pre></div></div>

<p>That&#8217;s it! I really like this change since it makes sense for engine-specific tests to belong inside the storage engine&#8217;s directory. It makes conceptual sense and it&#8217;s a good step towards differentiating the database kernel and the storage engine, which <a href="http://inaugust.com/">Monty Taylor</a> is actively hacking on. Hopefully he&#8217;ll blog more about these changes soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2009/12/storage-engine-tests-in-drizzle-organized/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tips on Drizzle Development and Valgrind</title>
		<link>http://torum.net/2009/12/tips-on-drizzle-and-valgrind/</link>
		<comments>http://torum.net/2009/12/tips-on-drizzle-and-valgrind/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 14:05:03 +0000</pubDate>
		<dc:creator>Toru Maesaka</dc:creator>
				<category><![CDATA[drizzle]]></category>
		<category><![CDATA[knowledge]]></category>
		<category><![CDATA[oss]]></category>
		<category><![CDATA[hacking]]></category>

		<guid isPermaLink="false">http://torum.net/?p=2312</guid>
		<description><![CDATA[In brief, valgrind is a framework of awesome tools that does an amazing job at detecting memory errors. It will catch silly (often unexpected) mistakes and memory leaks that you&#8217;ve made in your code. IMHO, it&#8217;s a must have tool for open source hackers that work with Linux. If you develop a plugin or a [...]]]></description>
			<content:encoded><![CDATA[<p>In brief, <a href="http://valgrind.org/">valgrind</a> is a framework of awesome tools that does an amazing job at detecting memory errors. It will catch silly (often unexpected) mistakes and memory leaks that you&#8217;ve made in your code. IMHO, it&#8217;s a must have tool for open source hackers that work with Linux. If you develop a plugin or a storage engine for Drizzle/MySQL, you often end up wanting to test your program for memory errors. Actually, it&#8217;s not a &#8220;want&#8221;, it&#8217;s a <strong>MUST</strong>.</p>
<p>Conveniently by supplying a simple startup option, Drizzle and MySQL&#8217;s test runner will run the daemon process on valgrind&#8217;s virtual machine. I&#8217;m not sure about MySQL since I&#8217;ve never developed anything for it but at least with Drizzle you can run a test case independently by supplying the desired test name to the test runner.</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;"> $ ./dtr your_test_file_name --valgrind</pre></div></div>

<p>So, with BlitzDB this is what I do to isolate the test runner to only run my tests:</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;"> $ ./dtr blitzdb.test --valgrind</pre></div></div>

<p>Very simple.</p>
<p>The minor complication here is that the test runner will not output the valgrind report to the console and instead it writes the output to a file. So where is this file? the answer is, it&#8217;s written to the daemon&#8217;s error log which is located in the source tree:</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ less drizzle_src/tests/var/log/master.err
CURRENT_TEST: main.blitzdb
==24563== Memcheck, a memory error detector
==24563== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
...</pre></div></div>

<p>Here&#8217;s another tip. If you ever wondered where the files that were generated in the test (like table and index files) are stored, they are stored inside the source tree as well. Here&#8217;s an example on my machine:</p>

<div class="wp_syntax"><div class="code"><pre class="null" style="font-family:monospace;">$ ll drizzle_src/tests/var/master-data/
total 20528
-rw-rw---- 1 tmaesaka tmaesaka 10485760 2009-12-01 22:06 ibdata1
-rw-rw---- 1 tmaesaka tmaesaka  5242880 2009-12-01 22:06 ib_logfile0
-rw-rw---- 1 tmaesaka tmaesaka  5242880 2009-12-01 22:06 ib_logfile1
drwxr-xr-x 2 tmaesaka tmaesaka     4096 2009-12-01 22:06 mysql
drwxr-xr-x 2 tmaesaka tmaesaka     4096 2009-12-01 22:06 test</pre></div></div>

<p>So, with all that in mind, happy hacking :)</p>
]]></content:encoded>
			<wfw:commentRss>http://torum.net/2009/12/tips-on-drizzle-and-valgrind/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
