Bug #64344 malloc, free done for compressed pages when buffer pool mutex locked
Submitted: 15 Feb 2012 17:00 Modified: 9 Mar 2012 20:36
Reporter: Mark Callaghan Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: InnoDB Plugin storage engine Severity:S5 (Performance)
Version:5.1.52 OS:Any
Assigned to: Assigned Account CPU Architecture:Any
Tags: contention.malloc, FREE, innodb, mutex

[15 Feb 2012 17:00] Mark Callaghan
Description:
One path is for BUF_BLOCK_ZIP_PAGE from buf_LRU_block_remove_hashed_page so this is new with compression.

ut_free   
buf_page_free_descriptor
buf_LRU_block_remove_hashed_page
buf_LRU_free_block
buf_LRU_free_from_common_LRU_list,buf_LRU_search_and_free_block

From reading the code malloc can also be called for compressed pages as buf_page_alloc_descriptor calls malloc and that is called by:
* buf_LRU_free_block when the buffer pool mutex is held
* buf_page_init_for_read when the buffer pool mutex might be held

How to repeat:
read the code

Suggested fix:
Don't call malloc/free while holding the buffer pool, kernel, log sys, purge, dictionary, per-index or any other highly contended lock.
[16 Feb 2012 9:23] Marko Mäkelä
This is a design problem. Originally, the compressed block descriptors (buf_page_t) were allocated from buf_buddy_alloc(). Inaam changed it to use malloc/free, so that the buf_pool_mutex would not be acquired that often. It seems that we could at least defer the free() until after releasing the mutexes. I am not sure if we can pre-malloc() a block descriptor easily.
[19 Feb 2012 18:29] Inaam Rana
Mark,

Your analysis is correct. As Marko mentioned this is a design issue. To move allocation/deallocation outside buf_LRU_free_block() or to allow release of buf_pool::mutex will need some careful thought. I'll put this on my TODO.
[9 Mar 2012 20:36] Mark Callaghan
Performance results are at https://www.facebook.com/note.php?note_id=10150580052310933
[16 Jan 2015 19:40] Laurynas Biveinis
The buffer pool mutex split patch at bug 75534 makes buf_page_init_for_read allocated memory with mutexes released. It should also make it easier to fix this bug for buf_LRU_free_page too.