Stop the madness: SHOW STATUS

Are you a MySQL user? Have you tried 5.0? Did you notice that SHOW STATUS was giving you strange results?

Here’s the skinny: The SHOW STATUS command, which has been in MySQL, well forever, has had a long-standing feature request; to have the ability to report its metrics per-session. That functionality was added in MySQL 5.0, in the form of two new syntaxes: SHOW SESSION STATUS and SHOW GLOBAL STATUS to give the per-session and server-wide statistics, respectively. It’s great, and I’m happy to see it.

The problem comes in because of the default behaviour that was chosen for the basic SHOW STATUS with no SESSION or GLOBAL keyword—that is, the command that every MySQL DBA has been using for years—now defaults to per-session statistics.

Every tool, program, monitoring script, performance graph, etc., that uses SHOW STATUS (which is pretty much all of them) is broken in 5.0. Why? Well, for no reason, in my opinion. There is absolutely no advantage to defaulting to per-session statistics instead of the old standard of global statistics.

If you’re upset about this, add your comment to MySQL Bug #19093 and fight the good fight with me.

DHL: Clueless?

I recently signed up with Vonage, since it seems pretty cool. They sent me the VoIP adapter via DHL, who picked it up on Thursday, April 6th. It was sent 2nd day delivery, which means it should have been delivered on Monday, April 10th. Did I get it? Nope!

All through yesterday, April 10th, the DHL website claimed:

Est. Delivery Date: 4/10/2006

Today, Tuesday, April 11th, I figured I’d give them a call to see what’s up, and when I should expect to really receive the package, since the site still claims that the estimated delivery date is yesterday, which doesn’t inspire much confidence. The conversation went something like this:

DHL: Thanks for calling DHL, what can I help you with?
Me: I was sent a package which was supposed to be delivered yesterday, but I haven’t received it. I tracked the package on your website, and it still claims an estimated delivery date of yesterday, which can’t be right.
DHL: OK, can you give me the tracking number?
Me: OK, (reads tracking number)
DHL: Well, we have a lot of packages and not all of them go out every day etc. etc. … your package is here at the sorting facility, it hasn’t gone out today.
Me: Uh, well, it was sent 2nd day delivery, the 2nd day was yesterday. Should I at least expect to receive it today?
DHL: Well, I can’t really tell you that. I don’t know if it will go out today, it’s still here… I don’t know if you’ll get it today.
Me: Don’t you have some sort of service guarantee, or the shipping is free?
DHL: Uh, uh, I don’t know, you’d have to talk to billing about that, I don’t know anything about that…

What the hell? You are DHL. Your only real business is moving other people’s stuff around. How is this considered customer service?

Gmail on Sony Ericsson W600i

I managed to get Gmail‘s POP3 and SMTP support (via SSL/TLS, which they require) working on my spiffy new Sony Ericsson W600i, but not without a bit of headache.

After setting everything up, using their provided information, the W600i was complaining about not trusting the SSL certificates that Gmail uses, and would refuse to send mail because of it (although it would still receive mail, after asking you to acknowledge a stern warning). In order to get it working I needed to install two certificates on my phone:

In order to get the phone to accept and install them, you have to use OBEX Object Push (aka “Send File…” under the Bluetooth menu in Mac OS X) to send the .cer files to the phone. The “Send File…” client will complain that your the device doesn’t accept the file type you are sending it; choose the “Send Anyway” option, it works fine. If you just transfer the files as regular files, you will see them on the phone, but will have no option (that I could find) to install them.

The phone is rockin’ now!

I’ve provided the above information here, because figuring out which certificates I needed, where to get them, and how to install them is like pulling teeth. I got each tiny bit of information from various different places. Hopefully this page will index well and help others. :)

Oops, BLOB/TEXT overrides tmp_table_size

First, a bit of background information… MySQL has a variable called tmp_table_size which is used whenever a temporary table is needed for many types of operations, but it’s mainly used for ORDER BY and GROUP BY. The tmp_table_size variable (in correlation with the max_heap_table_size variable) decide at what point to convert an in-memory (that is, HEAP storage engine) temporary table to an on-disk (that is, MyISAM) one.

So, if the result of your query will end up greater than the lesser of tmp_table_size or max_heap_table_size, once it reaches that point, it will be automatically converted to a MyISAM table, on-disk (in tmpdir, incidentally).

Here’s a scenario: You have a SELECT query, nothing particularly special. It isn’t any more complex than another query on the same tables, but it performs a bit worse. You put some load on it, and it performs miserably, even putting the server in pain in the process. You check what’s happening… hmm, lots of blocks being written? Why would there be any blocks written, this is a SELECT!

Does the SELECT have a BLOB or TEXT column in it? Are you using a GROUP BY or ORDER BY that can’t use the same index that MySQL is choosing? (Check EXPLAIN for Using temporary or Using filesort.)

In that case, MySQL will need to create a temporary table to do the sort. Since your query contains a BLOB or TEXT column, the temporary table will have to be created as a MyISAM table, as the HEAP storage engine doesn’t support BLOB or TEXT (or even VARCHAR, for that matter, which is changed to CHAR automatically).

This will mean a lot of extra writes to the disk, for no good reason. What can you do about it?

Short term, for 4.1+: Abuse a subquery in the FROM to read the primary key of the table with the BLOB/TEXT and do the sorting that is necessary. In the outer query, select the full row, with BLOB/TEXT and return it, but don’t use ORDER BY.

Long term: Support for BLOB and TEXT need to be added to the HEAP storage engine.

What if you need to ORDER BY or GROUP BY the BLOB or TEXT column? Well, you’re screwed. Think about redesigning your database. :) (Hint: Add a column containing the first up to 255 bytes of the column as a VARCHAR and sort on that instead…)

Good luck!

Tips: Hacking MySQL Server

Hacking the latest storage engine? Working on a fancy new SHOW command? Hunting for a bug in mysqld? This is for you!

Once you’ve got MySQL compiled, how do you test your mysqld binary? You’ll need to get it started. Stop! Don’t make install it!

  1. Set up your sandbox
    $ mkdir ~/t
    $ vi ~/t/my.cnf
    

    Add the following to ~/t/my.cnf (modify to taste):

    [mysqld]
    basedir=.
    datadir=/Users/jcole/t 
    port=3307
    socket=/Users/jcole/t/mysql.sock
    skip-grant
    skip-innodb
    skip-bdb
    
    [client]
    port=3307
    socket=/Users/jcole/t/mysql.sock
    
  2. Build your source
  3. Set up a symlink for share/mysql pointing to the share directory.
    $ mkdir share && ln -s ../sql/share share/mysql
    

    This, combined with the basedir=. in my.cnf means that MySQL will be able to find its error message and character set files, so that the release you’re building doesn’t have to match the release installed on the system.

  4. Start mysqld
    $ sql/mysqld --defaults-file=~/t/my.cnf
    
  5. Start a mysql client (in another window)
    $ client/mysql --defaults-file=~/t/my.cnf
    
  6. Shutdown the mysqld (if it didn’t crash :) )
    $ client/mysqladmin --defaults-file=~/t/my.cnf shutdown
    

That’s it! Much easier, safer, and faster than using make install, and you don’t need to remember all the options to specify to start and test your newly built mysqld! If you manage to break your sandbox, just delete everything except my.cnf and you are back to a clean slate.