SHOW RELAYLOG EVENTS

June 26th, 2009

I reported a bug about SHOW BINLOG EVENTS not working with relay logs a couple of years ago - Bug #28777.

It’s now been fixed in MySQL 5.4, by adding a new SHOW statement - SHOW RELAYLOG EVENTS.

The replication team are really hammering through things at the moment - Kudos!

Mark Leith MySQL, MySQL 5.4 , ,

Past Presentations Now Online

June 16th, 2009

I uploaded all of my past presentations to Slideshare recently, and realized that I hadn’t actually posted some of these on my blog in the past as well.

So I’ve created a new Presentations Page that has all of these together now.

It’s kind of funny to see the “MySQL for Oracle DBAs” presentation again - a lot has changed since 2006!

In any case, enjoy if you haven’t seen them - give them a look over if interested, and feel free to post comments or questions on the page!

Mark Leith MySQL , , , , ,

MySQL Support Blogs

May 29th, 2009

As planetmysql moved towards “team blogs” and “individual authors”, we in MySQL Support wanted to show our team affiliation as well.

Dups took this on and created a new MySQL Support Blog on dev.mysql.com - thanks Dups!

picture-16

This aggregates all of our individual blogs - so if you click the blog title in planetmysql, you will be taken to our own blogs. Clicking our names takes you to our aggregated blog:

planetmysql blog snippet

Mark Leith MySQL ,

Goodbye MySQL 6.0!

May 22nd, 2009

The announcement for 6.0.11 went out not along ago. 

Within it:

6.0.11 will be the last release of 6.0. After this we will be
transitioning into a New Release Model for the MySQL Server

http://forge.mysql.com/wiki/Development_Cycle

The goal of this transition is to enable more frequent and timely
releases of the MySQL Server.

The planned milestone for September 2009 will probably include most of
the features from 6.0. More detail on which, will be communicated
before end of June. Features not in this milestone (e.g. Online Backup,
Falcon, Connection thread pooling, and 4 Byte UTF Support) are planned
for future milestones when they stabilize.

We’re still ironing out the details internally, but please do read up on the above wiki about our current plans for the development schedule!

We’ve still got quite a road ahead to get things settled, but to my mind, we’re on the right path.

Thoughts?

Mark Leith MySQL

InnoDB Monitor Docs Extended

May 14th, 2009

After I blogged about the InnoDB Table and Tablespace monitors, the docs guys got in touch with me, and asked if I’d mind the information being integrated in to the official documentation. “Of course not!” I said.

So Paul DuBois picked up the task, and set about integrating what I had in the docs, as well as sending the InnoDB developers and myself some extra questions for more detail, and adding that in too. 

Paul is finished with this for now - and now there are two new sections within the “SHOW ENGINE INNODB STATUS and the InnoDB Monitors” page of the manual:

Thanks for the work Paul!

Mark Leith MySQL , ,

innodb_stats_on_metadata / innodb_adaptive_hash_index

May 13th, 2009

It occurred to me at the MySQL UC that I hadn’t blogged about either innodb_status_on_metadata or innodb_adaptive_hash_index - Morgan Tocker convinced me to do a lightning talk at the end of the Percona conference about them - so I thought I’d do a quick write up on them here as well.
 
First - what’s the point in them? Being the guy that wrote the originating patches for both of them, I have a little background:

innodb_stats_on_metadata

InnoDB is fairly light weight when it gathers table and index statistics. In the default compiled in InnoDB for most users it will do 8 random(ish) dives in to the index and samples the page to try to ascertain the cardinality (selectivity) of the index for use by the optimizer. This being the case, not only is this done when you run ANALYZE TABLE on a table, it is also done during various other points:

The first is easy to digest.

The second and third both occur for each row change within InnoDB. row_update_statistics_if_needed() is called from row_insert_for_mysql()row_update_cascade_for_mysql(), and row_update_for_mysql().

The last in the list is interesting. In order to get an accurate(ish) count of the rows in the table, or the cardinality results etc. for the metadata commands, InnoDB runs the same procedure as an ANALYZE TABLE for all of the tables, because it doesn’t maintain accurate statistics in a table or index header somewhere like MyISAM (being MVCC getting an accurate row count is far more difficult for example).

