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