mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
MDEV-8696: Adding indexes on empty table is slow with large innodb_sort_buffer_size.
Analysis: Current implementation will write and read at least one block (sort_buffer_size bytes) from disk / index even if that block does not contain any records. Fix: Avoid writing / reading empty blocks to temporary files (disk).
This commit is contained in:
parent
d6480f49ff
commit
13884cf206
19 changed files with 297 additions and 42 deletions
|
|
@ -1,6 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2014, 2015, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
|
@ -871,6 +872,8 @@ row_merge_read(
|
|||
|
||||
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
|
||||
ofs, srv_sort_buf_size);
|
||||
srv_stats.merge_buffers_read.inc();
|
||||
|
||||
#ifdef POSIX_FADV_DONTNEED
|
||||
/* Each block is read exactly once. Free up the file cache. */
|
||||
posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED);
|
||||
|
|
@ -905,6 +908,7 @@ row_merge_write(
|
|||
DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
|
||||
|
||||
ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf, ofs, buf_len);
|
||||
srv_stats.merge_buffers_written.inc();
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (row_merge_print_block_write) {
|
||||
|
|
@ -1736,7 +1740,7 @@ write_buffers:
|
|||
/* We have enough data tuples to form a block.
|
||||
Sort them and write to disk. */
|
||||
|
||||
if (buf->n_tuples) {
|
||||
if (UNIV_LIKELY(buf->n_tuples)) {
|
||||
if (dict_index_is_unique(buf->index)) {
|
||||
row_merge_dup_t dup = {
|
||||
buf->index, table, col_map, 0};
|
||||
|
|
@ -1777,13 +1781,17 @@ write_buffers:
|
|||
dict_index_get_lock(buf->index));
|
||||
}
|
||||
|
||||
row_merge_buf_write(buf, file, block);
|
||||
/* Do not write empty buffers to temporary file */
|
||||
if (buf->n_tuples) {
|
||||
|
||||
if (!row_merge_write(file->fd, file->offset++,
|
||||
block)) {
|
||||
err = DB_TEMP_FILE_WRITE_FAILURE;
|
||||
trx->error_key_num = i;
|
||||
break;
|
||||
row_merge_buf_write(buf, file, block);
|
||||
|
||||
if (!row_merge_write(file->fd, file->offset++,
|
||||
block)) {
|
||||
err = DB_TEMP_FILE_WRITE_FAILURE;
|
||||
trx->error_key_num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
|
||||
|
|
@ -2068,6 +2076,9 @@ done1:
|
|||
mem_heap_free(heap);
|
||||
b2 = row_merge_write_eof(&block[2 * srv_sort_buf_size],
|
||||
b2, of->fd, &of->offset);
|
||||
|
||||
srv_stats.merge_buffers_merged.inc();
|
||||
|
||||
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
|
||||
}
|
||||
|
||||
|
|
@ -3747,17 +3758,21 @@ wait_again:
|
|||
DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n");
|
||||
#endif
|
||||
} else {
|
||||
row_merge_dup_t dup = {
|
||||
sort_idx, table, col_map, 0};
|
||||
/* Sorting and inserting is required only if
|
||||
there really is records */
|
||||
if (UNIV_LIKELY(merge_files[i].n_rec)) {
|
||||
row_merge_dup_t dup = {
|
||||
sort_idx, table, col_map, 0};
|
||||
|
||||
error = row_merge_sort(
|
||||
trx, &dup, &merge_files[i],
|
||||
block, &tmpfd);
|
||||
error = row_merge_sort(
|
||||
trx, &dup, &merge_files[i],
|
||||
block, &tmpfd);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
error = row_merge_insert_index_tuples(
|
||||
trx->id, sort_idx, old_table,
|
||||
merge_files[i].fd, block);
|
||||
if (error == DB_SUCCESS) {
|
||||
error = row_merge_insert_index_tuples(
|
||||
trx->id, sort_idx, old_table,
|
||||
merge_files[i].fd, block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue