Bug #110091 | optimize for innodb recovery | ||
---|---|---|---|
Submitted: | 16 Feb 2023 5:27 | Modified: | 20 Feb 2023 13:58 |
Reporter: | alex xing (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S5 (Performance) |
Version: | 8.0.32 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | Contribution |
[16 Feb 2023 5:27]
alex xing
[16 Feb 2023 5:27]
alex xing
a simple patch to describe the optimization (*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.
Contribution: optimize.patch (text/plain), 8.95 KiB.
[16 Feb 2023 5:53]
MySQL Verification Team
Hello Alex Xing, Thank you for the report and contribution. regards, umesh
[17 Feb 2023 9:00]
Jakub Lopuszanski
Thank you for contributing to MySQL! Can you share results of performance tests have you performed to measure the benefit of this optimisation? I ask, because I thought that that the page is already in buffer pool is very rare. In particular our code coverage tools show this code is never executed during our test runs. ``` 1121 350837 : static void recv_apply_log_rec(recv_addr_t *recv_addr) { 1122 350837 : if (recv_addr->state == RECV_DISCARDED) { 1123 1821 : ut_a(recv_sys->n_addrs > 0); 1124 1821 : --recv_sys->n_addrs; 1125 1821 : return; 1126 : } 1127 : 1128 349016 : bool found; 1129 349016 : const page_id_t page_id(recv_addr->space, recv_addr->page_no); 1130 : 1131 349016 : const page_size_t page_size = 1132 349016 : fil_space_get_page_size(recv_addr->space, &found); 1133 : 1134 698032 : if (!found || recv_sys->missing_ids.find(recv_addr->space) != 1135 349016 : recv_sys->missing_ids.end()) { 1136 : /* Tablespace was discarded or dropped after changes were 1137 : made to it. Or, we have ignored redo log for this tablespace 1138 : earlier and somehow it has been found now. We can't apply 1139 : this redo log out of order. */ 1140 : 1141 0 : recv_addr->state = RECV_PROCESSED; 1142 : 1143 0 : ut_a(recv_sys->n_addrs > 0); 1144 0 : --recv_sys->n_addrs; 1145 : 1146 : /* If the tablespace has been explicitly deleted, we 1147 : can safely ignore it. */ 1148 : 1149 0 : if (recv_sys->deleted.find(recv_addr->space) == recv_sys->deleted.end()) { 1150 0 : recv_sys->missing_ids.insert(recv_addr->space); 1151 : } 1152 : 1153 349016 : } else if (recv_addr->state == RECV_NOT_PROCESSED) { 1154 51470 : mutex_exit(&recv_sys->mutex); 1155 : 1156 51470 : if (buf_page_peek(page_id)) { 1157 0 : mtr_t mtr; 1158 : 1159 0 : mtr_start(&mtr); 1160 : 1161 0 : buf_block_t *block; 1162 : 1163 0 : block = 1164 0 : buf_page_get(page_id, page_size, RW_X_LATCH, UT_LOCATION_HERE, &mtr); 1165 : 1166 0 : buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK); 1167 : 1168 0 : recv_recover_page(false, block); 1169 : 1170 0 : mtr_commit(&mtr); 1171 : 1172 0 : } else { 1173 51470 : recv_read_in_area(page_id); 1174 : } 1175 : 1176 51470 : mutex_enter(&recv_sys->mutex); 1177 : } 1178 : } ``` This intuitively makes sense to me (and I even wanted to remove this code some time ago). The redo log records are processed in batches, and before each batch the BP is empty. Processing of a batch starts by iterating over the page_id -> records map, and trying to process each page_id. If the page is not in BP we use `recv_read_in_area` issue asynchronous reads for this page and neighbouring pages which also have changes to be applied. The `recv_read_in_area` also adds the "placeholder" for the page to the BP and changes the recv_addr->state of the changes for these pages to `RECV_BEING_READ`. This means that even though the `buf_page_peek()` would return true for such neighbour, the `if (recv_addr->state == RECV_NOT_PROCESSED)` will not be executed for these neighboring pages, because they will either be still `RECV_BEING_READ`, or once they are read in the `buf_page_io_complete()` run by io thread will call `recv_recover_page(true, (buf_block_t *)bpage)` which will fully recover that page and further change the state to RECV_BEING_PROCESSED and finally RECV_PROCESSED. As you see, my current mental model is that this code can not be reached at all, so if you can show a test which demonstrates that it can be executed, I'd be grateful. Even more so, if you can show a case in which it becomes performance bottleneck.
[20 Feb 2023 13:58]
alex xing
Thanks for your reply! First , how to download the code coverage tools you mentioned , I'd like to study it. Second, If the page is read ahead and hasn't started redo apply yet, the patch might works, as you said this scene is rare. And I haven't run crash recovery tests yet.But I am working on redo replication lately, and this optimization is readly useful.