This is great, if you run these commands periodically to check on their output yourself. Once you start trying to read these tables very often in a monitoring solution of any kind though, you will likely hit two distinct problems:

  1. God Damn that INFORMATION_SCHEMA access is SLLLOOOWWWWW
  2. If you are monitoring your queries, and their EXPLAIN plans, you may start to see “plan instability” - the optimizer randomly choosing different access paths for the queries

Behind door #1 there’s a couple of issues - we traverse the directories and table files in the  data directory for a lot of the information used in the output, as well as the ANALYZE that is done for InnoDB. We’ve done work in Worklog #3732 to optimize certain accesses to these INFORMATION_SCHEMA tables, but this didn’t solve the statistics issue.

The second issue is a little more subtle. You may have benchmarked your application statements in Dev and QA environments - but data sets change when they are in production. If table and index statistics are constantly being recalculated, there is a high probability that the optimizer will in fact choose different access paths for certain queries and tables where the rows that need to be scanned could be satisfied by more than one index.

Unless you are closely monitoring individual statements for their run time, access paths (EXPLAIN) etc. this is far more difficult to catch (often you will be seeing the “good” EXPLAIN plan a lot, and the “bad” one only surfaces every now and then too - so interactive debugging is made harder as well).

So, at the request of a pretty large SaaS customer, who was having both problems, innodb_stats_on_metadata was born - originally in Bug #26598. If you see any of the situations above, give it a try, and see how it works for you, as well.

Originally it was created as a non-dynamic variable, you could only set it on the command line or in an option file. It was altered by the InnoDB guys to be dynamic, and settable by SUPER privileged users. It’s documented in the InnoDB plugin documentation under the “Changes for Flexibility, Ease of Use and Reliability” chapter.

I’m on the fence about allowing this dynamically, as it still allows tools to change the setting as well (which often have the SUPER privilege to get at things like SHOW INNODB STATUS), when the DBA may have wanted this explicitly not allowed for all users.

Be good citizens tool vendors, and respect this setting please.

innodb_adaptive_hash_index

InnoDB has a really unique feature in the database world called “Adaptive Hash Indexes“. It monitors which rows are being accessed via index searches, and dynamically decides to cache those that are used the most often, by taking the BTREE index for the table the rows are from and converting it to a HASH index in memory, for quick row lookups.  Historically, this has performed really well (and still does today in most workloads).

Prior to the fix for the infamous Bug #15815 (the true start of our multi-core scalability jaunt, imho), it just hummed along with most people not noticing it around. Once we had the fix though, we started to see mutex contention in other places, in certain cases leading to InnoDB getting locked up, and stopping the server due to long semaphore waits - this happened within the code for adaptive hash indexes as well, and was reported as Bug #20358.

This has hit a pretty large number of users - many Support customers as well, and has had many engineer hours in trying to reproduce it reliably (without result, the bug is still “Open”, not “Verified”). As this started to hit a number of customers, I wrote a pretty simple patch for innodb_adaptive_hash_index to allow you to switch off the use of adaptive hash indexes altogether within InnoDB.

Now, for some this comes as a performance trade off - if you hit the above bug, it does allow you to work around it, but your application may benefit from Adaptive Hash Indexes too. If you favor reliability over performance, then use it - it fixes the problem (in a somewhat hackish way).

Yasufumi Kinoshita did a lot of great work, in Bug #29560 and Bug #26442, and there have been other issues found and fixed by the InnoDB team - Bug #39483 (closed at the time of writing) - and Mark over at Google - Bug #32149 (still verified at the time of writing). We hardly ever see Bug#20358 any more though, unless it’s on older versions.

This variable also gets a good mention in the InnoDB plugin documentation, under the ”Changes for Flexibility, Ease of Use and Reliability” again, and in it’s own section “Controlling Adaptive Hash Indexing“, because the variable has a nice side effect as well - it can also help to scale, specifically because of the kind of mutex contention that also lead to Bug #20358. 

The InnoDB manual mentions that you can monitor the contention via the SEMAPHORES section of SHOW INNODB STATUS by looking for “many threads waiting on an RW-latch created in btr0sea.c” - quite correctly.

