<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3824530923832102616</id><updated>2011-11-27T17:22:02.382-08:00</updated><category term='mysql'/><category term='innodb'/><title type='text'>Mysql Insights</title><subtitle type='html'>Cool things I have learned or noticed about Mysql and Mysql Internals.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-2696299370576383557</id><published>2009-08-31T18:27:00.000-07:00</published><updated>2009-08-31T18:33:13.937-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>Oprofile for IO bound apps</title><content type='html'>I am using Oprofile to look into the performance of a Mysql Storage engine.  Upon reading further into the oprofile docs I find:&lt;br /&gt;&lt;br /&gt;"OProfile is oriented to finding problems with CPU-limited processes. OProfile does not identify processes that are asleep because they are waiting on locks or for some other event to occur (for example an I/O device to finish an operation)."&lt;br /&gt;&lt;br /&gt;That is kind of a drag since the results I am expecting to see include the largest bottlenecks for IO and waiting for locks.&lt;br /&gt;&lt;br /&gt;From my experience with gprof I seem to remember the same thing: CPU profiling primarily.&lt;br /&gt;&lt;br /&gt;Does any one know of a good off the shelf tool that can integrate CPU profiling with IO?  I don't even expect to see anything out there that can include time waiting for locks because it is not generic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-2696299370576383557?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/2696299370576383557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/08/oprofile-for-io-bound-apps.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/2696299370576383557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/2696299370576383557'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/08/oprofile-for-io-bound-apps.html' title='Oprofile for IO bound apps'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-7056583462534090332</id><published>2009-04-23T08:48:00.000-07:00</published><updated>2009-04-23T09:29:31.231-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>Highly Available Storage (without high prices)</title><content type='html'>One of the most interesting themes I have been paying attention to at this years Mysql users conference is techniques to create highly available storage volumes without spending a million dollars on a SAN or NAS infrastructure using companies like EMC or Network Appliance or IBM.&lt;br /&gt;&lt;br /&gt;At least 3 options exist that I was not aware of before:&lt;br /&gt;&lt;br /&gt;&lt;span class="h3"&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Amazon Elastic Block Store:&lt;/span&gt;  as part of Amazon's EC2 web services you can have a virtual block level device available from your EC2 instance.  Using this block level device you can either mount a typical linux filesystem and access the device with standard file access system calls or you can even do raw IO against the device without a filesystem.  The data is stored on amazon's cloud, and is thus relatively highly available.  As with all Amazon services you only pay for what you use.  I was quoted performance numbers around 100 MB / sec which seems quite reasonable.  You can only mount the storage on one instance at a time for the moment, but you could set up NFS between instances if you really wanted to.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Rackspace Virtualized Storage:&lt;/span&gt; I talked breifly with some guys from Rackspace and they said they have a service backed by a Network Appliance NAS farm that allows hosting clients to have access to NetApp volumes on a rental basis.  This sounds pretty cool in that you can have NetApp storage space without actually buying the hardware.  NetApps are usually highly available so you don't have to worry as you do with commodity linux boxes that it may go down at anytime.  However when I went to the Rackspace site I couldn't really find the exact offering they were talking about so this option needs some more research.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;DRBD:&lt;/span&gt;  &lt;/span&gt;DRBD seems to be a fairly popular product, that I not heard about until now.  It allows you to have a volume on one machine that appears to be a standard filesystem volume but is actually replicated using DRBD to another machine.  There seems to be a few modes one of which allows your fsync calls to block until all data is flushed both on the local disk and the remote disk, another allows you to block until the data is in memory on the other machine but not flushed to disk, etc.  Choosing the modes and finding out the exact characteristics of write and fsync with each mode, and the relative performance of these combinations will be important details (hopefully with no devil in there).  At their booth they were quoting numbers that looked very similar to the IO throughput you would get on a commodity box for around 100MB / sec,  but again this all depends on your config.&lt;br /&gt;&lt;br /&gt;More info is available in these links:&lt;br /&gt;&lt;a href="http://aws.amazon.com/ec2/#functionality"&gt;http://aws.amazon.com/ec2/#functionality&lt;br /&gt;&lt;/a&gt;&lt;a href="http://www.mosso.com/?CMP=rackspacehome"&gt;http://www.mosso.com/?CMP=rackspacehome&lt;br /&gt;&lt;/a&gt;&lt;a href="http://www.drbd.org/"&gt;http://www.drbd.org/&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-7056583462534090332?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/7056583462534090332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/04/highly-available-storage-without-high.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/7056583462534090332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/7056583462534090332'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/04/highly-available-storage-without-high.html' title='Highly Available Storage (without high prices)'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-2104684175500477710</id><published>2009-03-13T09:57:00.000-07:00</published><updated>2009-03-13T10:12:50.148-07:00</updated><title type='text'>Auto Increment Stability</title><content type='html'>Over the last few years I have come to realize that Auto-Increment is a difficult problem for RDMS vendors to solve.  When I was working with Sybase, the company I was with had a rule against using auto-increment for stability reasons.&lt;br /&gt;&lt;br /&gt;Mysql storage engines seem to be a bit troublesome with auto increment as well.   I believe that auto increment in Innodb was implemented using some global variables and mutexes which recently was &lt;a href="http://www.mysqlperformanceblog.com/2007/09/26/innodb-auto-inc-scalability-fixed/"&gt;patched&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For some fun with auto increment try executing the somewhat seemingly simple SQL on Innodb, listed at the end of this article.  Which gives what to me appears to be unintuitive results.&lt;br /&gt;&lt;br /&gt;The message here is not that the implementators of auto-increment have not done a good job, but that creating this functionality is actually really difficult.  Personally I would recommend against using auto-increment in large scale complex applications, unless you really know what you are doing and are accepting the limitations that exist.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;span style="font-weight: bold;"&gt;INTERESTING QUERY&lt;/span&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;drop table if exists t1;&lt;br /&gt;CREATE TABLE t1&lt;br /&gt;( id integer auto_increment primary key,&lt;br /&gt;k integer NOT NULL,&lt;br /&gt;INDEX k(k)&lt;br /&gt;) engine = innodb;&lt;br /&gt;&lt;br /&gt;insert into t1 (k) values (0);&lt;br /&gt;insert into t1 (k) values (1);&lt;br /&gt;insert into t1 (k) values (2);&lt;br /&gt;insert into t1 (k) values (3);&lt;br /&gt;insert into t1 (k) values (4);&lt;br /&gt;insert into t1 (k) values (5);&lt;br /&gt;insert into t1 (k) values (6);&lt;br /&gt;insert into t1 (k) values (7);&lt;br /&gt;insert into t1 (k) values (8);&lt;br /&gt;insert into t1 (k) values (9);&lt;br /&gt;insert into t1 (k) select k from t1;&lt;br /&gt;insert into t1 (k) select k from t1;&lt;br /&gt;select * from t1 order by id;&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------&lt;br /&gt;Here are the results I get.  Notice the gaps in the numbers:&lt;br /&gt;&lt;br /&gt;+----+---+&lt;br /&gt;| id | k |&lt;br /&gt;+----+---+&lt;br /&gt;|  1 | 0 |&lt;br /&gt;|  2 | 1 |&lt;br /&gt;|  3 | 2 |&lt;br /&gt;|  4 | 3 |&lt;br /&gt;|  5 | 4 |&lt;br /&gt;|  6 | 5 |&lt;br /&gt;|  7 | 6 |&lt;br /&gt;|  8 | 7 |&lt;br /&gt;|  9 | 8 |&lt;br /&gt;| 10 | 9 |&lt;br /&gt;| 11 | 0 |&lt;br /&gt;| 12 | 1 |&lt;br /&gt;| 13 | 2 |&lt;br /&gt;| 14 | 3 |&lt;br /&gt;| 15 | 4 |&lt;br /&gt;| 16 | 5 |&lt;br /&gt;| 17 | 6 |&lt;br /&gt;| 18 | 7 |&lt;br /&gt;| 19 | 8 |&lt;br /&gt;| 20 | 9 |&lt;br /&gt;| 26 | 0 |&lt;br /&gt;| 27 | 0 |&lt;br /&gt;| 28 | 1 |&lt;br /&gt;| 29 | 1 |&lt;br /&gt;| 30 | 2 |&lt;br /&gt;| 31 | 2 |&lt;br /&gt;| 32 | 3 |&lt;br /&gt;| 33 | 3 |&lt;br /&gt;| 34 | 4 |&lt;br /&gt;| 35 | 4 |&lt;br /&gt;| 36 | 5 |&lt;br /&gt;| 37 | 5 |&lt;br /&gt;| 38 | 6 |&lt;br /&gt;| 39 | 6 |&lt;br /&gt;| 40 | 7 |&lt;br /&gt;| 41 | 7 |&lt;br /&gt;| 42 | 8 |&lt;br /&gt;| 43 | 8 |&lt;br /&gt;| 44 | 9 |&lt;br /&gt;| 45 | 9 |&lt;br /&gt;+----+---+&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-2104684175500477710?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/2104684175500477710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/03/auto-increment-stability.html#comment-form' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/2104684175500477710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/2104684175500477710'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/03/auto-increment-stability.html' title='Auto Increment Stability'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-352861191474101782</id><published>2009-02-19T09:43:00.000-08:00</published><updated>2009-02-19T19:35:56.487-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='innodb'/><title type='text'>Understanding UNIV_LIKELY and other Optimization Macros in the Innodb Codebase</title><content type='html'>When you first start browsing the code for Innodb (a Mysql Storage Engine) you will notice several strange macros like UNIV_LIKELY popping up all over the place.  Its good to get clear on what those mean so as not to distract you from understanding the actual logic of the code you are reading.&lt;br /&gt;&lt;br /&gt;The set of macros described below all wrap GCC builtin functions which are used for performance optimization.  The macros are defined as blank space on other platforms not supporting these builtin functions.  The macros are in two categories the expect and prefetch macros which I will describe separately:&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;&lt;u&gt;EXPECT MACROS&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;These macros take expressions and return the exact same value as the expression would return without the macros.  From the user's point of view, they are the same as just enclosing the expression in an extra set of parenthesis.  However the macros, provide hints to the optimizer about the expected value of the expression which lets them optimize branches.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;UNIV_EXPECT&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;(expr, constant)&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;This is a wrapper around the gnu builtin function &lt;span style="font-style: italic;"&gt;'__builtin_expect'&lt;/span&gt; .  The macro is intended to be used within an if condition or other branching statement to tell the compiler the expected outcome of the expression.  The compiler than uses that information to optimize the generated code for that outcome.  The args to the function UNIV_EXPECT are an expression that will be evaluated and the expected output which must be a compile time constant integer.  Here is an example of how to use this macro:&lt;br /&gt;&lt;pre style="font-style: italic;"&gt;if (UNIV_EXPECT(retCode, 0)){&lt;br /&gt;&lt;br /&gt;fprintf(stderr, "failure, got a non-zero return code\n");&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;This will evaluate the same as doing just &lt;span style="font-style: italic;"&gt;if (retCode)&lt;/span&gt; but the optimizer will understand that retCode is most likely to always be 0.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;UNIV_LIKELY(cond)&lt;br /&gt;&lt;/span&gt;&lt;span&gt;The macro returns the value of the condition, and indicates a hint to the compiler that the likely value of the condition is TRUE or 1&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;UNIV_UNLIKELY(cond)&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;The macro returns the value of the condition, and i&lt;/span&gt;&lt;span&gt;ndicates a hint to the compiler that the likely value of the condition is FALSE or 0&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;UNIV_LIKELY_NULL(ptr)&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;The macro returns the value of the ptr, and i&lt;/span&gt;&lt;span&gt;&lt;span&gt;ndicates a hint to the compiler that the likely value of the ptr is NULL.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;u&gt;Prefetch macros&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;There are two prefetch macros in Innodb, that are both wrappers around GCC's &lt;span style="font-style: italic;"&gt;'__builtin_prefetch'&lt;/span&gt;.  By telling the system you will be reading or writing to a given address in the near future, the compiler/hardware can try to pre-fetch this address, making the actual memory accesses faster.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;UNIV_PREFETCH_R(addr)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;Give a hint to the compiler that the &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;addr specified will soon be accessed for reading.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;UNIV_PREFETCH_RW(addr)&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;Give a hint to the compiler that the &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;addr specified will soon be accessed for&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;writing.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;More details on the inner workings of these Macros can be found in the &lt;a href="http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Other-Builtins.html#Other-Builtins"&gt;GCC documentation, Builtin Functions&lt;/a&gt; section.  Just look for info about &lt;span style="font-style: italic;"&gt;'__builtin_expect&lt;/span&gt;' and &lt;span style="font-style: italic;"&gt;'__builtin_prefetch'&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Now that you will not be distracted by these macros anymore, &lt;span&gt;Happy Browsing,&lt;br /&gt;&lt;br /&gt;Ivan Novick&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-352861191474101782?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/352861191474101782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/02/understanding-univlikely-and-other.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/352861191474101782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/352861191474101782'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/02/understanding-univlikely-and-other.html' title='Understanding UNIV_LIKELY and other Optimization Macros in the Innodb Codebase'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-412394061024653044</id><published>2009-02-04T09:51:00.001-08:00</published><updated>2009-02-07T10:53:42.389-08:00</updated><title type='text'>Understanding the InnoDB Source Code Structure</title><content type='html'>Innodb source code is organized into directories where each directory holds the C source code files for a given module.  Within the directory are 1 or more files that are part of the module.  The file names have a structure which I will describe below.&lt;br /&gt;&lt;br /&gt;The first part of the file name indicates the module name.  The module name is followed by a '0' character which is a separator.  The second part of the file name represents the sub-module.  Most modules have one file where the sub-module is the same name as the module, this file represents the primary file in the module.&lt;br /&gt;&lt;br /&gt;For, example the main file for Btree is located in the btr directory and named: btr0btr.c&lt;br /&gt;The first btr indicates the module name, the 0 is a separator and the the second btr is the sub module name which is the same for the primary file.&lt;br /&gt;&lt;br /&gt;The file that handles the Btree cursor is also located in the btr directory and named: btr0cur.c&lt;br /&gt;The first btr is the module name, the 0 is a separator, and the cur is the sub module name which stands for cursor in this case.&lt;br /&gt;&lt;br /&gt;There is also a include directory which contains all the header files.  The header files are also named in a similar way.&lt;br /&gt;&lt;br /&gt;For example, the file 'btr0cur.h' is the header file for the Btree cursor module.  Note the include files contain both '.h' files and '.ic' files which are included C files.&lt;br /&gt;&lt;br /&gt;Now that we understand the naming conventions, I am going to give you a list of all the modules in the Innodb source code base and a description of what they are for.  The list below is sorted by lines of code in the module, with the biggest modules coming first.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(153, 0, 0);font-size:180%;" &gt;&lt;span style="color: rgb(51, 102, 255); font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="color: rgb(153, 0, 0); font-weight: bold;"&gt;INNODB MODULES&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;row&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;Row Abstraction, 19,768 lines&lt;br /&gt;sub-modules: Updates, Undo, Undo Modify, Undo Insert, Select, Purge, Mysql Interface&lt;br /&gt;The logic for the mysql row formatting and the innodb row formatting is quite lengthy.  This module also seems to have a lot of the high-level business logic for Innodb.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;trx&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Transactions, 13,138 lines&lt;br /&gt;sub-modules: Rollback, Rollback Segment, Undo, Log Records, Purge&lt;br /&gt;&lt;span&gt;As Innodb is a transactional storage engine there is a lot of logic to implement this&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;btr&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Btree data structure, 12,228 lines&lt;br /&gt;sub-modules: Btree Cursor, Btree Persistent Cursor, Btree Adaptive Search&lt;br /&gt;&lt;span&gt;Btree is the index of Innodb and is core functionality&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;pars&lt;/span&gt;&lt;br /&gt;SQL parser, 11,691 lines&lt;br /&gt;sub-modules: Symbol Table, Optimizer, Lexical Analyzer, Grammar&lt;br /&gt;I am pretty sure you can ignore this directory if you are using innodb with mysql, as it is dead code in that case (please do correct me if I am wrong)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;dict&lt;/span&gt;&lt;br /&gt;Data Dictionary (meta-data), 10,446 lines&lt;br /&gt;sub-modules: Boot, Creation,  Load, Memory&lt;br /&gt;Table names, column names, key names, etc. all in this code&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;handler&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Mysql Storage Engine Interface, 8498 lines&lt;br /&gt;This is the primary interface between Mysql and the innodb storage engine and the entry point for all mysql API calls.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;log&lt;/span&gt;&lt;br /&gt;Database Log, 8379 lines&lt;br /&gt;sub-modules: Recovery&lt;br /&gt;Database logging is core functionality&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;buf&lt;/span&gt;&lt;br /&gt;Buffer Pool, 7784 lines&lt;br /&gt;sub-modules: Buffer Flush Algorithm, Buffer Replacement Algorithm, Buffer Read Abstraction&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;os&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;Operating System Interface, 7659 lines&lt;br /&gt;sub-modules: Files, Processes, Threads, Synchronization&lt;br /&gt;This is the fun stuff, all the low level OS specific code&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;lock&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Transaction Lock System, 6224 lines&lt;br /&gt;sub-modules: Lock Queue Iterator&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;page&lt;/span&gt;&lt;br /&gt;Index Page, 5675 lines&lt;br /&gt;sub-modules: Page Cursor&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;srv&lt;/span&gt;&lt;br /&gt;Main Server Driver, 5469 lines&lt;br /&gt;sub-modules: Startup, Query Execution&lt;br /&gt;Look here for configuration option handling coding and other startup issues&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;sync&lt;/span&gt;&lt;br /&gt;Synchronization, 5361 lines&lt;br /&gt;sub-modules: ReadWrite Lock, Wait Array&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;fil&lt;/span&gt;&lt;br /&gt;Table Space Memory Cache, 5282 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;rem&lt;/span&gt;&lt;br /&gt;Records Abstraction, 4965 lines&lt;br /&gt;sub-modules: Record Manager, Record Comparison Service&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;fsp&lt;/span&gt;&lt;br /&gt;File Space Management, 4405 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ibuf&lt;/span&gt;&lt;br /&gt;Insert Buffer, 4125 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ut&lt;/span&gt;  &lt;br /&gt;Utilities, 4113 lines&lt;br /&gt;sub-modules: Vector, Random Numbers, Memory, List, Debug, Byte Manipulation, Work Queue&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;mem&lt;/span&gt;&lt;br /&gt;Memory Management, 3598 lines&lt;br /&gt;sub-modules: Memory Debug, Memory Pool&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;data&lt;/span&gt;&lt;br /&gt;Data Element Abstraction, 2867 lines&lt;br /&gt;sub-modules: Data Types&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;que&lt;/span&gt;&lt;br /&gt;Query Graph, 2255 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;mtr&lt;/span&gt;&lt;br /&gt;Mini-transaction Buffer, 1967 lines&lt;br /&gt;sub-modules: Mini-transaction Log&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;eval&lt;/span&gt;&lt;br /&gt;SQL evaluator, 1603 lines&lt;br /&gt;sub-modules: Stored Procedures&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;ha&lt;/span&gt;&lt;br /&gt;Hash table, 1422 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;mach&lt;/span&gt;&lt;br /&gt;Machine Dependent Utilities, 1198 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;fut&lt;/span&gt;&lt;br /&gt;File Based Utilities, 951 lines&lt;br /&gt;sub-modules: File Based List&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;read&lt;/span&gt;&lt;br /&gt;Cursor Read, 788 lines&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;dyn&lt;/span&gt;&lt;br /&gt;Dynamically Allocated Array, 560 lines&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;thr&lt;/span&gt;&lt;br /&gt;Threads, 302 lines&lt;br /&gt;sub-modules: Thread Local Storage&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;usr&lt;/span&gt;&lt;br /&gt;Sessions, 163 lines&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-412394061024653044?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/412394061024653044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/02/understanding-innodb-source-code.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/412394061024653044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/412394061024653044'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/02/understanding-innodb-source-code.html' title='Understanding the InnoDB Source Code Structure'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-6230233896450488479</id><published>2009-02-02T08:33:00.000-08:00</published><updated>2009-02-02T08:49:35.088-08:00</updated><title type='text'>Portable condition variables in Mysql codebase</title><content type='html'>How can you write good multi-threaded code without using condition variables?&lt;br /&gt;&lt;br /&gt;On most flavors of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;unix&lt;/span&gt; you have the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;pthread&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;api&lt;/span&gt; which gives you &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;pthread&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;cond&lt;/span&gt;_t structures and the related &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;API&lt;/span&gt; functions.  However on all version of Windows before Windows Vista and Windows Server 2008, the Windows &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;API's&lt;/span&gt; did not come with any kind of condition variables.  This makes it really hard to write multi-threaded code that works on both Windows and Unix systems especially if you want the code to behave in a similar way on all platforms.&lt;br /&gt;&lt;br /&gt;Well &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Mysql&lt;/span&gt; developers solved this issue by writing their own version &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;pthread&lt;/span&gt;_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;cond&lt;/span&gt;_t and related functions which can be found in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;codebase&lt;/span&gt; in the files my_&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;wincond&lt;/span&gt;.c.  The code is #&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;ifdef&lt;/span&gt; enabled on Windows platforms otherwise the standard &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;pthread&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;api&lt;/span&gt; is used.  The implementation of condition variables in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;mysql&lt;/span&gt; code base utilizes one CRITICAL_SECTION variable, and 3 arrays of Windows' Event objects.  The code is short but hard to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_16"&gt;truly&lt;/span&gt; understand.  Please do take a look at this code.&lt;br /&gt;&lt;br /&gt;There have been several other attempts by people to create Windows versions of Condition variables, which you can find by searching the web.  Almost always these solutions include notes about how the solutions are not perfect.&lt;br /&gt;&lt;br /&gt;Thankfully Microsoft has released Condition variables as part of their latest OS versions which they are supporting as part of the OS and system &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;APIs&lt;/span&gt;.  I don't know if &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;Mysql&lt;/span&gt; developers are going to add #&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;ifdef's&lt;/span&gt; to use these new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;APIs&lt;/span&gt; when available but I sure think it would be a good idea.&lt;br /&gt;&lt;br /&gt;Ivan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-6230233896450488479?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/6230233896450488479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/02/portable-condition-variables-in-mysql.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/6230233896450488479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/6230233896450488479'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/02/portable-condition-variables-in-mysql.html' title='Portable condition variables in Mysql codebase'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-1821976827131445499</id><published>2009-01-29T15:17:00.001-08:00</published><updated>2009-01-29T15:40:08.558-08:00</updated><title type='text'>NULL fields in Mysql row format</title><content type='html'>As a storage engine developer you need to take rows of data given by Mysql and interpret the meaning.  You also need to take data from your storage engine format and convert this to Mysql format before returning the data to the engine.  One important aspect of this is determining which fields have NULL values.  Here is how the NULL values work in Mysql internal row format:&lt;br /&gt;&lt;br /&gt;There is a table object that is part of the storage engine handler class:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;struct st_table *table;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This table object contains a field member, which is an array of fields in the table:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Field **field;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Any individual field within a table has the following members:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;uchar* null_ptr;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;uchar  null_bit;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The null_ptr is used to reference the byte location in the mysql row where the null bit mask for this field is located.&lt;br /&gt;&lt;br /&gt;The null_bit is a bit mask for a single byte that can be used to set or test the NULL value for this field.  So for example if you want to test the value of a specific field to see if it is NULL, you do it like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;if (table-&gt;field[0]-&gt;null_ptr &amp;amp; table-&gt;field[0]-&gt;null_bit){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  // field 0 is null&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to set a field to be null you can do it like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;table-&gt;field[0]-&gt;null_ptr |= table-&gt;field[0]-&gt;null_bit;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Hope this helps.&lt;br /&gt;&lt;br /&gt;Ivan &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Novick&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-1821976827131445499?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/1821976827131445499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/null-fields-in-mysql-row-format.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/1821976827131445499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/1821976827131445499'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/null-fields-in-mysql-row-format.html' title='NULL fields in Mysql row format'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-1464792226993133441</id><published>2009-01-28T15:01:00.001-08:00</published><updated>2009-01-28T15:10:33.802-08:00</updated><title type='text'>Innodb data types mapped to mysql data types</title><content type='html'>Today, I found the function in Innodb which maps Mysql data types to innodb data types.  It is get_innobase_type_from_mysql_type which is located in the file ha_innodb.cc.  The function takes an input parameter of type Field from mysql classes.  This filed is then analyzed to set an output function paremeter that indicates whether the field is signed or unsigned and then the return value of the function is a macro integer code.  The codes are defined in data0type.h as follows:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;/*-------------------------------------------*/&lt;br /&gt;/* The 'MAIN TYPE' of a column */&lt;br /&gt;#define DATA_VARCHAR      1  &lt;br /&gt;#define DATA_CHAR         2&lt;br /&gt;#define DATA_FIXBINARY    3&lt;br /&gt;#define DATA_BINARY       4&lt;br /&gt;#define DATA_BLOB         5&lt;br /&gt;#define DATA_INT          6&lt;br /&gt;#define DATA_SYS_CHILD    7&lt;br /&gt;#define DATA_SYS          8&lt;br /&gt;#define DATA_FLOAT        9&lt;br /&gt;#define DATA_DOUBLE       10&lt;br /&gt;#define DATA_DECIMAL      11&lt;br /&gt;#define DATA_VARMYSQL     12&lt;br /&gt;#define DATA_MYSQL        13&lt;br /&gt;#define DATA_MTYPE_MAX    63&lt;br /&gt;/*-------------------------------------------*/&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;More info on the data types in a later post.&lt;br /&gt;Ivan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-1464792226993133441?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/1464792226993133441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/innodb-data-types-mapped-to-mysql-data.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/1464792226993133441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/1464792226993133441'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/innodb-data-types-mapped-to-mysql-data.html' title='Innodb data types mapped to mysql data types'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-3964032603136397702</id><published>2009-01-27T17:45:00.001-08:00</published><updated>2009-01-27T18:05:01.094-08:00</updated><title type='text'>Starting place for debugging Mysql</title><content type='html'>This post gives some brief tips for debugging Mysql.&lt;br /&gt;&lt;br /&gt;First of all you can run Mysql on many different platforms.  So start by choosing the platform that will make your particular debugging task easier.  For memory leaks I would run the server on linux so that I can take advantage of the Valgrind tool, for memory leak checking, which is only available on linux.  For bugs where you want to use a debugger to step into the code, Windows is a surprisingly great option due the ease of use of the debugger that comes with Visual C++.&lt;br /&gt;&lt;br /&gt;Now that you have your debugger of choice up and running, you want to see what is Mysql doing in some scenario.  Mysql code is quite complex so finding the right place to put the breakpoint can be a challenge.  If I don't know what function calls mysql is making, normally I would start with a breakpoint in sql_parse.cc in the mysql_execute_command function at the point where the code says:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;switch (lex-&gt;sql_command) {&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;which in my install is on sql_parse.cc line 2125&lt;br /&gt;&lt;br /&gt;Once the code reaches this breakpoint then I usually add watches for the variables &lt;code&gt;thd-&gt;query&lt;/code&gt; which gives the full text of the query currently being handled and also &lt;code&gt;lex-&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;sql&lt;/span&gt;_command&lt;/code&gt; which gives the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;enum&lt;/span&gt; of the command type that is being executed.   From this point you can step through the code and see what &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Mysql&lt;/span&gt; is doing for each command.&lt;br /&gt;&lt;br /&gt;This is just the very beginning, I hope to add more posts in the future with additional details.&lt;br /&gt;&lt;br /&gt;Ivan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-3964032603136397702?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/3964032603136397702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/starting-place-for-debugging-mysql.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/3964032603136397702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/3964032603136397702'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/starting-place-for-debugging-mysql.html' title='Starting place for debugging Mysql'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-5988971164657928164</id><published>2009-01-25T22:18:00.000-08:00</published><updated>2009-01-25T22:50:26.540-08:00</updated><title type='text'>Mysql BLOBs and memory allocation</title><content type='html'>&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;BLOBs&lt;/span&gt; have performance limits due to the way they are currently handled by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;mysql&lt;/span&gt;.  First I will give you a little background info, then describe the problem, and potential solutions.&lt;br /&gt;&lt;br /&gt;BLOB is an acronym for Binary Large Object.  It is a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;datatype&lt;/span&gt; available in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Mysql&lt;/span&gt; in 4 different sizes.  There are also 4 text data types that are almost the same as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;BLOBs&lt;/span&gt; accept they contain string information instead of binary information.  Text also has different comparison characteristics than &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;BLOBs&lt;/span&gt; since it is a string oriented type.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;BLOBs&lt;/span&gt; can be used to store &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;JPEG&lt;/span&gt; files or any other large binary data.  BLOB data types come in 4 sizes: tiny,  regular, medium, and long which have size &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_8"&gt;limitations&lt;/span&gt; respectively of 25 bytes,  64 KB, 16 MB, and 4GB.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;Ok&lt;/span&gt;, so here is the issue: when a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;mysql&lt;/span&gt; storage engine returns a BLOB from disk to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;mysql&lt;/span&gt; it has to provide a contiguous buffer where the data is stored and a pointer to that buffer.  In other words "The entire BLOB has to fit into memory at once!!" even for a 4GB long blob.  Now imaging you have 100 different 4GB long BLOB files (let's imagine movie files) and there are select statements being run &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;simultaneously&lt;/span&gt; to retrieve all 100 files.   Your storage engine would need to allocate 400 GB of memory to put all those &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;BLOBs&lt;/span&gt; into.  Clearly, this is not scalable since boxes today cap out around 64GB of ram.&lt;br /&gt;&lt;br /&gt;So what is the solution?  Conceptually, the storage engine needs to give the data back to the user in chunks.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Mysql&lt;/span&gt; could have some fixed buffers, say 100 MB large and the storage engine could pump data into the buffers as the last chunk was sent to the client over the network.  Seems pretty straight forward, but it does require changes in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;mysql&lt;/span&gt; server and maybe &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;mysql&lt;/span&gt; client as well as all of the storage engines.  I wonder if this is already on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;Mysql's&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;roadmap&lt;/span&gt; (anyone know, please leave a comment).&lt;br /&gt;&lt;br /&gt;One storage engine did try work around the problem.  The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;PBXT&lt;/span&gt; storage engine has created a streaming BLOB infrastructure that seems to be pretty generic.  The problem is it requires changes to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;mysql&lt;/span&gt; client and server in addition to the storage engine and those changes don't seem to be integrated into the main line &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;mysql&lt;/span&gt; development branch as far as I can tell.&lt;br /&gt;&lt;br /&gt;Any comments or additional ideas on the subject please post a comment.  Thanks,&lt;br /&gt;Ivan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-5988971164657928164?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/5988971164657928164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/mysql-blobs-and-memory-allocation.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/5988971164657928164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/5988971164657928164'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/mysql-blobs-and-memory-allocation.html' title='Mysql BLOBs and memory allocation'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3824530923832102616.post-8584625006344162076</id><published>2009-01-24T09:57:00.000-08:00</published><updated>2009-01-24T09:59:19.496-08:00</updated><title type='text'>First Post</title><content type='html'>Hi there,&lt;br /&gt;&lt;br /&gt;This is my first post on the Mysql Insights Blog :) !&lt;br /&gt;&lt;br /&gt;The idea of this blog is to share things I learn about Mysql that might be interesting to others.  Currently, I am working at a small company where we are developing a Mysql storage engine so I have been learning lots of cool things about Mysql.&lt;br /&gt;&lt;br /&gt;Ivan&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3824530923832102616-8584625006344162076?l=mysqlinsights.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mysqlinsights.blogspot.com/feeds/8584625006344162076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/first-post.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/8584625006344162076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3824530923832102616/posts/default/8584625006344162076'/><link rel='alternate' type='text/html' href='http://mysqlinsights.blogspot.com/2009/01/first-post.html' title='First Post'/><author><name>Ivan Novick</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
