| Bug #75235 | Optimize ibuf merge when reading a page from disk | ||
|---|---|---|---|
| Submitted: | 16 Dec 2014 11:46 | Modified: | 16 Dec 2014 18:58 |
| Reporter: | Naga Satyanarayana Bodapati | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S3 (Non-critical) |
| Version: | 5.7.6 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
[16 Dec 2014 18:07]
Daniel Price
Posted by developer:
Bug#20220909 - OPTIMIZE IBUF MERGE WHEN READING A PAGE FROM DISK
Problem:
--------
For every page we read, we check if there are pending ibuf entries.
We acquire RW_X_LATCH on the IBUF page, check if there is ibuf
entry for the page. Change buffer is applicable only on for B-tree
secondary leaf pages in non-temporary tablespace. So for other page
types, we unnecessarily acquire & release latch on IBUF page (page 1).
Fix:
---
We can skip the ibuf merge early without acquiring & releasing the latch
on IBUF page.
We will use the page_type, page_level & the tablespace type from the
page which is read from disk to skip the ibuf merge.
[16 Dec 2014 18:58]
Daniel Price
Posted by developer: Fixed as of the upcoming 5.7.6 release, and here's the changelog entry: When a page is read from disk, there is a check for pending insert buffer entries which involves acquiring a latch on the insert buffer page. If pending entries are found, they are merged. Because the change buffer is only applicable to B-tree secondary leaf pages in non-temporary tablespaces, insert buffer merge is not necessary for all page types. Using page_type, page_level, and tablespace type information from the page that is read from disk, insert buffer merge is now skipped for non-applicable page types.
[30 Aug 2016 9:58]
Laurynas Biveinis
It might be beneficial to backport this to 5.6 for correctness too, see bug 82798

Description: When ever a page is read from disk, we check if there are pending ibuf entries and merge them. i.e. in buf_page_io_complete() /* If space is being truncated then avoid ibuf operation. During re-init we have already freed ibuf entries. */ if (uncompressed && !recv_no_ibuf_operations && !Tablespace::is_undo_tablespace(bpage->id.space()) && !srv_is_tablespace_truncated(bpage->id.space())) { ibuf_merge_or_delete_for_page( (buf_block_t*) bpage, bpage->id, &bpage->size, TRUE); } We acquire RW_X_LATCH on the IBUF bitmap page, process the bitmap and skip for the IBUF merge for BLOB pages, clustered index pages, etc. We could optimise this by checking the page type very early since we just read the page from disk. Also we could skip ibuf merge check for temporary tablespace since IBUF is disabled for temproary tables. How to repeat: Read code Suggested fix: diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index b0e95e2..2230731 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5543,11 +5543,16 @@ corrupt: } /* If space is being truncated then avoid ibuf operation. - During re-init we have already freed ibuf entries. */ + During re-init we have already freed ibuf entries. + Change buffer is applicable only for B-tree secondary + leaf pages in non-temporary tablespace. */ if (uncompressed && !recv_no_ibuf_operations && !Tablespace::is_undo_tablespace(bpage->id.space()) - && !srv_is_tablespace_truncated(bpage->id.space())) { + && bpage->id.space() != srv_tmp_space.space_id() + && !srv_is_tablespace_truncated(bpage->id.space()) + && fil_page_get_type(frame) == FIL_PAGE_INDEX + && page_is_leaf(frame)) { ibuf_merge_or_delete_for_page( (buf_block_t*) bpage, bpage->id,