summaryrefslogtreecommitdiff
path: root/storage/xtradb/buf
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2010-10-19 14:16:15 +0200
committerunknown <knielsen@knielsen-hq.org>2010-10-19 14:16:15 +0200
commitc6ccd3f34693198883d905b98638db49ea6e6a76 (patch)
treeca49772d376816b7d08173489e9eae4447eef0d7 /storage/xtradb/buf
parentf0c6576b85a57ec82fd911f73cce7c99683b378c (diff)
parent4f907dc75b44bca9d9f3c293e7ada0911645837d (diff)
downloadmariadb-git-c6ccd3f34693198883d905b98638db49ea6e6a76.tar.gz
Merge XtraDB from Percona-server-5.1.51-12 into MariaDB.
Diffstat (limited to 'storage/xtradb/buf')
-rw-r--r--storage/xtradb/buf/buf0buf.c135
-rw-r--r--storage/xtradb/buf/buf0lru.c122
2 files changed, 171 insertions, 86 deletions
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index 94a67c1759c..55ff207cf11 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -792,7 +792,7 @@ buf_block_reuse(
ptrdiff_t frame_offset)
{
/* block_init */
- block->frame = ((byte*)(block->frame) + frame_offset);
+ block->frame += frame_offset;
UNIV_MEM_DESC(block->frame, UNIV_PAGE_SIZE, block);
@@ -809,7 +809,7 @@ buf_block_reuse(
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
if (block->page.zip.data)
- block->page.zip.data = ((byte*)(block->page.zip.data) + frame_offset);
+ block->page.zip.data += frame_offset;
block->is_hashed = FALSE;
@@ -845,6 +845,8 @@ buf_chunk_init(
although it already should be. */
mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
+ srv_buffer_pool_shm_is_reused = FALSE;
+
if (srv_buffer_pool_shm_key) {
/* zip_hash size */
zip_hash_n = (mem_size / UNIV_PAGE_SIZE) * 2;
@@ -870,39 +872,46 @@ buf_chunk_init(
ut_a(buf_pool->n_chunks == 1);
fprintf(stderr,
- "InnoDB: Notice: innodb_buffer_pool_shm_key option is specified.\n"
- "InnoDB: This option may not be safe to keep consistency of datafiles.\n"
- "InnoDB: Because InnoDB cannot lock datafiles when shutdown until reusing shared memory segment.\n"
- "InnoDB: You should ensure no change of InnoDB files while using innodb_buffer_pool_shm_key.\n");
+ "InnoDB: Warning: The innodb_buffer_pool_shm_key option has been specified.\n"
+ "InnoDB: Do not change the following between restarts of the server while this option is being used:\n"
+ "InnoDB: * the mysqld executable between restarts of the server.\n"
+ "InnoDB: * the value of innodb_buffer_pool_size.\n"
+ "InnoDB: * the value of innodb_page_size.\n"
+ "InnoDB: * datafiles created by InnoDB during this session.\n"
+ "InnoDB: Otherwise, data corruption in datafiles may result.\n");
/* FIXME: This is vague id still */
- binary_id = (ulint) ((char*)mtr_commit - (char *)btr_root_get)
- + (ulint) ((char *)os_get_os_version - (char *)buf_calc_page_new_checksum)
- + (ulint) ((char *)page_dir_find_owner_slot - (char *)dfield_data_is_binary_equal)
- + (ulint) ((char *)que_graph_publish - (char *)dict_casedn_str)
- + (ulint) ((char *)read_view_oldest_copy_or_open_new - (char *)fil_space_get_version)
- + (ulint) ((char *)rec_get_n_extern_new - (char *)fsp_get_size_low)
- + (ulint) ((char *)row_get_trx_id_offset - (char *)ha_create_func)
- + (ulint) ((char *)srv_set_io_thread_op_info - (char *)thd_is_replication_slave_thread)
- + (ulint) ((char *)mutex_create_func - (char *)ibuf_inside)
- + (ulint) ((char *)trx_set_detailed_error - (char *)lock_check_trx_id_sanity)
- + (ulint) ((char *)ut_time - (char *)mem_heap_strdup);
+ binary_id = (ulint) ((byte*)mtr_commit - (byte*)btr_root_get)
+ + (ulint) ((byte*)os_get_os_version - (byte*)buf_calc_page_new_checksum)
+ + (ulint) ((byte*)page_dir_find_owner_slot - (byte*)dfield_data_is_binary_equal)
+ + (ulint) ((byte*)que_graph_publish - (byte*)dict_casedn_str)
+ + (ulint) ((byte*)read_view_oldest_copy_or_open_new - (byte*)fil_space_get_version)
+ + (ulint) ((byte*)rec_get_n_extern_new - (byte*)fsp_get_size_low)
+ + (ulint) ((byte*)row_get_trx_id_offset - (byte*)ha_create_func)
+ + (ulint) ((byte*)srv_set_io_thread_op_info - (byte*)thd_is_replication_slave_thread)
+ + (ulint) ((byte*)mutex_create_func - (byte*)ibuf_inside)
+ + (ulint) ((byte*)trx_set_detailed_error - (byte*)lock_check_trx_id_sanity)
+ + (ulint) ((byte*)ut_time - (byte*)mem_heap_strdup);
chunk->mem = os_shm_alloc(&chunk->mem_size, srv_buffer_pool_shm_key, &is_new);
if (UNIV_UNLIKELY(chunk->mem == NULL)) {
return(NULL);
}
-
+init_again:
#ifdef UNIV_SET_MEM_TO_ZERO
if (is_new) {
memset(chunk->mem, '\0', chunk->mem_size);
}
#endif
+ /* for ut_fold_binary_32(), these values should be 32-bit aligned */
+ ut_a(sizeof(buf_shm_info_t) % 4 == 0);
+ ut_a((ulint)chunk->mem % 4 == 0);
+ ut_a(chunk->mem_size % 4 == 0);
shm_info = chunk->mem;
- zip_hash_tmp = (hash_table_t*)((char *)chunk->mem + chunk->mem_size - zip_hash_mem_size);
+ zip_hash_tmp = (hash_table_t*)((byte*)chunk->mem + chunk->mem_size - zip_hash_mem_size);
if (is_new) {
strncpy(shm_info->head_str, BUF_SHM_INFO_HEAD, 8);
@@ -932,16 +941,6 @@ buf_chunk_init(
"InnoDB: Error: The shared memory was not initialized yet.\n");
return(NULL);
}
- if (!shm_info->clean) {
- fprintf(stderr,
- "InnoDB: Error: The shared memory was not shut down cleanly.\n");
- return(NULL);
- }
- if (!shm_info->reusable) {
- fprintf(stderr,
- "InnoDB: Error: The shared memory has unrecoverable contents.\n");
- return(NULL);
- }
if (shm_info->buf_pool_size != srv_buf_pool_size) {
fprintf(stderr,
"InnoDB: Error: srv_buf_pool_size is different (shm=%lu current=%lu).\n",
@@ -954,14 +953,34 @@ buf_chunk_init(
shm_info->page_size, srv_page_size);
return(NULL);
}
+ if (!shm_info->reusable) {
+ fprintf(stderr,
+ "InnoDB: Warning: The shared memory has unrecoverable contents.\n"
+ "InnoDB: The shared memory segment is initialized.\n");
+ is_new = TRUE;
+ goto init_again;
+ }
+ if (!shm_info->clean) {
+ fprintf(stderr,
+ "InnoDB: Warning: The shared memory was not shut down cleanly.\n"
+ "InnoDB: The shared memory segment is initialized.\n");
+ is_new = TRUE;
+ goto init_again;
+ }
ut_a(shm_info->zip_hash_offset == chunk->mem_size - zip_hash_mem_size);
ut_a(shm_info->zip_hash_n == zip_hash_n);
/* check checksum */
- checksum = ut_fold_binary((byte*)chunk->mem + sizeof(buf_shm_info_t),
- chunk->mem_size - sizeof(buf_shm_info_t));
- if (shm_info->checksum != checksum) {
+ if (srv_buffer_pool_shm_checksum) {
+ checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t),
+ chunk->mem_size - sizeof(buf_shm_info_t));
+ } else {
+ checksum = BUF_NO_CHECKSUM_MAGIC;
+ }
+
+ if (shm_info->checksum != BUF_NO_CHECKSUM_MAGIC
+ && shm_info->checksum != checksum) {
fprintf(stderr,
"InnoDB: Error: checksum of the shared memory is not match. "
"(stored=%lu calculated=%lu)\n",
@@ -979,6 +998,8 @@ buf_chunk_init(
} else {
/* adjust offset is done later */
hash_create_reuse(zip_hash_tmp);
+
+ srv_buffer_pool_shm_is_reused = TRUE;
}
} else {
chunk->mem = os_mem_alloc_large(&chunk->mem_size);
@@ -992,7 +1013,7 @@ buf_chunk_init(
/* Allocate the block descriptors from
the start of the memory block. */
if (srv_buffer_pool_shm_key) {
- chunk->blocks = (buf_block_t*)((char*)chunk->mem + sizeof(buf_shm_info_t));
+ chunk->blocks = (buf_block_t*)((byte*)chunk->mem + sizeof(buf_shm_info_t));
} else {
chunk->blocks = chunk->mem;
}
@@ -1039,10 +1060,10 @@ buf_chunk_init(
}
chunk->size = shm_info->chunk_backup.size;
- phys_offset = (char*)frame - ((char*)chunk->mem + shm_info->frame_offset);
- logi_offset = (char *)frame - (char *)chunk->blocks[0].frame;
+ phys_offset = frame - ((byte*)chunk->mem + shm_info->frame_offset);
+ logi_offset = frame - chunk->blocks[0].frame;
previous_frame_address = chunk->blocks[0].frame;
- blocks_offset = (char *)chunk->blocks - (char *)shm_info->chunk_backup.blocks;
+ blocks_offset = (byte*)chunk->blocks - (byte*)shm_info->chunk_backup.blocks;
if (phys_offset || logi_offset || blocks_offset) {
fprintf(stderr,
@@ -1053,10 +1074,10 @@ buf_chunk_init(
"InnoDB: Pysical offset : %ld (%#lx)\n"
"InnoDB: Logical offset (frames) : %ld (%#lx)\n"
"InnoDB: Logical offset (blocks) : %ld (%#lx)\n",
- (char *)chunk->mem + shm_info->frame_offset,
+ (byte*)chunk->mem + shm_info->frame_offset,
chunk->blocks[0].frame, frame,
- (ulong) phys_offset, (ulong) phys_offset, (ulong) logi_offset, (ulong) logi_offset,
- (ulong) blocks_offset, (ulong) blocks_offset);
+ (long) phys_offset, (ulong) phys_offset, (long) logi_offset, (ulong) logi_offset,
+ (long) blocks_offset, (ulong) blocks_offset);
} else {
fprintf(stderr,
"InnoDB: Buffer pool in the shared memory segment can be used as it is.\n");
@@ -1066,24 +1087,24 @@ buf_chunk_init(
fprintf(stderr,
"InnoDB: Aligning physical offset...");
- memmove(frame, ((char*)chunk->mem + shm_info->frame_offset),
+ memmove(frame, (byte*)chunk->mem + shm_info->frame_offset,
chunk->size * UNIV_PAGE_SIZE);
fprintf(stderr,
" Done.\n");
}
+ /* buf_block_t */
+ block = chunk->blocks;
+ for (i = chunk->size; i--; ) {
+ buf_block_reuse(block, logi_offset);
+ block++;
+ }
+
if (logi_offset || blocks_offset) {
fprintf(stderr,
"InnoDB: Aligning logical offset...");
- /* buf_block_t */
- block = chunk->blocks;
-
- for (i = chunk->size; i--; ) {
- buf_block_reuse(block, logi_offset);
- block++;
- }
/* buf_pool_t buf_pool_backup */
UT_LIST_OFFSET(flush_list, buf_page_t, shm_info->buf_pool_backup.flush_list,
@@ -1094,8 +1115,8 @@ buf_chunk_init(
previous_frame_address, logi_offset, blocks_offset);
if (shm_info->buf_pool_backup.LRU_old)
shm_info->buf_pool_backup.LRU_old =
- (buf_page_t*)((char*)(shm_info->buf_pool_backup.LRU_old)
- + (((byte*)shm_info->buf_pool_backup.LRU_old > previous_frame_address)
+ (buf_page_t*)((byte*)(shm_info->buf_pool_backup.LRU_old)
+ + (((void*)shm_info->buf_pool_backup.LRU_old > previous_frame_address)
? logi_offset : blocks_offset));
UT_LIST_OFFSET(unzip_LRU, buf_block_t, shm_info->buf_pool_backup.unzip_LRU,
@@ -1141,7 +1162,7 @@ buf_chunk_init(
}
if (shm_info) {
- shm_info->frame_offset = (char*)chunk->blocks[0].frame - (char*)chunk->mem;
+ shm_info->frame_offset = chunk->blocks[0].frame - (byte*)chunk->mem;
}
return(chunk);
@@ -1396,10 +1417,10 @@ buf_pool_init(void)
if (srv_buffer_pool_shm_key) {
buf_shm_info_t* shm_info;
- ut_a((char*)chunk->blocks == (char*)chunk->mem + sizeof(buf_shm_info_t));
+ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
shm_info = chunk->mem;
- buf_pool->zip_hash = (hash_table_t*)((char*)chunk->mem + shm_info->zip_hash_offset);
+ buf_pool->zip_hash = (hash_table_t*)((byte*)chunk->mem + shm_info->zip_hash_offset);
if(shm_info->is_new) {
shm_info->is_new = FALSE; /* initialization was finished */
@@ -1504,7 +1525,7 @@ buf_pool_free(void)
chunk = buf_pool->chunks;
shm_info = chunk->mem;
- ut_a((char*)chunk->blocks == (char*)chunk->mem + sizeof(buf_shm_info_t));
+ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
/* validation the shared memory segment doesn't have unrecoverable contents. */
/* Currently, validation became not needed */
@@ -1514,8 +1535,12 @@ buf_pool_free(void)
memcpy(&(shm_info->chunk_backup), chunk, sizeof(buf_chunk_t));
if (srv_fast_shutdown < 2) {
- shm_info->checksum = ut_fold_binary((byte*)chunk->mem + sizeof(buf_shm_info_t),
- chunk->mem_size - sizeof(buf_shm_info_t));
+ if (srv_buffer_pool_shm_checksum) {
+ shm_info->checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t),
+ chunk->mem_size - sizeof(buf_shm_info_t));
+ } else {
+ shm_info->checksum = BUF_NO_CHECKSUM_MAGIC;
+ }
shm_info->clean = TRUE;
}
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index 14ec1720873..79c7c0d3bbe 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -2228,6 +2228,26 @@ end:
return(ret);
}
+
+typedef struct {
+ ib_uint32_t space_id;
+ ib_uint32_t page_no;
+} dump_record_t;
+
+static int dump_record_cmp(const void *a, const void *b)
+{
+ const dump_record_t *rec1 = (dump_record_t *) a;
+ const dump_record_t *rec2 = (dump_record_t *) b;
+
+ if (rec1->space_id < rec2->space_id)
+ return -1;
+ if (rec1->space_id > rec2->space_id)
+ return 1;
+ if (rec1->page_no < rec2->page_no)
+ return -1;
+ return rec1->page_no > rec2->page_no;
+}
+
/********************************************************************//**
Read the pages based on the specific file.*/
UNIV_INTERN
@@ -2245,25 +2265,34 @@ buf_LRU_file_restore(void)
ulint req = 0;
ibool terminated = FALSE;
ibool ret = FALSE;
-
- buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
- buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
- if (!buffer) {
- fprintf(stderr,
- " InnoDB: cannot allocate buffer.\n");
- goto end;
- }
+ dump_record_t* records;
+ ulint size;
+ ulint size_high;
+ ulint length;
dump_file = os_file_create_simple_no_error_handling(
LRU_DUMP_FILE, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success);
- if (!success) {
+ if (!success || !os_file_get_size(dump_file, &size, &size_high)) {
os_file_get_last_error(TRUE);
fprintf(stderr,
" InnoDB: cannot open %s\n", LRU_DUMP_FILE);
goto end;
}
+ if (size == 0 || size_high > 0 || size % 8) {
+ fprintf(stderr, " InnoDB: broken LRU dump file\n");
+ goto end;
+ }
+ buffer_base = ut_malloc(2 * UNIV_PAGE_SIZE);
+ buffer = ut_align(buffer_base, UNIV_PAGE_SIZE);
+ records = ut_malloc(size);
+ if (!buffer || !records) {
+ fprintf(stderr,
+ " InnoDB: cannot allocate buffer.\n");
+ goto end;
+ }
buffers = 0;
+ length = 0;
while (!terminated) {
success = os_file_read(dump_file, buffer,
(buffers << UNIV_PAGE_SIZE_SHIFT) & 0xFFFFFFFFUL,
@@ -2272,15 +2301,14 @@ buf_LRU_file_restore(void)
if (!success) {
fprintf(stderr,
" InnoDB: cannot read page %lu of %s,"
- " or meet unexpected terminal.",
+ " or meet unexpected terminal.\n",
buffers, LRU_DUMP_FILE);
goto end;
}
for (offset = 0; offset < UNIV_PAGE_SIZE/4; offset += 2) {
- ulint space_id, zip_size, page_no;
- ulint err;
- ib_int64_t tablespace_version;
+ ulint space_id;
+ ulint page_no;
space_id = mach_read_from_4(buffer + offset * 4);
page_no = mach_read_from_4(buffer + (offset + 1) * 4);
@@ -2290,31 +2318,61 @@ buf_LRU_file_restore(void)
break;
}
- if (offset % 16 == 15) {
- os_aio_simulated_wake_handler_threads();
- buf_flush_free_margin(FALSE);
+ records[length].space_id = space_id;
+ records[length].page_no = page_no;
+ length++;
+ if (length * 8 >= size) {
+ fprintf(stderr,
+ " InnoDB: could not find the "
+ "end-of-file marker after reading "
+ "the expected %lu bytes from the "
+ "LRU dump file.\n"
+ " InnoDB: this could be caused by a "
+ "broken or incomplete file.\n"
+ " InnoDB: trying to process what has "
+ "been read so far.\n",
+ size);
+ terminated= TRUE;
+ break;
}
+ }
+ buffers++;
+ }
- zip_size = fil_space_get_zip_size(space_id);
- if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
- continue;
- }
+ qsort(records, length, sizeof(dump_record_t), dump_record_cmp);
- if (fil_area_is_exist(space_id, zip_size, page_no, 0,
- zip_size ? zip_size : UNIV_PAGE_SIZE)) {
+ for (offset = 0; offset < length; offset++) {
+ ulint space_id;
+ ulint page_no;
+ ulint zip_size;
+ ulint err;
+ ib_int64_t tablespace_version;
- tablespace_version = fil_space_get_version(space_id);
+ space_id = records[offset].space_id;
+ page_no = records[offset].page_no;
- req++;
- reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
- | OS_AIO_SIMULATED_WAKE_LATER,
- space_id, zip_size, TRUE,
- tablespace_version, page_no, NULL);
- buf_LRU_stat_inc_io();
- }
+ if (offset % 16 == 15) {
+ os_aio_simulated_wake_handler_threads();
+ buf_flush_free_margin(FALSE);
}
- buffers++;
+ zip_size = fil_space_get_zip_size(space_id);
+ if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
+ continue;
+ }
+
+ if (fil_area_is_exist(space_id, zip_size, page_no, 0,
+ zip_size ? zip_size : UNIV_PAGE_SIZE)) {
+
+ tablespace_version = fil_space_get_version(space_id);
+
+ req++;
+ reads += buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
+ | OS_AIO_SIMULATED_WAKE_LATER,
+ space_id, zip_size, TRUE,
+ tablespace_version, page_no, NULL);
+ buf_LRU_stat_inc_io();
+ }
}
os_aio_simulated_wake_handler_threads();
@@ -2330,6 +2388,8 @@ end:
os_file_close(dump_file);
if (buffer_base)
ut_free(buffer_base);
+ if (records)
+ ut_free(records);
return(ret);
}