MDEV-31875 ROW_FORMAT=COMPRESSED table: InnoDB: ... Only 0 bytes read
buf_read_ahead_random(), buf_read_ahead_linear(): Avoid read-ahead of the last page(s) of ROW_FORMAT=COMPRESSED tablespaces that use a page size of 1024 or 2048 bytes. We invoke os_file_set_size() on integer multiples of 4096 bytes in order to be compatible with the requirements of innodb_flush_method=O_DIRECT regardless of the physical block size of the underlying storage. This change must be null-merged to MariaDB Server 10.5 and later. There, out-of-bounds read-ahead should be handled gracefully by simply discarding the buffer page that had been allocated. Tested by: Matthias Leich
This commit is contained in:
parent
34e8585437
commit
44df6f35aa
@ -266,8 +266,24 @@ buf_read_ahead_random(const page_id_t page_id, ulint zip_size, bool ibuf)
|
||||
* buf_read_ahead_random_area;
|
||||
|
||||
if (fil_space_t* space = fil_space_acquire(page_id.space())) {
|
||||
high = space->max_page_number_for_io(high);
|
||||
ulint space_size = space->committed_size;
|
||||
ulint zip_size = space->zip_size();
|
||||
space->release();
|
||||
/* Avoid read-ahead of the last page(s) of
|
||||
small-page-size ROW_FORMAT=COMPRESSED tablespaces,
|
||||
because fil_space_extend_must_retry() would invoke
|
||||
os_file_set_size() on integer multiples of 4 KiB. */
|
||||
switch (UNIV_EXPECT(zip_size, 0)) {
|
||||
case 1024:
|
||||
space_size &= ~ulint{3};
|
||||
break;
|
||||
case 2048:
|
||||
space_size &= ~ulint{1};
|
||||
break;
|
||||
}
|
||||
if (high > space_size) {
|
||||
high = space_size;
|
||||
}
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
@ -531,7 +547,20 @@ buf_read_ahead_linear(const page_id_t page_id, ulint zip_size, bool ibuf)
|
||||
|
||||
if (fil_space_t* space = fil_space_acquire(page_id.space())) {
|
||||
space_size = space->committed_size;
|
||||
ulint zip_size = space->zip_size();
|
||||
space->release();
|
||||
/* Avoid read-ahead of the last page(s) of
|
||||
small-page-size ROW_FORMAT=COMPRESSED tablespaces,
|
||||
because fil_space_extend_must_retry() would invoke
|
||||
os_file_set_size() on integer multiples of 4 KiB. */
|
||||
switch (UNIV_EXPECT(zip_size, 0)) {
|
||||
case 1024:
|
||||
space_size &= ~ulint{3};
|
||||
break;
|
||||
case 2048:
|
||||
space_size &= ~ulint{1};
|
||||
break;
|
||||
}
|
||||
|
||||
if (high > space_size) {
|
||||
/* The area is not whole */
|
||||
|
Loading…
x
Reference in New Issue
Block a user