[MDEV-14602] Reduce malloc()/free() usage in InnoDB Created: 2017-12-07 Updated: 2024-01-18 |
|
| Status: | Confirmed |
| Project: | MariaDB Server |
| Component/s: | Data Manipulation - Insert |
| Fix Version/s: | None |
| Type: | Task | Priority: | Major |
| Reporter: | Sergey Chernomorets | Assignee: | Marko Mäkelä |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | memory, performance | ||
| Attachments: |
|
||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||
| Description |
|
I load backup to mariadb and break it. In processlist still present one killed thread:
----
----
Table which been loading: |
| Comments |
| Comment by Sergey Chernomorets [ 2017-12-07 ] | |||||||||||||||||||||||||||||||
|
madvise calls repeated:
46 different calls from 22397 collected | |||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
chernomorets, can you please provide some more information? What was the SQL statement that you attempted to kill? Can you show some stack traces of the statement execution? For example, use Poor man’s profiler or Quickstack, or attach gdb to the mysqld process. As far as I can tell, MariaDB 10.1 calls madvise() from MyISAM and Aria, not from InnoDB. Assuming that the table definition was not interpreted as something else (say, ENGINE=InnoDB could have been interpreted as ENGINE=MyISAM), then the other usage of MyISAM or Aria would be due to internal temporary tables for query execution, say, INSERT INTO…SELECT…ORDER BY non_indexed_column. It would seem to me that some loop is forgetting the thd_killed() check. Inside InnoDB, that check is only done in special long-running operations, such as CHECK TABLE. Otherwise it is supposed to be checked by the SQL executor. | |||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
Sorry, I should have looked at the gdb.txt
This stack trace is part of the transaction rollback inside InnoDB. Unfortunately, this is working as designed. Sure, we should try to use fewer mem_heap_create() and mem_heap_free() operations, but the real issue is that ROLLBACK in InnoDB is slow. On the other hand, COMMIT is fast, because all changes have been already made into the persistent data structures, and all that needs to be done is to ensure that all redo log up to the transaction state change has been persistently written to the file. If this was an insert into an empty table or partition, then | |||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
I only know of one work-around to this problem: Kill the server, delete the tablename.ibd file (not tablename.frm), and restart the server. The rollback will still be executed after restart, but it will be much faster, because the data will be missing. I think that DROP TABLE should still work, removing the .frm file and the InnoDB internal data dictionary entries. Of course, this advice should be tried with caution. Test in a staging environment first. | |||||||||||||||||||||||||||||||
| Comment by Sergey Chernomorets [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
Thank for answer! I loaded many "INSERT INTO...VALUES" from mysqldump. This case is not very important for me (it was interrupted experiment with backup recovery), but such state of mysqld seems very strange for me, so I create this bug. | |||||||||||||||||||||||||||||||
| Comment by Sergey Chernomorets [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
Marko, I see 10491 calls of "madvise(0x7f36cb617000, 466944, MADV_DONTNEED) = 0" and many duplicates with several other arguments, is it correct behaviour? | |||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
chernomorets, the madvise() system calls are apparently how jemalloc lets the operating system reclaim the memory in free(). I assume that malloc() would allocate private anonymous pages with mmap(). Maybe other memory allocation libraries use munmap() or something else; I have not checked lately. That InnoDB uses an excessive amount of heap memory allocations is a known problem. Fixing it would require massive changes to the code, and it is not feasible to do in a GA release. Furthermore, I think that the usefulness of ROW_FORMAT=COMPRESSED is limited. When I designed and implemented it in 2005, data file fragmentation was considered to be an issue, and also FALLOC_FL_PUNCH_HOLE did not exist. With flash-based storage, PAGE_COMPRESSED=YES ought to work work better. | |||||||||||||||||||||||||||||||
| Comment by Sergey Chernomorets [ 2017-12-12 ] | |||||||||||||||||||||||||||||||
|
Thanks a lot, Marko! | |||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2019-03-29 ] | |||||||||||||||||||||||||||||||
|
I retitled the bug, because while I consider my implementation of ROW_FORMAT=COMPRESSED in InnoDB obsolete by now, something definitely needs to be done about the frequent memory heap operations in InnoDB. | |||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2023-12-11 ] | |||||||||||||||||||||||||||||||
|
In |