<?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>PlanetMysql.ru - информация о СУБД MySQL</title>
	<atom:link href="http://planetmysql.ru/feed/" rel="self" type="application/rss+xml" />
	<link>http://planetmysql.ru</link>
	<description>Блог о самой популярной СУБД MySQL</description>
	<lastBuildDate>Fri, 12 Mar 2010 17:01:59 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Log Buffer #182, a Carnival of the Vanities for DBAs</title>
		<link>http://www.pythian.com/news/9417/log-buffer-182-a-carnival-of-the-vanities-for-dbas/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=log-buffer-182-a-carnival-of-the-vanities-for-dbas</link>
		<comments>http://www.pythian.com/news/9417/log-buffer-182-a-carnival-of-the-vanities-for-dbas/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 17:01:59 +0000</pubDate>
		<dc:creator>Sheeri K. Cabral</dc:creator>
				<category><![CDATA[DB2]]></category>
		<category><![CDATA[Drizzle]]></category>
		<category><![CDATA[Humor]]></category>
		<category><![CDATA[Log Buffer]]></category>
		<category><![CDATA[M&A]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[Technical Blog]]></category>
		<category><![CDATA[alias]]></category>
		<category><![CDATA[batch]]></category>
		<category><![CDATA[best practice]]></category>
		<category><![CDATA[capacity planning]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[column]]></category>
		<category><![CDATA[column store]]></category>
		<category><![CDATA[column-oriented]]></category>
		<category><![CDATA[confoo]]></category>
		<category><![CDATA[convention]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[dw]]></category>
		<category><![CDATA[e-book]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[etl]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[implicit commit]]></category>
		<category><![CDATA[infinidb]]></category>
		<category><![CDATA[internship]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://www.pythian.com/news/?p=9417</guid>
		<description><![CDATA[This is the 182nd edition of Log Buffer, the weekly review of database blogs.  Make sure to read the whole edition so you do not miss where to submit your SQL limerick!
This week started out with me posting about International Women&#8217;s Day, and has me personally attending Confoo (Montreal) which is an excellent conference I hope to return to next year.  I learned a lot from confoo, especially the blending nosql and sql session I attended.
This week was also the Hotsos Symposium.  Doug&#8217;s Oracle Blog has a series of posts about Hotsos.  If all this talk about conferences has gotten you excited, Joshua Drake notes that 14 days and the hotel is almost full for postgresql conference east which is March 25th-28th in Philadelphia.  And the Oracle database insider notes that the Oracle OpenWorld call for papers is now open.
According to Susan Visser this week (ending tomorrow) is also read an e-book week.  So if you have not already done so, read an e-book!  She links a coupon for an e-book in the post.

Craig Mullins notes that the mainframe is a good career choice in Mainframes: The Safe IT Career Choice.  He notes that the mainframe is still not dead:
People having been predicting the death of the mainframe since the advent of client/server in the late 1980s. That is more than 20 years! Think of all the things that have died in that timespan while the mainframe keeps on chugging away: IBM&#8217;s PC business, Circuit City, Koogle peanut butter, public pay phones, Johnny Cash&#8230; the list is endless.
In other career-related news, Antonio Cangiano is looking for [2] top-notch student hackers for a 16-month internship at IBM in Toronto starting in May.  All the details, including how to apply, are in Cangiano&#8217;s blog post.
Willie Favero wants to know how you &#8220;solve the batch dilemma&#8221; for issues like &#8220;shrinking your batch window, designing your batch to play nicely with &#8230; OLTP&#8221; in how&#8217;s your batch workload doing?  Perhaps Favero should read the updated batch best practices posted by Anthony Shorten.
Bryan Smith surveys a more personal question by asking if you go both ways and &#8220;manage both DB2 for Linux, UNIX, and Windows and DB2 for z/OS&#8221; in don&#8217;t ask, don&#8217;t tell, bi-platform DBAs.  This week&#8217;s Log Buffer editor admits to being a tri-platform DBA &#8212; she has tried many platforms, and in fact, many databases (MySQL, Oracle, DB2, SQL Server, Sybase, Postgres and Ingres)!
Hari Prasanna Srinivasan promotes a patching survey in Oracle really wants to hear from you! Patching Survey.
Henrik Loeser explains what a deadlock and a hot spot are by using a real life analogy taken from a police report in deadlock and hot spot in real life.
Jamie Thomson asks why do you abbreviate schema names?.  Shlomi Noach tries to solve the issue that &#8220;there is no consistent convention as for how to write [about table aliases in] an SQL query&#8221; in proper sql table alias use conventions.  Noach also gives us a tip: faster than truncate.
Leons Petrazickis reminds us that &#8220;rulesets are chains&#8221; and it is important to have your rulesets in the proper order in iptables firewall pitfall.
Anyone interested in the history of MySQL AB will be informed after reading Dries Buytaert&#8217;s article.
Gavin Towey shares his software that helps centrally manage 120 MySQL servers in qsh.pl: distributed query tool  For those who want to learn more about column-oriented databases, particularly in MySQL, Robin Schumacher of the InfiniDB blog announces that there is a MySQL University session recording on MySQL column databases now available.  MySQL join-fu expert Jay Pipes has moved his blog to www.joinfu.com and starts with An SQL Puzzle and of course a follow up on the sql puzzle.
Ivan Zoratti is happy that finally, slides posted for the MySQL DW breakfast.  Venu Anuganti gives you tips on one of the most common MySQL frustrations:  optimizing subqueries in how to improve subqueries derived tables performance.  Justin Swanhart posts the way in which he Gets Linux performance information from your MySQL database without shell access and emulates a &#8216;top&#8217; CPU summary using /proc/stat and MySQL using the same method.
The Oracle Apps blog has an introduction to Oracle user productivity kit (UPK).  Even though in this editor&#8217;s opinion the article is very sales-pitchy, it has valuable information, and does indeed live up to its promise:
UPK is a software tool that can capture all the steps in a system process. It records every keystroke, every click of the mouse, each menu option chosen and each button pressed. All this is done in the UPK Recorder by going through the transaction and pressing “printscreen” after every user action. From this, without any further effort from the developer, UPK builds a number of valuable outputs.
Allen White gives a great tip on how to optimize queries in keep your data clean.
Mike Dietrich reminds you to remove &#8220;old&#8221; parameters and events from your init.ora when upgrading, &#8220;as keeping them will definitely slow down the database performance in the new release.&#8221;  He shows evidence of slowness when this is not done.  Dietrich also shows how you can be gathering workload statistics &#8220;to give the optimizer some good knowledge about how powerful your IO-system might be&#8221;, especially &#8220;a few days after upgrading to the new release&#8230;while a real workload is running.&#8221;
Brian Aker shows the exciting features coming soon in Drizzle in Drizzle, Cherry, Roadmap for our Next Release.
Maybe you are thinking of migrating, not upgrading&#8230;..The O&#8217;Reilly Radar shows how to asses an Oracle to MySQL migration in MySQL migration and risk management.  Actually, that article interviews Ronald Bradford on the subject &#8212; Bradford has been prolific lately, updating free my.cnf advice series and &#8220;Don&#8217;t Assume&#8221;: MySQL for the Oracle DBA series.  Nick Quarmby also talks about migrating Oracle, but not to a new database, just to a new platform, in his primer on migrating Oracle Applications to new platforms.  And the big news comes from Carlos of dataprix that Twitter will migrate from MySQL to Cassandra DB.
Paul S. Randal explains his way of benchmarking: 1 Tb table population on SQL Server.
Pete Finnigan shares his slides from a webinar on how to secure oracle, and Denis Pilipchuk shares his approaches for discovering security vulnerabilities in software applications.
Jeff Davis shares his thoughts about scalability and the relational model.  Robert Treat responds actually, the relational model doesn&#8217;t scale and Baron Schwartz counters with NoSQL doesn&#8217;t mean non-relational.
Buck Woody explains &#8220;whenever you want to know something about SQL Server’s configuration, whether that’s the Instance itself or a database, you have a few options&#8221; &#8212; and of course what those options are &#8212; in system variables, stored procedures or functions for meta data.
This week&#8217;s T-SQL Tuesday topic was I/O.  There are many links to great blog posts in the comments; three random posts I chose to highlight: Michael Zilberstein talks about IO capacity planning, while Kalen Delaney talks about using STATISTICS IO in I/O, you know, and Merrill Aldrich chimes in with information on real world SSD&#8217;s.  Aldrich also begs folks not to waste resources and make more work for developers and DBAs in dear ISV, you&#8217;re keeping me awake nights with your VARCHAR() dates.
And we end with a bit of fin:  Paul Nielsen wants us all to have a bit of fun; he has posted an SQL limerick and asks readers to create there own in there once was in Dublin a query.]]></description>
			<content:encoded><![CDATA[<p>This is the 182nd edition of Log Buffer, the weekly review of database blogs.  Make sure to read the whole edition so you do not miss where to submit your SQL limerick!</p>
<p>This week started out with <a href="http://www.pythian.com/news/author/sheeri/">me</a> posting about <a href="http://www.pythian.com/news/9207/international-womens-day/">International Women&#8217;s Day</a>, and has me personally attending <a href="http://www.confoo.ca">Confoo</a> (Montreal) which is an excellent conference I hope to return to next year.  I learned a lot from confoo, especially the <a href="http://www.pythian.com/news/9387/liveblogging-at-confoo-blending-nosql-and-sql/">blending nosql and sql</a> session I attended.</p>
<p>This week was also the <a href="http://www.hotsos.com/sym10.html">Hotsos Symposium</a>.  <a href="http://oracledoug.com/serendipity/index.php">Doug&#8217;s Oracle Blog</a> has a <a href="http://oracledoug.com/serendipity/index.php?/plugin/tag/hotsos+2010">series of posts about Hotsos</a>.  If all this talk about conferences has gotten you excited, <a href="http://www.commandprompt.com/blogs/joshua_drake/">Joshua Drake</a> notes that <a href="http://www.commandprompt.com/blogs/joshua_drake/2010/03/14_days_and_the_hotel_is_almost_full_for_postgresql_conference_east/">14 days and the hotel is almost full for postgresql conference east</a> which is <a href="http://www.postgresqlconference.org/">March 25th-28th in Philadelphia</a>.  And the <a href="http://blogs.oracle.com/databaseinsider/">Oracle database insider</a> notes that the <a href="http://blogs.oracle.com/databaseinsider/2010/03/oracle_openworld_2010_call_for.html">Oracle OpenWorld call for papers</a> is now open.</p>
<p>According to <a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/SusanVisser/">Susan Visser</a> this week (ending tomorrow) is also <a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/SusanVisser/entry/read_an_e_book_week_march_7_1312?lang=en">read an e-book week</a>.  So if you have not already done so, read an e-book!  She links a coupon for an e-book in the post.<br />
<span></span></p>
<p><a href="http://db2portal.blogspot.com/">Craig Mullins</a> notes that the mainframe is a good career choice in <a href="http://db2portal.blogspot.com/2010/03/mainframes-safe-it-career-choice.html">Mainframes: The Safe IT Career Choice</a>.  He notes that the mainframe is still not dead:</p>
<blockquote><p>People having been predicting the death of the mainframe since the advent of client/server in the late 1980s. That is more than 20 years! Think of all the things that have died in that timespan while the mainframe keeps on chugging away: IBM&#8217;s PC business, Circuit City, Koogle peanut butter, public pay phones, Johnny Cash&#8230; the list is endless.</p></blockquote>
<p>In other career-related news, <a href="http://antoniocangiano.com/">Antonio Cangiano</a> is <a href="http://antoniocangiano.com/2010/03/05/heads-up-ibm-is-looking-for-top-notch-student-hackers/">looking for [2] top-notch student hackers</a> for a 16-month internship at IBM in Toronto starting in May.  All the details, including how to apply, are in Cangiano&#8217;s blog post.</p>
<p><a href="http://it.toolbox.com/blogs/db2zos/">Willie Favero</a> wants to know how you &#8220;solve the batch dilemma&#8221; for issues like &#8220;shrinking your batch window, designing your batch to play nicely with &#8230; OLTP&#8221; in <a href="http://it.toolbox.com/blogs/db2zos/hows-your-batch-workload-doing-37343">how&#8217;s your batch workload doing?</a>  Perhaps Favero should read the <a href="http://blogs.oracle.com/theshortenspot/2010/03/updated_batch_best_practices.html">updated batch best practices</a> posted by <a href="http://blogs.oracle.com/theshortenspot/">Anthony Shorten</a>.</p>
<p><a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/idm/">Bryan Smith</a> surveys a more personal question by asking if you <a href="http://www.urbandictionary.com/products.php?defid=1793756">go both ways</a> and &#8220;manage both DB2 for Linux, UNIX, and Windows and DB2 for z/OS&#8221; in <a href="https://www.ibm.com/developerworks/mydeveloperworks/blogs/idm/entry/don_t_ask_don_t_tell_bi_platform_dbas?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed:+ManagingTheDataLifecycle+(Data+Studio+Team)&amp;lang=en">don&#8217;t ask, don&#8217;t tell, bi-platform DBAs</a>.  This week&#8217;s Log Buffer editor admits to being a tri-platform DBA &#8212; she has tried many platforms, and in fact, many databases (MySQL, Oracle, DB2, SQL Server, Sybase, Postgres and Ingres)!</p>
<p><a href="http://blogs.oracle.com/gridautomation/">Hari Prasanna Srinivasan</a> promotes a patching survey in <a href="http://blogs.oracle.com/gridautomation/2010/03/oracle_really_wants_to_hear_fr.html">Oracle really wants to hear from you! Patching Survey</a>.</p>
<p><a href="http://blog.4loeser.net/">Henrik Loeser</a> explains what a deadlock and a hot spot are by using a real life analogy taken from a police report in <a href="http://blog.4loeser.net/2010/03/deadlock-and-hot-spot-in-real-life.html">deadlock and hot spot in real life</a>.</p>
<p><a href="http://sqlblog.com/blogs/jamie_thomson/">Jamie Thomson</a> asks <a href="http://sqlblog.com/blogs/jamie_thomson/archive/2010/03/08/why-do-you-abbreviate-schema-names.aspx">why do you abbreviate schema names?</a>.  <a href="http://code.openark.org/blog/">Shlomi Noach</a> tries to solve the issue that &#8220;there is no consistent convention as for how to write [about table aliases in] an SQL query&#8221; in <a href="http://code.openark.org/blog/mysql/proper-sql-table-alias-use-conventions">proper sql table alias use conventions</a>.  Noach also gives us a <a href="http://code.openark.org/blog/mysql/tip-faster-than-truncate">tip: faster than truncate</a>.</p>
<p><a href="http://lpetr.org/blog/archives/">Leons Petrazickis</a> reminds us that &#8220;rulesets are chains&#8221; and it is important to have your rulesets in the proper order in <a href="http://lpetr.org/blog/archives/iptables-firewall-pitfall">iptables firewall pitfall</a>.</p>
<p>Anyone interested in <a href="http://buytaert.net/the-history-of-mysql-ab">the history of MySQL AB</a> will be informed after reading <a href="http://buytaert.net/">Dries Buytaert</a>&#8217;s article.<br />
<a href="http://gtowey.blogspot.com/">Gavin Towey</a> shares his software that helps centrally manage 120 MySQL servers in <a href="http://gtowey.blogspot.com/2010/03/qshpl-distributed-query-tool.html">qsh.pl: distributed query tool</a>  For those who want to learn more about column-oriented databases, particularly in MySQL, <a href="http://infinidb.org/infinidb-blog/">Robin Schumacher of the InfiniDB blog</a> announces that there is a <a href="http://infinidb.org/infinidb-blog/mysql-university-session-recording-on-mysql-column-databases-now-available.html">MySQL University session recording on MySQL column databases now available</a>.  MySQL join-fu expert <a href="http://www.joinfu.com/">Jay Pipes</a> has moved his blog to <a href="http://www.joinfu.com">www.joinfu.com</a> and starts with <a href="http://www.joinfu.com/2010/03/a-sql-puzzle/">An SQL Puzzle</a> and of course <a href="http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/">a follow up on the sql puzzle</a>.</p>
<p><a href="http://izoratti.blogspot.com/">Ivan Zoratti</a> is happy that <a href="http://izoratti.blogspot.com/2010/03/finally-slides-posted-for-dw-breakfast.html">finally, slides posted for the MySQL DW breakfast</a>.  <a href="http://venublog.com/">Venu Anuganti</a> gives you tips on one of the most common MySQL frustrations:  optimizing subqueries in <a href="http://venublog.com/2010/03/06/how-to-improve-subqueries-derived-tables-performance/">how to improve subqueries derived tables performance</a>.  <a href="http://swanhart.livejournal.com/">Justin Swanhart</a> posts the way in which he <a href="http://swanhart.livejournal.com/131541.html">Gets Linux performance information from your MySQL database without shell access</a> and <a href="http://swanhart.livejournal.com/131788.html">emulates a &#8216;top&#8217; CPU summary using /proc/stat and MySQL</a> using the same method.</p>
<p>The <a href="http://www.oracleappsblog.com/index.php">Oracle Apps blog</a> has an <a href="http://www.oracleappsblog.com/index.php/weblog/introduction-to-oracle-user-productivity-kit-upk/">introduction to Oracle user productivity kit</a> (UPK).  Even though in this editor&#8217;s opinion the article is very sales-pitchy, it has valuable information, and does indeed live up to its promise:</p>
<blockquote><p>UPK is a software tool that can capture all the steps in a system process. It records every keystroke, every click of the mouse, each menu option chosen and each button pressed. All this is done in the UPK Recorder by going through the transaction and pressing “printscreen” after every user action. From this, without any further effort from the developer, UPK builds a number of valuable outputs.</p></blockquote>
<p><a href="http://sqlblog.com/blogs/allen_white/">Allen White</a> gives a great tip on how to optimize queries in <a href="http://sqlblog.com/blogs/allen_white/archive/2010/03/05/keep-your-data-clean.aspx">keep your data clean</a>.</p>
<p><a href="http://blogs.oracle.com/UPGRADE/">Mike Dietrich</a> reminds you to <a href="http://blogs.oracle.com/UPGRADE/2010/03/remove_old_parameters_and_even.html">remove &#8220;old&#8221; parameters and events from your init.ora</a> when upgrading, &#8220;as keeping them will definitely slow down the database performance in the new release.&#8221;  He shows evidence of slowness when this is not done.  Dietrich also shows how you can be <a href="http://blogs.oracle.com/UPGRADE/2010/03/gathering_workload_statistics.html">gathering workload statistics</a> &#8220;to give the optimizer some good knowledge about how powerful your IO-system might be&#8221;, especially &#8220;a few days after upgrading to the new release&#8230;while a real workload is running.&#8221;</p>
<p><a href="http://krow.livejournal.com/">Brian Aker</a> shows the exciting features coming soon in Drizzle in <a href="http://krow.livejournal.com/686178.html">Drizzle, Cherry, Roadmap for our Next Release</a>.</p>
<p>Maybe you are thinking of migrating, not upgrading&#8230;..<a href="http://radar.oreilly.com/">The O&#8217;Reilly Radar</a> shows how to asses an Oracle to MySQL migration in <a href="http://radar.oreilly.com/2010/03/oracle-to-mysql.html">MySQL migration and risk management</a>.  Actually, that article interviews <a href="http://ronaldbradford.com">Ronald Bradford</a> on the subject &#8212; Bradford has been prolific lately, updating <a href="http://ronaldbradford.com/blog/tag/my-cnf/">free my.cnf advice series</a> and <a href="http://ronaldbradford.com/blog/tag/mysql4oracledba/">&#8220;Don&#8217;t Assume&#8221;: MySQL for the Oracle DBA series</a>.  <a href="http://blogs.oracle.com/stevenChan/">Nick Quarmby</a> also talks about migrating Oracle, but not to a new database, just to a new platform, in his <a href="http://blogs.oracle.com/stevenChan/2010/03/migrating_oracle_applications_to_new_platforms.html">primer on migrating Oracle Applications to new platforms</a>.  And the big news comes from <a href="http://www.dataprix.com/en/blogs/carlos">Carlos of dataprix</a> that <a href="http://www.dataprix.com/en/blogs/carlos/twitter-will-migrate-mysql-cassandra-db">Twitter will migrate from MySQL to Cassandra DB</a>.</p>
<p><a href="http://www.sqlskills.com/BLOGS/PAUL/">Paul S. Randal</a> explains his way of <a href="http://www.sqlskills.com/BLOGS/PAUL/post/Benchmarking-1-TB-table-population-(part-4-network-optimization).aspx">benchmarking: 1 Tb table population</a> on SQL Server.</p>
<p><a href="http://www.petefinnigan.com/weblog/entries/">Pete Finnigan</a> shares his slides from <a href="http://www.petefinnigan.com/weblog/archives/00001314.htm">a webinar on how to secure oracle</a>, and <a href="http://blogs.oracle.com/security/">Denis Pilipchuk</a> shares his <a href="http://blogs.oracle.com/security/2010/03/approaches_for_discovering_sec.html">approaches for discovering security vulnerabilities in software applications</a>.</p>
<p><a href="http://thoughts.j-davis.com/">Jeff Davis</a> shares his thoughts about <a href="http://thoughts.j-davis.com/2010/03/07/scalability-and-the-relational-model/">scalability and the relational model</a>.  <a href="http://www.xzilla.net/">Robert Treat</a> responds <a href="http://www.xzilla.net/blog/2010/Mar/Actually,-the-Relational-Model-doesnt-scale.html">actually, the relational model doesn&#8217;t scale</a> and <a href="http://www.xaprb.com/">Baron Schwartz</a> counters with <a href="http://www.xaprb.com/blog/2010/03/08/nosql-doesnt-mean-non-relational/">NoSQL doesn&#8217;t mean non-relational</a>.</p>
<p><a href="http://sqlblog.com/blogs/buck_woody/">Buck Woody</a> explains &#8220;whenever you want to know something about SQL Server’s configuration, whether that’s the Instance itself or a database, you have a few options&#8221; &#8212; and of course what those options are &#8212; in <a href="http://sqlblog.com/blogs/buck_woody/archive/2010/03/11/system-variables-stored-procedures-or-functions-for-meta-data.aspx">system variables, stored procedures or functions for meta data</a>.</p>
<p>This week&#8217;s <a href="http://www.straightpathsql.com/archives/2010/03/invitation-for-t-sql-tuesday-004-io/">T-SQL Tuesday</a> topic was I/O.  There are many links to great blog posts in the comments; three random posts I chose to highlight: <a href="http://sqlblog.com/blogs/michael_zilberstein/">Michael Zilberstein</a> talks about <a href="http://sqlblog.com/blogs/michael_zilberstein/archive/2010/03/09/23065.aspx">IO capacity planning</a>, while <a href="http://sqlblog.com/blogs/kalen_delaney/">Kalen Delaney</a> talks about using STATISTICS IO in <a href="http://sqlblog.com/blogs/kalen_delaney/archive/2010/03/09/tsql-tuesday-4-io.aspx">I/O, you know</a>, and <a href="http://sqlblog.com/blogs/merrill_aldrich/">Merrill Aldrich</a> chimes in with information on <a href="http://sqlblog.com/blogs/merrill_aldrich/archive/2010/03/08/t-sql-tuesday-004-real-world-ssd-s.aspx">real world SSD&#8217;s</a>.  Aldrich also begs folks not to waste resources and make more work for developers and DBAs in <a href="http://sqlblog.com/blogs/merrill_aldrich/archive/2010/03/11/dear-isv-you-re-keeping-me-awake-nights-with-your-varchar-dates.aspx">dear ISV, you&#8217;re keeping me awake nights with your VARCHAR() dates</a>.</p>
<p>And we end with a bit of fin:  <a href="http://sqlblog.com/blogs/paul_nielsen/">Paul Nielsen</a> wants us all to have a bit of fun; he has posted an SQL limerick and asks readers to create there own in <a href="http://sqlblog.com/blogs/paul_nielsen/archive/2010/03/11/there-once-was-in-dublin-a-query.aspx">there once was in Dublin a query</a>.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23887&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23887&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/9417/log-buffer-182-a-carnival-of-the-vanities-for-dbas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using ext4 for MySQL</title>
		<link>http://ronaldbradford.com/blog/using-ext4-for-mysql-2010-03-12/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-ext4-for-mysql</link>
		<comments>http://ronaldbradford.com/blog/using-ext4-for-mysql-2010-03-12/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 16:51:32 +0000</pubDate>
		<dc:creator>Ronald Bradford</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[disk performance]]></category>
		<category><![CDATA[ext4]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[raid]]></category>

		<guid isPermaLink="false">http://ronaldbradford.com/blog/?p=2623</guid>
		<description><![CDATA[This week with a client I saw ext4 used for the first time on a production MySQL system which was running Ubuntu 9.10 (Karmic Koala).  I observe today while installing 9.10 Server locally that ext4 is the default option.  The ext4 filesystem is described as better performance, reliability and features while there is also information about improvements in journaling.
At OSCON 2009 I attended a presentation on Linux Filesystem Performance for Databases by Selena Deckelmann in which ext4 was included.  While providing some improvements in sequential reading and writing, there were issue with random I/O which is the key for RDBMS products.  
Is the RAID configuration (e.g. RAID 5, RAID 10), strip size, buffer caches, LVM etc more important then upgrading from ext3 to ext4?   I don&#8217;t have access to any test equipment in order to determine myself however I&#8217;d like to know of any experiences from members of the MySQL community and if anybody has experienced any general problems running ext4.
ext4 References

Ext 4 How To on kernel.org
Ext4 on kernelnewbies.org
ext4ext4 overview via wikipedia.org
First benchmarks of the ext4 file system
]]></description>
			<content:encoded><![CDATA[<p>This week with a client I saw ext4 used for the first time on a production MySQL system which was running <a href="http://releases.ubuntu.com/releases/9.10/">Ubuntu 9.10 (Karmic Koala)</a>.  I observe today while installing 9.10 Server locally that ext4 is the default option.  The ext4 filesystem is described as better performance, reliability and features while there is also information about improvements in journaling.</p>
<p>At OSCON 2009 I attended a presentation on <a href="http://www.oscon.com/oscon2009/public/schedule/detail/8432">Linux Filesystem Performance for Databases</a> by <a href="http://twitter.com/Selenamarie">Selena Deckelmann</a> in which ext4 was included.  While providing some improvements in sequential reading and writing, there were issue with random I/O which is the key for RDBMS products.  </p>
<p>Is the RAID configuration (e.g. RAID 5, RAID 10), strip size, buffer caches, LVM etc more important then upgrading from ext3 to ext4?   I don&#8217;t have access to any test equipment in order to determine myself however I&#8217;d like to know of any experiences from members of the MySQL community and if anybody has experienced any general problems running ext4.</p>
<h3>ext4 References</h3>
<ul>
<li><a href="http://ext4.wiki.kernel.org/index.php/Ext4_Howto">Ext 4 How To</a> on kernel.org</li>
<li><a href="http://kernelnewbies.org/Ext4">Ext4</a> on kernelnewbies.org</li>
<li><a href="http://en.wikipedia.org/wiki/Ext4">ext4</a>ext4 overview</a> via wikipedia.org</li>
<li><a href="http://www.linuxinsight.com/first_benchmarks_of_the_ext4_file_system.html">First benchmarks of the ext4 file system</a></li>
</ul><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23889&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23889&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://ronaldbradford.com/blog/using-ext4-for-mysql-2010-03-12/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Art of &quot;What is going on inside of my database?&quot;</title>
		<link>http://krow.livejournal.com/686599.html?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=the-art-of-what-is-going-on-inside-of-my-database</link>
		<comments>http://krow.livejournal.com/686599.html#comments</comments>
		<pubDate>Fri, 12 Mar 2010 16:50:02 +0000</pubDate>
		<dc:creator>Brian Aker</dc:creator>
				<category><![CDATA[Новости]]></category>

		<guid isPermaLink="false">http://krow.livejournal.com/686599.html</guid>
		<description><![CDATA[Yesterday we were having a conversation on IRC about the need for more useful information about the internals of the database."SHOW STATUS" is just too primitive in its design to provide the sort of detailed information you need to do operations. Yesterday we got a bug request over the number of "open tables" found after a particular query. The user had assumed the number was off, but what they hadn't realized was that the number was accurate (in this particular case, MySQL fudges a number on open tables because it can't handle count its derived tables).One of the patches coming into the tree right now fully exposes the contents of the table cache and table definition cache to the user. You can see who holds what locks on what tables, and you can see the actual count on table access per table.

drizzle&#62; select * from TABLE_DEFINITION_CACHE;
+-----------------+------------------------+---------+-------------+----------------+
&#124; TABLE_SCHEMA    &#124; TABLE_NAME             &#124; VERSION &#124; TABLE_COUNT &#124; IS_NAME_LOCKED &#124;
+-----------------+------------------------+---------+-------------+----------------+
&#124; data_dictionary &#124; schema_names           &#124;       1 &#124;           1 &#124; FALSE          &#124;
&#124; data_dictionary &#124; table_definition_cache &#124;       1 &#124;           1 &#124; FALSE          &#124;
&#124; data_dictionary &#124; show_tables            &#124;       1 &#124;           1 &#124; FALSE          &#124;
+-----------------+------------------------+---------+-------------+----------------+
3 rows in set (0 sec)

drizzle&#62; select * from TABLE_CACHE;
+------------+-----------------+------------------------+-----------+----------------+---------+----------------+------+----------------+------------+----------------+
&#124; SESSION_ID &#124; TABLE_SCHEMA    &#124; TABLE_NAME             &#124; ARCHETYPE &#124; ENGINE         &#124; VERSION &#124; IS_NAME_LOCKED &#124; ROWS &#124; AVG_ROW_LENGTH &#124; TABLE_SIZE &#124; AUTO_INCREMENT &#124;
+------------+-----------------+------------------------+-----------+----------------+---------+----------------+------+----------------+------------+----------------+
&#124;          0 &#124; data_dictionary &#124; schema_names           &#124; FUNCTION  &#124; FunctionEngine &#124;       1 &#124; FALSE          &#124;  100 &#124;            260 &#124;          0 &#124;              0 &#124;
&#124;          0 &#124; data_dictionary &#124; show_tables            &#124; FUNCTION  &#124; FunctionEngine &#124;       1 &#124; FALSE          &#124;  100 &#124;            260 &#124;          0 &#124;              0 &#124;
&#124;          1 &#124; data_dictionary &#124; table_cache            &#124; FUNCTION  &#124; FunctionEngine &#124;       1 &#124; FALSE          &#124;  100 &#124;           1113 &#124;          0 &#124;              0 &#124;
&#124;          0 &#124; data_dictionary &#124; table_definition_cache &#124; FUNCTION  &#124; FunctionEngine &#124;       1 &#124; FALSE          &#124;  100 &#124;            559 &#124;          0 &#124;              0 &#124;
+------------+-----------------+------------------------+-----------+----------------+---------+----------------+------+----------------+------------+----------------+
4 rows in set (0 sec)

drizzle&#62; select * from TABLE_DEFINITION_CACHE WHERE TABLE_COUNT &#62; 1;
Empty set (0 sec)

drizzle&#62; select * from TABLE_DEFINITION_CACHE WHERE TABLE_COUNT &#62; 0;
+-----------------+------------------------+---------+-------------+----------------+
&#124; TABLE_SCHEMA    &#124; TABLE_NAME             &#124; VERSION &#124; TABLE_COUNT &#124; IS_NAME_LOCKED &#124;
+-----------------+------------------------+---------+-------------+----------------+
&#124; data_dictionary &#124; schema_names           &#124;       1 &#124;           1 &#124; FALSE          &#124;
&#124; data_dictionary &#124; table_cache            &#124;       1 &#124;           1 &#124; FALSE          &#124;
&#124; data_dictionary &#124; table_definition_cache &#124;       1 &#124;           1 &#124; FALSE          &#124;
&#124; data_dictionary &#124; show_tables            &#124;       1 &#124;           1 &#124; FALSE          &#124;
+-----------------+------------------------+---------+-------------+----------------+
4 rows in set (0 sec)

drizzle&#62; select count(*) from TABLE_DEFINITION_CACHE WHERE TABLE_COUNT  &#62; 0;
+----------+
&#124; count(*) &#124;
+----------+
&#124;        4 &#124;
+----------+
1 row in set (0 sec)

The term "ARCHETYPE" is the base primitive about what sort of table was used. It is more detailed then the ANSI "TABLE_TYPE" that exists in I_S. We still have a debate on what exactly this term should mean. One of the things I enjoy about working on Drizzle? I am not stuck in a room full of people who will spend hours on this sort of bike shed decisions. Version gives you the current definition count for the table. Right now that number is still based on "since opened" but we will soon be storing the metadata for this so you will know how many times in the life of an object it has been changed.We are still working out the details to SHOW TABLE STATUS. Our SHOW commands are just query rewrites to tables.Here is a partial example of the new table that is outputted from a SHOW TABLE STATUS:
+---------+--------+-------------------+-----------
&#124; Session &#124; Schema &#124; Name              &#124; Type
+---------+--------+-------------------+-----------
&#124;       0 &#124; Schema &#124; b                 &#124; STANDARD
&#124;       0 &#124; Schema &#124; show_tables       &#124; FUNCTION
&#124;       1 &#124; Schema &#124; show_table_status &#124; FUNCTION
&#124;       0 &#124; Schema &#124; schema_names      &#124; FUNCTION
&#124;       0 &#124; Schema &#124; dfsdf             &#124; STANDARD
&#124;       1 &#124; Schema &#124; b                 &#124; TEMPORARY
&#124;       1 &#124; Schema &#124; a                 &#124; TEMPORARY
+---------+--------+-------------------+-----------+
7 rows in set (0 sec)

Notice Session? Notice that type can be Temporary?  With our system you can see the current owner of the open table and we now include whatever temporary tables you have in your own session. We have also included a larger table which you can see just your own temporary tables (and most likely I will soon create a table so that you can see all temporary tables open across all sessions). The current "Type" in SHOW TABLE STATUS is an Archetype so we will be changing that so that terms match up across the database. Consistency in design is an awesome thing :)There is a lot more to come!P.S. Just wait until I push the code for tracking locks in Drizzle, I demoed it at SCALE and got a lot of both positive and constructive feedback on it.]]></description>
			<content:encoded><![CDATA[Yesterday we were having a conversation on IRC about the need for more useful information about the internals of the database.<br /><br />"SHOW STATUS" is just too primitive in its design to provide the sort of detailed information you need to do operations. Yesterday we got a bug request over the number of "open tables" found after a particular query. The user had assumed the number was off, but what they hadn't realized was that the number was accurate (in this particular case, MySQL fudges a number on open tables because it can't handle count its derived tables).<br /><br />One of the patches coming into the tree right now fully exposes the contents of the table cache and table definition cache to the user. You can see who holds what locks on what tables, and you can see the actual count on table access per table.<br /><br /><pre>

drizzle&gt; select * from TABLE_DEFINITION_CACHE;
+-----------------+------------------------+---------+-------------+----------------+
| TABLE_SCHEMA    | TABLE_NAME             | VERSION | TABLE_COUNT | IS_NAME_LOCKED |
+-----------------+------------------------+---------+-------------+----------------+
| data_dictionary | schema_names           |       1 |           1 | FALSE          |
| data_dictionary | table_definition_cache |       1 |           1 | FALSE          |
| data_dictionary | show_tables            |       1 |           1 | FALSE          |
+-----------------+------------------------+---------+-------------+----------------+
3 rows in set (0 sec)

drizzle&gt; select * from TABLE_CACHE;
+------------+-----------------+------------------------+-----------+----------------+---------+----------------+------+----------------+------------+----------------+
| SESSION_ID | TABLE_SCHEMA    | TABLE_NAME             | ARCHETYPE | ENGINE         | VERSION | IS_NAME_LOCKED | ROWS | AVG_ROW_LENGTH | TABLE_SIZE | AUTO_INCREMENT |
+------------+-----------------+------------------------+-----------+----------------+---------+----------------+------+----------------+------------+----------------+
|          0 | data_dictionary | schema_names           | FUNCTION  | FunctionEngine |       1 | FALSE          |  100 |            260 |          0 |              0 |
|          0 | data_dictionary | show_tables            | FUNCTION  | FunctionEngine |       1 | FALSE          |  100 |            260 |          0 |              0 |
|          1 | data_dictionary | table_cache            | FUNCTION  | FunctionEngine |       1 | FALSE          |  100 |           1113 |          0 |              0 |
|          0 | data_dictionary | table_definition_cache | FUNCTION  | FunctionEngine |       1 | FALSE          |  100 |            559 |          0 |              0 |
+------------+-----------------+------------------------+-----------+----------------+---------+----------------+------+----------------+------------+----------------+
4 rows in set (0 sec)

drizzle&gt; select * from TABLE_DEFINITION_CACHE WHERE TABLE_COUNT &gt; 1;
Empty set (0 sec)

drizzle&gt; select * from TABLE_DEFINITION_CACHE WHERE TABLE_COUNT &gt; 0;
+-----------------+------------------------+---------+-------------+----------------+
| TABLE_SCHEMA    | TABLE_NAME             | VERSION | TABLE_COUNT | IS_NAME_LOCKED |
+-----------------+------------------------+---------+-------------+----------------+
| data_dictionary | schema_names           |       1 |           1 | FALSE          |
| data_dictionary | table_cache            |       1 |           1 | FALSE          |
| data_dictionary | table_definition_cache |       1 |           1 | FALSE          |
| data_dictionary | show_tables            |       1 |           1 | FALSE          |
+-----------------+------------------------+---------+-------------+----------------+
4 rows in set (0 sec)

drizzle&gt; select count(*) from TABLE_DEFINITION_CACHE WHERE TABLE_COUNT  &gt; 0;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0 sec)

</pre><br /><br /><br /><br />The term "ARCHETYPE" is the base primitive about what sort of table was used. It is more detailed then the ANSI "TABLE_TYPE" that exists in I_S. We still have a debate on what exactly this term should mean. One of the things I enjoy about working on Drizzle? I am not stuck in a room full of people who will spend hours on this sort of <a href="http://bikeshed.com/">bike shed</a> decisions. <br /><br />Version gives you the current definition count for the table. Right now that number is still based on "since opened" but we will soon be storing the metadata for this so you will know how many times in the life of an object it has been changed.<br /><br />We are still working out the details to SHOW TABLE STATUS. Our SHOW commands are just query rewrites to tables.<br /><br />Here is a partial example of the new table that is outputted from a SHOW TABLE STATUS:<br /><br /><pre>
+---------+--------+-------------------+-----------
| Session | Schema | Name              | Type
+---------+--------+-------------------+-----------
|       0 | Schema | b                 | STANDARD
|       0 | Schema | show_tables       | FUNCTION
|       1 | Schema | show_table_status | FUNCTION
|       0 | Schema | schema_names      | FUNCTION
|       0 | Schema | dfsdf             | STANDARD
|       1 | Schema | b                 | TEMPORARY
|       1 | Schema | a                 | TEMPORARY
+---------+--------+-------------------+-----------+
7 rows in set (0 sec)

</pre><br /><br />Notice Session? Notice that type can be Temporary?  With our system you can see the current owner of the open table and we now include whatever temporary tables you have in your own session. We have also included a larger table which you can see just your own temporary tables (and most likely I will soon create a table so that you can see all temporary tables open across all sessions). The current "Type" in SHOW TABLE STATUS is an Archetype so we will be changing that so that terms match up across the database. Consistency in design is an awesome thing :)<br /><br />There is a lot more to come!<br /><br />P.S. Just wait until I push the code for tracking locks in Drizzle, I demoed it at SCALE and got a lot of both positive and constructive feedback on it.<br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23888&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23888&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://krow.livejournal.com/686599.html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>But I DO want MySQL to say “ERROR”!</title>
		<link>http://code.openark.org/blog/mysql/but-i-do-want-mysql-to-say-error?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=but-i-do-want-mysql-to-say-%25e2%2580%259cerror%25e2%2580%259d</link>
		<comments>http://code.openark.org/blog/mysql/but-i-do-want-mysql-to-say-error#comments</comments>
		<pubDate>Fri, 12 Mar 2010 04:53:28 +0000</pubDate>
		<dc:creator>Shlomi Noach</dc:creator>
				<category><![CDATA[Syntax]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[data-types]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql_mode]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=2005</guid>
		<description><![CDATA[MySQL is known for its willingness to accept invalid queries, data values. It can silently commit your transaction, truncate your data.

Using GROUP_CONCAT with a small group_concat_max_len setting? Your result will be silently truncated (make sure to check the warnings though).
Calling CREATE TEMPORARY TABLE? You get silent commit.
Issuing a ROLLBACK on non-transactional involved engines? Have a warning; no error.
Using LOCK IN SHARE MODE on non transactional tables? Not a problem. Nothing reported.
Adding a FOREIGN KEY on a MyISAM table? Good for you; no action actually taken.
Inserting 300 to a TINYINT column in a relaxed sql_mode? Give me 255, I&#8217;ll silently drop the remaining 45. I owe you.

Warnings and errors
It would be nice to:

Have an auto_propagate_warning_to_error server variable (global/session/both) which, well, does what it says.
Have an i_am_really_not_a_dummy server variable which implies stricter checks for all the above and prevents you from doing with anything that may be problematic (or rolls back your transactions on your invalid actions).

Connectors may be nice enough to propagate warnings to errors &#8211; that&#8217;s good. But not enough: since data is already committed in MySQL.
If I understand correctly, and maybe it&#8217;s just a myth, it all relates to the times where MySQL had interest in a widespread adoption across the internet, in such way that it does not interfere too much with the users (hence leading to the common myth that &#8220;MySQL just works out of the box and does not require me to configure or understand anything&#8221;).
MySQL is a database system, and is now widespread, and is used by serious companies and products. It is time to stop play nice to everyone and provide with strict integrity &#8212; or, be nice to everyone, just allow me to specify what &#8220;nice&#8221; means for me.]]></description>
			<content:encoded><![CDATA[<p>MySQL is known for its willingness to accept invalid queries, data values. It can silently commit your transaction, truncate your data.</p>
<ul>
<li>Using <strong>GROUP_CONCAT</strong> with a small <strong>group_concat_max_len</strong> setting? Your result will be silently truncated (make sure to check the warnings though).</li>
<li>Calling <strong>CREATE TEMPORARY TABLE</strong>? You get <a href="http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/">silent commit</a>.</li>
<li>Issuing a <strong>ROLLBACK</strong> on non-transactional involved engines? Have a warning; no error.</li>
<li>Using <strong>LOCK IN SHARE MODE</strong> on non transactional tables? Not a problem. Nothing reported.</li>
<li>Adding a <strong>FOREIGN KEY</strong> on a MyISAM table? Good for you; no action actually taken.</li>
<li>Inserting <strong>300</strong> to a <strong>TINYINT</strong> column in a relaxed <strong>sql_mode</strong>? Give me <strong>255</strong>, I&#8217;ll silently drop the remaining <strong>45</strong>. I owe you.</li>
</ul>
<h4>Warnings and errors</h4>
<p>It would be nice to:<span></span></p>
<ul>
<li>Have an <strong>auto_propagate_warning_to_error</strong> server variable (global/session/both) which, well, does what it says.</li>
<li>Have an <strong>i_am_really_not_a_dummy</strong> server variable which implies stricter checks for all the above and prevents you from doing with <em>anything</em> that may be problematic (or rolls back your transactions on your invalid actions).</li>
</ul>
<p>Connectors may be nice enough to propagate warnings to errors &#8211; that&#8217;s good. But not enough: since data is already committed in MySQL.</p>
<p>If I understand correctly, and maybe it&#8217;s just a myth, it all relates to the times where MySQL had interest in a widespread adoption across the internet, in such way that it does not interfere too much with the users (hence leading to the common myth that &#8220;MySQL just works out of the box and does not require me to configure or understand anything&#8221;).</p>
<p>MySQL is a database system, and is now widespread, and is used by serious companies and products. It is time to stop play nice to everyone and provide with strict integrity &#8212; or, be nice to everyone, just allow me to specify what &#8220;nice&#8221; means for me.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23883&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23883&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/but-i-do-want-mysql-to-say-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Follow Up on the SQL Puzzle</title>
		<link>http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-follow-up-on-the-sql-puzzle</link>
		<comments>http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 22:12:35 +0000</pubDate>
		<dc:creator>Jay Pipes</dc:creator>
				<category><![CDATA[Drizzle]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.joinfu.com/?p=340</guid>
		<description><![CDATA[Or&#8230;What the Heck is Wrong with CREATE TABLE IF NOT EXISTS ... SELECT?
So, earlier this week, I blogged about an SQL puzzle that had come up in my current work on Drizzle&#8217;s new transaction log.
I posed the question to readers what the &#8220;correct&#8221; result of the following would be:

CREATE TABLE t1 &#40;a int, b int&#41;;
INSERT INTO t1 VALUES &#40;1,1&#41;,&#40;1,2&#41;;
CREATE TEMPORARY TABLE t2 &#40;a int, b int, PRIMARY KEY &#40;a&#41;&#41;;
BEGIN;
INSERT INTO t2 VALUES &#40;100,100&#41;;
CREATE TEMPORARY TABLE IF NOT EXISTS t2 &#40;PRIMARY KEY &#40;a&#41;&#41; SELECT * FROM t1;
&#160;
# The above statement will correctly produce an ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
# What should the below result be?
&#160;
SELECT * FROM t2;
COMMIT;

A number of readers responded, and, to be fair, most everyone was &#8220;correct&#8221; in their own way.   Why?  Well, because the way that MySQL deals with calls to CREATE TABLE ... SELECT, CREATE TABLE IF NOT EXISTS ... SELECT and their temporary-table counterparts is completely stupid, as I learned this week.  Rob Wultsch essentially sums up my feelings about the behaviour of DDL statements in regards to transactions in a session:

Implicit commit is evil and stupid. Ideally we the server should error and roll back, imho.

The Officially Correct Answer (at least in MySQL)
OK, so here&#8217;s the &#8220;official&#8221; correct answer:
CREATE TABLE IF NOT EXISTS ... SELECT does not first check for the existence of the table in question.  Instead, if the table in question does exist, CREATE TABLE IF NOT EXISTS ... SELECT behaves like an INSERT INTO ... SELECT statement.  Yep, you heard right.  So, instead of throwing a warning when it notices that the table exists, MySQL instead attempts to insert rows from the SELECT query into the existing table.
Here is the official MySQL explanation:

 For CREATE TABLE &#8230; SELECT, if IF NOT EXISTS is given and the table already exists, MySQL handles the statement as follows:
    * The table definition given in the CREATE TABLE part is ignored. No error occurs, even if the definition does not match that of the existing table.
    * If there is a mismatch between the number of columns in the table and the number of columns produced by the SELECT part, the selected values are assigned to the rightmost columns. For example, if the table contains n columns and the SELECT produces m columns, where m  n), an error occurs.
    * If strict SQL mode is enabled and any of these initial columns do not have an explicit default value, the statement fails with an error.

So, given the above manual explanation, the correct answer to the original blog post is:

  a  &#124;  b
100 &#124; 100

partly because there is an implicit COMMIT directly before the CREATE TABLE is executed (committing the 100,100 record to the table) and the primary key violation kills off the INSERTs of 1,1 in InnoDB.  For a MyISAM table, the 1,1 record would be in the table, since MyISAM has no idea what a ROLLBACK is.
I Think Drizzle Should Follow PostgreSQL&#8217;s Example Here
On implicit commits before DDL operations, I believe they should all go bye-bye.  DDL should be transactional in Drizzle and if a statement cannot be executed in a transaction, it should throw an error if there is an active transaction.  Period.
For behaviour of CREATE TABLE ... SELECT acting like an INSERT INTO ... SELECT, that entire code path should be ripped out.
PostgreSQL&#8217;s DDL operations, IMHO, are sane.  Sane is good.  PostgreSQL allows quite a bit of flexibility by implementing the SQL standard&#8217;s CREATE TABLE and CREATE TABLE AS statements.  I believe Drizzle should scrap all the DDL table-creation code and instead implement PostgreSQL&#8217;s much-nicer DDL methods.  There, I said it.  Slashdot MySQL haters, there ya go.]]></description>
			<content:encoded><![CDATA[<h3>Or&#8230;What the Heck is Wrong with <tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt>?</h3>
<p>So, earlier this week, I <a href="http://joinfu.com/2010/03/a-sql-puzzle">blogged about</a> an SQL puzzle that had come up in my current work on Drizzle&#8217;s new transaction log.</p>
<p>I posed the question to readers what the &#8220;correct&#8221; result of the following would be:</p>

<div><div><pre><span>CREATE</span> <span>TABLE</span> t1 <span>&#40;</span>a int<span>,</span> b int<span>&#41;</span>;
<span>INSERT</span> <span>INTO</span> t1 <span>VALUES</span> <span>&#40;</span><span>1</span><span>,</span><span>1</span><span>&#41;</span><span>,</span><span>&#40;</span><span>1</span><span>,</span><span>2</span><span>&#41;</span>;
<span>CREATE</span> <span>TEMPORARY</span> <span>TABLE</span> t2 <span>&#40;</span>a int<span>,</span> b int<span>,</span> <span>PRIMARY</span> <span>KEY</span> <span>&#40;</span>a<span>&#41;</span><span>&#41;</span>;
BEGIN;
<span>INSERT</span> <span>INTO</span> t2 <span>VALUES</span> <span>&#40;</span><span>100</span><span>,</span><span>100</span><span>&#41;</span>;
<span>CREATE</span> <span>TEMPORARY</span> <span>TABLE</span> <span>IF</span> <span>NOT</span> <span>EXISTS</span> t2 <span>&#40;</span><span>PRIMARY</span> <span>KEY</span> <span>&#40;</span>a<span>&#41;</span><span>&#41;</span> <span>SELECT</span> <span>*</span> <span>FROM</span> t1;
&nbsp;
<span># The above statement will correctly produce an ERROR 23000: Duplicate entry '1' for key 'PRIMARY'</span>
<span># What should the below result be?</span>
&nbsp;
<span>SELECT</span> <span>*</span> <span>FROM</span> t2;
COMMIT;</pre></div></div>

<p>A number of readers responded, and, to be fair, most everyone was &#8220;correct&#8221; in their own way.   Why?  Well, because the way that MySQL deals with calls to <tt>CREATE TABLE ... SELECT</tt>, <tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt> and their temporary-table counterparts is completely stupid, as I learned this week.  Rob Wultsch <a href="http://www.joinfu.com/2010/03/a-sql-puzzle/#comment-214877">essentially sums up</a> my feelings about the behaviour of DDL statements in regards to transactions in a session:</p>
<blockquote><p>
Implicit commit is evil and stupid. Ideally we the server should error and roll back, imho.
</p></blockquote>
<h3>The Officially Correct Answer (at least in MySQL)</h3>
<p>OK, so here&#8217;s the &#8220;official&#8221; correct answer:</p>
<p><tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt> does <em>not</em> first check for the existence of the table in question.  Instead, if the table in question does exist, <tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt> behaves like an <tt>INSERT INTO ... SELECT</tt> statement.  Yep, you heard right.  <strong><em>So, instead of throwing a warning when it notices that the table exists, MySQL instead attempts to insert rows from the <tt>SELECT</tt> query into the existing table</em></strong>.</p>
<p>Here is the official MySQL explanation:</p>
<blockquote><p>
 For CREATE TABLE &#8230; SELECT, if IF NOT EXISTS is given and the table already exists, MySQL handles the statement as follows:<br />
    * The table definition given in the CREATE TABLE part is ignored. No error occurs, even if the definition does not match that of the existing table.<br />
    * If there is a mismatch between the number of columns in the table and the number of columns produced by the SELECT part, the selected values are assigned to the rightmost columns. For example, if the table contains n columns and the SELECT produces m columns, where m < n, the selected values are assigned to the m rightmost columns in the table. Each of the initial n – m columns is assigned its default value, either that specified explicitly in the column definition or the implicit column data type default if the definition contains no default. If the SELECT part produces too many columns (m > n), an error occurs.<br />
    * If strict SQL mode is enabled and any of these initial columns do not have an explicit default value, the statement fails with an error.
</p></blockquote>
<p>So, given the above manual explanation, the correct answer to the original blog post is:</p>
<pre>
  a  |  b
100 | 100
</pre>
<p>partly because there is an implicit COMMIT directly before the CREATE TABLE is executed (committing the 100,100 record to the table) and the primary key violation kills off the INSERTs of 1,1 in InnoDB.  For a MyISAM table, the 1,1 record would be in the table, since MyISAM has no idea what a ROLLBACK is.</p>
<h3>I Think Drizzle Should Follow PostgreSQL&#8217;s Example Here</h3>
<p>On implicit commits before DDL operations, I believe they should all go bye-bye.  DDL should be transactional in Drizzle and if a statement cannot be executed in a transaction, it should throw an error if there is an active transaction.  Period.</p>
<p>For behaviour of <tt>CREATE TABLE ... SELECT</tt> acting like an <tt>INSERT INTO ... SELECT</tt>, that entire code path should be ripped out.</p>
<p>PostgreSQL&#8217;s DDL operations, IMHO, are sane.  Sane is good.  PostgreSQL allows quite a bit of flexibility by implementing the SQL standard&#8217;s <tt><a href="http://www.postgresql.org/docs/current/static/sql-createtable.html">CREATE TABLE</a></tt> and <tt><a href="http://www.postgresql.org/docs/current/static/sql-createtableas.html">CREATE TABLE AS</a></tt> statements.  I believe Drizzle should scrap all the DDL table-creation code and instead implement PostgreSQL&#8217;s much-nicer DDL methods.  There, I said it.  Slashdot MySQL haters, there ya go.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23871&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23871&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Follow Up on the SQL Puzzle</title>
		<link>http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-follow-up-on-the-sql-puzzle</link>
		<comments>http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 22:12:35 +0000</pubDate>
		<dc:creator>Jay Pipes</dc:creator>
				<category><![CDATA[Drizzle]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.joinfu.com/?p=340</guid>
		<description><![CDATA[Or&#8230;What the Heck is Wrong with CREATE TABLE IF NOT EXISTS ... SELECT?
So, earlier this week, I blogged about an SQL puzzle that had come up in my current work on Drizzle&#8217;s new transaction log.
I posed the question to readers what the &#8220;correct&#8221; result of the following would be:

CREATE TABLE t1 &#40;a int, b int&#41;;
INSERT INTO t1 VALUES &#40;1,1&#41;,&#40;1,2&#41;;
CREATE TEMPORARY TABLE t2 &#40;a int, b int, PRIMARY KEY &#40;a&#41;&#41;;
BEGIN;
INSERT INTO t2 VALUES &#40;100,100&#41;;
CREATE TEMPORARY TABLE IF NOT EXISTS t2 &#40;PRIMARY KEY &#40;a&#41;&#41; SELECT * FROM t1;
&#160;
# The above statement will correctly produce an ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
# What should the below result be?
&#160;
SELECT * FROM t2;
COMMIT;

A number of readers responded, and, to be fair, most everyone was &#8220;correct&#8221; in their own way.   Why?  Well, because the way that MySQL deals with calls to CREATE TABLE ... SELECT, CREATE TABLE IF NOT EXISTS ... SELECT and their temporary-table counterparts is completely stupid, as I learned this week.  Rob Wultsch essentially sums up my feelings about the behaviour of DDL statements in regards to transactions in a session:

Implicit commit is evil and stupid. Ideally we the server should error and roll back, imho.

The Officially Correct Answer (at least in MySQL)
OK, so here&#8217;s the &#8220;official&#8221; correct answer:
CREATE TABLE IF NOT EXISTS ... SELECT does not first check for the existence of the table in question.  Instead, if the table in question does exist, CREATE TABLE IF NOT EXISTS ... SELECT behaves like an INSERT INTO ... SELECT statement.  Yep, you heard right.  So, instead of throwing a warning when it notices that the table exists, MySQL instead attempts to insert rows from the SELECT query into the existing table.
Here is the official MySQL explanation:

 For CREATE TABLE &#8230; SELECT, if IF NOT EXISTS is given and the table already exists, MySQL handles the statement as follows:
    * The table definition given in the CREATE TABLE part is ignored. No error occurs, even if the definition does not match that of the existing table.
    * If there is a mismatch between the number of columns in the table and the number of columns produced by the SELECT part, the selected values are assigned to the rightmost columns. For example, if the table contains n columns and the SELECT produces m columns, where m  n), an error occurs.
    * If strict SQL mode is enabled and any of these initial columns do not have an explicit default value, the statement fails with an error.

So, given the above manual explanation, the correct answer to the original blog post is:

  a  &#124;  b
100 &#124; 100

partly because there is an implicit COMMIT directly before the CREATE TABLE is executed (committing the 100,100 record to the table) and the primary key violation kills off the INSERTs of 1,1 in InnoDB.  For a MyISAM table, the 1,1 record would be in the table, since MyISAM has no idea what a ROLLBACK is.
I Think Drizzle Should Follow PostgreSQL&#8217;s Example Here
On implicit commits before DDL operations, I believe they should all go bye-bye.  DDL should be transactional in Drizzle and if a statement cannot be executed in a transaction, it should throw an error if there is an active transaction.  Period.
For behaviour of CREATE TABLE ... SELECT acting like an INSERT INTO ... SELECT, that entire code path should be ripped out.
PostgreSQL&#8217;s DDL operations, IMHO, are sane.  Sane is good.  PostgreSQL allows quite a bit of flexibility by implementing the SQL standard&#8217;s CREATE TABLE and CREATE TABLE AS statements.  I believe Drizzle should scrap all the DDL table-creation code and instead implement PostgreSQL&#8217;s much-nicer DDL methods.  There, I said it.  Slashdot MySQL haters, there ya go.]]></description>
			<content:encoded><![CDATA[<h3>Or&#8230;What the Heck is Wrong with <tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt>?</h3>
<p>So, earlier this week, I <a href="http://joinfu.com/2010/03/a-sql-puzzle">blogged about</a> an SQL puzzle that had come up in my current work on Drizzle&#8217;s new transaction log.</p>
<p>I posed the question to readers what the &#8220;correct&#8221; result of the following would be:</p>

<div><div><pre><span>CREATE</span> <span>TABLE</span> t1 <span>&#40;</span>a int<span>,</span> b int<span>&#41;</span>;
<span>INSERT</span> <span>INTO</span> t1 <span>VALUES</span> <span>&#40;</span><span>1</span><span>,</span><span>1</span><span>&#41;</span><span>,</span><span>&#40;</span><span>1</span><span>,</span><span>2</span><span>&#41;</span>;
<span>CREATE</span> <span>TEMPORARY</span> <span>TABLE</span> t2 <span>&#40;</span>a int<span>,</span> b int<span>,</span> <span>PRIMARY</span> <span>KEY</span> <span>&#40;</span>a<span>&#41;</span><span>&#41;</span>;
BEGIN;
<span>INSERT</span> <span>INTO</span> t2 <span>VALUES</span> <span>&#40;</span><span>100</span><span>,</span><span>100</span><span>&#41;</span>;
<span>CREATE</span> <span>TEMPORARY</span> <span>TABLE</span> <span>IF</span> <span>NOT</span> <span>EXISTS</span> t2 <span>&#40;</span><span>PRIMARY</span> <span>KEY</span> <span>&#40;</span>a<span>&#41;</span><span>&#41;</span> <span>SELECT</span> <span>*</span> <span>FROM</span> t1;
&nbsp;
<span># The above statement will correctly produce an ERROR 23000: Duplicate entry '1' for key 'PRIMARY'</span>
<span># What should the below result be?</span>
&nbsp;
<span>SELECT</span> <span>*</span> <span>FROM</span> t2;
COMMIT;</pre></div></div>

<p>A number of readers responded, and, to be fair, most everyone was &#8220;correct&#8221; in their own way.   Why?  Well, because the way that MySQL deals with calls to <tt>CREATE TABLE ... SELECT</tt>, <tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt> and their temporary-table counterparts is completely stupid, as I learned this week.  Rob Wultsch <a href="http://www.joinfu.com/2010/03/a-sql-puzzle/#comment-214877">essentially sums up</a> my feelings about the behaviour of DDL statements in regards to transactions in a session:</p>
<blockquote><p>
Implicit commit is evil and stupid. Ideally we the server should error and roll back, imho.
</p></blockquote>
<h3>The Officially Correct Answer (at least in MySQL)</h3>
<p>OK, so here&#8217;s the &#8220;official&#8221; correct answer:</p>
<p><tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt> does <em>not</em> first check for the existence of the table in question.  Instead, if the table in question does exist, <tt>CREATE TABLE IF NOT EXISTS ... SELECT</tt> behaves like an <tt>INSERT INTO ... SELECT</tt> statement.  Yep, you heard right.  <strong><em>So, instead of throwing a warning when it notices that the table exists, MySQL instead attempts to insert rows from the <tt>SELECT</tt> query into the existing table</em></strong>.</p>
<p>Here is the official MySQL explanation:</p>
<blockquote><p>
 For CREATE TABLE &#8230; SELECT, if IF NOT EXISTS is given and the table already exists, MySQL handles the statement as follows:<br />
    * The table definition given in the CREATE TABLE part is ignored. No error occurs, even if the definition does not match that of the existing table.<br />
    * If there is a mismatch between the number of columns in the table and the number of columns produced by the SELECT part, the selected values are assigned to the rightmost columns. For example, if the table contains n columns and the SELECT produces m columns, where m < n, the selected values are assigned to the m rightmost columns in the table. Each of the initial n – m columns is assigned its default value, either that specified explicitly in the column definition or the implicit column data type default if the definition contains no default. If the SELECT part produces too many columns (m > n), an error occurs.<br />
    * If strict SQL mode is enabled and any of these initial columns do not have an explicit default value, the statement fails with an error.
</p></blockquote>
<p>So, given the above manual explanation, the correct answer to the original blog post is:</p>
<pre>
  a  |  b
100 | 100
</pre>
<p>partly because there is an implicit COMMIT directly before the CREATE TABLE is executed (committing the 100,100 record to the table) and the primary key violation kills off the INSERTs of 1,1 in InnoDB.  For a MyISAM table, the 1,1 record would be in the table, since MyISAM has no idea what a ROLLBACK is.</p>
<h3>I Think Drizzle Should Follow PostgreSQL&#8217;s Example Here</h3>
<p>On implicit commits before DDL operations, I believe they should all go bye-bye.  DDL should be transactional in Drizzle and if a statement cannot be executed in a transaction, it should throw an error if there is an active transaction.  Period.</p>
<p>For behaviour of <tt>CREATE TABLE ... SELECT</tt> acting like an <tt>INSERT INTO ... SELECT</tt>, that entire code path should be ripped out.</p>
<p>PostgreSQL&#8217;s DDL operations, IMHO, are sane.  Sane is good.  PostgreSQL allows quite a bit of flexibility by implementing the SQL standard&#8217;s <tt><a href="http://www.postgresql.org/docs/current/static/sql-createtable.html">CREATE TABLE</a></tt> and <tt><a href="http://www.postgresql.org/docs/current/static/sql-createtableas.html">CREATE TABLE AS</a></tt> statements.  I believe Drizzle should scrap all the DDL table-creation code and instead implement PostgreSQL&#8217;s much-nicer DDL methods.  There, I said it.  Slashdot MySQL haters, there ya go.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23871&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23871&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://www.joinfu.com/2010/03/a-follow-up-on-the-sql-puzzle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drizzle&#8217;s Data Dictionary and Global Status</title>
		<link>http://ronaldbradford.com/blog/drizzles-data-dictionary-and-global-status-2010-03-11/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=drizzles-data-dictionary-and-global-status</link>
		<comments>http://ronaldbradford.com/blog/drizzles-data-dictionary-and-global-status-2010-03-11/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 21:33:14 +0000</pubDate>
		<dc:creator>Ronald Bradford</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Drizzle]]></category>
		<category><![CDATA[Professional]]></category>
		<category><![CDATA[data dictionary]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://ronaldbradford.com/blog/?p=2617</guid>
		<description><![CDATA[With the recent news by Brian about the Data Dictionary in Drizzle replacing the INFORMATION_SCHEMA, I was looking into the server status variables (aka INFORMATION_SCHEMA.GLOBAL_STATUS) and I came across an interesting discovery.

select * from data_dictionary.global_status;
...
&#124; Table_locks_immediate      &#124; 0              &#124;
&#124; Table_locks_waited         &#124; 0              &#124;
&#124; Threads_connected          &#124; 8134064        &#124;
&#124; Uptime                     &#124; 332            &#124;
&#124; Uptime_since_flush_status  &#124; 332            &#124;
+----------------------------+----------------+
51 rows in set (0 sec)

This only retrieved 51 rows, which is way less then previous.  What I wanted was clearly missing, all the old com_ status variables. Looking at what the data_dictionary actually has available revealed a new table.

drizzle&#62; select * from data_dictionary.global_statements;
+-----------------------+----------------+
&#124; VARIABLE_NAME         &#124; VARIABLE_VALUE &#124;
+-----------------------+----------------+
&#124; admin_commands        &#124; 0              &#124;
&#124; alter_db              &#124; 0              &#124;
&#124; alter_table           &#124; 0              &#124;
&#124; analyze               &#124; 0              &#124;
&#124; begin                 &#124; 0              &#124;
&#124; change_db             &#124; 1              &#124;
&#124; check                 &#124; 0              &#124;
&#124; checksum              &#124; 0              &#124;
&#124; commit                &#124; 0              &#124;
&#124; create_db             &#124; 0              &#124;
&#124; create_index          &#124; 0              &#124;
&#124; create_table          &#124; 0              &#124;
&#124; delete                &#124; 0              &#124;
&#124; drop_db               &#124; 0              &#124;
&#124; drop_index            &#124; 0              &#124;
&#124; drop_table            &#124; 0              &#124;
&#124; empty_query           &#124; 0              &#124;
&#124; flush                 &#124; 0              &#124;
&#124; insert                &#124; 0              &#124;
&#124; insert_select         &#124; 0              &#124;
&#124; kill                  &#124; 0              &#124;
&#124; load                  &#124; 0              &#124;
&#124; release_savepoint     &#124; 0              &#124;
&#124; rename_table          &#124; 0              &#124;
&#124; replace               &#124; 0              &#124;
&#124; replace_select        &#124; 0              &#124;
&#124; rollback              &#124; 0              &#124;
&#124; rollback_to_savepoint &#124; 0              &#124;
&#124; savepoint             &#124; 0              &#124;
&#124; select                &#124; 10             &#124;
&#124; set_option            &#124; 0              &#124;
&#124; show_create_db        &#124; 0              &#124;
&#124; show_create_table     &#124; 0              &#124;
&#124; show_errors           &#124; 0              &#124;
&#124; show_warnings         &#124; 0              &#124;
&#124; truncate              &#124; 0              &#124;
&#124; unlock_tables         &#124; 0              &#124;
&#124; update                &#124; 0              &#124;
+-----------------------+----------------+
38 rows in set (0 sec)

Kudos to this.  Looking at list I saw an obvious omission, of &#8220;ping&#8221;. Something that caught me out some years ago with huge (300-500 per second admin_commands).  I&#8217;m also a fan of Mark&#8217;s recent work An evening hack &#8211; Com_ping in MySQL. ]]></description>
			<content:encoded><![CDATA[<p>With the recent news by Brian about the <a href="http://krow.livejournal.com/685840.html">Data Dictionary</a> in Drizzle replacing the INFORMATION_SCHEMA, I was looking into the server status variables (aka INFORMATION_SCHEMA.GLOBAL_STATUS) and I came across an interesting discovery.</p>
<pre>
select * from data_dictionary.global_status;
...
| Table_locks_immediate      | 0              |
| Table_locks_waited         | 0              |
| Threads_connected          | 8134064        |
| Uptime                     | 332            |
| Uptime_since_flush_status  | 332            |
+----------------------------+----------------+
51 rows in set (0 sec)
</pre>
<p>This only retrieved 51 rows, which is way less then previous.  What I wanted was clearly missing, all the old com_ status variables. Looking at what the data_dictionary actually has available revealed a new table.</p>
<pre>
drizzle> select * from data_dictionary.global_statements;
+-----------------------+----------------+
| VARIABLE_NAME         | VARIABLE_VALUE |
+-----------------------+----------------+
| admin_commands        | 0              |
| alter_db              | 0              |
| alter_table           | 0              |
| analyze               | 0              |
| begin                 | 0              |
| change_db             | 1              |
| check                 | 0              |
| checksum              | 0              |
| commit                | 0              |
| create_db             | 0              |
| create_index          | 0              |
| create_table          | 0              |
| delete                | 0              |
| drop_db               | 0              |
| drop_index            | 0              |
| drop_table            | 0              |
| empty_query           | 0              |
| flush                 | 0              |
| insert                | 0              |
| insert_select         | 0              |
| kill                  | 0              |
| load                  | 0              |
| release_savepoint     | 0              |
| rename_table          | 0              |
| replace               | 0              |
| replace_select        | 0              |
| rollback              | 0              |
| rollback_to_savepoint | 0              |
| savepoint             | 0              |
| select                | 10             |
| set_option            | 0              |
| show_create_db        | 0              |
| show_create_table     | 0              |
| show_errors           | 0              |
| show_warnings         | 0              |
| truncate              | 0              |
| unlock_tables         | 0              |
| update                | 0              |
+-----------------------+----------------+
38 rows in set (0 sec)
</pre>
<p>Kudos to this.  Looking at list I saw an obvious omission, of &#8220;ping&#8221;. Something that caught me out some years ago with huge (300-500 per second admin_commands).  I&#8217;m also a fan of Mark&#8217;s recent work <a href="http://www.markleith.co.uk/?p=327">An evening hack &#8211; Com_ping</a> in MySQL. </p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23870&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23870&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://ronaldbradford.com/blog/drizzles-data-dictionary-and-global-status-2010-03-11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Liveblogging at Confoo: Blending NoSQL and SQL</title>
		<link>http://www.pythian.com/news/9387/liveblogging-at-confoo-blending-nosql-and-sql/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=liveblogging-at-confoo-blending-nosql-and-sql</link>
		<comments>http://www.pythian.com/news/9387/liveblogging-at-confoo-blending-nosql-and-sql/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 16:11:53 +0000</pubDate>
		<dc:creator>Sheeri K. Cabral</dc:creator>
				<category><![CDATA[Group Blog Posts]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Pythian]]></category>
		<category><![CDATA[bigtable]]></category>
		<category><![CDATA[bson]]></category>
		<category><![CDATA[cassandra]]></category>
		<category><![CDATA[column store]]></category>
		<category><![CDATA[column-oriented]]></category>
		<category><![CDATA[confoo]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[datamapper]]></category>
		<category><![CDATA[document database]]></category>
		<category><![CDATA[dynomite]]></category>
		<category><![CDATA[gloo]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[graph database]]></category>
		<category><![CDATA[gridfs]]></category>
		<category><![CDATA[hbase]]></category>
		<category><![CDATA[hypertable]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[key-value]]></category>
		<category><![CDATA[map reduce]]></category>
		<category><![CDATA[memcacheddb]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[neo4j]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[redi]]></category>

		<guid isPermaLink="false">http://www.pythian.com/news/?p=9387</guid>
		<description><![CDATA[Persistence Smoothie:  Blending NoSQL and SQL &#8211; see user feedback and comments at http://joind.in/talk/view/1332.
Michael Bleigh from Intridea, high-end Ruby and Ruby on Rails consultants, build apps from start to finish, making it scalable.   He&#8217;s written a lot of stuff, available at http://github.com/intridea.  @mbleigh on twitter
NoSQL is a new way to think about persistence.  Most NoSQL systems are not ACID compliant (Atomicity, Consistency, Isolation, Durability).
Generally, most NoSQL systems have:

Denormalization
Eventual Consistency
Schema-Free
Horizontal Scale

NoSQL tries to scale (more) simply, it is starting to go mainstream &#8211; NY Times, BBC, SourceForge, Digg, Sony, ShopWiki, Meebo, and more.  But it&#8217;s not *entirely* mainstream, it&#8217;s still hard to sell due to compliance and other reasons.
NoSQL has gotten very popular, lots of blog posts about them, but they reach this hype peak and obviously it can&#8217;t do everything.
&#8220;NoSQL is a (growing) collection of tools, not a new way of life.&#8221;
What is NoSQL?  Can be several things:
Key-Value Stores
Document Databases
Column-oriented data stores
Graph Databases

Key-Value Stores
memcached is a &#8220;big hash in the sky&#8221; &#8211; it is a key value store.  Similarly, NoSQL key-value stores &#8220;add to that big hash in the sky&#8221; and store to disk.
Speaker&#8217;s favorite is Redis because it&#8217;s similar to memcached.
key-value store + datatypes (list, sets, scored sets, soon hashes will be there)
cache-like functions (like expiration)
(Mostly) in-memory

Another interesting key-value store is Riak
Combination of key-value store and document database
heavy into HTTP REST
You can create links between documents, and do &#8220;link walking&#8221; that you don&#8217;t normally get out of a key-value store
built-in Map Reduce

Map Reduce:
Massively parallel way to process large datasets
First you scour data and &#8220;map&#8221; a new set of dataM
Then you &#8220;reduce&#8221; the data down to a salient result &#8212; for example, map reduce function to make a tag cloud:  map function makes an array with a tag name and a count of 1 for each instance of that tag, and the reduce tag goes through that array and counts them&#8230;
http://en.wikipedia.org/wiki/MapReduce

Other key-value stores:
Tokyo Cabinet
Dynomite
memcachedDB
Voldemort

Document Databases
Some say that it&#8217;s the &#8220;closest&#8221; thing to real SQL.
MongoDB &#8211; Document store that speaks BSON (Binary JSON, which is compact).  This is the speaker&#8217;s favorite because it has a rich query syntax that makes it close to SQL.  Can&#8217;t do joins, but can embed objects in other objects, so it&#8217;s a tradeoff
  Also has GridFS that can store large files efficiently, can scale to petabytes of data
  does have MapReduce but it&#8217;s deliberate and you run it every so often.
  
CouchDB
Pure JSON Document Store &#8211; can query directly with nearly pure javascript (there are auth issues) but it&#8217;s an interesting paradigm to be able to run your app almost entirely through javascript.
HTTP REST interface
MapReduce only to see items in CouchDB.  Incremental MapReduce, every time you add or modify a document, it dynamically changes the functions you&#8217;ve written.  You can do really powerful queries as easy as you can do simple queries.  However, some things are really complex, ie, pagination is almost impossible to do.
Intelligent Replication &#8211; CouchDB is designed to work with offline integration.  Could be used instead of SQLite as the HTML5 data store, but you need CouchDB running locally to be doing offline stuff w/CouchDB


Column-oriented store
Columns are stored together (ie, names) instead of rows.  Lets you be schema-less because you don&#8217;t care about a row&#8217;s consistency, you can just add a column to a table very easily.
Cassandra &#8211; Built by Facebook, also used by Twitter
BigTable
Hypertable
HBase

Graph Databases
speaker&#8217;s opinion &#8211; there aren&#8217;t enough of these.
Neo4J &#8211; can handle modeling complex relationships &#8211; &#8220;friends of friends of cousins&#8221; but it requires a license.
When should I use this stuff?
If you have:Use
Complex, slow joins for an &#8220;activity stream&#8221;Denormalize, use a key-value store.
Variable schema, vertical interactionDocument database or column store
Modeling multi-step relationships (linkedin, friends of friends, etc)Graph
Don&#8217;t look for a single tool that does every job.  Use more than one if it&#8217;s appropriate, weigh the tradeoffs (ie, don&#8217;t have 7 different data stores either!)
NoSQL solves real scalability and data design issues.  But financial transactions HAVE to be atomic, so don&#8217;t use NoSQL for those.
A good presentation is http://www.slideshare.net/bscofield/the-state-of-nosql.
Using SQL and NoSQL together
Why?  Well, your data is already in an SQL database (most likely).
You can blend by hand, but the easy way is DataMapper:
Generic, relational ORM (adapters for many SQL dbs and many NoSQL stores)
Implements Identity Map
Module-based inclusion (instead of extending from a class, you just include into a class).
You can set up multiple data targets (default is MySQL, example sets up MongoDB too).
DataMapper is:
Ultimate Polyglot ORM
simple r&#8217;ships btween persistence engines are easy
jack of all, master none
Sometimes perpetuates false assumptions &#8211;
If you&#8217;re in Ruby, your legacy stuff is in ActiveRecord, so you&#8217;re going to have to rewrite your code anyway.

Speaker&#8217;s idea to be less generic and better use of features of each data store &#8211; Gloo &#8211; &#8220;Gloo glues together different ORMs by providing relationship proxies.&#8221;  this software is ALPHA ALPHA ALPHA.  
The goal is to be able to define relationships on the terms of any ORM from any class, ORM or not
Right now &#8211; partially working activeRecord relationships
Is he doing it wrong? Is it a crazy/stupid idea?  Maybe.
Example:
NeedUse
Assume you already have an auth systemit&#8217;s already in SQL, so leave it there.
Need users to be able to purchase items from the storefront &#8211; Can&#8217;t lose transactions, need full ACID complianceuse MySQL.
Social Graph &#8211; want to have activity streams and 1-way and 2-way relationships.  Need speed, but not consistencyuse Redis
Product Listings &#8212; selling moves and books, both have different properties, products are pretty much non-relationaluse MongoDB
He wrote the example in about 3 hours, so integration of multiple data stores can be done quickly and work.]]></description>
			<content:encoded><![CDATA[<p>Persistence Smoothie:  Blending NoSQL and SQL &#8211; see user feedback and comments at <a href="http://joind.in/talk/view/1332">http://joind.in/talk/view/1332</a>.</p>
<p>Michael Bleigh from <a href="http://intridea.com/">Intridea</a>, high-end Ruby and Ruby on Rails consultants, build apps from start to finish, making it scalable.   He&#8217;s written a lot of stuff, available at <a href="http://github.com/intridea">http://github.com/intridea</a>.  @mbleigh on twitter</p>
<p>NoSQL is a new way to think about persistence.  Most NoSQL systems are not ACID compliant (Atomicity, Consistency, Isolation, Durability).</p>
<p>Generally, most NoSQL systems have:<br />
<span></span><br />
<UL><LI>Denormalization<br />
</LI><LI>Eventual Consistency<br />
</LI><LI>Schema-Free<br />
</LI><LI>Horizontal Scale<br />
</LI></UL></p>
<p>NoSQL tries to scale (more) simply, it is starting to go mainstream &#8211; NY Times, BBC, SourceForge, Digg, Sony, ShopWiki, Meebo, and more.  But it&#8217;s not *entirely* mainstream, it&#8217;s still hard to sell due to compliance and other reasons.</p>
<p>NoSQL has gotten very popular, lots of blog posts about them, but they reach this hype peak and obviously it can&#8217;t do everything.</p>
<p>&#8220;NoSQL is a (growing) collection of tools, not a new way of life.&#8221;</p>
<p>What is NoSQL?  Can be several things:<br />
<UL><LI>Key-Value Stores<br />
</LI><LI>Document Databases<br />
</LI><LI>Column-oriented data stores<br />
</LI><LI>Graph Databases<br />
</LI></UL></p>
<p><H2>Key-Value Stores</H2><br />
<a href="http://www.memcached.org">memcached</a> is a &#8220;big hash in the sky&#8221; &#8211; it is a key value store.  Similarly, NoSQL key-value stores &#8220;add to that big hash in the sky&#8221; and store to disk.</p>
<p>Speaker&#8217;s favorite is <a href="http://code.google.com/p/redis/">Redis</a> because it&#8217;s similar to memcached.<br />
<UL><LI>key-value store + datatypes (list, sets, scored sets, soon hashes will be there)<br />
</LI><LI>cache-like functions (like expiration)<br />
</LI><LI>(Mostly) in-memory<br />
</LI></UL></p>
<p>Another interesting key-value store is <a href="http://riak.basho.com">Riak</a><br />
<UL><LI>Combination of key-value store and document database<br />
</LI><LI>heavy into HTTP REST<br />
</LI><LI>You can create links between documents, and do &#8220;link walking&#8221; that you don&#8217;t normally get out of a key-value store<br />
</LI><LI>built-in Map Reduce<br />
</LI></UL></p>
<p><H2>Map Reduce:</H2><br />
<UL><LI>Massively parallel way to process large datasets<br />
</LI><LI>First you scour data and &#8220;map&#8221; a new set of dataM<br />
</LI><LI>Then you &#8220;reduce&#8221; the data down to a salient result &#8212; for example, map reduce function to make a tag cloud:  map function makes an array with a tag name and a count of 1 for each instance of that tag, and the reduce tag goes through that array and counts them&#8230;<br />
</LI><LI><a href="http://en.wikipedia.org/wiki/MapReduce">http://en.wikipedia.org/wiki/MapReduce</a><br />
</LI></UL></p>
<p>Other key-value stores:<br />
<UL><LI><a href="http://1978th.net/tokyocabinet">Tokyo Cabinet</a><br />
</LI><LI><a href="http://github.com/cliffmoon/dynomite">Dynomite</a><br />
</LI><LI><a href="http://memcachedb.org">memcachedDB</a><br />
</LI><LI><a href="http://project-voldemort.com/">Voldemort</a><br />
</LI></UL></p>
<p><H2>Document Databases</H2><br />
Some say that it&#8217;s the &#8220;closest&#8221; thing to real SQL.<br />
<UL><LI><a href="http://www.mongodb.org">MongoDB</a> &#8211; Document store that speaks <a href="http://en.wikipedia.org/wiki/BSON">BSON</a> (Binary JSON, which is compact).  This is the speaker&#8217;s favorite because it has a rich query syntax that makes it close to SQL.  Can&#8217;t do joins, but can embed objects in other objects, so it&#8217;s a tradeoff</LI><br />
  <UL><LI>Also has <a href="http://www.mongodb.org/display/DOCS/GridFS">GridFS</a> that can store large files efficiently, can scale to petabytes of data<br />
  </LI><LI>does have MapReduce but it&#8217;s deliberate and you run it every so often.<br />
  </LI></UL></p>
<p><LI><a href="http://couchdb.apache.org">CouchDB</a><br />
<UL><LI>Pure <a href="http://www.json.org">JSON</a> Document Store &#8211; can query directly with nearly pure javascript (there are auth issues) but it&#8217;s an interesting paradigm to be able to run your app almost entirely through javascript.<br />
</LI><LI>HTTP REST interface<br />
</LI><LI>MapReduce only to see items in CouchDB.  Incremental MapReduce, every time you add or modify a document, it dynamically changes the functions you&#8217;ve written.  You can do really powerful queries as easy as you can do simple queries.  However, some things are really complex, ie, pagination is almost impossible to do.<br />
</LI><LI>Intelligent Replication &#8211; CouchDB is designed to work with offline integration.  Could be used instead of SQLite as the HTML5 data store, but you need CouchDB running locally to be doing offline stuff w/CouchDB<br />
</LI></UL><br />
</UL></p>
<p><H2>Column-oriented store</H2><br />
Columns are stored together (ie, names) instead of rows.  Lets you be schema-less because you don&#8217;t care about a row&#8217;s consistency, you can just add a column to a table very easily.</LI></p>
<p><UL><LI><a href="http://incubator.apache.org/cassandra/">Cassandra</a> &#8211; Built by Facebook, also used by Twitter<br />
</LI><LI><a href="http://en.wikipedia.org/wiki/BigTable">BigTable</a><br />
</LI><LI><a href="http://hypertable.org">Hypertable</a><br />
</LI><LI><a href="http://hadoop.apache.org/hbase/">HBase</a><br />
</LI></UL></p>
<p><H2>Graph Databases</H2><br />
speaker&#8217;s opinion &#8211; there aren&#8217;t enough of these.<br />
<a href="http://neo4j.org">Neo4J</a> &#8211; can handle modeling complex relationships &#8211; &#8220;friends of friends of cousins&#8221; but it requires a license.</p>
<p><H2>When should I use this stuff?</H2><br />
<TABLE><TR><TH>If you have:</TH><TH>Use</TH></TR><br />
<TR><TD>Complex, slow joins for an &#8220;activity stream&#8221;</TD><TD>Denormalize, use a key-value store.</TD></TR><br />
<TR><TD>Variable schema, vertical interaction</TD><TD>Document database or column store</TD></TR><br />
<TR><TD>Modeling multi-step relationships (linkedin, friends of friends, etc)</TD><TD>Graph</TD></TR></TABLE></p>
<p>Don&#8217;t look for a single tool that does every job.  Use more than one if it&#8217;s appropriate, weigh the tradeoffs (ie, don&#8217;t have 7 different data stores either!)</p>
<p>NoSQL solves real scalability and data design issues.  But financial transactions HAVE to be atomic, so don&#8217;t use NoSQL for those.</p>
<p>A good presentation is <a href="http://www.slideshare.net/bscofield/the-state-of-nosql">http://www.slideshare.net/bscofield/the-state-of-nosql</a>.</p>
<p><H2>Using SQL and NoSQL together</H2><br />
Why?  Well, your data is already in an SQL database (most likely).</p>
<p>You can blend by hand, but the easy way is <a href="http://datamapper.org">DataMapper</a>:<br />
Generic, relational ORM (adapters for many SQL dbs and many NoSQL stores)<br />
Implements Identity Map<br />
Module-based inclusion (instead of extending from a class, you just include into a class).</p>
<p>You can set up multiple data targets (default is MySQL, example sets up MongoDB too).<br />
DataMapper is:<br />
<UL><LI>Ultimate Polyglot ORM<br />
</LI><LI>simple r&#8217;ships btween persistence engines are easy<br />
</LI><LI>jack of all, master none<br />
</LI><LI>Sometimes perpetuates false assumptions &#8211;<br />
</LI><LI>If you&#8217;re in Ruby, your legacy stuff is in ActiveRecord, so you&#8217;re going to have to rewrite your code anyway.<br />
</LI></UL></p>
<p>Speaker&#8217;s idea to be less generic and better use of features of each data store &#8211; <a href="http://github.com/intridea/gloo">Gloo</a> &#8211; &#8220;Gloo glues together different ORMs by providing relationship proxies.&#8221;  this software is ALPHA ALPHA ALPHA.  </p>
<p>The goal is to be able to define relationships on the terms of any ORM from any class, ORM or not<br />
Right now &#8211; partially working activeRecord relationships<br />
Is he doing it wrong? Is it a crazy/stupid idea?  Maybe.</p>
<p>Example:<br />
<TABLE><TH>Need</TH><TH>Use</TH></TR><br />
<TR><TD>Assume you already have an auth system</TD><TD>it&#8217;s already in SQL, so leave it there.</TD></TR><br />
<TR><TD>Need users to be able to purchase items from the storefront &#8211; Can&#8217;t lose transactions, need full ACID compliance</TD><TD>use MySQL.</TD></TR><br />
<TR><TD>Social Graph &#8211; want to have activity streams and 1-way and 2-way relationships.  Need speed, but not consistency</TD><TD>use Redis</TD></TR><br />
<TR><TD>Product Listings &#8212; selling moves and books, both have different properties, products are pretty much non-relational</TD><TD>use MongoDB</TD></TR></TABLE></p>
<p>He wrote the example in about 3 hours, so integration of multiple data stores <strong>can</strong> be done quickly and work.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23868&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23868&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/9387/liveblogging-at-confoo-blending-nosql-and-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Liveblogging at Confoo:  [not just] PHP Performance by Rasmus Lerdorf</title>
		<link>http://www.pythian.com/news/9337/liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf</link>
		<comments>http://www.pythian.com/news/9337/liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 14:29:46 +0000</pubDate>
		<dc:creator>Sheeri K. Cabral</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Pythian]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technical Blog]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[callgrind]]></category>
		<category><![CDATA[confoo]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[inclued]]></category>
		<category><![CDATA[opcode cache]]></category>
		<category><![CDATA[pagespeed]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rasmus]]></category>
		<category><![CDATA[siege]]></category>
		<category><![CDATA[strace]]></category>
		<category><![CDATA[twit]]></category>
		<category><![CDATA[valgrind]]></category>
		<category><![CDATA[xdebug]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://www.pythian.com/news/?p=9337</guid>
		<description><![CDATA[Most of this stuff is not PHP specific, and Python or Ruby or Java or .NET developers can use the tools in this talk.
The session on joind.in, with user comments/feedback, is at http://joind.in/talk/view/1320.
Slides are at http://talks.php.net/show/confoo10
&#8220;My name is Rasmus, I&#8217;ve been around for a long time.  I&#8217;ve been doing this web stuff since 1992/1993.&#8221;
&#8220;Generally performance is not a PHP problem.&#8221;  Webservers not config&#8217;d, no expire headers on images, no favicon.  
Tools:  Firefox/Firebug extension called YSlow (developed by yahoo) gives you a grade on your site.

Google has developed the Firefox/Firebug pagespeed tool.
Today Rasmus will pick on wordpress.  He checks out the code, then uses Siege to do a baseline benchmark &#8212; see the slide for the results.
Before you do anything else install an opcode cache like APC.  Wordpress really likes this type of caching, see this slide for the results.  Set the timezone, to make sure conversions aren&#8217;t being done all the time.
Make sure you are cpu-bound, NOT I/O bound.  Otherwise, speed up the I/O.
Then strace your webserver processs.  There are common config issues that you can spot in your strace code.  grep for ENOENT which shows you &#8220;No such file or directory&#8221; errors.  
AllowOverride None to turn off .htaccess for every directory, just read settings once from your config file&#8230;.(unless you&#8217;re an ISP).
Make sure DirectoryIndex is set appropriately, watch your include_path.  All this low-hanging fruit has examples on the common config issues slide.
Install pecl/inclued and generate a graph &#8211; here is the graph image (I have linked it because you really want to zoom in to the graph&#8230;)
In strace output check the open() calls.  Conditional includes, function calls that include files, etc. need runtime context before knowing what to open.  In the example, every request checks to see if we have the config file, once we have config&#8217;d we can get rid of that stuff.  Get rid of all the conditionals and hard-code &#8220;include wp-config.php&#8221;.  Examples are on the slide.
His tips to change:
Conditional config include in wp-load.php (as just mentioned)
Conditional did-header check in wp-blog-header.php
Don&#8217;t call require_wp_db() from wp-settings.php
Remove conditional require logic from wp_start_object_cache
Then check strace again, now all Rasmus sees is theming and translations, which he decided to keep, because that&#8217;s the good benefit of Wordpress &#8211; Performance is all about costs vs. flexibility.  You don&#8217;t want to get rid of all of your flexibility, but you want to be fast.
Set error_reporting(-1) in wp-settings.php to catch all warnings &#8212; warnings slow you down, so get rid of all errors.  PHP error handling is very slow, so getting rid of errors will make you faster.
The slide of warnings that wordpress throws.
Look at all C-level calls made, using callgrind, which sits under valgrind, a CPU emulator used for debugging.  See the image of what callgrind shows.
Now dive into the PHP executor, by installing XDebug.
Check xhprof &#8211; Facebook open sourced this about a year ago, it&#8217;s a PECL extension.  The output is pretty cool, try it on your own site, Rasmus does show you how to use it.  It shows you functions sorted by the most expensive to the least expensive.
For example, use $_SERVER[REQUEST_TIME] instead of time().  Use pconnect() if MySQL can handle the amount of webserver connections that will be persistent, etc.
After you have changed a lot of the stuff above, benchmark again with siege to see how much faster you are.  In this case there is not much gained so far.
So keep going&#8230;.the blogroll is very slow &#8212; Rasmus gets rid of it by commenting out in the sidebar.php file.  I&#8217;d like to see something to make it &#8220;semi-dynamic&#8221; &#8212; that is, make it a static file that can be re-generated, since you might want the blogroll but links are not changed every second&#8230;..
At this point we&#8217;re out of low-hanging fruit.
HipHop is a PHP to C++ converter &#38; compiler, including a threaded, event-driven server that replaces apache.  Rasmus&#8217; slide says &#8220;Wordpress is well-suited for HipHop because it doesn&#8217;t have a lot of dynamic runtime code. This is using the standard Wordpress-svn checkout with a few tweaks.&#8221; 
Then, of course, benchmark again.  
The first time you compile Wordpress with HipHop, you give it a list of files to add to the binary, it will complain about php code that generate file names, so you do have to fix that kind of stuff.  There&#8217;s a huge mess of errors the first time you run it (&#8221;pages and pages&#8221;), and Rasmus had to patch HipHop (and Wordpress) but the changes in HipHop have been put back into HipHop, so you should be good for the most part.
Check out the errors, lots of them show logical errors like $foo.&#8221;bar&#8221; instead of $foo.=&#8221;bar&#8221; and $foo=&#8221;bar&#8221; instead of $foo==&#8221;bar&#8221; in an if statement.  Which of course is nice for your own code, to find those logical errors.
(Wordpress takes in a $user_ID argument and immediately initializes a global $user_ID variable, which overwrites the argument passed in, so you can change the name of the argument passed in&#8230;.)
You can also get rid of some code, things that check for existence of the same thing more than once.  So it will take a bit of tweaking, but it&#8217;s worth it.
There are limitations to HipHop, for example:
It doesn&#8217;t support any of the new PHP 5.3 language features
Private properties don&#8217;t really exist under HipHop. They are treated as if they are protected instead.
You can&#8217;t unset variables. unset will clear the variable, but it will still be in the symbol table.
eval and create_function are limited
Variable variables $$var are not supported
Dynamic defines won&#8217;t work: define($name,$value)
get_loaded_extensions(), get_extension_funcs(), phpinfo(), debug_backtrace() don&#8217;t work
Conditional and dynamically created include filenames don&#8217;t work as you might expect
Default unix-domain socket filename isn&#8217;t set for MySQL so connecting to localhost doesn&#8217;t work
and HipHop does not support all extensions &#8212; see the list Rasmus has of extensions HipHop supports.
Then Rasmus showed an example using Twit (which he wrote) including the benchmarks.  He shows that you can see what&#8217;s going on, like 5 MySQL calls on the home page and what happens when you don&#8217;t have a favicon.ico (in yellow).
In summary, &#8220;performance is all about architecture&#8221;, &#8220;know your costs&#8221;.
Be careful, because some tools (like valgrind and xdebug) you don&#8217;t want to put it on production systems, you could capture production traffic and replay it on a dev/testing box, but &#8220;you just have to minimize the differences and do your best&#8221;.]]></description>
			<content:encoded><![CDATA[<p>Most of this stuff is not PHP specific, and Python or Ruby or Java or .NET developers can use the tools in this talk.</p>
<p>The session on <a href="http://joind.in/">joind.in</a>, with user comments/feedback, is at <a href="http://joind.in/talk/view/1320">http://joind.in/talk/view/1320</a>.</p>
<p>Slides are at <a href="http://talks.php.net/show/confoo10">http://talks.php.net/show/confoo10</a></p>
<p>&#8220;My name is Rasmus, I&#8217;ve been around for a long time.  I&#8217;ve been doing this web stuff since 1992/1993.&#8221;</p>
<p>&#8220;Generally performance is not a PHP problem.&#8221;  Webservers not config&#8217;d, no expire headers on images, no favicon.  </p>
<p>Tools:  Firefox/Firebug extension called <a href="http://developer.yahoo.com/yslow/">YSlow</a> (developed by yahoo) gives you a grade on your site.<br />
<span></span><br />
<a href="http://www.google.com">Google</a> has developed the Firefox/Firebug <a href="http://code.google.com/speed/page-speed/">pagespeed</a> tool.</p>
<p>Today Rasmus will pick on <a href="http://www.wordpress.com">wordpress</a>.  He checks out the code, then uses <a href="http://www.joedog.org/JoeDog/Siege">Siege</a> to do a baseline benchmark &#8212; see <a href="http://talks.php.net/show/confoo10/3">the slide</a> for the results.</p>
<p>Before you do anything else install an opcode cache like <a href="http://pecl.php.new/APC">APC</a>.  Wordpress really likes this type of caching, see <a href="http://talks.php.net/show/confoo10/4">this slide</a> for the results.  Set the timezone, to make sure conversions aren&#8217;t being done all the time.</p>
<p>Make sure you are cpu-bound, NOT I/O bound.  Otherwise, speed up the I/O.</p>
<p>Then strace your webserver processs.  There are <a href="http://talks.php.net/show/confoo10/5">common config issues</a> that you can spot in your strace code.  grep for ENOENT which shows you &#8220;No such file or directory&#8221; errors.  </p>
<p>AllowOverride None to turn off .htaccess for every directory, just read settings once from your config file&#8230;.(unless you&#8217;re an ISP).</p>
<p>Make sure DirectoryIndex is set appropriately, watch your include_path.  All this low-hanging fruit has examples on the <a href="http://talks.php.net/show/confoo10/5">common config issues</a> slide.</p>
<p><a href="http://talks.php.net/show/confoo10/6">Install pecl/inclued and generate a graph</a> &#8211; here is the <a href="http://talks.php.net/presentations/slides/intro/wp_inclued1.png">graph image</a> (I have linked it because you really want to zoom in to the graph&#8230;)</p>
<p>In strace output check the open() calls.  Conditional includes, function calls that include files, etc. need runtime context before knowing what to open.  In the example, every request checks to see if we have the config file, once we have config&#8217;d we can get rid of that stuff.  Get rid of all the conditionals and hard-code &#8220;include wp-config.php&#8221;.  Examples are on <a href="http://talks.php.net/show/confoo10/7">the slide</a>.</p>
<p>His tips to change:<br />
Conditional config include in wp-load.php (as just mentioned)<br />
Conditional did-header check in wp-blog-header.php<br />
Don&#8217;t call require_wp_db() from wp-settings.php<br />
Remove conditional require logic from wp_start_object_cache</p>
<p>Then check strace again, now all Rasmus sees is theming and translations, which he decided to keep, because that&#8217;s the good benefit of Wordpress &#8211; Performance is all about costs vs. flexibility.  You don&#8217;t want to get rid of all of your flexibility, but you want to be fast.</p>
<p>Set error_reporting(-1) in wp-settings.php to catch all warnings &#8212; warnings slow you down, so get rid of all errors.  PHP error handling is very slow, so getting rid of errors will make you faster.</p>
<p><a href="http://talks.php.net/show/confoo10/8">The slide of warnings that wordpress throws</a>.</p>
<p>Look at all C-level calls made, using <a href="http://valgrind.org/info/tools.html#callgrind">callgrind</a>, which sits under <a href="http://valgrind.org/">valgrind</a>, a CPU emulator used for debugging.  See the <a href="http://talks.php.net/presentations/slides/intro/wp_cg.png">image</a> of what callgrind shows.</p>
<p>Now dive into the PHP executor, by installing <a href="http://xdebug.org/">XDebug</a>.</p>
<p>Check <a href="http://developers.facebook.com/xhprof/">xhprof</a> &#8211; <a href="http://www.facebook.com">Facebook</a> open sourced this about a year ago, it&#8217;s a PECL extension.  The output is pretty cool, try it on your own site, Rasmus does <a href="http://talks.php.net/show/confoo10/11">show you how to use it</a>.  It shows you functions sorted by the most expensive to the least expensive.</p>
<p>For example, use $_SERVER[REQUEST_TIME] instead of time().  Use pconnect() if MySQL can handle the amount of webserver connections that will be persistent, etc.</p>
<p>After you have changed a lot of the stuff above, benchmark again with siege to see how much faster you are.  In this case there <a href="http://talks.php.net/show/confoo10/12">is not much gained so far</a>.</p>
<p>So keep going&#8230;.the blogroll is very slow &#8212; Rasmus gets rid of it by commenting out in the sidebar.php file.  I&#8217;d like to see something to make it &#8220;semi-dynamic&#8221; &#8212; that is, make it a static file that can be re-generated, since you might want the blogroll but links are not changed every second&#8230;..</p>
<p>At this point we&#8217;re out of low-hanging fruit.</p>
<p><a href="http://wiki.github.com/facebook/hiphop-php/">HipHop</a> is a PHP to C++ converter &#038; compiler, including a threaded, event-driven server that replaces apache.  Rasmus&#8217; slide says &#8220;Wordpress is well-suited for HipHop because it doesn&#8217;t have a lot of dynamic runtime code. This is using the standard Wordpress-svn checkout with a few tweaks.&#8221; </p>
<p>Then, of course, benchmark again.  </p>
<p>The first time you compile Wordpress with HipHop, you give it a list of files to add to the binary, it will complain about php code that generate file names, so you do have to fix that kind of stuff.  There&#8217;s a huge mess of errors the first time you run it (&#8221;pages and pages&#8221;), and Rasmus had to patch HipHop (and Wordpress) but the changes in HipHop have been put back into HipHop, so you should be good for the most part.</p>
<p>Check out the errors, lots of them show logical errors like $foo.&#8221;bar&#8221; instead of $foo.=&#8221;bar&#8221; and $foo=&#8221;bar&#8221; instead of $foo==&#8221;bar&#8221; in an if statement.  Which of course is nice for your own code, to find those logical errors.</p>
<p>(Wordpress takes in a $user_ID argument and immediately initializes a global $user_ID variable, which overwrites the argument passed in, so you can change the name of the argument passed in&#8230;.)</p>
<p>You can also get rid of some code, things that check for existence of the same thing more than once.  So it will take a bit of tweaking, but it&#8217;s worth it.</p>
<p>There are <a href="http://talks.php.net/show/confoo10/15">limitations to HipHop</a>, for example:<br />
<UL><LI>It doesn&#8217;t support any of the new PHP 5.3 language features<br />
</LI><LI>Private properties don&#8217;t really exist under HipHop. They are treated as if they are protected instead.<br />
</LI><LI>You can&#8217;t unset variables. unset will clear the variable, but it will still be in the symbol table.<br />
</LI><LI>eval and create_function are limited<br />
</LI><LI>Variable variables $$var are not supported<br />
</LI><LI>Dynamic defines won&#8217;t work: define($name,$value)<br />
</LI><LI>get_loaded_extensions(), get_extension_funcs(), phpinfo(), debug_backtrace() don&#8217;t work<br />
</LI><LI>Conditional and dynamically created include filenames don&#8217;t work as you might expect<br />
</LI><LI>Default unix-domain socket filename isn&#8217;t set for MySQL so connecting to localhost doesn&#8217;t work</LI></UL></p>
<p>and HipHop does not support all extensions &#8212; see the list Rasmus has of <a href="http://talks.php.net/show/confoo10/15">extensions HipHop supports</a>.</p>
<p>Then Rasmus showed <a href="http://talks.php.net/show/confoo10/16">an example using Twit</a> (which he wrote) including the <a href="http://talks.php.net/show/confoo10/17">benchmarks</a>.  He shows that you can see what&#8217;s going on, like <a href="http://talks.php.net/show/confoo10/18">5 MySQL calls on the home page and what happens when you don&#8217;t have a favicon.ico</a> (in yellow).</p>
<p>In summary, &#8220;performance is all about architecture&#8221;, &#8220;know your costs&#8221;.</p>
<p>Be careful, because some tools (like valgrind and xdebug) you don&#8217;t want to put it on production systems, you could capture production traffic and replay it on a dev/testing box, but &#8220;you just have to minimize the differences and do your best&#8221;.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23866&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23866&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/9337/liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Liveblogging at Confoo:  [not just] PHP Performance by Rasmus Lerdorf</title>
		<link>http://www.pythian.com/news/9337/liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf</link>
		<comments>http://www.pythian.com/news/9337/liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 14:29:46 +0000</pubDate>
		<dc:creator>Sheeri K. Cabral</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Pythian]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Technical Blog]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[callgrind]]></category>
		<category><![CDATA[confoo]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[inclued]]></category>
		<category><![CDATA[opcode cache]]></category>
		<category><![CDATA[pagespeed]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rasmus]]></category>
		<category><![CDATA[siege]]></category>
		<category><![CDATA[strace]]></category>
		<category><![CDATA[twit]]></category>
		<category><![CDATA[valgrind]]></category>
		<category><![CDATA[xdebug]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://www.pythian.com/news/?p=9337</guid>
		<description><![CDATA[Most of this stuff is not PHP specific, and Python or Ruby or Java or .NET developers can use the tools in this talk.
The session on joind.in, with user comments/feedback, is at http://joind.in/talk/view/1320.
Slides are at http://talks.php.net/show/confoo10
&#8220;My name is Rasmus, I&#8217;ve been around for a long time.  I&#8217;ve been doing this web stuff since 1992/1993.&#8221;
&#8220;Generally performance is not a PHP problem.&#8221;  Webservers not config&#8217;d, no expire headers on images, no favicon.  
Tools:  Firefox/Firebug extension called YSlow (developed by yahoo) gives you a grade on your site.

Google has developed the Firefox/Firebug pagespeed tool.
Today Rasmus will pick on wordpress.  He checks out the code, then uses Siege to do a baseline benchmark &#8212; see the slide for the results.
Before you do anything else install an opcode cache like APC.  Wordpress really likes this type of caching, see this slide for the results.  Set the timezone, to make sure conversions aren&#8217;t being done all the time.
Make sure you are cpu-bound, NOT I/O bound.  Otherwise, speed up the I/O.
Then strace your webserver processs.  There are common config issues that you can spot in your strace code.  grep for ENOENT which shows you &#8220;No such file or directory&#8221; errors.  
AllowOverride None to turn off .htaccess for every directory, just read settings once from your config file&#8230;.(unless you&#8217;re an ISP).
Make sure DirectoryIndex is set appropriately, watch your include_path.  All this low-hanging fruit has examples on the common config issues slide.
Install pecl/inclued and generate a graph &#8211; here is the graph image (I have linked it because you really want to zoom in to the graph&#8230;)
In strace output check the open() calls.  Conditional includes, function calls that include files, etc. need runtime context before knowing what to open.  In the example, every request checks to see if we have the config file, once we have config&#8217;d we can get rid of that stuff.  Get rid of all the conditionals and hard-code &#8220;include wp-config.php&#8221;.  Examples are on the slide.
His tips to change:
Conditional config include in wp-load.php (as just mentioned)
Conditional did-header check in wp-blog-header.php
Don&#8217;t call require_wp_db() from wp-settings.php
Remove conditional require logic from wp_start_object_cache
Then check strace again, now all Rasmus sees is theming and translations, which he decided to keep, because that&#8217;s the good benefit of Wordpress &#8211; Performance is all about costs vs. flexibility.  You don&#8217;t want to get rid of all of your flexibility, but you want to be fast.
Set error_reporting(-1) in wp-settings.php to catch all warnings &#8212; warnings slow you down, so get rid of all errors.  PHP error handling is very slow, so getting rid of errors will make you faster.
The slide of warnings that wordpress throws.
Look at all C-level calls made, using callgrind, which sits under valgrind, a CPU emulator used for debugging.  See the image of what callgrind shows.
Now dive into the PHP executor, by installing XDebug.
Check xhprof &#8211; Facebook open sourced this about a year ago, it&#8217;s a PECL extension.  The output is pretty cool, try it on your own site, Rasmus does show you how to use it.  It shows you functions sorted by the most expensive to the least expensive.
For example, use $_SERVER[REQUEST_TIME] instead of time().  Use pconnect() if MySQL can handle the amount of webserver connections that will be persistent, etc.
After you have changed a lot of the stuff above, benchmark again with siege to see how much faster you are.  In this case there is not much gained so far.
So keep going&#8230;.the blogroll is very slow &#8212; Rasmus gets rid of it by commenting out in the sidebar.php file.  I&#8217;d like to see something to make it &#8220;semi-dynamic&#8221; &#8212; that is, make it a static file that can be re-generated, since you might want the blogroll but links are not changed every second&#8230;..
At this point we&#8217;re out of low-hanging fruit.
HipHop is a PHP to C++ converter &#38; compiler, including a threaded, event-driven server that replaces apache.  Rasmus&#8217; slide says &#8220;Wordpress is well-suited for HipHop because it doesn&#8217;t have a lot of dynamic runtime code. This is using the standard Wordpress-svn checkout with a few tweaks.&#8221; 
Then, of course, benchmark again.  
The first time you compile Wordpress with HipHop, you give it a list of files to add to the binary, it will complain about php code that generate file names, so you do have to fix that kind of stuff.  There&#8217;s a huge mess of errors the first time you run it (&#8221;pages and pages&#8221;), and Rasmus had to patch HipHop (and Wordpress) but the changes in HipHop have been put back into HipHop, so you should be good for the most part.
Check out the errors, lots of them show logical errors like $foo.&#8221;bar&#8221; instead of $foo.=&#8221;bar&#8221; and $foo=&#8221;bar&#8221; instead of $foo==&#8221;bar&#8221; in an if statement.  Which of course is nice for your own code, to find those logical errors.
(Wordpress takes in a $user_ID argument and immediately initializes a global $user_ID variable, which overwrites the argument passed in, so you can change the name of the argument passed in&#8230;.)
You can also get rid of some code, things that check for existence of the same thing more than once.  So it will take a bit of tweaking, but it&#8217;s worth it.
There are limitations to HipHop, for example:
It doesn&#8217;t support any of the new PHP 5.3 language features
Private properties don&#8217;t really exist under HipHop. They are treated as if they are protected instead.
You can&#8217;t unset variables. unset will clear the variable, but it will still be in the symbol table.
eval and create_function are limited
Variable variables $$var are not supported
Dynamic defines won&#8217;t work: define($name,$value)
get_loaded_extensions(), get_extension_funcs(), phpinfo(), debug_backtrace() don&#8217;t work
Conditional and dynamically created include filenames don&#8217;t work as you might expect
Default unix-domain socket filename isn&#8217;t set for MySQL so connecting to localhost doesn&#8217;t work
and HipHop does not support all extensions &#8212; see the list Rasmus has of extensions HipHop supports.
Then Rasmus showed an example using Twit (which he wrote) including the benchmarks.  He shows that you can see what&#8217;s going on, like 5 MySQL calls on the home page and what happens when you don&#8217;t have a favicon.ico (in yellow).
In summary, &#8220;performance is all about architecture&#8221;, &#8220;know your costs&#8221;.
Be careful, because some tools (like valgrind and xdebug) you don&#8217;t want to put it on production systems, you could capture production traffic and replay it on a dev/testing box, but &#8220;you just have to minimize the differences and do your best&#8221;.]]></description>
			<content:encoded><![CDATA[<p>Most of this stuff is not PHP specific, and Python or Ruby or Java or .NET developers can use the tools in this talk.</p>
<p>The session on <a href="http://joind.in/">joind.in</a>, with user comments/feedback, is at <a href="http://joind.in/talk/view/1320">http://joind.in/talk/view/1320</a>.</p>
<p>Slides are at <a href="http://talks.php.net/show/confoo10">http://talks.php.net/show/confoo10</a></p>
<p>&#8220;My name is Rasmus, I&#8217;ve been around for a long time.  I&#8217;ve been doing this web stuff since 1992/1993.&#8221;</p>
<p>&#8220;Generally performance is not a PHP problem.&#8221;  Webservers not config&#8217;d, no expire headers on images, no favicon.  </p>
<p>Tools:  Firefox/Firebug extension called <a href="http://developer.yahoo.com/yslow/">YSlow</a> (developed by yahoo) gives you a grade on your site.<br />
<span></span><br />
<a href="http://www.google.com">Google</a> has developed the Firefox/Firebug <a href="http://code.google.com/speed/page-speed/">pagespeed</a> tool.</p>
<p>Today Rasmus will pick on <a href="http://www.wordpress.com">wordpress</a>.  He checks out the code, then uses <a href="http://www.joedog.org/JoeDog/Siege">Siege</a> to do a baseline benchmark &#8212; see <a href="http://talks.php.net/show/confoo10/3">the slide</a> for the results.</p>
<p>Before you do anything else install an opcode cache like <a href="http://pecl.php.new/APC">APC</a>.  Wordpress really likes this type of caching, see <a href="http://talks.php.net/show/confoo10/4">this slide</a> for the results.  Set the timezone, to make sure conversions aren&#8217;t being done all the time.</p>
<p>Make sure you are cpu-bound, NOT I/O bound.  Otherwise, speed up the I/O.</p>
<p>Then strace your webserver processs.  There are <a href="http://talks.php.net/show/confoo10/5">common config issues</a> that you can spot in your strace code.  grep for ENOENT which shows you &#8220;No such file or directory&#8221; errors.  </p>
<p>AllowOverride None to turn off .htaccess for every directory, just read settings once from your config file&#8230;.(unless you&#8217;re an ISP).</p>
<p>Make sure DirectoryIndex is set appropriately, watch your include_path.  All this low-hanging fruit has examples on the <a href="http://talks.php.net/show/confoo10/5">common config issues</a> slide.</p>
<p><a href="http://talks.php.net/show/confoo10/6">Install pecl/inclued and generate a graph</a> &#8211; here is the <a href="http://talks.php.net/presentations/slides/intro/wp_inclued1.png">graph image</a> (I have linked it because you really want to zoom in to the graph&#8230;)</p>
<p>In strace output check the open() calls.  Conditional includes, function calls that include files, etc. need runtime context before knowing what to open.  In the example, every request checks to see if we have the config file, once we have config&#8217;d we can get rid of that stuff.  Get rid of all the conditionals and hard-code &#8220;include wp-config.php&#8221;.  Examples are on <a href="http://talks.php.net/show/confoo10/7">the slide</a>.</p>
<p>His tips to change:<br />
Conditional config include in wp-load.php (as just mentioned)<br />
Conditional did-header check in wp-blog-header.php<br />
Don&#8217;t call require_wp_db() from wp-settings.php<br />
Remove conditional require logic from wp_start_object_cache</p>
<p>Then check strace again, now all Rasmus sees is theming and translations, which he decided to keep, because that&#8217;s the good benefit of Wordpress &#8211; Performance is all about costs vs. flexibility.  You don&#8217;t want to get rid of all of your flexibility, but you want to be fast.</p>
<p>Set error_reporting(-1) in wp-settings.php to catch all warnings &#8212; warnings slow you down, so get rid of all errors.  PHP error handling is very slow, so getting rid of errors will make you faster.</p>
<p><a href="http://talks.php.net/show/confoo10/8">The slide of warnings that wordpress throws</a>.</p>
<p>Look at all C-level calls made, using <a href="http://valgrind.org/info/tools.html#callgrind">callgrind</a>, which sits under <a href="http://valgrind.org/">valgrind</a>, a CPU emulator used for debugging.  See the <a href="http://talks.php.net/presentations/slides/intro/wp_cg.png">image</a> of what callgrind shows.</p>
<p>Now dive into the PHP executor, by installing <a href="http://xdebug.org/">XDebug</a>.</p>
<p>Check <a href="http://developers.facebook.com/xhprof/">xhprof</a> &#8211; <a href="http://www.facebook.com">Facebook</a> open sourced this about a year ago, it&#8217;s a PECL extension.  The output is pretty cool, try it on your own site, Rasmus does <a href="http://talks.php.net/show/confoo10/11">show you how to use it</a>.  It shows you functions sorted by the most expensive to the least expensive.</p>
<p>For example, use $_SERVER[REQUEST_TIME] instead of time().  Use pconnect() if MySQL can handle the amount of webserver connections that will be persistent, etc.</p>
<p>After you have changed a lot of the stuff above, benchmark again with siege to see how much faster you are.  In this case there <a href="http://talks.php.net/show/confoo10/12">is not much gained so far</a>.</p>
<p>So keep going&#8230;.the blogroll is very slow &#8212; Rasmus gets rid of it by commenting out in the sidebar.php file.  I&#8217;d like to see something to make it &#8220;semi-dynamic&#8221; &#8212; that is, make it a static file that can be re-generated, since you might want the blogroll but links are not changed every second&#8230;..</p>
<p>At this point we&#8217;re out of low-hanging fruit.</p>
<p><a href="http://wiki.github.com/facebook/hiphop-php/">HipHop</a> is a PHP to C++ converter &#038; compiler, including a threaded, event-driven server that replaces apache.  Rasmus&#8217; slide says &#8220;Wordpress is well-suited for HipHop because it doesn&#8217;t have a lot of dynamic runtime code. This is using the standard Wordpress-svn checkout with a few tweaks.&#8221; </p>
<p>Then, of course, benchmark again.  </p>
<p>The first time you compile Wordpress with HipHop, you give it a list of files to add to the binary, it will complain about php code that generate file names, so you do have to fix that kind of stuff.  There&#8217;s a huge mess of errors the first time you run it (&#8221;pages and pages&#8221;), and Rasmus had to patch HipHop (and Wordpress) but the changes in HipHop have been put back into HipHop, so you should be good for the most part.</p>
<p>Check out the errors, lots of them show logical errors like $foo.&#8221;bar&#8221; instead of $foo.=&#8221;bar&#8221; and $foo=&#8221;bar&#8221; instead of $foo==&#8221;bar&#8221; in an if statement.  Which of course is nice for your own code, to find those logical errors.</p>
<p>(Wordpress takes in a $user_ID argument and immediately initializes a global $user_ID variable, which overwrites the argument passed in, so you can change the name of the argument passed in&#8230;.)</p>
<p>You can also get rid of some code, things that check for existence of the same thing more than once.  So it will take a bit of tweaking, but it&#8217;s worth it.</p>
<p>There are <a href="http://talks.php.net/show/confoo10/15">limitations to HipHop</a>, for example:<br />
<UL><LI>It doesn&#8217;t support any of the new PHP 5.3 language features<br />
</LI><LI>Private properties don&#8217;t really exist under HipHop. They are treated as if they are protected instead.<br />
</LI><LI>You can&#8217;t unset variables. unset will clear the variable, but it will still be in the symbol table.<br />
</LI><LI>eval and create_function are limited<br />
</LI><LI>Variable variables $$var are not supported<br />
</LI><LI>Dynamic defines won&#8217;t work: define($name,$value)<br />
</LI><LI>get_loaded_extensions(), get_extension_funcs(), phpinfo(), debug_backtrace() don&#8217;t work<br />
</LI><LI>Conditional and dynamically created include filenames don&#8217;t work as you might expect<br />
</LI><LI>Default unix-domain socket filename isn&#8217;t set for MySQL so connecting to localhost doesn&#8217;t work</LI></UL></p>
<p>and HipHop does not support all extensions &#8212; see the list Rasmus has of <a href="http://talks.php.net/show/confoo10/15">extensions HipHop supports</a>.</p>
<p>Then Rasmus showed <a href="http://talks.php.net/show/confoo10/16">an example using Twit</a> (which he wrote) including the <a href="http://talks.php.net/show/confoo10/17">benchmarks</a>.  He shows that you can see what&#8217;s going on, like <a href="http://talks.php.net/show/confoo10/18">5 MySQL calls on the home page and what happens when you don&#8217;t have a favicon.ico</a> (in yellow).</p>
<p>In summary, &#8220;performance is all about architecture&#8221;, &#8220;know your costs&#8221;.</p>
<p>Be careful, because some tools (like valgrind and xdebug) you don&#8217;t want to put it on production systems, you could capture production traffic and replay it on a dev/testing box, but &#8220;you just have to minimize the differences and do your best&#8221;.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23866&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=23866&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://www.pythian.com/news/9337/liveblogging-at-confoo-not-just-php-performance-by-rasmus-lerdorf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 15.660 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2010-03-12 23:27:03 -->
<!-- Compression = gzip -->