You can also check out how much memory the hash index is using, and how well it’s being utilized, in the INSERT BUFFER AND ADAPTIVE HASH INDEX section:

-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 5, seg size 7,
16104 inserts, 16104 merged recs, 15379 merges
Hash table size 2212699, used cells 846306, node heap has 1574 buffer(s)
0.03 hash searches/s, 0.63 non-hash searches

The last two rows apply to the Adaptive Hash index. “Hash Table size” and “used cells” are the number of cells (array slots) assigned to the hash table (always a prime number), and the number of those which are used, respectively. “used cells” was removed as part of Bug #36941 because of it having perform issues by scanning the hash table to find the used cells - in 5.1.28 - so you may not see this on your server. 

“node heap has 1574 buffer(s)” is where you can find out how much memory the hash index is using - the number here is the number of pages that are allocated to the hash index (and a page is 16K in InnoDB by default). 

The last row gives the number of searches both in the adaptive hash index, as well as those not satisfied by it - which can give you a hit ratio for hash read efficiency. 

I’ve made a few graphs for MEM to track these, so they can be monitored over time to get a better picture of adaptive hash index usage, to give you a better tool to judge for yourself what the impact may be for disabling it (see below). I’ll push these up today, and after some testing on a number of other servers, you should hopefully see them in a new advisor update soon.

InnoDB Adaptive Hash Index graphs for MEM

InnoDB Adaptive Hash Index graphs for MEM

Mark Leith MySQL 5.1 ,

MySQL UC Talk Online

May 6th, 2009

I hadn’t gotten around to this as soon as I would have liked, but here it is!

The talk was moderately attended, but all seemed to be knowledgeable users of MEM, and asked some good insightful questions around how they want to use it.

There was also some talk of being able to set up a “Community” around these kinds of customizations from the users, which I think sounds great. What kind of things would you users want from this? Would a forge wiki section suffice, or what about a new launchpad project? Other ideas?

Interested in your thoughts! :)

Mark Leith MySQL ,

PERFORMANCE_SCHEMA, Maria and the Tokutek Challenge

February 6th, 2009

As Peter Gulutzan just announced - we’re opening up a “new” worklog that we’ve been working on, Worklog #2360. PERFORMANCE_SCHEMA.

In fact - it’s not “new”, it’s something that has been in the worklog system for a long time, and has had much much much discussion internally between some of the brightest engineers in the group.

The astute among you out there that read my post on the benchmark with Maria for the the tokutek challenge, may have noted this in the configure line that I used:

./configure –prefix=/usr/local/mysql –localstatedir=/data0/mysqldata \
–without-query-cache –with-extra-charsets=complex –with-pic –with-fast-mutexes \
–enable-thread-safe-client –with-readline –with-big-tables –with-zlib-dir=bundled \
–with-plugin-maria –with-plugin-partition –with-plugin-perfschema \
–without-innodb –without-falcon –without-ndbcluster –without-archive-storage-engine \
–without-example-storage-engine –without-federated-storage-engine –without-backhole-storage-engine

I don’t wish to steal Peter’s thunder (he’s worked enormously hard with this project), but I’m going to take this opportunity to post a couple of snippets that I took away from the first benchmark, and let Peter explain them, and the other tables, in his coming posts.

First, let’s check what are the hottest parts of the server where mutexes, IO (there has been more added with Maria in the tree since my tests here, in fact as a result of them I think), conditions or rw locks etc. are concerned whilst I was running the benchmark:

mysql> SELECT *
    ->   FROM events_waits_summary_by_event_name
    ->  WHERE sum_timer_wait != 0
    -> ORDER BY sum_timer_wait DESC;
