Merge lp:~percona-dev/percona-server/5.1.57-minimize_buf_pool_shm into lp:percona-server/5.1
- 5.1.57-minimize_buf_pool_shm
- Merge into 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 |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith | Pending | ||
Review via email: mp+65319@code.launchpad.net |
Commit message
Description of the change
invalidate the options added by innodb_
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; |
http:// jenkins. percona. com/view/ Percona% 20Server% 205.1/job/ percona- server- 5.1-param/ 15/
(running build)