Merge XtraDB from Percona-Server-5.1.59-13 into MariaDB 5.1.

This commit is contained in:
unknown 2011-11-21 14:21:13 +01:00
commit ec889cd2e2
88 changed files with 4335 additions and 2954 deletions

View file

@ -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);
@ -3008,6 +3010,97 @@ func_exit:
return(success);
}
/********************************************************************//**
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
@ -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);