+----------------------------------------------------------+------------+----------------+----------------+----------------+----------------+
| EVENT_NAME                                               | COUNT_WAIT | SUM_TIMER_WAIT | MIN_TIMER_WAIT | AVG_TIMER_WAIT | MAX_TIMER_WAIT |
+----------------------------------------------------------+------------+----------------+----------------+----------------+----------------+
| wait/synch/mutex/maria/PAGECACHE::cache_lock             | 2147483647 | 13466583113436 |            138 |           1678 |      544893048 |
| wait/synch/cond/maria/translog_d::log_flush              |       5769 |  2961643469364 |          48942 |      513372069 |     4294177986 |
| wait/synch/cond/mysys/my_thread_var::suspend             |        776 |   805743293206 |          12936 |     1038328986 |     4283692164 |
| wait/synch/mutex/maria/translog_buffer::mutex            | 2147483647 |   577561613332 |            138 |            234 |     4231638106 |
| wait/synch/mutex/maria/translog_d:file_header            | 2147483647 |   422453242530 |            138 |            171 |       10497066 |
| wait/synch/mutex/maria/MARIA_FILE_BITMAP::bitmap_lock    |  735984803 |   169563172188 |            144 |            230 |     1244470326 |
| wait/synch/rwlock/maria/MARIA_KEYDEF::root_lock          |  248027518 |    65520201900 |            162 |            264 |       10019208 |
| wait/io/file/sql/FRM                                     |        801 |    12940295718 |            150 |       16155175 |      515501940 |
| wait/synch/mutex/maria/MARIA_SHARE::intern_lock          |    3854083 |     4986469182 |            150 |           1293 |     2181619680 |
| wait/synch/mutex/sql/LOCK_global_system_variables        |    5208428 |      863439342 |            144 |            165 |         559086 |
| wait/synch/mutex/maria/translog_d::sent_to_disk          |     735999 |      508699002 |            150 |            691 |        1163784 |
| wait/synch/rwlock/maria/translog_d::open_files           |     491046 |      434394126 |            168 |            884 |         473808 |
| wait/synch/mutex/maria/MARIA_SHARE::key_del_lock         |    1665267 |      429800430 |            150 |            258 |        1077558 |
| wait/io/file/maria/Control                               |         92 |      429294504 |          12552 |        4666244 |       31523556 |
| wait/synch/mutex/mysys/LOCK_alarm                        |     882996 |      350870472 |            150 |            397 |         479982 |
| wait/synch/mutex/sql/LOCK_mdl                            |     758523 |      312468192 |            150 |            411 |         147180 |
| wait/synch/mutex/sql/LOCK_open                           |     736908 |      308840712 |            150 |            419 |         475176 |
| wait/synch/mutex/sql/LOCK_thread_count                   |    1036629 |      244505298 |            144 |            235 |         375186 |
| wait/synch/mutex/maria/translog_d::log_flush             |     565581 |      227091810 |            138 |            401 |         177606 |
| wait/synch/mutex/sql/LOCK_global_read_lock               |     490683 |      198332490 |            144 |            404 |         476472 |
| wait/synch/mutex/sql/LOCK_plugin                         |     588674 |      158860836 |            144 |            269 |          56688 |
| wait/synch/rwlock/sql/LOCK_grant                         |     267378 |      157255554 |            180 |            588 |        2143872 |
| wait/synch/mutex/maria/TRN::state_lock                   |     735985 |      147520044 |            150 |            200 |         154188 |
| wait/synch/mutex/maria/translog_d::dirty_buffer_mask     |     490790 |      110804592 |            162 |            225 |         135702 |
| wait/synch/mutex/maria/LOCK_trn_list                     |     490678 |      106710882 |            156 |            217 |         474672 |
| wait/synch/mutex/mysys/THD_LOCK_mutex                    |     490848 |       97715760 |            162 |            199 |          65340 |
| wait/synch/cond/maria/translog_b::waiting_filling_buffer |          5 |       20083674 |        1284888 |        4016734 |        6963702 |
| wait/synch/mutex/mysys/THR_LOCK_lock                     |      43560 |       19417026 |            162 |            445 |          25980 |
| wait/io/file/maria/DataFile                              |         20 |       14346036 |           4596 |         717301 |       14193714 |
| wait/synch/mutex/mysys/BITMAP_mutex                      |      43538 |       11462268 |            156 |            263 |          16278 |
| wait/synch/mutex/sql/LOCK_status                         |      21718 |       10181124 |            198 |            468 |           7518 |
| wait/synch/mutex/sql/LOCK_active_mi                      |      43440 |        9080496 |            180 |            209 |          17550 |
| wait/synch/mutex/sql/LOCK_event_metadata                 |      10804 |        4669272 |            210 |            432 |           8166 |
| wait/synch/mutex/sql/RLI_data_lock                       |      21718 |        4548996 |            180 |            209 |          17376 |
| wait/synch/rwlock/sql/LOCK_system_variables_hash         |      10866 |        4383222 |            186 |            403 |           7410 |
| wait/synch/mutex/sql/LOCK_prepared_stmt_count            |      10877 |        2389752 |            186 |            219 |          14400 |
| wait/synch/mutex/mysys/THR_LOCK_open                     |       1260 |         451236 |            156 |            358 |           2622 |
| wait/io/file/maria/KeyFile                               |         50 |         317220 |           2676 |           6344 |          30624 |
| wait/io/file/sql/ERRMSG                                  |          3 |         115410 |          13980 |          38470 |          81966 |
| wait/synch/mutex/sql/hash_filo::LOCK                     |        557 |         105720 |            150 |            189 |            654 |
| wait/io/file/mysys/charset                               |          1 |          46644 |          46644 |          46644 |          46644 |
| wait/io/file/sql/DbOpt                                   |          1 |          40734 |          40734 |          40734 |          40734 |
| wait/synch/mutex/mysys/KEY_CACHE::cache_lock             |        158 |          32664 |            150 |            206 |            516 |
| wait/io/file/sql/pid                                     |          1 |          32382 |          32382 |          32382 |          32382 |
| wait/synch/mutex/mysys/my_thread_var::mutex              |        115 |          31194 |            162 |            271 |            834 |
| wait/synch/mutex/mysys/THR_LOCK_charset                  |        157 |          28620 |            150 |            182 |            528 |
| wait/synch/mutex/mysys/THR_LOCK_threads                  |         22 |          25920 |            498 |           1178 |           5838 |
| wait/synch/mutex/myisam/MYISAM_SHARE::intern_lock        |         82 |          20502 |            150 |            250 |            480 |
| wait/synch/rwlock/myisam/MYISAM_SHARE::key_root_lock     |         66 |          19386 |            174 |            293 |            900 |
| wait/synch/mutex/maria/THR_LOCK_maria                    |         42 |          17574 |            204 |            418 |            798 |
| wait/synch/mutex/sql/LOCK_connection_count               |         39 |           9258 |            192 |            237 |            468 |
| wait/synch/mutex/sql/THR_LOCK_DDL_blocker                |         22 |           5664 |            156 |            257 |            534 |
| wait/synch/mutex/sql/LOCK_xid_cache                      |         18 |           5178 |            234 |            287 |            456 |
| wait/synch/mutex/sql/LOCK_delete                         |         18 |           4932 |            192 |            274 |            534 |
| wait/synch/mutex/sql/LOCK_ha_data                        |         12 |           3954 |            222 |            329 |            546 |
| wait/synch/mutex/sql/THR_LOCK_DDL_is_blocked             |         11 |           3294 |            210 |            299 |            528 |
| wait/synch/mutex/maria/MARIA_SHARE::close_lock           |         15 |           3114 |            150 |            207 |            234 |
| wait/synch/mutex/sql/LOCK_lock_db                        |         10 |           3036 |            198 |            303 |            444 |
| wait/synch/mutex/mysys/THR_LOCK_myisam                   |          3 |           1560 |            402 |            520 |            708 |
| wait/synch/mutex/sql/LOCK_user_conn                      |          2 |            696 |            240 |            348 |            456 |
| wait/synch/mutex/sql/LOCK_mysql_create_db                |          2 |            522 |            258 |            261 |            264 |
+----------------------------------------------------------+------------+----------------+----------------+----------------+----------------+
61 rows IN SET (0.00 sec)

