Merge lp:~percona-dev/percona-server/5.1.57-minimize_buf_pool_shm into lp:percona-server/5.1

Proposed by Yasufumi Kinoshita
Status: Merged
Approved by: Stewart Smith
Approved revision: no longer in the source branch.
Merged at revision: 235
Proposed branch: lp:~percona-dev/percona-server/5.1.57-minimize_buf_pool_shm
Merge into: lp:percona-server/5.1
Diff against target: 1236 lines (+30/-1087)
2 files modified
innodb_buffer_pool_shm.patch (+22/-1079)
innodb_fast_shutdown.patch (+8/-8)
To merge this branch: bzr merge lp:~percona-dev/percona-server/5.1.57-minimize_buf_pool_shm
Reviewer Review Type Date Requested Status
Stewart Smith Pending
Review via email: mp+65319@code.launchpad.net

Description of the change

invalidate the options added by innodb_buffer_pool_shm.patch
chunk size alignment is remained for compatibility

To post a comment you must log in.
Revision history for this message
Stewart Smith (stewart) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'innodb_buffer_pool_shm.patch'
2--- innodb_buffer_pool_shm.patch 2011-05-10 07:31:20 +0000
3+++ innodb_buffer_pool_shm.patch 2011-06-21 09:06:00 +0000
4@@ -8,300 +8,20 @@
5 diff -ruN a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c
6 --- a/storage/innodb_plugin/buf/buf0buf.c 2010-07-14 16:32:49.669501663 +0900
7 +++ b/storage/innodb_plugin/buf/buf0buf.c 2010-07-14 16:40:16.149438645 +0900
8-@@ -53,6 +53,10 @@
9- #include "page0zip.h"
10- #include "trx0trx.h"
11- #include "srv0start.h"
12-+#include "que0que.h"
13-+#include "read0read.h"
14-+#include "row0row.h"
15-+#include "ha_prototypes.h"
16-
17- /* prototypes for new functions added to ha_innodb.cc */
18- trx_t* innobase_get_trx();
19-@@ -310,6 +314,30 @@
20- UNIV_INTERN ibool buf_debug_prints = FALSE;
21- #endif /* UNIV_DEBUG */
22-
23-+/* Buffer pool shared memory segment information */
24-+typedef struct buf_shm_info_struct buf_shm_info_t;
25-+
26-+struct buf_shm_info_struct {
27-+ char head_str[8];
28-+ ulint binary_id;
29-+ ibool is_new; /* during initializing */
30-+ ibool clean; /* clean shutdowned and free */
31-+ ibool reusable; /* reusable */
32-+ ulint buf_pool_size; /* backup value */
33-+ ulint page_size; /* backup value */
34-+ ulint frame_offset; /* offset of the first frame based on chunk->mem */
35-+ ulint zip_hash_offset;
36-+ ulint zip_hash_n;
37-+
38-+ ulint checksum;
39-+
40-+ buf_pool_t buf_pool_backup;
41-+ buf_chunk_t chunk_backup;
42-+
43-+ ib_uint64_t dummy;
44-+};
45-+
46-+#define BUF_SHM_INFO_HEAD "XTRA_SHM"
47- #endif /* !UNIV_HOTBACKUP */
48-
49- /********************************************************************//**
50-@@ -756,6 +784,45 @@
51- #endif /* UNIV_SYNC_DEBUG */
52- }
53-
54-+static
55-+void
56-+buf_block_reuse(
57-+/*============*/
58-+ buf_block_t* block,
59-+ ptrdiff_t frame_offset)
60-+{
61-+ /* block_init */
62-+ block->frame += frame_offset;
63-+
64-+ UNIV_MEM_DESC(block->frame, UNIV_PAGE_SIZE, block);
65-+
66-+ block->index = NULL;
67-+
68-+#ifdef UNIV_DEBUG
69-+ /* recreate later */
70-+ block->page.in_page_hash = FALSE;
71-+ block->page.in_zip_hash = FALSE;
72-+#endif /* UNIV_DEBUG */
73-+
74-+#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
75-+ block->n_pointers = 0;
76-+#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
77-+
78-+ if (block->page.zip.data)
79-+ block->page.zip.data += frame_offset;
80-+
81-+ block->is_hashed = FALSE;
82-+
83-+ mutex_create(&block->mutex, SYNC_BUF_BLOCK);
84-+
85-+ rw_lock_create(&block->lock, SYNC_LEVEL_VARYING);
86-+ ut_ad(rw_lock_validate(&(block->lock)));
87-+
88-+#ifdef UNIV_SYNC_DEBUG
89-+ rw_lock_create(&block->debug_latch, SYNC_NO_ORDER_CHECK);
90-+#endif /* UNIV_SYNC_DEBUG */
91-+}
92-+
93- /********************************************************************//**
94- Allocates a chunk of buffer frames.
95- @return chunk, or NULL on failure */
96-@@ -768,26 +835,190 @@
97- {
98+@@ -769,10 +769,12 @@
99 buf_block_t* block;
100 byte* frame;
101-+ ulint zip_hash_n = 0;
102-+ ulint zip_hash_mem_size = 0;
103-+ hash_table_t* zip_hash_tmp = NULL;
104 ulint i;
105 + ulint size_target;
106-+ buf_shm_info_t* shm_info = NULL;
107
108 /* Round down to a multiple of page size,
109 although it already should be. */
110 mem_size = ut_2pow_round(mem_size, UNIV_PAGE_SIZE);
111 + size_target = (mem_size / UNIV_PAGE_SIZE) - 1;
112-+
113-+ srv_buffer_pool_shm_is_reused = FALSE;
114-+
115-+ if (srv_buffer_pool_shm_key) {
116-+ /* zip_hash size */
117-+ zip_hash_n = (mem_size / UNIV_PAGE_SIZE) * 2;
118-+ zip_hash_mem_size = ut_2pow_round(hash_create_needed(zip_hash_n)
119-+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
120-+ }
121-+
122 /* Reserve space for the block descriptors. */
123 mem_size += ut_2pow_round((mem_size / UNIV_PAGE_SIZE) * (sizeof *block)
124 + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
125-+ if (srv_buffer_pool_shm_key) {
126-+ mem_size += ut_2pow_round(sizeof(buf_shm_info_t)
127-+ + (UNIV_PAGE_SIZE - 1), UNIV_PAGE_SIZE);
128-+ mem_size += zip_hash_mem_size;
129-+ }
130-
131- chunk->mem_size = mem_size;
132-+
133-+ if (srv_buffer_pool_shm_key) {
134-+ ulint binary_id;
135-+ ibool is_new;
136-+
137-+ ut_a(buf_pool->n_chunks == 1);
138-+
139-+ fprintf(stderr,
140-+ "InnoDB: Warning: The innodb_buffer_pool_shm_key option has been specified.\n"
141-+ "InnoDB: Do not change the following between restarts of the server while this option is being used:\n"
142-+ "InnoDB: * the mysqld executable between restarts of the server.\n"
143-+ "InnoDB: * the value of innodb_buffer_pool_size.\n"
144-+ "InnoDB: * the value of innodb_page_size.\n"
145-+ "InnoDB: * datafiles created by InnoDB during this session.\n"
146-+ "InnoDB: Otherwise, data corruption in datafiles may result.\n");
147-+
148-+ /* FIXME: This is vague id still */
149-+ binary_id = (ulint) ((byte*)mtr_commit - (byte*)btr_root_get)
150-+ + (ulint) ((byte*)os_get_os_version - (byte*)buf_calc_page_new_checksum)
151-+ + (ulint) ((byte*)page_dir_find_owner_slot - (byte*)dfield_data_is_binary_equal)
152-+ + (ulint) ((byte*)que_graph_publish - (byte*)dict_casedn_str)
153-+ + (ulint) ((byte*)read_view_oldest_copy_or_open_new - (byte*)fil_space_get_version)
154-+ + (ulint) ((byte*)rec_get_n_extern_new - (byte*)fsp_get_size_low)
155-+ + (ulint) ((byte*)row_get_trx_id_offset - (byte*)ha_create_func)
156-+ + (ulint) ((byte*)srv_set_io_thread_op_info - (byte*)thd_is_replication_slave_thread)
157-+ + (ulint) ((byte*)mutex_create_func - (byte*)ibuf_inside)
158-+ + (ulint) ((byte*)trx_set_detailed_error - (byte*)lock_check_trx_id_sanity)
159-+ + (ulint) ((byte*)ut_time - (byte*)mem_heap_strdup);
160-+
161-+ chunk->mem = os_shm_alloc(&chunk->mem_size, srv_buffer_pool_shm_key, &is_new);
162-+
163-+ if (UNIV_UNLIKELY(chunk->mem == NULL)) {
164-+ return(NULL);
165-+ }
166-+init_again:
167-+#ifdef UNIV_SET_MEM_TO_ZERO
168-+ if (is_new) {
169-+ memset(chunk->mem, '\0', chunk->mem_size);
170-+ }
171-+#endif
172-+ /* for ut_fold_binary_32(), these values should be 32-bit aligned */
173-+ ut_a(sizeof(buf_shm_info_t) % 4 == 0);
174-+ ut_a((ulint)chunk->mem % 4 == 0);
175-+ ut_a(chunk->mem_size % 4 == 0);
176-+
177-+ shm_info = chunk->mem;
178-+
179-+ zip_hash_tmp = (hash_table_t*)((byte*)chunk->mem + chunk->mem_size - zip_hash_mem_size);
180-+
181-+ if (is_new) {
182-+ strncpy(shm_info->head_str, BUF_SHM_INFO_HEAD, 8);
183-+ shm_info->binary_id = binary_id;
184-+ shm_info->is_new = TRUE; /* changed to FALSE when the initialization is finished */
185-+ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
186-+ shm_info->reusable = FALSE; /* changed to TRUE when validation is finished. */
187-+ shm_info->buf_pool_size = srv_buf_pool_size;
188-+ shm_info->page_size = srv_page_size;
189-+ shm_info->zip_hash_offset = chunk->mem_size - zip_hash_mem_size;
190-+ shm_info->zip_hash_n = zip_hash_n;
191-+ } else {
192-+ ulint checksum;
193-+
194-+ if (strncmp(shm_info->head_str, BUF_SHM_INFO_HEAD, 8)) {
195-+ fprintf(stderr,
196-+ "InnoDB: Error: The shared memory segment seems not to be for buffer pool.\n");
197-+ return(NULL);
198-+ }
199-+ if (shm_info->binary_id != binary_id) {
200-+ fprintf(stderr,
201-+ "InnoDB: Error: The shared memory segment seems not to be for this binary.\n");
202-+ return(NULL);
203-+ }
204-+ if (shm_info->is_new) {
205-+ fprintf(stderr,
206-+ "InnoDB: Error: The shared memory was not initialized yet.\n");
207-+ return(NULL);
208-+ }
209-+ if (shm_info->buf_pool_size != srv_buf_pool_size) {
210-+ fprintf(stderr,
211-+ "InnoDB: Error: srv_buf_pool_size is different (shm=%lu current=%lu).\n",
212-+ shm_info->buf_pool_size, srv_buf_pool_size);
213-+ return(NULL);
214-+ }
215-+ if (shm_info->page_size != srv_page_size) {
216-+ fprintf(stderr,
217-+ "InnoDB: Error: srv_page_size is different (shm=%lu current=%lu).\n",
218-+ shm_info->page_size, srv_page_size);
219-+ return(NULL);
220-+ }
221-+ if (!shm_info->reusable) {
222-+ fprintf(stderr,
223-+ "InnoDB: Warning: The shared memory has unrecoverable contents.\n"
224-+ "InnoDB: The shared memory segment is initialized.\n");
225-+ is_new = TRUE;
226-+ goto init_again;
227-+ }
228-+ if (!shm_info->clean) {
229-+ fprintf(stderr,
230-+ "InnoDB: Warning: The shared memory was not shut down cleanly.\n"
231-+ "InnoDB: The shared memory segment is initialized.\n");
232-+ is_new = TRUE;
233-+ goto init_again;
234-+ }
235-+
236-+ ut_a(shm_info->zip_hash_offset == chunk->mem_size - zip_hash_mem_size);
237-+ ut_a(shm_info->zip_hash_n == zip_hash_n);
238-+
239-+ /* check checksum */
240-+ if (srv_buffer_pool_shm_checksum) {
241-+ checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t),
242-+ chunk->mem_size - sizeof(buf_shm_info_t));
243-+ } else {
244-+ checksum = BUF_NO_CHECKSUM_MAGIC;
245-+ }
246-+
247-+ if (shm_info->checksum != BUF_NO_CHECKSUM_MAGIC
248-+ && shm_info->checksum != checksum) {
249-+ fprintf(stderr,
250-+ "InnoDB: Error: checksum of the shared memory is not match. "
251-+ "(stored=%lu calculated=%lu)\n",
252-+ shm_info->checksum, checksum);
253-+ return(NULL);
254-+ }
255-+
256-+ /* flag to use the segment. */
257-+ shm_info->clean = FALSE; /* changed to TRUE when free the segment. */
258-+ }
259-+
260-+ /* init zip_hash contents */
261-+ if (is_new) {
262-+ hash_create_init(zip_hash_tmp, zip_hash_n);
263-+ } else {
264-+ /* adjust offset is done later */
265-+ hash_create_reuse(zip_hash_tmp);
266-+
267-+ srv_buffer_pool_shm_is_reused = TRUE;
268-+ }
269-+ } else {
270- chunk->mem = os_mem_alloc_large(&chunk->mem_size);
271-
272- if (UNIV_UNLIKELY(chunk->mem == NULL)) {
273-
274- return(NULL);
275- }
276-+ }
277-
278- /* Allocate the block descriptors from
279- the start of the memory block. */
280-+ if (srv_buffer_pool_shm_key) {
281-+ chunk->blocks = (buf_block_t*)((byte*)chunk->mem + sizeof(buf_shm_info_t));
282-+ } else {
283- chunk->blocks = chunk->mem;
284-+ }
285-
286- /* Align a pointer to the first frame. Note that when
287- os_large_page_size is smaller than UNIV_PAGE_SIZE,
288-@@ -795,8 +1026,13 @@
289- it is bigger, we may allocate more blocks than requested. */
290-
291- frame = ut_align(chunk->mem, UNIV_PAGE_SIZE);
292-+ if (srv_buffer_pool_shm_key) {
293-+ /* reserve zip_hash space and always -1 for reproductibity */
294-+ chunk->size = (chunk->mem_size - zip_hash_mem_size) / UNIV_PAGE_SIZE - 1;
295-+ } else {
296- chunk->size = chunk->mem_size / UNIV_PAGE_SIZE
297- - (frame != chunk->mem);
298-+ }
299-
300- /* Subtract the space needed for block descriptors. */
301- {
302-@@ -810,6 +1046,102 @@
303+@@ -810,6 +812,10 @@
304 chunk->size = size;
305 }
306
307@@ -309,404 +29,52 @@
308 + chunk->size = size_target;
309 + }
310 +
311-+ if (shm_info && !(shm_info->is_new)) {
312-+ /* convert the shared memory segment for reuse */
313-+ ptrdiff_t phys_offset;
314-+ ptrdiff_t logi_offset;
315-+ ptrdiff_t blocks_offset;
316-+ void* previous_frame_address;
317-+
318-+ if (chunk->size < shm_info->chunk_backup.size) {
319-+ fprintf(stderr,
320-+ "InnoDB: Error: The buffer pool became smaller because of allocated address.\n"
321-+ "InnoDB: Retrying may avoid this situation.\n");
322-+ shm_info->clean = TRUE; /* release the flag for retrying */
323-+ return(NULL);
324-+ }
325-+
326-+ chunk->size = shm_info->chunk_backup.size;
327-+ phys_offset = frame - ((byte*)chunk->mem + shm_info->frame_offset);
328-+ logi_offset = frame - chunk->blocks[0].frame;
329-+ previous_frame_address = chunk->blocks[0].frame;
330-+ blocks_offset = (byte*)chunk->blocks - (byte*)shm_info->chunk_backup.blocks;
331-+
332-+ if (phys_offset || logi_offset || blocks_offset) {
333-+ fprintf(stderr,
334-+ "InnoDB: Buffer pool in the shared memory segment should be converted.\n"
335-+ "InnoDB: Previous frames in address : %p\n"
336-+ "InnoDB: Previous frames were located : %p\n"
337-+ "InnoDB: Current frames should be located: %p\n"
338-+ "InnoDB: Pysical offset : %ld (%#lx)\n"
339-+ "InnoDB: Logical offset (frames) : %ld (%#lx)\n"
340-+ "InnoDB: Logical offset (blocks) : %ld (%#lx)\n",
341-+ (byte*)chunk->mem + shm_info->frame_offset,
342-+ chunk->blocks[0].frame, frame,
343-+ phys_offset, phys_offset, logi_offset, logi_offset,
344-+ blocks_offset, blocks_offset);
345-+ } else {
346-+ fprintf(stderr,
347-+ "InnoDB: Buffer pool in the shared memory segment can be used as it is.\n");
348-+ }
349-+
350-+ if (phys_offset) {
351-+ fprintf(stderr,
352-+ "InnoDB: Aligning physical offset...");
353-+
354-+ memmove(frame, (byte*)chunk->mem + shm_info->frame_offset,
355-+ chunk->size * UNIV_PAGE_SIZE);
356-+
357-+ fprintf(stderr,
358-+ " Done.\n");
359-+ }
360-+
361-+ /* buf_block_t */
362-+ block = chunk->blocks;
363-+ for (i = chunk->size; i--; ) {
364-+ buf_block_reuse(block, logi_offset);
365-+ block++;
366-+ }
367-+
368-+ if (logi_offset || blocks_offset) {
369-+ fprintf(stderr,
370-+ "InnoDB: Aligning logical offset...");
371-+
372-+
373-+ /* buf_pool_t buf_pool_backup */
374-+ UT_LIST_OFFSET(flush_list, buf_page_t, shm_info->buf_pool_backup.flush_list,
375-+ previous_frame_address, logi_offset, blocks_offset);
376-+ UT_LIST_OFFSET(free, buf_page_t, shm_info->buf_pool_backup.free,
377-+ previous_frame_address, logi_offset, blocks_offset);
378-+ UT_LIST_OFFSET(LRU, buf_page_t, shm_info->buf_pool_backup.LRU,
379-+ previous_frame_address, logi_offset, blocks_offset);
380-+ if (shm_info->buf_pool_backup.LRU_old)
381-+ shm_info->buf_pool_backup.LRU_old =
382-+ (buf_page_t*)((byte*)(shm_info->buf_pool_backup.LRU_old)
383-+ + (((void*)shm_info->buf_pool_backup.LRU_old > previous_frame_address)
384-+ ? logi_offset : blocks_offset));
385-+
386-+ UT_LIST_OFFSET(unzip_LRU, buf_block_t, shm_info->buf_pool_backup.unzip_LRU,
387-+ previous_frame_address, logi_offset, blocks_offset);
388-+
389-+ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_clean,
390-+ previous_frame_address, logi_offset, blocks_offset);
391-+ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
392-+ UT_LIST_OFFSET(zip_list, buf_page_t, shm_info->buf_pool_backup.zip_free[i],
393-+ previous_frame_address, logi_offset, blocks_offset);
394-+ }
395-+
396-+ HASH_OFFSET(zip_hash_tmp, buf_page_t, hash,
397-+ previous_frame_address, logi_offset, blocks_offset);
398-+
399-+ fprintf(stderr,
400-+ " Done.\n");
401-+ }
402-+ } else {
403 /* Init block structs and assign frames for them. Then we
404 assign the frames to the first blocks (we already mapped the
405 memory above). */
406-@@ -833,6 +1165,11 @@
407- block++;
408- frame += UNIV_PAGE_SIZE;
409- }
410-+ }
411-+
412-+ if (shm_info) {
413-+ shm_info->frame_offset = chunk->blocks[0].frame - (byte*)chunk->mem;
414-+ }
415-
416- return(chunk);
417- }
418-@@ -1014,6 +1351,8 @@
419- UNIV_MEM_UNDESC(block);
420- }
421-
422-+ ut_a(!srv_buffer_pool_shm_key);
423-+
424- os_mem_free_large(chunk->mem, chunk->mem_size);
425- }
426-
427-@@ -1063,7 +1402,10 @@
428- srv_buf_pool_curr_size = buf_pool->curr_size * UNIV_PAGE_SIZE;
429-
430- buf_pool->page_hash = hash_create(2 * buf_pool->curr_size);
431-+ /* zip_hash is allocated to shm when srv_buffer_pool_shm_key is enabled */
432-+ if (!srv_buffer_pool_shm_key) {
433- buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size);
434-+ }
435-
436- buf_pool->last_printout_time = time(NULL);
437-
438-@@ -1078,6 +1420,86 @@
439- --------------------------- */
440- /* All fields are initialized by mem_zalloc(). */
441-
442-+ if (srv_buffer_pool_shm_key) {
443-+ buf_shm_info_t* shm_info;
444-+
445-+ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
446-+ shm_info = chunk->mem;
447-+
448-+ buf_pool->zip_hash = (hash_table_t*)((byte*)chunk->mem + shm_info->zip_hash_offset);
449-+
450-+ if(shm_info->is_new) {
451-+ shm_info->is_new = FALSE; /* initialization was finished */
452-+ } else {
453-+ buf_block_t* block = chunk->blocks;
454-+ buf_page_t* b;
455-+
456-+ /* shm_info->buf_pool_backup should be converted */
457-+ /* at buf_chunk_init(). So copy simply. */
458-+ buf_pool->flush_list = shm_info->buf_pool_backup.flush_list;
459-+ buf_pool->freed_page_clock = shm_info->buf_pool_backup.freed_page_clock;
460-+ buf_pool->free = shm_info->buf_pool_backup.free;
461-+ buf_pool->LRU = shm_info->buf_pool_backup.LRU;
462-+ buf_pool->LRU_old = shm_info->buf_pool_backup.LRU_old;
463-+ buf_pool->LRU_old_len = shm_info->buf_pool_backup.LRU_old_len;
464-+ buf_pool->unzip_LRU = shm_info->buf_pool_backup.unzip_LRU;
465-+ buf_pool->zip_clean = shm_info->buf_pool_backup.zip_clean;
466-+ for (i = 0; i < BUF_BUDDY_SIZES_MAX; i++) {
467-+ buf_pool->zip_free[i] = shm_info->buf_pool_backup.zip_free[i];
468-+ }
469-+
470-+ for (i = 0; i < chunk->size; i++, block++) {
471-+ if (buf_block_get_state(block)
472-+ == BUF_BLOCK_FILE_PAGE) {
473-+ ut_d(block->page.in_page_hash = TRUE);
474-+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
475-+ buf_page_address_fold(
476-+ block->page.space,
477-+ block->page.offset),
478-+ &block->page);
479-+ }
480-+ }
481-+
482-+ for (b = UT_LIST_GET_FIRST(buf_pool->zip_clean); b;
483-+ b = UT_LIST_GET_NEXT(zip_list, b)) {
484-+ ut_ad(!b->in_flush_list);
485-+ ut_ad(b->in_LRU_list);
486-+
487-+ ut_d(b->in_page_hash = TRUE);
488-+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
489-+ buf_page_address_fold(b->space, b->offset), b);
490-+ }
491-+
492-+ for (b = UT_LIST_GET_FIRST(buf_pool->flush_list); b;
493-+ b = UT_LIST_GET_NEXT(flush_list, b)) {
494-+ ut_ad(b->in_flush_list);
495-+ ut_ad(b->in_LRU_list);
496-+
497-+ switch (buf_page_get_state(b)) {
498-+ case BUF_BLOCK_ZIP_DIRTY:
499-+ ut_d(b->in_page_hash = TRUE);
500-+ HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
501-+ buf_page_address_fold(b->space,
502-+ b->offset), b);
503-+ break;
504-+ case BUF_BLOCK_FILE_PAGE:
505-+ /* uncompressed page */
506-+ break;
507-+ case BUF_BLOCK_ZIP_FREE:
508-+ case BUF_BLOCK_ZIP_PAGE:
509-+ case BUF_BLOCK_NOT_USED:
510-+ case BUF_BLOCK_READY_FOR_USE:
511-+ case BUF_BLOCK_MEMORY:
512-+ case BUF_BLOCK_REMOVE_HASH:
513-+ ut_error;
514-+ break;
515-+ }
516-+ }
517-+
518-+
519-+ }
520-+ }
521-+
522- mutex_exit(&LRU_list_mutex);
523- rw_lock_x_unlock(&page_hash_latch);
524- buf_pool_mutex_exit();
525-@@ -1102,6 +1524,34 @@
526- buf_chunk_t* chunk;
527- buf_chunk_t* chunks;
528-
529-+ if (srv_buffer_pool_shm_key) {
530-+ buf_shm_info_t* shm_info;
531-+
532-+ ut_a(buf_pool->n_chunks == 1);
533-+
534-+ chunk = buf_pool->chunks;
535-+ shm_info = chunk->mem;
536-+ ut_a((byte*)chunk->blocks == (byte*)chunk->mem + sizeof(buf_shm_info_t));
537-+
538-+ /* validation the shared memory segment doesn't have unrecoverable contents. */
539-+ /* Currently, validation became not needed */
540-+ shm_info->reusable = TRUE;
541-+
542-+ memcpy(&(shm_info->buf_pool_backup), buf_pool, sizeof(buf_pool_t));
543-+ memcpy(&(shm_info->chunk_backup), chunk, sizeof(buf_chunk_t));
544-+
545-+ if (srv_fast_shutdown < 2) {
546-+ if (srv_buffer_pool_shm_checksum) {
547-+ shm_info->checksum = ut_fold_binary_32((byte*)chunk->mem + sizeof(buf_shm_info_t),
548-+ chunk->mem_size - sizeof(buf_shm_info_t));
549-+ } else {
550-+ shm_info->checksum = BUF_NO_CHECKSUM_MAGIC;
551-+ }
552-+ shm_info->clean = TRUE;
553-+ }
554-+
555-+ os_shm_free(chunk->mem, chunk->mem_size);
556-+ } else {
557- chunks = buf_pool->chunks;
558- chunk = chunks + buf_pool->n_chunks;
559-
560-@@ -1110,10 +1560,13 @@
561- would fail at shutdown. */
562- os_mem_free_large(chunk->mem, chunk->mem_size);
563- }
564-+ }
565-
566- mem_free(buf_pool->chunks);
567- hash_table_free(buf_pool->page_hash);
568-+ if (!srv_buffer_pool_shm_key) {
569- hash_table_free(buf_pool->zip_hash);
570-+ }
571- mem_free(buf_pool);
572- buf_pool = NULL;
573- }
574-@@ -1308,6 +1761,11 @@
575- //buf_pool_mutex_enter();
576- mutex_enter(&LRU_list_mutex);
577-
578-+ if (srv_buffer_pool_shm_key) {
579-+ /* Cannot support shrink */
580-+ goto func_done;
581-+ }
582-+
583- shrink_again:
584- if (buf_pool->n_chunks <= 1) {
585-
586-@@ -1551,6 +2009,11 @@
587- buf_pool_resize(void)
588- /*=================*/
589- {
590-+ if (srv_buffer_pool_shm_key) {
591-+ /* Cannot support resize */
592-+ return;
593-+ }
594-+
595- //buf_pool_mutex_enter();
596- mutex_enter(&LRU_list_mutex);
597-
598-diff -ruN a/storage/innodb_plugin/ha/hash0hash.c b/storage/innodb_plugin/ha/hash0hash.c
599---- a/storage/innodb_plugin/ha/hash0hash.c 2010-06-04 00:49:59.000000000 +0900
600-+++ b/storage/innodb_plugin/ha/hash0hash.c 2010-07-14 16:40:16.150438366 +0900
601-@@ -128,6 +128,70 @@
602- }
603-
604- /*************************************************************//**
605-+*/
606-+UNIV_INTERN
607-+ulint
608-+hash_create_needed(
609-+/*===============*/
610-+ ulint n)
611-+{
612-+ ulint prime;
613-+ ulint offset;
614-+
615-+ prime = ut_find_prime(n);
616-+
617-+ offset = (sizeof(hash_table_t) + 7) / 8;
618-+ offset *= 8;
619-+
620-+ return(offset + sizeof(hash_cell_t) * prime);
621-+}
622-+
623-+UNIV_INTERN
624-+void
625-+hash_create_init(
626-+/*=============*/
627-+ hash_table_t* table,
628-+ ulint n)
629-+{
630-+ ulint prime;
631-+ ulint offset;
632-+
633-+ prime = ut_find_prime(n);
634-+
635-+ offset = (sizeof(hash_table_t) + 7) / 8;
636-+ offset *= 8;
637-+
638-+ table->array = (hash_cell_t*)(((byte*)table) + offset);
639-+ table->n_cells = prime;
640-+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
641-+ table->adaptive = FALSE;
642-+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
643-+ table->n_mutexes = 0;
644-+ table->mutexes = NULL;
645-+ table->heaps = NULL;
646-+ table->heap = NULL;
647-+ ut_d(table->magic_n = HASH_TABLE_MAGIC_N);
648-+
649-+ /* Initialize the cell array */
650-+ hash_table_clear(table);
651-+}
652-+
653-+UNIV_INTERN
654-+void
655-+hash_create_reuse(
656-+/*==============*/
657-+ hash_table_t* table)
658-+{
659-+ ulint offset;
660-+
661-+ offset = (sizeof(hash_table_t) + 7) / 8;
662-+ offset *= 8;
663-+
664-+ table->array = (hash_cell_t*)(((byte*)table) + offset);
665-+ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
666-+}
667-+
668-+/*************************************************************//**
669- Frees a hash table. */
670- UNIV_INTERN
671- void
672 diff -ruN a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
673 --- a/storage/innodb_plugin/handler/ha_innodb.cc 2010-07-14 16:34:18.597725479 +0900
674 +++ b/storage/innodb_plugin/handler/ha_innodb.cc 2010-07-14 16:40:16.159323612 +0900
675-@@ -198,6 +198,7 @@
676+@@ -198,6 +198,8 @@
677 static my_bool innobase_create_status_file = FALSE;
678 static my_bool innobase_stats_on_metadata = TRUE;
679 static my_bool innobase_use_sys_stats_table = FALSE;
680 +static my_bool innobase_buffer_pool_shm_checksum = TRUE;
681++static uint innobase_buffer_pool_shm_key = 0;
682
683 static char* internal_innobase_data_file_path = NULL;
684
685-@@ -2476,6 +2477,7 @@
686- srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
687- srv_use_checksums = (ibool) innobase_use_checksums;
688- srv_fast_checksum = (ibool) innobase_fast_checksum;
689-+ srv_buffer_pool_shm_checksum = (ibool) innobase_buffer_pool_shm_checksum;
690-
691- #ifdef HAVE_LARGE_PAGES
692- if ((os_use_large_pages = (ibool) my_use_large_pages))
693-@@ -11476,6 +11478,16 @@
694+@@ -2460,6 +2462,12 @@
695+
696+ srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
697+
698++ if (innobase_buffer_pool_shm_key) {
699++ fprintf(stderr,
700++ "InnoDB: Warning: innodb_buffer_pool_shm_key is deprecated function.\n"
701++ "InnoDB: innodb_buffer_pool_shm_key was ignored.\n");
702++ }
703++
704+ srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
705+
706+ srv_n_file_io_threads = (ulint) innobase_file_io_threads;
707+@@ -11476,6 +11484,16 @@
708 "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
709 NULL, NULL, 128*1024*1024L, 32*1024*1024L, LONGLONG_MAX, 1024*1024L);
710
711-+static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, srv_buffer_pool_shm_key,
712++static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, innobase_buffer_pool_shm_key,
713 + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
714-+ "[experimental] The key value of shared memory segment for the buffer pool. 0 (default) disables the feature.",
715++ "[Deprecated option] no effect",
716 + NULL, NULL, 0, 0, INT_MAX32, 0);
717 +
718 +static MYSQL_SYSVAR_BOOL(buffer_pool_shm_checksum, innobase_buffer_pool_shm_checksum,
719 + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
720-+ "Enable buffer_pool_shm checksum validation (enabled by default).",
721++ "[Deprecated option] no effect",
722 + NULL, NULL, TRUE);
723 +
724 static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
725 PLUGIN_VAR_RQCMDARG,
726 "Helps in performance tuning in heavily concurrent environments.",
727-@@ -11764,6 +11776,8 @@
728+@@ -11764,6 +11782,8 @@
729 MYSQL_SYSVAR(additional_mem_pool_size),
730 MYSQL_SYSVAR(autoextend_increment),
731 MYSQL_SYSVAR(buffer_pool_size),
732@@ -715,428 +83,3 @@
733 MYSQL_SYSVAR(checksums),
734 MYSQL_SYSVAR(fast_checksum),
735 MYSQL_SYSVAR(commit_concurrency),
736-diff -ruN a/storage/innodb_plugin/handler/innodb_patch_info.h b/storage/innodb_plugin/handler/innodb_patch_info.h
737---- a/storage/innodb_plugin/handler/innodb_patch_info.h 2010-07-14 16:34:18.603733950 +0900
738-+++ b/storage/innodb_plugin/handler/innodb_patch_info.h 2010-07-14 16:40:16.164323927 +0900
739-@@ -47,5 +47,6 @@
740- {"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
741- {"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
742- {"innodb_sys_tables_sys_indexes","Expose InnoDB SYS_TABLES and SYS_INDEXES schema tables","","http://www.percona.com/docs/wiki/percona-xtradb"},
743-+{"innodb_buffer_pool_shm","Put buffer pool contents to shared memory segment and reuse it at clean restart [experimental]","","http://www.percona.com/docs/wiki/percona-xtradb"},
744- {NULL, NULL, NULL, NULL}
745- };
746-diff -ruN a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h
747---- a/storage/innodb_plugin/include/buf0buf.h 2010-07-14 16:33:23.823323393 +0900
748-+++ b/storage/innodb_plugin/include/buf0buf.h 2010-07-14 16:40:16.166323436 +0900
749-@@ -36,6 +36,7 @@
750- #include "ut0rbt.h"
751- #ifndef UNIV_HOTBACKUP
752- #include "os0proc.h"
753-+#include "srv0srv.h"
754-
755- /** @name Modes for buf_page_get_gen */
756- /* @{ */
757-@@ -1302,7 +1303,10 @@
758- /**********************************************************************//**
759- Compute the hash fold value for blocks in buf_pool->zip_hash. */
760- /* @{ */
761--#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
762-+/* the fold should be relative when srv_buffer_pool_shm_key is enabled */
763-+#define BUF_POOL_ZIP_FOLD_PTR(ptr) (!srv_buffer_pool_shm_key\
764-+ ?((ulint) (ptr) / UNIV_PAGE_SIZE)\
765-+ :((ulint) ((byte*)ptr - (byte*)(buf_pool->chunks->blocks->frame)) / UNIV_PAGE_SIZE))
766- #define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
767- #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
768- /* @} */
769-diff -ruN a/storage/innodb_plugin/include/hash0hash.h b/storage/innodb_plugin/include/hash0hash.h
770---- a/storage/innodb_plugin/include/hash0hash.h 2010-06-04 00:49:59.000000000 +0900
771-+++ b/storage/innodb_plugin/include/hash0hash.h 2010-07-14 16:40:16.168323262 +0900
772-@@ -49,6 +49,28 @@
773- hash_create(
774- /*========*/
775- ulint n); /*!< in: number of array cells */
776-+
777-+/*************************************************************//**
778-+*/
779-+UNIV_INTERN
780-+ulint
781-+hash_create_needed(
782-+/*===============*/
783-+ ulint n);
784-+
785-+UNIV_INTERN
786-+void
787-+hash_create_init(
788-+/*=============*/
789-+ hash_table_t* table,
790-+ ulint n);
791-+
792-+UNIV_INTERN
793-+void
794-+hash_create_reuse(
795-+/*==============*/
796-+ hash_table_t* table);
797-+
798- #ifndef UNIV_HOTBACKUP
799- /*************************************************************//**
800- Creates a mutex array to protect a hash table. */
801-@@ -327,6 +349,33 @@
802- }\
803- }\
804- } while (0)
805-+
806-+/********************************************************************//**
807-+Align nodes with moving location.*/
808-+#define HASH_OFFSET(TABLE, NODE_TYPE, PTR_NAME, FADDR, FOFFSET, BOFFSET) \
809-+do {\
810-+ ulint i2222;\
811-+ ulint cell_count2222;\
812-+\
813-+ cell_count2222 = hash_get_n_cells(TABLE);\
814-+\
815-+ for (i2222 = 0; i2222 < cell_count2222; i2222++) {\
816-+ NODE_TYPE* node2222;\
817-+\
818-+ if ((TABLE)->array[i2222].node) \
819-+ (TABLE)->array[i2222].node = (void*)((byte*)(TABLE)->array[i2222].node \
820-+ + (((TABLE)->array[i2222].node > (void*)FADDR)?FOFFSET:BOFFSET));\
821-+ node2222 = HASH_GET_FIRST((TABLE), i2222);\
822-+\
823-+ while (node2222) {\
824-+ if (node2222->PTR_NAME) \
825-+ node2222->PTR_NAME = (void*)((byte*)(node2222->PTR_NAME) \
826-+ + ((((void*)node2222->PTR_NAME) > (void*)FADDR)?FOFFSET:BOFFSET));\
827-+\
828-+ node2222 = node2222->PTR_NAME;\
829-+ }\
830-+ }\
831-+} while (0)
832-
833- /************************************************************//**
834- Gets the mutex index for a fold value in a hash table.
835-diff -ruN a/storage/innodb_plugin/include/os0proc.h b/storage/innodb_plugin/include/os0proc.h
836---- a/storage/innodb_plugin/include/os0proc.h 2010-06-04 00:49:59.000000000 +0900
837-+++ b/storage/innodb_plugin/include/os0proc.h 2010-07-14 16:40:16.169321536 +0900
838-@@ -32,6 +32,11 @@
839- #ifdef UNIV_LINUX
840- #include <sys/ipc.h>
841- #include <sys/shm.h>
842-+#else
843-+# if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
844-+#include <sys/ipc.h>
845-+#include <sys/shm.h>
846-+# endif
847- #endif
848-
849- typedef void* os_process_t;
850-@@ -70,6 +75,29 @@
851- ulint size); /*!< in: size returned by
852- os_mem_alloc_large() */
853-
854-+
855-+/****************************************************************//**
856-+Allocates or attaches and reuses shared memory segment.
857-+The content is not cleared automatically.
858-+@return allocated memory */
859-+UNIV_INTERN
860-+void*
861-+os_shm_alloc(
862-+/*=========*/
863-+ ulint* n, /*!< in/out: number of bytes */
864-+ uint key,
865-+ ibool* is_new);
866-+
867-+/****************************************************************//**
868-+Detach shared memory segment. */
869-+UNIV_INTERN
870-+void
871-+os_shm_free(
872-+/*========*/
873-+ void *ptr, /*!< in: pointer returned by
874-+ os_shm_alloc() */
875-+ ulint size); /*!< in: size returned by
876-+ os_shm_alloc() */
877- #ifndef UNIV_NONINL
878- #include "os0proc.ic"
879- #endif
880-diff -ruN a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h
881---- a/storage/innodb_plugin/include/srv0srv.h 2010-07-14 16:32:49.695323045 +0900
882-+++ b/storage/innodb_plugin/include/srv0srv.h 2010-07-14 16:40:16.171325784 +0900
883-@@ -156,6 +156,10 @@
884- extern ulint srv_mem_pool_size;
885- extern ulint srv_lock_table_size;
886-
887-+extern uint srv_buffer_pool_shm_key;
888-+extern ibool srv_buffer_pool_shm_is_reused;
889-+extern ibool srv_buffer_pool_shm_checksum;
890-+
891- extern ibool srv_thread_concurrency_timer_based;
892-
893- extern ulint srv_n_file_io_threads;
894-diff -ruN a/storage/innodb_plugin/include/ut0lst.h b/storage/innodb_plugin/include/ut0lst.h
895---- a/storage/innodb_plugin/include/ut0lst.h 2010-06-04 00:49:59.000000000 +0900
896-+++ b/storage/innodb_plugin/include/ut0lst.h 2010-07-14 16:40:16.172321547 +0900
897-@@ -257,5 +257,48 @@
898- ut_a(ut_list_node_313 == NULL); \
899- } while (0)
900-
901-+/********************************************************************//**
902-+Align nodes with moving location.
903-+@param NAME the name of the list
904-+@param TYPE node type
905-+@param BASE base node (not a pointer to it)
906-+@param OFFSET offset moved */
907-+#define UT_LIST_OFFSET(NAME, TYPE, BASE, FADDR, FOFFSET, BOFFSET) \
908-+do { \
909-+ ulint ut_list_i_313; \
910-+ TYPE* ut_list_node_313; \
911-+ \
912-+ if ((BASE).start) \
913-+ (BASE).start = (void*)((byte*)((BASE).start) \
914-+ + (((void*)((BASE).start) > (void*)FADDR)?FOFFSET:BOFFSET));\
915-+ if ((BASE).end) \
916-+ (BASE).end = (void*)((byte*)((BASE).end) \
917-+ + (((void*)((BASE).end) > (void*)FADDR)?FOFFSET:BOFFSET));\
918-+ \
919-+ ut_list_node_313 = (BASE).start; \
920-+ \
921-+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
922-+ ut_a(ut_list_node_313); \
923-+ if ((ut_list_node_313->NAME).prev) \
924-+ (ut_list_node_313->NAME).prev = (void*)((byte*)((ut_list_node_313->NAME).prev)\
925-+ + (((void*)((ut_list_node_313->NAME).prev) > (void*)FADDR)?FOFFSET:BOFFSET));\
926-+ if ((ut_list_node_313->NAME).next) \
927-+ (ut_list_node_313->NAME).next = (void*)((byte*)((ut_list_node_313->NAME).next)\
928-+ + (((void*)((ut_list_node_313->NAME).next)> (void*)FADDR)?FOFFSET:BOFFSET));\
929-+ ut_list_node_313 = (ut_list_node_313->NAME).next; \
930-+ } \
931-+ \
932-+ ut_a(ut_list_node_313 == NULL); \
933-+ \
934-+ ut_list_node_313 = (BASE).end; \
935-+ \
936-+ for (ut_list_i_313 = (BASE).count; ut_list_i_313--; ) { \
937-+ ut_a(ut_list_node_313); \
938-+ ut_list_node_313 = (ut_list_node_313->NAME).prev; \
939-+ } \
940-+ \
941-+ ut_a(ut_list_node_313 == NULL); \
942-+} while (0)
943-+
944- #endif
945-
946-diff -ruN a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c
947---- a/storage/innodb_plugin/log/log0recv.c 2010-10-01 15:25:27.106299166 +0900
948-+++ b/storage/innodb_plugin/log/log0recv.c 2010-10-01 15:26:33.689261436 +0900
949-@@ -2899,6 +2899,7 @@
950- /*==========================*/
951- {
952- ut_a(!recv_needed_recovery);
953-+ ut_a(!srv_buffer_pool_shm_is_reused);
954-
955- recv_needed_recovery = TRUE;
956-
957-diff -ruN a/storage/innodb_plugin/os/os0proc.c b/storage/innodb_plugin/os/os0proc.c
958---- a/storage/innodb_plugin/os/os0proc.c 2010-06-04 00:49:59.000000000 +0900
959-+++ b/storage/innodb_plugin/os/os0proc.c 2010-07-14 16:40:16.174322953 +0900
960-@@ -229,3 +229,173 @@
961- }
962- #endif
963- }
964-+
965-+/****************************************************************//**
966-+Allocates or attaches and reuses shared memory segment.
967-+The content is not cleared automatically.
968-+@return allocated memory */
969-+UNIV_INTERN
970-+void*
971-+os_shm_alloc(
972-+/*=========*/
973-+ ulint* n, /*!< in/out: number of bytes */
974-+ uint key,
975-+ ibool* is_new)
976-+{
977-+ void* ptr;
978-+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
979-+ ulint size;
980-+ int shmid;
981-+
982-+ *is_new = FALSE;
983-+ fprintf(stderr,
984-+ "InnoDB: The shared memory segment containing the buffer pool is: key %#x (%d).\n",
985-+ key, key);
986-+# if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
987-+ if (!os_use_large_pages || !os_large_page_size) {
988-+ goto skip;
989-+ }
990-+
991-+ /* Align block size to os_large_page_size */
992-+ ut_ad(ut_is_2pow(os_large_page_size));
993-+ size = ut_2pow_round(*n + (os_large_page_size - 1),
994-+ os_large_page_size);
995-+
996-+ shmid = shmget((key_t)key, (size_t)size,
997-+ IPC_CREAT | IPC_EXCL | SHM_HUGETLB | SHM_R | SHM_W);
998-+ if (shmid < 0) {
999-+ if (errno == EEXIST) {
1000-+ fprintf(stderr,
1001-+ "InnoDB: HugeTLB: The shared memory segment exists.\n");
1002-+ shmid = shmget((key_t)key, (size_t)size,
1003-+ SHM_HUGETLB | SHM_R | SHM_W);
1004-+ if (shmid < 0) {
1005-+ fprintf(stderr,
1006-+ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n",
1007-+ size, errno);
1008-+ goto skip;
1009-+ } else {
1010-+ fprintf(stderr,
1011-+ "InnoDB: HugeTLB: The existent shared memory segment is used.\n");
1012-+ }
1013-+ } else {
1014-+ fprintf(stderr,
1015-+ "InnoDB: HugeTLB: Warning: Failed to allocate %lu bytes. (new) errno %d\n",
1016-+ size, errno);
1017-+ goto skip;
1018-+ }
1019-+ } else {
1020-+ *is_new = TRUE;
1021-+ fprintf(stderr,
1022-+ "InnoDB: HugeTLB: A new shared memory segment has been created .\n");
1023-+ }
1024-+
1025-+ ptr = shmat(shmid, NULL, 0);
1026-+ if (ptr == (void *)-1) {
1027-+ fprintf(stderr,
1028-+ "InnoDB: HugeTLB: Warning: Failed to attach shared memory segment, errno %d\n",
1029-+ errno);
1030-+ ptr = NULL;
1031-+ }
1032-+
1033-+ if (ptr) {
1034-+ *n = size;
1035-+ os_fast_mutex_lock(&ut_list_mutex);
1036-+ ut_total_allocated_memory += size;
1037-+ os_fast_mutex_unlock(&ut_list_mutex);
1038-+ UNIV_MEM_ALLOC(ptr, size);
1039-+ return(ptr);
1040-+ }
1041-+skip:
1042-+ *is_new = FALSE;
1043-+# endif /* HAVE_LARGE_PAGES && defined UNIV_LINUX */
1044-+# ifdef HAVE_GETPAGESIZE
1045-+ size = getpagesize();
1046-+# else
1047-+ size = UNIV_PAGE_SIZE;
1048-+# endif
1049-+ /* Align block size to system page size */
1050-+ ut_ad(ut_is_2pow(size));
1051-+ size = *n = ut_2pow_round(*n + (size - 1), size);
1052-+
1053-+ shmid = shmget((key_t)key, (size_t)size,
1054-+ IPC_CREAT | IPC_EXCL | SHM_R | SHM_W);
1055-+ if (shmid < 0) {
1056-+ if (errno == EEXIST) {
1057-+ fprintf(stderr,
1058-+ "InnoDB: A shared memory segment containing the buffer pool seems to already exist.\n");
1059-+ shmid = shmget((key_t)key, (size_t)size,
1060-+ SHM_R | SHM_W);
1061-+ if (shmid < 0) {
1062-+ fprintf(stderr,
1063-+ "InnoDB: Warning: Failed to allocate %lu bytes. (reuse) errno %d\n",
1064-+ size, errno);
1065-+ ptr = NULL;
1066-+ goto end;
1067-+ } else {
1068-+ fprintf(stderr,
1069-+ "InnoDB: The existent shared memory segment is used.\n");
1070-+ }
1071-+ } else {
1072-+ fprintf(stderr,
1073-+ "InnoDB: Warning: Failed to allocate %lu bytes. (new) errno %d\n",
1074-+ size, errno);
1075-+ ptr = NULL;
1076-+ goto end;
1077-+ }
1078-+ } else {
1079-+ *is_new = TRUE;
1080-+ fprintf(stderr,
1081-+ "InnoDB: A new shared memory segment has been created.\n");
1082-+ }
1083-+
1084-+ ptr = shmat(shmid, NULL, 0);
1085-+ if (ptr == (void *)-1) {
1086-+ fprintf(stderr,
1087-+ "InnoDB: Warning: Failed to attach shared memory segment, errno %d\n",
1088-+ errno);
1089-+ ptr = NULL;
1090-+ }
1091-+
1092-+ if (ptr) {
1093-+ *n = size;
1094-+ os_fast_mutex_lock(&ut_list_mutex);
1095-+ ut_total_allocated_memory += size;
1096-+ os_fast_mutex_unlock(&ut_list_mutex);
1097-+ UNIV_MEM_ALLOC(ptr, size);
1098-+ }
1099-+end:
1100-+#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1101-+ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
1102-+ ptr = NULL;
1103-+#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1104-+ return(ptr);
1105-+}
1106-+
1107-+/****************************************************************//**
1108-+Detach shared memory segment. */
1109-+UNIV_INTERN
1110-+void
1111-+os_shm_free(
1112-+/*========*/
1113-+ void *ptr, /*!< in: pointer returned by
1114-+ os_shm_alloc() */
1115-+ ulint size) /*!< in: size returned by
1116-+ os_shm_alloc() */
1117-+{
1118-+ os_fast_mutex_lock(&ut_list_mutex);
1119-+ ut_a(ut_total_allocated_memory >= size);
1120-+ os_fast_mutex_unlock(&ut_list_mutex);
1121-+
1122-+#if defined HAVE_SYS_IPC_H && HAVE_SYS_SHM_H
1123-+ if (!shmdt(ptr)) {
1124-+ os_fast_mutex_lock(&ut_list_mutex);
1125-+ ut_a(ut_total_allocated_memory >= size);
1126-+ ut_total_allocated_memory -= size;
1127-+ os_fast_mutex_unlock(&ut_list_mutex);
1128-+ UNIV_MEM_FREE(ptr, size);
1129-+ }
1130-+#else /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1131-+ fprintf(stderr, "InnoDB: shared memory segment is not supported.\n");
1132-+#endif /* HAVE_SYS_IPC_H && HAVE_SYS_SHM_H */
1133-+}
1134-diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
1135---- a/storage/innodb_plugin/srv/srv0srv.c 2010-07-14 16:33:23.848391648 +0900
1136-+++ b/storage/innodb_plugin/srv/srv0srv.c 2010-07-14 16:40:16.177323553 +0900
1137-@@ -211,6 +211,11 @@
1138- UNIV_INTERN ulint srv_mem_pool_size = ULINT_MAX;
1139- UNIV_INTERN ulint srv_lock_table_size = ULINT_MAX;
1140-
1141-+/* key value for shm */
1142-+UNIV_INTERN uint srv_buffer_pool_shm_key = 0;
1143-+UNIV_INTERN ibool srv_buffer_pool_shm_is_reused = FALSE;
1144-+UNIV_INTERN ibool srv_buffer_pool_shm_checksum = TRUE;
1145-+
1146- /* This parameter is deprecated. Use srv_n_io_[read|write]_threads
1147- instead. */
1148- UNIV_INTERN ulint srv_n_file_io_threads = ULINT_MAX;
1149-diff -ruN a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c
1150---- a/storage/innodb_plugin/srv/srv0start.c 2010-07-14 16:33:23.851391514 +0900
1151-+++ b/storage/innodb_plugin/srv/srv0start.c 2010-07-14 16:40:16.180321173 +0900
1152-@@ -1750,6 +1750,8 @@
1153- Note that this is not as heavy weight as it seems. At
1154- this point there will be only ONE page in the buf_LRU
1155- and there must be no page in the buf_flush list. */
1156-+ /* buffer_pool_shm should not be reused when recovery was needed. */
1157-+ if (!srv_buffer_pool_shm_is_reused)
1158- buf_pool_invalidate();
1159-
1160- /* We always try to do a recovery, even if the database had
1161
1162=== modified file 'innodb_fast_shutdown.patch'
1163--- innodb_fast_shutdown.patch 2011-05-12 11:00:37 +0000
1164+++ innodb_fast_shutdown.patch 2011-06-21 09:06:00 +0000
1165@@ -165,7 +165,7 @@
1166 diff -ruN a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c
1167 --- a/storage/innodb_plugin/srv/srv0srv.c 2010-11-16 21:33:00.000000000 +0300
1168 +++ b/storage/innodb_plugin/srv/srv0srv.c 2010-11-16 21:34:06.000000000 +0300
1169-@@ -713,6 +713,8 @@
1170+@@ -708,6 +708,8 @@
1171
1172 UNIV_INTERN os_event_t srv_lock_timeout_thread_event;
1173
1174@@ -174,7 +174,7 @@
1175 UNIV_INTERN srv_sys_t* srv_sys = NULL;
1176
1177 /* padding to prevent other memory update hotspots from residing on
1178-@@ -1018,6 +1020,7 @@
1179+@@ -1013,6 +1015,7 @@
1180 }
1181
1182 srv_lock_timeout_thread_event = os_event_create(NULL);
1183@@ -182,7 +182,7 @@
1184
1185 for (i = 0; i < SRV_MASTER + 1; i++) {
1186 srv_n_threads_active[i] = 0;
1187-@@ -2245,7 +2248,7 @@
1188+@@ -2240,7 +2243,7 @@
1189 /* Wake up every 5 seconds to see if we need to print
1190 monitor information. */
1191
1192@@ -191,7 +191,7 @@
1193
1194 current_time = time(NULL);
1195
1196-@@ -2387,7 +2390,7 @@
1197+@@ -2382,7 +2385,7 @@
1198 /* When someone is waiting for a lock, we wake up every second
1199 and check if a timeout has passed for a lock wait */
1200
1201@@ -200,7 +200,7 @@
1202
1203 srv_lock_timeout_active = TRUE;
1204
1205-@@ -2561,7 +2564,7 @@
1206+@@ -2556,7 +2559,7 @@
1207
1208 fflush(stderr);
1209
1210@@ -209,7 +209,7 @@
1211
1212 if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
1213
1214-@@ -2605,7 +2608,7 @@
1215+@@ -2600,7 +2603,7 @@
1216 last_dump_time = time(NULL);
1217
1218 loop:
1219@@ -218,7 +218,7 @@
1220
1221 if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
1222 goto exit_func;
1223-@@ -2788,7 +2791,7 @@
1224+@@ -2783,7 +2786,7 @@
1225 if (!skip_sleep) {
1226 if (next_itr_time > cur_time) {
1227
1228@@ -227,7 +227,7 @@
1229 srv_main_sleeps++;
1230
1231 /*
1232-@@ -3495,9 +3498,10 @@
1233+@@ -3490,9 +3493,10 @@
1234 mutex_exit(&kernel_mutex);
1235
1236 sleep_ms = 10;

Subscribers

People subscribed via source and target branches