MySQL tries to be smart and to cram as much performance out of
available hardware, and one thing that most MySQLers knows is
that opening a table (ie. opening the frm file, and depending on
the storage engine, any additional files related to the table) is
expensive from a performance point of view. When we see the
opened_tables status variable increasing, we tend to
increase the table_open_cache setting and keep as many
tables as possible open and avoid reopening them.
When it comes to MyISAM though, this has a nasty side-effect.
When the server crashes and there are MyISAM tables open, these
might well need to be REPAIRed. And if you have big MyISAM
tables, this is an issue. Let's say that your application use
several MyISAM tables, with the same content, and that you create
new tables after a certain time, to keep the size of each
individual table down? There are other reasons why you have this
effect also, say a large …
The other day at PSCE I worked on a customer case of what turned out to be a problem with poor data locality or a data fragmentation problem if you will. I tought that it would make a good article as it was a great demonstration of how badly it can affect MySQL performance. And while the post is mostly around MyISAM tables, the problem is not really specific to any particular storage engine, it can affect a database that runs on InnoDB in a very similar way.
The problem
MyISAM lacks support for clustering keys or even anything remotely similar. Its data file format allows new information to be written anywhere inside a table. Anywhere can be either at the end of a file where it can be simply appended or an empty space somewhere in the middle left after previously deleted row(s). This implies no particular order in which rows are stored unless there are absolutely no …
[Read more]
A short while after I fixed the legacy bug that prevented
temporary MyISAM tables from using the dynamic record format, I
got an email from Davi Arnaut @ Twitter. It turned out that
Twitter needed to fix the very same problem, but for the case
when INFORMATION_SCHEMA temporary tables use MyISAM.
In short, INFORMATION_SCHEMA tables provide access to database
metadata. Despite their name, they are more like views than
tables: when you query them, relevant data is gathered from the
dictionary and other server internals, not from tables. The
gathered data is stored in a temporary table (memory or MyISAM
depending on size) and then returned to the user.
The reason Davi emailed me was to let me know that he had further
improved the fix for temporary MyISAM tables to also enable the
use of dynamic record format for …
There are a few ways to implement counters. Even though it’s not a complex feature, often I see people having problems around it. This post describes how bad implementation can impact both application and MySQL performance and how to improve it.
A customer asked me for help with performance problem they were facing. I logged into their database and found many client connections waiting for table locks. Almost all threads were stuck on one, small table called hits. What was the reason?
The problem was related to the way they developed a very simple system for counting page views they later used in some reporting. The table structure was:
mysql> SHOW CREATE TABLE hits\G *************************** 1. row *************************** Table: hits Create Table: CREATE TABLE `hits` ( `cnt` int(11) NOT NULL ) ENGINE=MyISAM mysql> SELECT * FROM hits; +---------+ | cnt | +---------+ | 3823273 | +---------+
…
[Read more]
Last summer my colleague Marko Mäkelä committed this seemingly
innocent performance fix for InnoDB in MySQL 5.6:
3581 Marko Makela 2011-08-10
Bug#12835650 VARCHAR maximum length performance impact
row_sel_field_store_in_mysql_format(): Do not pad the unused part
of
the buffer reserved for a True VARCHAR column (introduced in
5.0.3).
Add Valgrind instrumentation ensuring that the unused part will
be
flagged uninitialized.
Before this, buffers which were used to send VARCHARs from InnoDB
to the MySQL server were padded with 0s if the string was shorter
than specified by the column. If, e.g., the string "foo" was
stored in a VARCHAR(8), InnoDB used to write "3foo00000" to the
buffer (the first character - 3 - determines the actual length of
the string). However, even though these trailing bytes are not
used anywhere, writing 0s to the buffer certainly has a cost.
Hence …
Issues addressed:
- Support complex and efficient indexes at 100+ million rows.
- Predicable and consistent performance regardless of data size growth.
- Fast recovery.
Ensuring Predictable Performance at Scale
The Company: FictionPress operates both FictionPress.com and FanFiction.net and is home to over 6 million works of fiction, with millions of writers/readers participating from around the world in over 30 languages
The Challenge: FictionPress offers a number of interactive features to its large user base. These …
[Read more]MySQL Tuning
This is another section that is broader than one would first imagine. There’s a reason that many large organizations employ dedicated database administrators. That said, this doesn’t prevent the average sysadmin from making some changes to enhance performance on their database.
The easiest way to start on this is to utilize a script to automatically check your configuration options and make suggestions based on status variables MySQL sets. I’ve had good luck with a script called mysqltuner.pl. You can visit the project page at GitHub here: …
[Read more]
For MyISAM one of the most important variables is the Key
Buffer. The Key Buffer is sometimes called the Key Cache.
It's used as a buffer for the indices of MyISAM tables. There is
some overhead in the buffer depending on the configured key block
size.
The official way to calculate the key buffer usage as documented
in the MySQL Reference manual:
1 - ((Key_blocks_unused * key_cache_block_size) / key_buffer_size)
This will return the factor, so you have to multiply it
with 100 to get the percentage. The Key_blocks_unused is used
instead of the more obvious Key_blocks_used. This is due to the
fact that Key_blocks_used is the maximum number of key blocks
ever used. It will not return to 0 after a FLUSH TABLES.
This calculation does not take the overhead in account. The key
buffer efficiency can be calculated if the key buffer is empty or
(has been) completely full.
If …
The other day while trying to move a schema from one MySQL server to another, I encountered a very odd issue. The schema to be moved contained both MyISAM and InnoDB tables, so the only option I had was to dump the schema using mysqldump on the source server and import it on the destination server. The dump on the source server went fine with absolutely no issues but it failed to import into the second server, and the error message was:
Can't create/write to file ‘/disk1/activity.MYI’ (Errcode: 2)
This was an extremely odd message as the data directory on the
destination server was properly setup in terms of ownership and
permission. The source and destination MySQL servers have been
running without issues for months. Prior to the error, four
tables in the dump file were imported into the destination server
without any issues whatsoever. Furthermore the source and
destination server have the exact same operating system …
Backups are an integral and very important part of any system. Backups allow you to recover your data and be up and running again, in the advent of problems such as system crashes, hardware failures or users deleting data by mistake. I had been evaluating backup solution for a while but to be honest I really wasn't satisfied with the solutions available until I came across XtraBackup and I am loving it since. In this post I intend on showing how to do backups and restores using XtraBackup.