The times that are being recorded above are actually CPU cycles, if you know the power of your CPUs you could convert those to microseconds fairly easily - or you can tell the PERFORMANCE_SCHEMA to record in other formats too.

mysql> SELECT * FROM setup_timers;
+------+------------+
| NAME | TIMER_NAME |
+------+------------+
| Wait | CYCLE      |
+------+------------+
1 row IN SET (0.00 sec)

Next, let’s take a look at what the thread that was inserting the 1 billion rows had been doing. Yes folks, this takes SHOW PROFILES and SHOW ENGINE INNODB MUTEX to a whole different level (it will pretty much make them defunct, imho, if we can get InnoDB using this instrumentation).

mysql> SELECT *
    ->   FROM events_waits_summary_by_thread_by_event_name
    ->  WHERE thread_id = 12
    ->    AND sum_timer_wait != 0
    -> ORDER BY sum_timer_wait DESC;
+-----------+----------------------------------------------------------+------------+----------------+----------------+----------------+----------------+
| THREAD_ID | EVENT_NAME                                               | COUNT_WAIT | SUM_TIMER_WAIT | MIN_TIMER_WAIT | AVG_TIMER_WAIT | MAX_TIMER_WAIT |
+-----------+----------------------------------------------------------+------------+----------------+----------------+----------------+----------------+
|        12 | wait/synch/mutex/maria/PAGECACHE::cache_lock             | 2147483647 | 13461313032030 |            138 |           1684 |      544893048 |
|        12 | wait/synch/cond/maria/translog_d::log_flush              |       5758 |  2961367306584 |          48942 |      514304846 |     4294177986 |
|        12 | wait/synch/cond/mysys/my_thread_var::suspend             |        769 |   805570319284 |          12936 |     1047555681 |     4283692164 |
|        12 | wait/synch/mutex/maria/translog_buffer::mutex            | 2147483647 |   575354215426 |            138 |            234 |     4231638106 |
|        12 | wait/synch/mutex/maria/translog_d:file_header            | 2147483647 |   420424031916 |            138 |            171 |       10497066 |
|        12 | wait/synch/mutex/maria/MARIA_FILE_BITMAP::bitmap_lock    |  732428925 |   168888242736 |            144 |            230 |     1244470326 |
|        12 | wait/synch/rwlock/maria/MARIA_KEYDEF::root_lock          |  246828873 |    65195270814 |            162 |            264 |       10019208 |
|        12 | wait/synch/mutex/maria/MARIA_SHARE::intern_lock          |    3836359 |     4981866294 |            150 |           1298 |     2181619680 |
|        12 | wait/synch/mutex/maria/translog_d::sent_to_disk          |     732420 |      506173524 |            150 |            691 |        1163784 |
|        12 | wait/synch/rwlock/maria/translog_d::open_files           |     488660 |      432319110 |            168 |            884 |         473808 |
|        12 | wait/io/file/maria/Control                               |         92 |      429294504 |          12552 |        4666244 |       31523556 |
|        12 | wait/synch/mutex/maria/MARIA_SHARE::key_del_lock         |    1658211 |      428136198 |            150 |            258 |        1077558 |
|        12 | wait/synch/mutex/mysys/LOCK_alarm                        |     834892 |      311987064 |            150 |            373 |         479982 |
|        12 | wait/synch/mutex/sql/LOCK_open                           |     732430 |      307217022 |            150 |            419 |         475176 |
|        12 | wait/synch/mutex/sql/LOCK_mdl                            |     732432 |      299536968 |            162 |            408 |         147180 |
|        12 | wait/synch/mutex/sql/LOCK_thread_count                   |     976577 |      230754018 |            144 |            236 |         375186 |
|        12 | wait/synch/mutex/maria/translog_d::log_flush             |     563195 |      226177674 |            138 |            401 |         177606 |
|        12 | wait/synch/mutex/sql/LOCK_global_read_lock               |     488287 |      197541498 |            180 |            404 |         476472 |
|        12 | wait/synch/mutex/maria/TRN::state_lock                   |     732430 |      146788518 |            150 |            200 |         154188 |
|        12 | wait/synch/rwlock/sql/LOCK_grant                         |     244146 |      137635878 |            180 |            563 |        2143872 |
|        12 | wait/synch/mutex/sql/LOCK_plugin                         |     488290 |      136693146 |            150 |            279 |          56688 |
|        12 | wait/synch/mutex/maria/translog_d::dirty_buffer_mask     |     488404 |      110289804 |            162 |            225 |         135702 |
|        12 | wait/synch/mutex/maria/LOCK_trn_list                     |     488288 |      106188246 |            156 |            217 |         474672 |
|        12 | wait/synch/mutex/mysys/THD_LOCK_mutex                    |     488287 |       97045002 |            180 |            198 |          65340 |
|        12 | wait/synch/cond/maria/translog_b::waiting_filling_buffer |          5 |       20083674 |        1284888 |        4016734 |        6963702 |
|        12 | wait/synch/mutex/mysys/THR_LOCK_open                     |         92 |         114222 |            414 |           1241 |           2622 |
|        12 | wait/io/file/maria/KeyFile                               |          3 |          20400 |           4374 |           6800 |           9606 |
|        12 | wait/synch/rwlock/sql/LOCK_system_variables_hash         |          3 |           1752 |            288 |            584 |            750 |
|        12 | wait/synch/mutex/mysys/THR_LOCK_threads                  |          1 |            852 |            852 |            852 |            852 |
|        12 | wait/synch/mutex/sql/LOCK_global_system_variables        |          2 |            498 |            234 |            249 |            264 |
|        12 | wait/synch/mutex/sql/LOCK_ha_data                        |          1 |            414 |            414 |            414 |            414 |
|        12 | wait/synch/mutex/sql/hash_filo::LOCK                     |          1 |            228 |            228 |            228 |            228 |
|        12 | wait/synch/mutex/sql/LOCK_connection_count               |          1 |            204 |            204 |            204 |            204 |
+-----------+----------------------------------------------------------+------------+----------------+----------------+----------------+----------------+
33 rows IN SET (0.00 sec)

Bonus points to those that spot the obvious “bug” in the above! :)

There is so much more to this worklog, there’s a number more tables, there’s a lot more information, and a lot more ways to look at it. The future of monitoring MySQL just got much brighter.

Stay tuned! I’m sure Peter is itching to spread more information!

Mark Leith General , ,

Speaking at the MySQL Conference 2009

February 5th, 2009

A little late to post (I’ve known a while), but I thought I’d plug my talk for any interested readers out there, that are going to the conference, and use MEM!

I’m talking about Extending MySQL Enterprise Monitor with Custom Advisors, Graphs and Data Collections.

I’ve had the pleasure of working with the team that writes the MEM software (the “Enterprise Tools” team, internally and lovingly known as the “Merlin Team“, the codename that has survived various renames of the product!) for a little over 3 years now. I can’t say I was there at it’s conception, but I started working with them before the initial release of the product, and have watched (and I like to think helped shape) the product very closely whilst being the “Support Coordinator” for the Support Team for MEM. It’s a great product already, but we have many ideas, it’s going to be an awesome product of the future.

Along the way I’ve helped to write many of the graphs and rules that are released for the MySQL Enterprise Monitor within the default Advisor bundles (along with Andy Bang, one of the original team with the concept) and hope to give MEM users some insights in to how they can extend MEM to suit their own needs.

