{"id":3705,"date":"2014-03-17T10:00:21","date_gmt":"2014-03-17T00:00:21","guid":{"rendered":"https:\/\/www.flamingspork.com\/blog\/?p=3705"},"modified":"2014-03-15T11:40:04","modified_gmt":"2014-03-15T01:40:04","slug":"ghosts-of-mysql-past-part-11-why-are-you-happy-about-this","status":"publish","type":"post","link":"https:\/\/www.flamingspork.com\/blog\/2014\/03\/17\/ghosts-of-mysql-past-part-11-why-are-you-happy-about-this\/","title":{"rendered":"Ghosts of MySQL Past, part 11: Why are you happy about this?"},"content":{"rendered":"<p>This is part 11 in what&#8217;s shaping up to be the best part of a 6 week series (<a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/03\/past-present-and-future-of-mysql-and-variants-part-1-ghosts-of-mysql-past\/\">Part 1<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/04\/ghosts-of-mysql-past-part-2\/\">2<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/05\/ghosts-of-mysql-past-part-3\/\">3,<\/a><a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/06\/ghosts-of-mysql-past-part-4-a-million-features-for-enterprise\/\"> 4<\/a>,<a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/14\/ghosts-of-mysql-past-part-5-the-era-of-acquisitions\/\"> 5<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/16\/ghosts-of-mysql-past-part-6-the-engine-revs\/\">6<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/02\/25\/ghosts-of-mysql-past-part-7-pbxt\/\">7<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/03\/10\/ghosts-of-mysql-past-part-7-1-hey-look-i-found-an-old-business-card\/\">7.1<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/03\/11\/ghosts-of-mysql-past-part-8-the-first-fork\/\">8<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/03\/12\/ghosts-of-mysql-past-part-8-1-five-years\/?preview=true\">8.1<\/a>, <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/03\/13\/ghosts-of-mysql-past-part-9-best-team-name-ever\/\">9<\/a> and <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/03\/14\/ghosts-of-mysql-past-part-10\/\">10<\/a>) on various history bits of MySQL, somewhat following my LCA2014 talk (<a href=\"http:\/\/mirror.linux.org.au\/linux.conf.au\/2014\/Wednesday\/28-Past_Present_and_future_of_MySQL_and_variants_-_Stewart_Smith.mp4\">video here<\/a>).<\/p>\n<p>One of my favorite MySQL stories is the introduction of the Random Query Generator &#8211; or randgen. While I&#8217;ve talked for a while now about the quality problems that were plaguing MySQL, there were positive steps going on. The introduction of continuous regression testing with pushbuild, increasing test case coverage and a focus on bug fixing were all helping. However&#8230; a database server is a complex beast that can accept arbitrary queries and transactions and at the very least is expected not to segfault. How on earth do you test it beyond simple manual testing (or automated manual testing: running the same set of static queries)?<\/p>\n<p>Well, at some point in development, David Axmark (one of the founders of MySQL AB) decided that if they were going to be a real database, they should have a test suite &#8211; so he wrote one. It was comprised of two parts: a small binary named mysqltest which basically read a file of SQL, ran it against the server and then displayed the results (and also had a couple of small bits of language such as variables and loops) and the other half was a shell script that started a mysqld and ran mysqltest for each .test file in the mysql-test\/t\/ directory and diffed the output against the mysql-test\/r\/*.result files.<\/p>\n<p>This system still exists today, although the shell script has been replaced by a perl script which has been replaced with mysql-test-run.pl version 2 which dealt with replication, starting MySQL Cluster daemons, running tests in parallel and dealt with Windows a lot better. The mysqltest binary is largely unchanged however, and so the now MUCH larger suite of SQL based tests would be familiar a dozen years ago, when the mysql-test suite was in infancy.<\/p>\n<p>But how do you ensure you&#8217;re testing enough of the server? Well&#8230; you can do code coverage analysis and write more tests manually, but wouldn&#8217;t it be much better if you could automatically generate tests? Wouldn&#8217;t it be great if you could automatically find a set of queries that caused the server to crash? Or a set of queries where the results differed between versions or other database servers (which would strongly indicate that somebody was buggy)?<\/p>\n<p>Well, it turns out that Microsoft had a similar problem back in the 1990s with Microsoft SQL Server and a system called RAGS was used in the development of Microsoft SQL Server 7.0 (released in 1998).<\/p>\n<p>So, fast forward about ten years and a relatively new hire of MySQL AB, Philip Stoev was working on something called &#8220;RQG&#8221; or Random Query Generator for MySQL AB. The basic idea was to be able to supply a grammar of what type of queries you would like it to generate, point it at a MySQL server and see what happens.<\/p>\n<p>It turns out that what happened was that after a while, the MySQL server would segfault. To a room of MySQL Server developers, this was a pretty amazing advancement in testing the server &#8211; an automated way to find new bugs!<\/p>\n<p>Throwing the Random Query Generator at the in-progress MySQL 6.0 optimizer caused a new innovation: automatic stack trace deduplication and test case minimization. RQG would automatically pair down the list of generated queries to the minimal set required to crash the server, so that you could import that set of queries into the existing mysqltest based regression test suite.<\/p>\n<p>The dataset that RQG would work against was rather fixed, it was about 10 already prepared tables with some easily generated data. In MySQL Cluster, we had a set of C++ classes that ran a multithreaded application that would use integer columns as a checksum for the whole row, so updates would also update the checksum and at the end of your test (which may cause node failures in various scenarios) you can check that each row is intact and hasn&#8217;t been corrupted. So, IIRC it may have been me (or Jonas, I honestly cannot remember) who asked if such a feature would be added to RQG and the reply was &#8220;when I can no longer crash the server in 4 or 5 queries&#8230; I&#8217;ll think about it&#8221;.<\/p>\n<p>So, developers expressed happiness, and Philip expressed this: &#8220;Why are you happy about this? We are about 10 years behind Microsoft in QA, why are you possibly happy about this?&#8221;<\/p>\n<p>So with this great new tool, the true state of the current server version, the in-development server version (6.0) and all the optimizer enhancements it was bringing, the new Falcon storage engine and the in progress Maria (now Aria) storage engine would be exposed.<\/p>\n<p>The news was not good.<\/p>\n<p>(although, in the long run, the news was really good, and it&#8217;s because of RQG that we now have a really solid MySQL Server)<\/p>\n<p>Further reading:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.vldb.org\/conf\/1998\/p618.pdf\">Massive Stochastic Testing of SQL<\/a>, from VLDB98<\/li>\n<li><a href=\"http:\/\/citeseerx.ist.psu.edu\/viewdoc\/download?doi=10.1.1.97.3435&amp;rep=rep1&amp;type=pdf\">A Genetic Approach for Random Testing of Database Systems<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This is part 11 in what&#8217;s shaping up to be the best part of a 6 week series (Part 1, 2, 3, 4, 5, 6, 7, 7.1, 8, 8.1, 9 and 10) on various history bits of MySQL, somewhat following &hellip; <a href=\"https:\/\/www.flamingspork.com\/blog\/2014\/03\/17\/ghosts-of-mysql-past-part-11-why-are-you-happy-about-this\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[14],"tags":[],"class_list":["post-3705","post","type-post","status-publish","format-standard","hentry","category-mysql"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5a6n8-XL","jetpack-related-posts":[{"id":3235,"url":"https:\/\/www.flamingspork.com\/blog\/2013\/03\/05\/mysql-code-size\/","url_meta":{"origin":3705,"position":0},"title":"MySQL code size over releases","author":"Stewart Smith","date":"2013-03-05","format":false,"excerpt":"As the start of a bit of a delve into the various MySQL branches and patch sets that have been around, let's start looking at the history of MySQL itself. This is how big MySQL has been over all of the major releases since the beginning (where beginning=3.23). (edit: These\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"increase in MySQL source code size over version","src":"https:\/\/docs.google.com\/spreadsheet\/oimg?key=0Ar7e3-N2Y32IdHFGRWI2ODk4ZUY4TkhrclJSVC1mb3c&oid=1&zx=5h67vlc175bd","width":350,"height":200,"srcset":"https:\/\/docs.google.com\/spreadsheet\/oimg?key=0Ar7e3-N2Y32IdHFGRWI2ODk4ZUY4TkhrclJSVC1mb3c&oid=1&zx=5h67vlc175bd 1x, https:\/\/docs.google.com\/spreadsheet\/oimg?key=0Ar7e3-N2Y32IdHFGRWI2ODk4ZUY4TkhrclJSVC1mb3c&oid=1&zx=5h67vlc175bd 1.5x"},"classes":[]},{"id":1199,"url":"https:\/\/www.flamingspork.com\/blog\/2008\/09\/08\/building-mysql-on-windows-mysql-forge-wiki\/","url_meta":{"origin":3705,"position":1},"title":"Building MySQL on Windows &#8211; MySQL Forge Wiki","author":"Stewart Smith","date":"2008-09-08","format":false,"excerpt":"Building MySQL on Windows - MySQL Forge Wiki This one covers running mysqld in the VisualStudio debugger, which can be useful. I have no special ndb_mgmd.exe or ndbd.exe in debugger instructions or wisdom (running them from mysql-test-run.pl at least). I've attached debugger to already running (started by mysql-test-run.pl) ndb processes,\u2026","rel":"","context":"In &quot;mysql&quot;","block_context":{"text":"mysql","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3263,"url":"https:\/\/www.flamingspork.com\/blog\/2013\/03\/15\/diffstat-of-mysql-5-6-versus-5-5\/","url_meta":{"origin":3705,"position":2},"title":"diffstat of MySQL 5.6 versus 5.5","author":"Stewart Smith","date":"2013-03-15","format":false,"excerpt":"Yesterday I wrote about what the diffstat between MySQL 5.5 and MariaDB 5.5 was, and previously to that, about the MariaDB code size as reported by sloccount. Let's look at MySQL 5.6. A naive wc based \"lines of code\" for MySQL 5.6 sql\/ directory is ~490kLOC which contasts with MySQL\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":562,"url":"https:\/\/www.flamingspork.com\/blog\/2006\/01\/20\/mysql-can-mysql-be-run-from-a-cdrom\/","url_meta":{"origin":3705,"position":3},"title":"MySQL: Can MySQL be run from a CDROM?","author":"Stewart Smith","date":"2006-01-20","format":false,"excerpt":"MySQL: Can MySQL be run from a CDROM? The question is asked. The answer is - yes! Temporary tables can be store anywhere - e.g. the system's temporary directory (\/tmp on unix, probably c:\\temp or something on windows... i'm sure there's one of those %FOO% things for it). IIRC you\u2026","rel":"","context":"In &quot;mysql&quot;","block_context":{"text":"mysql","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":908,"url":"https:\/\/www.flamingspork.com\/blog\/2007\/10\/23\/mysql-user-conference-2008-mysql-cluster-sessions\/","url_meta":{"origin":3705,"position":4},"title":"MySQL User Conference 2008 &#8211; MySQL Cluster Sessions","author":"Stewart Smith","date":"2007-10-23","format":false,"excerpt":"So... stealing the idea from Peter, does anybody have any suggestions for MySQL Cluster related things to have at the UC next year (April)? Either leave a comment or email me (first name at mysql dot com).","rel":"","context":"In &quot;mysql&quot;","block_context":{"text":"mysql","link":"https:\/\/www.flamingspork.com\/blog\/category\/work-et-al\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3738,"url":"https:\/\/www.flamingspork.com\/blog\/2014\/05\/26\/awesome-mysql-5-7-improvements\/","url_meta":{"origin":3705,"position":5},"title":"Awesome MySQL 5.7 improvements","author":"Stewart Smith","date":"2014-05-26","format":false,"excerpt":"Recently, I've had reason to poke at MySQL performance on some pretty cool hardware. Comparing MySQL 5.6 to MySQL 5.7 is a pretty interesting thing to do when you have many CPU cores. The improvements to creating read views in InnoDB is absolutely huge for small statements with large concurrency\u2026","rel":"","context":"In &quot;code&quot;","block_context":{"text":"code","link":"https:\/\/www.flamingspork.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/3705","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/comments?post=3705"}],"version-history":[{"count":1,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/3705\/revisions"}],"predecessor-version":[{"id":3707,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/posts\/3705\/revisions\/3707"}],"wp:attachment":[{"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/media?parent=3705"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/categories?post=3705"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.flamingspork.com\/blog\/wp-json\/wp\/v2\/tags?post=3705"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}