summaryrefslogtreecommitdiff
path: root/storage/xtradb/fil/fil0fil.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/fil/fil0fil.c')
-rw-r--r--storage/xtradb/fil/fil0fil.c560
1 files changed, 447 insertions, 113 deletions
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index 3c535bf7331..1ef0a9a46fb 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -46,6 +46,8 @@ Created 10/25/1995 Heikki Tuuri
#include "row0mysql.h"
#include "row0row.h"
#include "que0que.h"
+#include "btr0btr.h"
+#include "btr0sea.h"
#ifndef UNIV_HOTBACKUP
# include "buf0lru.h"
# include "ibuf0ibuf.h"
@@ -817,7 +819,7 @@ fil_node_close_file(
ut_ad(node && system);
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->open);
- ut_a(node->n_pending == 0 || srv_lazy_drop_table);
+ ut_a(node->n_pending == 0 || node->space->is_being_deleted);
ut_a(node->n_pending_flushes == 0);
ut_a(node->modification_counter == node->flush_counter);
@@ -830,7 +832,7 @@ fil_node_close_file(
ut_a(system->n_open > 0);
system->n_open--;
- if (node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
+ if (node->n_pending == 0 && node->space->purpose == FIL_TABLESPACE && !trx_sys_sys_space(node->space->id)) {
ut_a(UT_LIST_GET_LEN(system->LRU) > 0);
/* The node is in the LRU list, remove it */
@@ -1029,7 +1031,7 @@ fil_node_free(
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->magic_n == FIL_NODE_MAGIC_N);
- ut_a(node->n_pending == 0 || srv_lazy_drop_table);
+ ut_a(node->n_pending == 0 || space->is_being_deleted);
if (node->open) {
/* We fool the assertion in fil_node_close_file() to think
@@ -2579,7 +2581,7 @@ retry:
os_thread_sleep(20000);
- fil_flush(id);
+ fil_flush(id, TRUE);
goto retry;
@@ -2792,7 +2794,7 @@ error_exit2:
goto error_exit;
}
- ret = os_file_flush(file);
+ ret = os_file_flush(file, TRUE);
if (!ret) {
fputs("InnoDB: Error: file flush of tablespace ", stderr);
@@ -2977,7 +2979,7 @@ fil_reset_too_high_lsns(
}
}
- success = os_file_flush(file);
+ success = os_file_flush(file, TRUE);
if (!success) {
goto func_exit;
@@ -2999,7 +3001,7 @@ fil_reset_too_high_lsns(
goto func_exit;
}
- success = os_file_flush(file);
+ success = os_file_flush(file, TRUE);
func_exit:
os_file_close(file);
ut_free(buf2);
@@ -3009,6 +3011,97 @@ func_exit:
}
/********************************************************************//**
+Checks if a page is corrupt. (for offline page)
+*/
+static
+ibool
+fil_page_buf_page_is_corrupted_offline(
+/*===================================*/
+ const byte* page, /*!< in: a database page */
+ ulint zip_size) /*!< in: size of compressed page;
+ 0 for uncompressed pages */
+{
+ ulint checksum_field;
+ ulint old_checksum_field;
+
+ if (!zip_size
+ && memcmp(page + FIL_PAGE_LSN + 4,
+ page + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
+ return(TRUE);
+ }
+
+ checksum_field = mach_read_from_4(page
+ + FIL_PAGE_SPACE_OR_CHKSUM);
+
+ if (zip_size) {
+ return(checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && checksum_field
+ != page_zip_calc_checksum(page, zip_size));
+ }
+
+ old_checksum_field = mach_read_from_4(
+ page + UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM);
+
+ if (old_checksum_field != mach_read_from_4(page
+ + FIL_PAGE_LSN)
+ && old_checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && old_checksum_field
+ != buf_calc_page_old_checksum(page)) {
+ return(TRUE);
+ }
+
+ if (!srv_fast_checksum
+ && checksum_field != 0
+ && checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && checksum_field
+ != buf_calc_page_new_checksum(page)) {
+ return(TRUE);
+ }
+
+ if (srv_fast_checksum
+ && checksum_field != 0
+ && checksum_field != BUF_NO_CHECKSUM_MAGIC
+ && checksum_field
+ != buf_calc_page_new_checksum_32(page)
+ && checksum_field
+ != buf_calc_page_new_checksum(page)) {
+ return(TRUE);
+ }
+
+ return(FALSE);
+}
+
+/********************************************************************//**
+*/
+static
+void
+fil_page_buf_page_store_checksum(
+/*=============================*/
+ byte* page,
+ ulint zip_size)
+{
+ if (!zip_size) {
+ mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
+ srv_use_checksums
+ ? (!srv_fast_checksum
+ ? buf_calc_page_new_checksum(page)
+ : buf_calc_page_new_checksum_32(page))
+ : BUF_NO_CHECKSUM_MAGIC);
+ mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
+ srv_use_checksums
+ ? buf_calc_page_old_checksum(page)
+ : BUF_NO_CHECKSUM_MAGIC);
+ } else {
+ mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
+ srv_use_checksums
+ ? page_zip_calc_checksum(page, zip_size)
+ : BUF_NO_CHECKSUM_MAGIC);
+ }
+}
+
+/********************************************************************//**
Tries to open a single-table tablespace and optionally checks the space id is
right in it. If does not succeed, prints an error message to the .err log. This
function is used to open a tablespace when we start up mysqld, and also in
@@ -3123,6 +3216,7 @@ fil_open_single_table_tablespace(
fil_system_t* system;
fil_node_t* node = NULL;
fil_space_t* space;
+ ulint zip_size;
buf3 = ut_malloc(2 * UNIV_PAGE_SIZE);
descr_page = ut_align(buf3, UNIV_PAGE_SIZE);
@@ -3140,12 +3234,15 @@ fil_open_single_table_tablespace(
/* store as first descr page */
memcpy(descr_page, page, UNIV_PAGE_SIZE);
+ zip_size = dict_table_flags_to_zip_size(flags);
+ ut_a(zip_size == dict_table_flags_to_zip_size(space_flags));
+
/* get free limit (page number) of the table space */
/* these should be same to the definition in fsp0fsp.c */
#define FSP_HEADER_OFFSET FIL_PAGE_DATA
#define FSP_FREE_LIMIT 12
free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page);
- free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)UNIV_PAGE_SIZE;
+ free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)(zip_size ? zip_size : UNIV_PAGE_SIZE);
/* overwrite fsp header */
fsp_header_init_fields(page, id, flags);
@@ -3154,16 +3251,9 @@ fil_open_single_table_tablespace(
space_flags = flags;
if (mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn)
mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
- mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
- srv_use_checksums
- ? (!srv_fast_checksum
- ? buf_calc_page_new_checksum(page)
- : buf_calc_page_new_checksum_32(page))
- : BUF_NO_CHECKSUM_MAGIC);
- mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
- srv_use_checksums
- ? buf_calc_page_old_checksum(page)
- : BUF_NO_CHECKSUM_MAGIC);
+
+ fil_page_buf_page_store_checksum(page, zip_size);
+
success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE);
/* get file size */
@@ -3173,7 +3263,7 @@ fil_open_single_table_tablespace(
if (size_bytes < free_limit_bytes) {
free_limit_bytes = size_bytes;
- if (size_bytes >= (ib_int64_t) (FSP_EXTENT_SIZE * UNIV_PAGE_SIZE)) {
+ if (size_bytes >= (ib_int64_t) (FSP_EXTENT_SIZE * (zip_size ? zip_size : UNIV_PAGE_SIZE))) {
fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath);
file_is_corrupt = TRUE;
}
@@ -3237,75 +3327,41 @@ skip_info:
size_bytes = ut_2pow_round(size_bytes, 1024 * 1024);
}
*/
- if (!(flags & DICT_TF_ZSSIZE_MASK)) {
+
+ if (zip_size) {
+ fprintf(stderr, "InnoDB: Warning: importing compressed table is still EXPERIMENTAL, currently.\n");
+ }
+
+ {
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
ib_int64_t offset;
- size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
+ size = (ulint) (size_bytes / (zip_size ? zip_size : UNIV_PAGE_SIZE));
/* over write space id of all pages */
rec_offs_init(offsets_);
fprintf(stderr, "InnoDB: Progress in %%:");
- for (offset = 0; offset < free_limit_bytes; offset += UNIV_PAGE_SIZE) {
- ulint checksum_field;
- ulint old_checksum_field;
+ for (offset = 0; offset < free_limit_bytes;
+ offset += zip_size ? zip_size : UNIV_PAGE_SIZE) {
ibool page_is_corrupt;
success = os_file_read(file, page,
(ulint)(offset & 0xFFFFFFFFUL),
- (ulint)(offset >> 32), UNIV_PAGE_SIZE);
+ (ulint)(offset >> 32),
+ zip_size ? zip_size : UNIV_PAGE_SIZE);
page_is_corrupt = FALSE;
/* check consistency */
- if (memcmp(page + FIL_PAGE_LSN + 4,
- page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) {
-
+ if (fil_page_buf_page_is_corrupted_offline(page, zip_size)) {
page_is_corrupt = TRUE;
}
if (mach_read_from_4(page + FIL_PAGE_OFFSET)
- != offset / UNIV_PAGE_SIZE) {
-
- page_is_corrupt = TRUE;
- }
-
- checksum_field = mach_read_from_4(page
- + FIL_PAGE_SPACE_OR_CHKSUM);
-
- old_checksum_field = mach_read_from_4(
- page + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM);
-
- if (old_checksum_field != mach_read_from_4(page
- + FIL_PAGE_LSN)
- && old_checksum_field != BUF_NO_CHECKSUM_MAGIC
- && old_checksum_field
- != buf_calc_page_old_checksum(page)) {
-
- page_is_corrupt = TRUE;
- }
-
- if (!srv_fast_checksum
- && checksum_field != 0
- && checksum_field != BUF_NO_CHECKSUM_MAGIC
- && checksum_field
- != buf_calc_page_new_checksum(page)) {
-
- page_is_corrupt = TRUE;
- }
-
- if (srv_fast_checksum
- && checksum_field != 0
- && checksum_field != BUF_NO_CHECKSUM_MAGIC
- && checksum_field
- != buf_calc_page_new_checksum_32(page)
- && checksum_field
- != buf_calc_page_new_checksum(page)) {
+ != offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) {
page_is_corrupt = TRUE;
}
@@ -3316,7 +3372,8 @@ skip_info:
/* it should be overwritten already */
ut_a(!page_is_corrupt);
- } else if (!((offset / UNIV_PAGE_SIZE) % UNIV_PAGE_SIZE)) {
+ } else if (!((offset / (zip_size ? zip_size : UNIV_PAGE_SIZE))
+ % (zip_size ? zip_size : UNIV_PAGE_SIZE))) {
/* descr page (not header) */
if (page_is_corrupt) {
file_is_corrupt = TRUE;
@@ -3327,7 +3384,7 @@ skip_info:
}
/* store as descr page */
- memcpy(descr_page, page, UNIV_PAGE_SIZE);
+ memcpy(descr_page, page, (zip_size ? zip_size : UNIV_PAGE_SIZE));
} else if (descr_is_corrupt) {
/* unknown state of the page */
@@ -3355,9 +3412,12 @@ skip_info:
ulint bit_index;
descr = descr_page + XDES_ARR_OFFSET
- + XDES_SIZE * (ut_2pow_remainder((offset / UNIV_PAGE_SIZE), UNIV_PAGE_SIZE) / FSP_EXTENT_SIZE);
+ + XDES_SIZE * (ut_2pow_remainder(
+ (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)),
+ (zip_size ? zip_size : UNIV_PAGE_SIZE)) / FSP_EXTENT_SIZE);
- index = XDES_FREE_BIT + XDES_BITS_PER_PAGE * ((offset / UNIV_PAGE_SIZE) % FSP_EXTENT_SIZE);
+ index = XDES_FREE_BIT
+ + XDES_BITS_PER_PAGE * ((offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) % FSP_EXTENT_SIZE);
byte_index = index / 8;
bit_index = index % 8;
@@ -3375,7 +3435,7 @@ skip_info:
}
if (page_is_corrupt) {
- fprintf(stderr, " [errp:%ld]", (long) (offset / UNIV_PAGE_SIZE));
+ fprintf(stderr, " [errp:%ld]", (long) (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)));
/* cannot treat corrupt page */
goto skip_write;
@@ -3385,7 +3445,13 @@ skip_info:
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
for (i = 0; (ulint) i < n_index; i++) {
- if ((ulint) (offset / UNIV_PAGE_SIZE) == root_page[i]) {
+ if ((ulint) (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) == root_page[i]) {
+ if (fil_page_get_type(page) != FIL_PAGE_INDEX) {
+ file_is_corrupt = TRUE;
+ fprintf(stderr, " [etyp:%lld]",
+ offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
+ goto skip_write;
+ }
/* this is index root page */
mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
+ FSEG_HDR_SPACE, id);
@@ -3398,7 +3464,14 @@ skip_info:
if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
dulint tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID));
- if (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
+ for (i = 0; i < n_index; i++) {
+ if (ut_dulint_cmp(old_id[i], tmp) == 0) {
+ mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), new_id[i]);
+ break;
+ }
+ }
+
+ if (!zip_size && mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
&& ut_dulint_cmp(old_id[0], tmp) == 0) {
/* leaf page of cluster index, reset trx_id of records */
rec_t* rec;
@@ -3417,7 +3490,7 @@ skip_info:
ULINT_UNDEFINED, &heap);
n_fields = rec_offs_n_fields(offsets);
if (!offset) {
- offset = row_get_trx_id_offset(rec, index, offsets);
+ offset = row_get_trx_id_offset(index, offsets);
}
trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
@@ -3437,44 +3510,34 @@ skip_info:
rec = page_rec_get_next(rec);
n_recs--;
}
- }
-
- for (i = 0; i < n_index; i++) {
- if (ut_dulint_cmp(old_id[i], tmp) == 0) {
- mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), new_id[i]);
- break;
- }
+ } else if (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0
+ && ut_dulint_cmp(old_id[0], tmp) != 0) {
+ mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), ut_dulint_create(0, 1));
}
}
if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) {
mach_write_ull(page + FIL_PAGE_LSN, current_lsn);
- mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
- current_lsn);
+ if (!zip_size) {
+ mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
+ current_lsn);
+ }
}
- mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
- srv_use_checksums
- ? (!srv_fast_checksum
- ? buf_calc_page_new_checksum(page)
- : buf_calc_page_new_checksum_32(page))
- : BUF_NO_CHECKSUM_MAGIC);
- mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
- srv_use_checksums
- ? buf_calc_page_old_checksum(page)
- : BUF_NO_CHECKSUM_MAGIC);
+ fil_page_buf_page_store_checksum(page, zip_size);
success = os_file_write(filepath, file, page,
(ulint)(offset & 0xFFFFFFFFUL),
- (ulint)(offset >> 32), UNIV_PAGE_SIZE);
+ (ulint)(offset >> 32),
+ zip_size ? zip_size : UNIV_PAGE_SIZE);
}
skip_write:
if (free_limit_bytes
- && ((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / free_limit_bytes)
+ && ((ib_int64_t)((offset + (zip_size ? zip_size : UNIV_PAGE_SIZE)) * 100) / free_limit_bytes)
!= ((offset * 100) / free_limit_bytes)) {
fprintf(stderr, " %lu",
- (ulong)((ib_int64_t)((offset + UNIV_PAGE_SIZE) * 100) / free_limit_bytes));
+ (ulong)((ib_int64_t)((offset + (zip_size ? zip_size : UNIV_PAGE_SIZE)) * 100) / free_limit_bytes));
}
}
@@ -3530,13 +3593,6 @@ skip_write:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
- } else {
- /* zip page? */
- size = (ulint)
- (size_bytes
- / dict_table_flags_to_zip_size(flags));
- fprintf(stderr, "InnoDB: import: table %s seems to be in newer format."
- " It may not be able to treated for now.\n", name);
}
/* .exp file should be removed */
success = os_file_delete(info_file_path);
@@ -3618,6 +3674,271 @@ func_exit:
os_file_close(file);
mem_free(filepath);
+ if (srv_expand_import && dict_table_flags_to_zip_size(flags)) {
+ ulint page_no;
+ ulint zip_size;
+ ulint height;
+ ulint root_height = 0;
+ rec_t* node_ptr;
+ dict_table_t* table;
+ dict_index_t* index;
+ buf_block_t* block;
+ page_t* page;
+ page_zip_des_t* page_zip;
+ mtr_t mtr;
+
+ mem_heap_t* heap = NULL;
+ ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ ulint* offsets = offsets_;
+
+ rec_offs_init(offsets_);
+
+ zip_size = dict_table_flags_to_zip_size(flags);
+
+ table = dict_table_get_low(name);
+ index = dict_table_get_first_index(table);
+ page_no = dict_index_get_page(index);
+ ut_a(page_no == 3);
+
+ fprintf(stderr, "InnoDB: It is compressed .ibd file. need to convert additionaly on buffer pool.\n");
+
+ /* down to leaf */
+ mtr_start(&mtr);
+ mtr_set_log_mode(&mtr, MTR_LOG_NONE);
+
+ height = ULINT_UNDEFINED;
+
+ for (;;) {
+ block = buf_page_get(space_id, zip_size, page_no,
+ RW_NO_LATCH, &mtr);
+ page = buf_block_get_frame(block);
+
+ block->check_index_page_at_flush = TRUE;
+
+ if (height == ULINT_UNDEFINED) {
+ height = btr_page_get_level(page, &mtr);
+ root_height = height;
+ }
+
+ if (height == 0) {
+ break;
+ }
+
+ node_ptr = page_rec_get_next(page_get_infimum_rec(page));
+
+ height--;
+
+ offsets = rec_get_offsets(node_ptr, index, offsets, ULINT_UNDEFINED, &heap);
+ page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
+ }
+
+ mtr_commit(&mtr);
+
+ fprintf(stderr, "InnoDB: pages needs split are ...");
+
+ /* scan reaf pages */
+ while (page_no != FIL_NULL) {
+ rec_t* rec;
+ rec_t* supremum;
+ ulint n_recs;
+
+ mtr_start(&mtr);
+
+ block = buf_page_get(space_id, zip_size, page_no,
+ RW_X_LATCH, &mtr);
+ page = buf_block_get_frame(block);
+ page_zip = buf_block_get_page_zip(block);
+
+ if (!page_zip) {
+ /*something wrong*/
+ fprintf(stderr, "InnoDB: Something wrong with reading page %lu.\n", page_no);
+convert_err_exit:
+ mtr_commit(&mtr);
+ mutex_enter(&fil_system->mutex);
+ fil_space_free(space_id, FALSE);
+ mutex_exit(&fil_system->mutex);
+ success = FALSE;
+ goto convert_exit;
+ }
+
+ supremum = page_get_supremum_rec(page);
+ rec = page_rec_get_next(page_get_infimum_rec(page));
+ n_recs = page_get_n_recs(page);
+
+ /* illegal operation as InnoDB online system. so not logged */
+ while (rec && rec != supremum && n_recs > 0) {
+ ulint n_fields;
+ ulint i;
+ ulint offset = index->trx_id_offset;
+
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ n_fields = rec_offs_n_fields(offsets);
+ if (!offset) {
+ offset = row_get_trx_id_offset(index, offsets);
+ }
+ trx_write_trx_id(rec + offset, ut_dulint_create(0, 1));
+
+ for (i = 0; i < n_fields; i++) {
+ if (rec_offs_nth_extern(offsets, i)) {
+ ulint local_len;
+ byte* data;
+
+ data = rec_get_nth_field(rec, offsets, i, &local_len);
+
+ local_len -= BTR_EXTERN_FIELD_REF_SIZE;
+
+ mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id);
+ }
+ }
+
+ rec = page_rec_get_next(rec);
+ n_recs--;
+ }
+
+ /* dummy logged update for along with modified page path */
+ if (ut_dulint_cmp(index->id, btr_page_get_index_id(page)) != 0) {
+ /* this should be adjusted already */
+ fprintf(stderr, "InnoDB: The page %lu seems to be converted wrong.\n", page_no);
+ goto convert_err_exit;
+ }
+ btr_page_set_index_id(page, page_zip, index->id, &mtr);
+
+ /* confirm whether fits to the page size or not */
+ if (!page_zip_compress(page_zip, page, index, &mtr)
+ && !btr_page_reorganize(block, index, &mtr)) {
+ buf_block_t* new_block;
+ page_t* new_page;
+ page_zip_des_t* new_page_zip;
+ rec_t* split_rec;
+ ulint n_uniq;
+
+ /* split page is needed */
+ fprintf(stderr, " %lu", page_no);
+
+ mtr_x_lock(dict_index_get_lock(index), &mtr);
+
+ n_uniq = dict_index_get_n_unique_in_tree(index);
+
+ if(page_get_n_recs(page) < 2) {
+ /* no way to make smaller */
+ fprintf(stderr, "InnoDB: The page %lu cannot be store to the page size.\n", page_no);
+ goto convert_err_exit;
+ }
+
+ if (UNIV_UNLIKELY(page_no == dict_index_get_page(index))) {
+ ulint new_page_no;
+ dtuple_t* node_ptr;
+ ulint level;
+ rec_t* node_ptr_rec;
+ page_cur_t page_cursor;
+
+ /* it is root page, need to raise before split */
+
+ level = btr_page_get_level(page, &mtr);
+
+ new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, &mtr);
+ new_page = buf_block_get_frame(new_block);
+ new_page_zip = buf_block_get_page_zip(new_block);
+ btr_page_create(new_block, new_page_zip, index, level, &mtr);
+
+ btr_page_set_next(new_page, new_page_zip, FIL_NULL, &mtr);
+ btr_page_set_prev(new_page, new_page_zip, FIL_NULL, &mtr);
+
+ page_zip_copy_recs(new_page_zip, new_page,
+ page_zip, page, index, &mtr);
+ btr_search_move_or_delete_hash_entries(new_block, block, index);
+
+ rec = page_rec_get_next(page_get_infimum_rec(new_page));
+ new_page_no = buf_block_get_page_no(new_block);
+
+ node_ptr = dict_index_build_node_ptr(index, rec, new_page_no, heap,
+ level);
+ dtuple_set_info_bits(node_ptr,
+ dtuple_get_info_bits(node_ptr)
+ | REC_INFO_MIN_REC_FLAG);
+ btr_page_empty(block, page_zip, index, level + 1, &mtr);
+
+ btr_page_set_next(page, page_zip, FIL_NULL, &mtr);
+ btr_page_set_prev(page, page_zip, FIL_NULL, &mtr);
+
+ page_cur_set_before_first(block, &page_cursor);
+
+ node_ptr_rec = page_cur_tuple_insert(&page_cursor, node_ptr,
+ index, 0, &mtr);
+ ut_a(node_ptr_rec);
+
+ if (!btr_page_reorganize(block, index, &mtr)) {
+ fprintf(stderr, "InnoDB: failed to store the page %lu.\n", page_no);
+ goto convert_err_exit;
+ }
+
+ /* move to the raised page */
+ page_no = new_page_no;
+ block = new_block;
+ page = new_page;
+ page_zip = new_page_zip;
+
+ fprintf(stderr, "(raise_to:%lu)", page_no);
+ }
+
+ split_rec = page_get_middle_rec(page);
+
+ new_block = btr_page_alloc(index, page_no + 1, FSP_UP,
+ btr_page_get_level(page, &mtr), &mtr);
+ new_page = buf_block_get_frame(new_block);
+ new_page_zip = buf_block_get_page_zip(new_block);
+ btr_page_create(new_block, new_page_zip, index,
+ btr_page_get_level(page, &mtr), &mtr);
+
+ offsets = rec_get_offsets(split_rec, index, offsets, n_uniq, &heap);
+
+ btr_attach_half_pages(index, block,
+ split_rec, new_block, FSP_UP, &mtr);
+
+ page_zip_copy_recs(new_page_zip, new_page,
+ page_zip, page, index, &mtr);
+ page_delete_rec_list_start(split_rec - page + new_page,
+ new_block, index, &mtr);
+ btr_search_move_or_delete_hash_entries(new_block, block, index);
+ page_delete_rec_list_end(split_rec, block, index,
+ ULINT_UNDEFINED, ULINT_UNDEFINED, &mtr);
+
+ fprintf(stderr, "(new:%lu)", buf_block_get_page_no(new_block));
+
+ /* Are they needed? */
+ if (!btr_page_reorganize(block, index, &mtr)) {
+ fprintf(stderr, "InnoDB: failed to store the page %lu.\n", page_no);
+ goto convert_err_exit;
+ }
+ if (!btr_page_reorganize(new_block, index, &mtr)) {
+ fprintf(stderr, "InnoDB: failed to store the page %lu.\n", buf_block_get_page_no(new_block));
+ goto convert_err_exit;
+ }
+ }
+
+ page_no = btr_page_get_next(page, &mtr);
+
+ mtr_commit(&mtr);
+
+ if (heap) {
+ mem_heap_empty(heap);
+ }
+ }
+
+ fprintf(stderr, "...done.\nInnoDB: waiting the flush batch of the additional conversion.\n");
+
+ /* should wait for the not-logged changes are all flushed */
+ buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, mtr.end_lsn + 1);
+ buf_flush_wait_batch_end(BUF_FLUSH_LIST);
+
+ fprintf(stderr, "InnoDB: done.\n");
+convert_exit:
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+ }
+
return(success);
}
#endif /* !UNIV_HOTBACKUP */
@@ -4466,7 +4787,7 @@ fil_extend_space_to_desired_size(
mutex_exit(&fil_system->mutex);
mutex_exit(&fil_system->file_extend_mutex);
- fil_flush(space_id);
+ fil_flush(space_id, TRUE);
return(success);
}
@@ -4835,7 +5156,7 @@ _fil_io(
&& ((buf_page_t*)message)->space_was_being_deleted) {
if (mode == OS_AIO_NORMAL) {
- buf_page_io_complete(message, trx);
+ buf_page_io_complete(message);
return(DB_SUCCESS); /*fake*/
}
if (type == OS_FILE_READ) {
@@ -4946,14 +5267,14 @@ _fil_io(
ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
- if (srv_pass_corrupt_table && space->is_corrupt) {
+ if (srv_pass_corrupt_table == 1 && space->is_corrupt) {
/* should ignore i/o for the crashed space */
mutex_enter(&fil_system->mutex);
fil_node_complete_io(node, fil_system, type);
mutex_exit(&fil_system->mutex);
if (mode == OS_AIO_NORMAL) {
ut_a(space->purpose == FIL_TABLESPACE);
- buf_page_io_complete(message, trx);
+ buf_page_io_complete(message);
}
if (type == OS_FILE_READ) {
return(DB_TABLESPACE_DELETED);
@@ -4961,7 +5282,19 @@ _fil_io(
return(DB_SUCCESS);
}
} else {
- ut_a(!space->is_corrupt);
+ if (srv_pass_corrupt_table > 1 && space->is_corrupt) {
+ /* should ignore write i/o for the crashed space */
+ if (type == OS_FILE_WRITE) {
+ mutex_enter(&fil_system->mutex);
+ fil_node_complete_io(node, fil_system, type);
+ mutex_exit(&fil_system->mutex);
+ if (mode == OS_AIO_NORMAL) {
+ ut_a(space->purpose == FIL_TABLESPACE);
+ buf_page_io_complete(message);
+ }
+ return(DB_SUCCESS);
+ }
+ }
#ifdef UNIV_HOTBACKUP
/* In ibbackup do normal i/o, not aio */
if (type == OS_FILE_READ) {
@@ -5122,7 +5455,7 @@ fil_aio_wait(
|| buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE);
srv_set_io_thread_op_info(segment, "complete io for buf page");
- buf_page_io_complete(message, NULL);
+ buf_page_io_complete(message);
return;
}
@@ -5146,7 +5479,7 @@ fil_aio_wait(
if (fil_node->space->purpose == FIL_TABLESPACE) {
srv_set_io_thread_op_info(segment, "complete io for buf page");
- buf_page_io_complete(message, NULL);
+ buf_page_io_complete(message);
} else {
srv_set_io_thread_op_info(segment, "complete io for log");
log_io_complete(message);
@@ -5161,8 +5494,9 @@ UNIV_INTERN
void
fil_flush(
/*======*/
- ulint space_id) /*!< in: file space id (this can be a group of
+ ulint space_id, /*!< in: file space id (this can be a group of
log files or a tablespace of the database) */
+ ibool metadata)
{
fil_space_t* space;
fil_node_t* node;
@@ -5233,7 +5567,7 @@ retry:
/* fprintf(stderr, "Flushing to file %s\n",
node->name); */
- os_file_flush(file);
+ os_file_flush(file, metadata);
mutex_enter(&fil_system->mutex);
@@ -5316,7 +5650,7 @@ fil_flush_file_spaces(
a non-existing space id. */
for (i = 0; i < n_space_ids; i++) {
- fil_flush(space_ids[i]);
+ fil_flush(space_ids[i], TRUE);
}
mem_free(space_ids);