For example, many users have asked for us to add disk space monitoring - we’re working towards making it more seamless for the next releases (2.0 has taken an interim step for this) - but little know that you can already extend the Monitor to do this within the new 2.0 release:

MEM Disk Monitoring

MEM Disk Monitoring

Come to the talk to find out how - and more, like collecting your own data points (from various sources), graphing them and/or alerting on them! :)

Mark Leith General

Maria trundles the tokutek challenge

February 4th, 2009

So I saw the tokutek challenge, and wondered to myself how Maria would get along with it. I duly downloaded a 6.0 tree, and the iiBench code, tinkered with it to make it actually build, and fired things up.

I watched it closely, for about a day, then got bored and forgot about it. I remembered today that I should take a look!

CPU Usage (Quad Core)

CPU Usage (Quad Core)

Average rows per second inserted

Average rows per second inserted

Load Averages

Load Averages

You can see, in just over a day the IO load became too heavy to process efficiently.

MySQL was built like this:

./configure –prefix=/usr/local/mysql –localstatedir=/data0/mysqldata \
–without-query-cache –with-extra-charsets=complex –with-pic –with-fast-mutexes \
–enable-thread-safe-client –with-readline –with-big-tables –with-zlib-dir=bundled \
–with-plugin-maria –with-plugin-partition –with-plugin-perfschema \
–without-innodb –without-falcon –without-ndbcluster –without-archive-storage-engine \
–without-example-storage-engine –without-federated-storage-engine –without-backhole-storage-engine

