diff options
author | unknown <knielsen@knielsen-hq.org> | 2010-10-19 14:16:15 +0200 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2010-10-19 14:16:15 +0200 |
commit | c6ccd3f34693198883d905b98638db49ea6e6a76 (patch) | |
tree | ca49772d376816b7d08173489e9eae4447eef0d7 /storage/xtradb/buf | |
parent | f0c6576b85a57ec82fd911f73cce7c99683b378c (diff) | |
parent | 4f907dc75b44bca9d9f3c293e7ada0911645837d (diff) | |
download | mariadb-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.c | 135 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0lru.c | 122 |
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); } |