May 31, 2008

Tools to use for MySQL Performance Review

Posted by peter |

There are some tools we commonly use doing performance review and optimization and we often ask each other where that particular stuff is located on the web or what is exactly name of the command what does that.

Initially I thought creating internal Percona Wiki page, but thought there is no reason this information should not be public instead.

So now you can find our favorite MySQL Performance Review Tools on the site.

This is just list of tools which came from the top of my head and I’m sure it is far from complete. We will extend it and we would like to hear your suggestions on what else we should add to it.

In this list we focused on Open Source tools which are helpful for “in time” performance audit – for example you see no graphing software in this list or any commercial offerings.

Is DNS the Achilles heel in your MySQL installation?

Posted by Baron Schwartz |

Do you have skip_name_resolve set in your /etc/my.cnf? If not, consider it. DNS works fine, until it doesn’t. Don’t let it catch you off guard.

Do you really need to restrict MySQL users based on hostnames? If you don’t, you should probably disable this feature of MySQL’s authentication system. You never know when your hosting provider’s DNS (or your own for that matter) will go into the toilet. And when that happens, MySQL mysteriously stops letting users log in, and all kinds of chaos ensues. Worse, it can be kind of hard to know that this is the problem, and diagnosing adds to your downtime.

[read more...]

May 28, 2008

Should you name indexes while doing ALTER TABLE ?

Posted by peter |

MySQL Server does not require you to specify name of the index if you’re running ALTER TABLE statement – it is optional. Though what might be good practical reasons to specify the key name or omit ?

Things what you should be looking at is how MySQL names indexes automatically as well as what maintaining the indexes.
[read more...]

May 26, 2008

Can MySQL temporary tables be made safe for statement-based replication?

Posted by Baron Schwartz |

A while ago I wrote about how to make MySQL replication reliable, part of which is to eliminate temporary tables. The idea is this: if a slave is stopped (or crashed) while a temporary table is open and is then restarted, the temporary table doesn’t exist anymore, and the slave will have problems trying to replay any further statements that refer to these tables. Thus, I claimed, there’s no alternative but to eliminate temporary tables. This problem may not exist for row-based replication in MySQL 5.1 and later, but most installations I know of are using statement-based replication, even on MySQL 5.1

This is a contentious topic. People love their temporary tables and will ask hopefully “are you sure this isn’t safe?” They’ll propose all sorts of ways to mitigate the danger, and I’ve heard many of them. But I recently heard an angle on this I had not heard before.

[read more...]

May 24, 2008

INFORMATION_SCHEMA tables in the InnoDB pluggable storage engine

Posted by Baron Schwartz |

Much has been written about the new InnoDB pluggable storage engine, which Innobase released at the MySQL conference last month. We've written posts ourselves about its fast index creation capabilities and the compressed row format, and how that affects performance. One of the nice things they added in this InnoDB release is INFORMATION_SCHEMA tables that show some status information about InnoDB. Here are the tables:

SQL:
  1. mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB%';
  2. +----------------------------------------+
  3. | Tables_in_INFORMATION_SCHEMA (INNODB%) |
  4. +----------------------------------------+
  5. | INNODB_CMP                             |
  6. | INNODB_CMP_RESET                       |
  7. | INNODB_CMPMEM                          |
  8. | INNODB_CMPMEM_RESET                    |
  9. | INNODB_LOCK_WAITS                      |
  10. | INNODB_LOCKS                           |
  11. | INNODB_TRX                             |
  12. +----------------------------------------+

The _CMP tables show statistics about compression; they contain a lot of useful information about compression, decompression, memory management, fragmentation etc. Beware that selecting from the tables whose names contain RESET has a side effect: it resets the statistics back to 0.

