[MDEV-5649] Aria engine horrible performance TRANSACTIONAL=1 Created: 2014-02-11 Updated: 2022-09-08 |
|
| Status: | Open |
| Project: | MariaDB Server |
| Component/s: | None |
| Affects Version/s: | 5.5.36, 10.0.9 |
| Fix Version/s: | 5.5 |
| Type: | Bug | Priority: | Minor |
| Reporter: | Slawomir Pryczek | Assignee: | Michael Widenius |
| Resolution: | Unresolved | Votes: | 2 |
| Labels: | None | ||
| Environment: |
Debian-70-wheezy, 2xHDD in RAID1, 16GB Memory |
||
| Description |
|
Hi Guys, im having issue with aria engine, ONLY when using TRANSACTIONAL=1, which is unfortunately the default setting it seems. Basically IO subsystem on the server gets exhausted completely and queries like SELECT * FROM "raw_stats_other" LIMIT 1 take eg. 200-600 seconds to return a row that has 30 bytes of data. Traffic is almost write-only with 5-10 concurrent writes at a time, with occassional reads. Each single write consist of "packed" write to 100 rows with ON DUPLICATE KEY UPDATE. The difference is so huge that when i switched the table to TRANSACTIONAL=0, the server behaved like there's no traffic at all. The problem isn't really the very bad performance, but lack of documentation. There should be some info about flushing strategy, and how TRANSACTIONAL=1 affects the IO (i don't know maybe that's how it's supposed to work as it's flushing every write to disk?). And most important, if there's a way of improving it or not. Is it not suitable for conventional HDD's and high write enviroments at all? While i have not much experience with mariadb and considering lack of documentation i thought at first that... the engine is just broken which is a shame, because when properly configured it works very nicely... where there's not a single line of info of how badly transactional options i affecting write performance and how it really works. I marked this issue as critical, because i think many people would drop the DB altogether thinking it's broken because lack of information.
|
| Comments |
| Comment by Sergei Golubchik [ 2014-02-11 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
greenman, could you please take that? Ask Monty for any information you need about Aria. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2014-03-05 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
First some background: TRANSACTIONAL=1 is not on by default. This can be seen with:
TRANSACTIONAL=1 means that all changes are logged to a transaction log TRANSACTIONAL=1 makes the Aria table crash-proof. This means that if the The other overhead with TRANSACTIONAL=1 is that we need up to 6 byte more One can combine many writes/updates to one entity (ie sync) by using In effect, this is the same thing as using BEGIN ... COMMIT with With the current version if Aria INSERT and SELECT works concurrently, SELECT speed should be about equal if you are using TRANSACTIONAL=1 or Back to the JIRA entry: I don't have any straight explanation why a SELECT should take a long One should be able to verify this with a 'show processlist' One problem shown in your example is that your insert queries are in I tried the following with the mysql client: In one connection I did:
(Inserting a lot of rows into t1) In another connection I did while the second insert was running:
Both queries was instant. I also checked with having two insert queries run at the same time:
As you can see, both are in sending data, which means they are To be able to help you, I would need a way to repeat this. Could you by any chance create a short program that I could run to see I would also need the result of 'show create table' for your test Regards, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Slawomir Pryczek [ 2014-03-13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Hello Monty, first thank you for taking time to explain... I have written code to replicate the issue. It's working 100%... First as you say, when i switch the engine to innodb - no issues here, multiple queries are updating rows, as you said, some are waiting, etc. Most important... i can still do select. So i'll quickly explain why i reported this as critical issue... You're issuing 10 queries A, B, C ... at some point in time, and in between you're making a SELECT. Everything on the same table. I was accustomed that if server is having hard time processing the queries, eg. because of load spike then the queries will get processed in serial or semi-serial for (table / row level) locking. It always works like that
Now this is 100% ok... Now look at this... im issuing INSERTS over and over... the server can't process them fast... and in the middle of these INSERT's im doing SELECT. If i had 10 unfinished INSERTS when i issued SELECT... the server should complete these 10 inserts, because these were issued BEFORE SELECT. Then do SELECT, then if inserts will continue to come - confinue with inserts. The point is that this SELECT should be finished before 11'th INSERT could be made. Or at least they should be made together. Now the behaviour im experiencing with ariadb with TRANSACTIONAL = 1... Im keep throwing eg. 10 inserts from 10 threads... then one thread needs to SELECT...
And new inserts keep finishing while SELECT is locked. Now that SELECT will never happen, We'll have a deadlock. This select from the middle will get postponed indefinitely, untill INSERTS will stop to come, doesn't matter that the select was issued 10 minutes ago and new INSERT just NOW. The insert will execute first. Like said, this isn't happening when im using innodb nor myisam. The select will just wait for its "turn", for me it seems that aria has some priority queue where inserts are pushed to top and selects to bottom, so when the engine has some "free time" it'll just process select like something that can be delayed untill load is low. As you can see on the screen below, in TIME column... new inserts are executed BUT select, that was issued before is deadlocked. It'll never finish untill i stop inserting data. Now that's extreme case, but when i had less load in real-life scenario, this SELECT COUNT(*) query would just wait for 10 seconds, sometimes 40 seconds... sometimes it'd execute instantly... WHILE inserts were always instantly executed. So insert performance was predictable, while select times was ... "unstable"... Im not sure that's a bug or something that's made by-design and it should work like that. Im including PHP code that'll spawn 20 worker processes using CURL and old mysql functions, so pls disregard the warnings. The queries issued are randomly generated, like the one below... FILE FOR DOWNLOAD: Thanks,
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2014-03-13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Slawomir, thank you for the test. Monty, I converted it to an MTR test, with some modifications. The test case is at the end of the comment. It does the following:
Autocommit is always on. Variables can be set at the beginning of the test, they might require some tweaking depending on how fast your machine is (for example, on mine the test with transactional aria, 20 threads, 2000 inserts, takes ~30 seconds, and the results described below are quite obvious there). Observations:
Here is the test case:
Typical output looks like this: Soon after the beginning:
(Note thread 18 which performs SELECT, it has already been waiting for 3 seconds for the lock, while INSERT threads keep inserting ) Closer to the end:
(Many threads have already finished inserting, which means they have run 2000 inserts each, remaining threads are finishing the job, and SELECT is still waiting). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Jean Weisbuch [ 2014-12-08 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
It seems that even when running only SELECTs on an Aria table, enabling TRANSACTIONAL=1 has a significant impact on performances. Testing with sysbench from trunk (05 dec 14) using the oltp.lua script, using TRANSACTIONAL=1 makes the runs between 16% and 18% slower (from ~315tps to ~260tps). Here are the parameters i used (on MariaDB 10.0.15 using debian wheezy packages) :
(the --oltp-read-only=on option makes the test to only run SELECTs) Here is the oltp.lua script i used (the only modifications i did from the one shipped with sysbench are that i added the test for the aria engine and that i specified the right table name (sbtest1) for the LOCK TABLES) :
The tables are dropped then re-created at each runs ; aria pagecache size on the server is of 128M which is way more than the test DB size and nothing else is running on the server and on MariaDB and there is still plenty of spare memory and no swapping occuring nor a CPU bottleneck (none of the two cores gets less than 25% idle and there is no huge iowait bursts. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Jean Weisbuch [ 2014-12-08 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
ps: as a side note, running the same test using ROW_FORMAT=DYNAMIC (and thus TRANSACTIONAL=0) in both Aria (while still having PAGE_CHECKSUM=1) and MyISAM performs a little bit faster than using ROW_FORMAT=PAGE TRANSACTIONAL=1 (~270tps instead of ~260tps). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Ruslan Altynbaev [ 2019-03-09 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Possibly related: https://bugs.mysql.com/bug.php?id=39437 |