I tinkered with Maria right from the start though, I wanted to see what a longer checkpoint interval would give, so increased it to every 5 minutes - obviously this doesn’t seem great. :) I also wanted to use the same page size as InnoDB out of morbid curiosity. Here’s the my.cnf:

[mysqld]
basedir = /usr/local/mysql
datadir = /data0/mysqldata
log-error = /usr/local/mysql/logs/error.log

maria-block-size = 16384
maria_log_dir_path = /usr/local/mysql/logs
maria_page_checksum = 0
maria_pagecache_buffer_size = 12G
maria-checkpoint-interval = 300

The tables were defined as ENGINE = Maria - i.e TRANSACTIONAL = 1 (with crash recovery) by default.

I added a new custom graph for MEM, to track how the Maria Page Cache gets utilized:

Maria Page Cache Usage

Maria Page Cache Usage

I’ll be making a couple more for Maria as well - including the easy read and write physcial/logical requests from SHOW GLOBAL STATUS (to be released with MEM once Maria is ready, let me know if you want the custom graphs before hand).

The server is RHEL5, Quad Xeon, with 16G RAM, and a 4 disk 10krpm RAID 10 array for the /data0 mountpoint (although using ext3, along with the noop scheduler). Taking a look at iostat when I came back to it, it’s clear that this was my barrier (well, the io wait in the CPU graph is a pretty good indicator as well eh!):

avg-cpu: %user %nice %system %iowait %steal %idle
1.25 0.00 0.00 23.75 0.00 75.00

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
cciss/c0d0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
cciss/c0d1 0.00 7.00 9.00 813.00 288.00 6592.00 8.37 142.09 177.35 1.22 100.10

avg-cpu: %user %nice %system %iowait %steal %idle
4.00 0.00 0.25 20.75 0.00 75.00

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
cciss/c0d0 0.00 125.00 0.00 8.00 0.00 1064.00 133.00 0.05 6.25 4.38 3.50
cciss/c0d1 0.00 4.00 7.00 869.00 224.00 7008.00 8.26 142.00 163.25 1.14 100.10

avg-cpu: %user %nice %system %iowait %steal %idle
0.25 0.00 0.25 24.50 0.00 75.00

Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
cciss/c0d0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
cciss/c0d1 0.00 0.00 8.00 880.00 256.00 7040.00 8.22 143.06 162.75 1.13 100.10

Maria does not make use of bulk_insert_buffer_size, unfortunately, when TRANSACTIONAL = 1. It does when TRANSACTIONAL = 0 however. It also doesn’t use something like InnoDB’s Insert Buffer, so it’s clear that there is probably some way to go when it comes to bulk inserts within Maria for the TRANSACTIONAL mode.

Maria does support concurrent inserts with TRANSACTIONAL = 1, however this is disabled when the table has an AUTO_INCREMENT, (or FULLTEXT/GIS indexes) - so that makes this benchmark difficult from that respect too.

I’d like to restart this benchmark in a few ways:

TRANSACTIONAL = 0, single threaded, default checkpoint interval and block size, default auto_inc

The IO overhead for the log files (on cciss/c0d0 above) was not huge, so it will be interesting to see how this affects things (I’ll report back). This should show how just the new page cache works out as well.

TRANSACTIONAL = 1, 4 threads, default checkpoint interval and block size, default auto_inc

There’s only 4 CPUs on the system, so this will certainly max those out - but I’d like to see the performance differences with filling the cache as well, with concurrent INSERT still disabled.

TRANSACTIONAL = 1, 4 threads, default checkpoint interval and block size, synthetic auto_inc

This would really show how quickly concurrent inserts could start filling the cache concurrently. Sadly I think once the cache is full we will continue to see issues at least for now though.

Maybe I’ll get to those in my copious free time, but thought I’d at least post some initial findings on a “benchmark gone wrong” for amusement factor. :)

Mark Leith General , , ,