There are also locks and transactions tables. A while ago, the InnoDB developers contacted me to ask my opinion about what would be useful to put in the INFORMATION_SCHEMA. I told them the single biggest thing I could not get from InnoDB at the time was visibility into which transactions are blocking others when there are lock waits. It appears that they agreed this was important to add. (I subsequently discovered that it is possible to find out more information on InnoDB locks even in the older versions of InnoDB, but it's not really easy.)

These tables are fully documented in the InnoDB plugin manual, along with extensive examples of how to use them to find out what is blocking what and so on. Note that the InnoDB plugin manual is being maintained on www.innodb.com, not as part of the regular MySQL manual.

Using flow control functions for performance monitoring queries

Posted by peter |

I'm not big fan on flow control functions like IF or CASE used in MySQL Queries as they are often abused used to create queries which are poorly readable as well as can hardly be optimized well by MySQL Optimizer.

One way I find IF statement very useful is computing multiple aggregates over different set of rows in the single query sweep.
[read more...]

May 20, 2008

Apache PHP MySQL and Runaway Scripts

Posted by peter |

Sometimes due to programming error or due to very complex query you can get your PHP script running too long, well after user stopped waiting for the page to render and went browsing other sites.
Looking at Server-Status I've seen scripts executing for hours sometimes which is obviously the problem - they take Apache Slot, MySQL Connection and other resources.

I had discussion today who was thinking Apache would kill the script after "Timeout" specified in Apache configuration is reached - this was not my experience so I decided to run couple of tests to check it.

I wrote couple of very simple scripts which demonstrate different behavior for scripts running very long time. For simplicity I did not use MySQL, but other system call - sleep() which has similar behavior for sake of experiment:

[read more...]

Dangerous command

Posted by Vadim |

Remembering that I did RENAME DATABASE in MySQL 5.1.21 and found it useful I tried it with 5.1.24 (I was playing with 20GB InnoDB database, so dumping is not fastest way) and all my tries finished with "Syntax error".
So RTMF and documentation says
"This statement was added in MySQL 5.1.7 but was found to be dangerous and was removed in MySQL 5.1.23."

For me term 'dangerous' is interesting there , as I'd expect really dangerous is DROP DATABASE (which I hope will not be removed in next release) , and RENAME DATABASE is supposed to be kind of safe - just replaces old name to new one.

I guess there are some related bugs - and there are:
Bug#28360: RENAME DATABASE destroys routines
Bug#17565: RENAME DATABASE destroys events
so basically RENAME DATABASE destroyed all events and routines related to database.

And solution of bug is:

Removed the
RENAME DATABASE db1 TO db2
statement.

So it seems MySQL took an interesting practice to get GA released as soon as possible - just remove features that does not work instead of fix it.
The similar was with FEDERATED storage engine, which was disabled by default in 5.1.23 binaries, in contrast to previous version (but should be enabled again in 5.1.24).

That probably helps to get 'Zero P1 bugs reported'

May 18, 2008

Wanted: Better memory profiling for MySQL

Posted by peter |

Quite frequently I would log in to customers system and find MySQL using too much memory. I would look at memory consumed by Innodb (it is often higher than innodb_buffer_pool_size) substract memory used by other global buffers such as query_cache_size and key_buffer and will in many cases see some mysterous memory which I can't really explain. It can be several Gigabytes accounting for over 50% of memory usage of MySQL in some cases, though typically it is much smaller fraction.
[read more...]

May 14, 2008

Concurrent inserts on MyISAM and the binary log

Posted by Baron Schwartz |

Recently I had an interesting surprise with concurrent inserts into a MyISAM table. The inserts were not happening concurrently with SELECT statements; they were blocking and the process list was filling up with queries in Locked status.

My first thought was that the customer had deleted from the table, which leaves "holes" in the middle of it and prevents concurrent inserts. (You can configure the server to permit concurrent inserts even when there are holes, but it's disabled by default.) However, that turned out not to be the cause; the table was only inserted into (and selected from). Instead, the blocked statements were because of INSERT... SELECT statements that were running against the table, selecting data from it and inserting into another table.

Let's look at what happens here: suppose you have two tables tbl1 and tbl2 and concurrent inserts into tbl2 are running fine. If you now run the following query,

SQL:
  1. INSERT INTO tbl1 SELECT * FROM tbl2

The concurrent inserts into tbl2 can block. This happens if you have the binary log enabled. If you think about it, this makes sense and is correct behavior. The statements have to be serialized for the binary log; otherwise replaying the binary log can result in a different order of execution.

The MySQL manual actually says this, but not in the clearest way. It just says

If you are using the binary log, concurrent inserts are converted to normal inserts for CREATE ... SELECT or INSERT ... SELECT statements.

If you use mysqladmin debug, you'll see an ordinary SELECT gets a lock on the table like this:

CODE:
  1. Locked - read         Low priority read lock

But on INSERT...SELECT, you'll see this:

CODE:
  1. Read lock  without concurrent inserts

That read lock is what's blocking the concurrent inserts from happening.

There's no solution to this, if you need the binary log enabled. (It needs to be enabled for replication.) There are workarounds, though. You can use the old trick of SELECT INTO OUTFILE followed by LOAD DATA INFILE. You can use InnoDB instead. Or you can do something more elaborate and application-specific, but that's a topic for another post.