27 int mi_lock_database(
MI_INFO *info,
int lock_type)
32 DBUG_ENTER(
"mi_lock_database");
33 DBUG_PRINT(
"enter",(
"lock_type: %d old lock %d r_locks: %u w_locks: %u "
34 "global_changed: %d open_count: %u name: '%s'",
35 lock_type, info->lock_type, share->r_locks,
37 share->global_changed, share->state.open_count,
38 share->index_file_name));
39 if (share->options & HA_OPTION_READ_ONLY_DATA ||
40 info->lock_type == lock_type)
42 if (lock_type == F_EXTRA_LCK)
46 info->lock_type= lock_type;
47 info->s->in_use= list_add(info->s->in_use, &info->in_use);
53 if (share->kfile >= 0)
57 ftparser_call_deinitializer(info);
58 if (info->lock_type == F_RDLCK)
59 count= --share->r_locks;
61 count= --share->w_locks;
63 if (info->lock_type == F_WRLCK && !share->w_locks &&
64 !share->delay_key_write && flush_key_blocks(share->key_cache,
65 share->kfile,FLUSH_KEEP))
68 mi_print_error(info->s, HA_ERR_CRASHED);
69 mi_mark_crashed(info);
71 if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
73 if (end_io_cache(&info->rec_cache))
76 mi_print_error(info->s, HA_ERR_CRASHED);
77 mi_mark_crashed(info);
82 DBUG_PRINT(
"info",(
"changed: %u w_locks: %u",
83 (uint) share->changed, share->w_locks));
84 if (share->changed && !share->w_locks)
87 if ((info->s->mmaped_length != info->s->state.state.data_file_length) &&
88 (info->s->nonmmaped_inserts > MAX_NONMAPPED_INSERTS))
90 if (info->s->concurrent_insert)
92 mi_remap_file(info, info->s->state.state.data_file_length);
93 info->s->nonmmaped_inserts= 0;
94 if (info->s->concurrent_insert)
98 share->state.process= share->last_process=share->this_process;
99 share->state.unique= info->last_unique= info->this_unique;
100 share->state.update_count= info->last_loop= ++info->this_loop;
101 if (mi_state_info_write(share->kfile, &share->state, 1))
112 share->not_flushed=1;
115 mi_print_error(info->s, HA_ERR_CRASHED);
116 mi_mark_crashed(info);
119 if (info->lock_type != F_EXTRA_LCK)
123 if (my_lock(share->kfile,F_RDLCK,0L,F_TO_EOF,
124 MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
127 else if (!share->w_locks)
129 if (my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
130 MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
135 info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
136 info->lock_type= F_UNLCK;
137 info->s->in_use= list_delete(info->s->in_use, &info->in_use);
140 if (info->lock_type == F_WRLCK)
148 if (share->w_locks == 1)
150 if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
151 MYF(MY_SEEK_NOT_DONE)))
159 info->lock_type=lock_type;
162 if (!share->r_locks && !share->w_locks)
164 if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
165 info->lock_wait | MY_SEEK_NOT_DONE))
170 if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
173 (void) my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE));
178 (void) _mi_test_if_changed(info);
181 info->lock_type=lock_type;
182 info->s->in_use= list_add(info->s->in_use, &info->in_use);
185 if (info->lock_type == F_RDLCK)
187 if (share->r_locks == 1)
189 if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
190 MYF(info->lock_wait | MY_SEEK_NOT_DONE)))
197 info->lock_type=lock_type;
201 if (!(share->options & HA_OPTION_READ_ONLY_DATA))
205 if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
206 info->lock_wait | MY_SEEK_NOT_DONE))
213 if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
216 (void) my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
217 info->lock_wait | MY_SEEK_NOT_DONE);
224 (void) _mi_test_if_changed(info);
226 info->lock_type=lock_type;
227 info->invalidator=info->s->invalidator;
230 info->s->in_use= list_add(info->s->in_use, &info->in_use);
245 if( info->owned_by_merge && (info->s)->kfile < 0 )
247 error = HA_ERR_NO_SUCH_TABLE;
270 void mi_get_status(
void* param,
int concurrent_insert)
273 DBUG_ENTER(
"mi_get_status");
274 DBUG_PRINT(
"info",(
"key_file: %ld data_file: %ld concurrent_insert: %d",
275 (
long) info->s->state.state.key_file_length,
276 (
long) info->s->state.state.data_file_length,
279 if (info->state->key_file_length > info->s->state.state.key_file_length ||
280 info->state->data_file_length > info->s->state.state.data_file_length)
281 DBUG_PRINT(
"warning",(
"old info: key_file: %ld data_file: %ld",
282 (
long) info->state->key_file_length,
283 (
long) info->state->data_file_length));
285 info->save_state=info->s->state.state;
286 info->state= &info->save_state;
287 info->append_insert_at_end= concurrent_insert;
288 if (concurrent_insert)
289 info->s->state.state.uncacheable= TRUE;
294 void mi_update_status(
void* param)
303 if (info->state == &info->save_state)
306 DBUG_PRINT(
"info",(
"updating status: key_file: %ld data_file: %ld",
307 (
long) info->state->key_file_length,
308 (
long) info->state->data_file_length));
309 if (info->state->key_file_length < info->s->state.state.key_file_length ||
310 info->state->data_file_length < info->s->state.state.data_file_length)
311 DBUG_PRINT(
"warning",(
"old info: key_file: %ld data_file: %ld",
312 (
long) info->s->state.state.key_file_length,
313 (
long) info->s->state.state.data_file_length));
315 info->s->state.state= *info->state;
317 info->state= &info->s->state.state;
318 info->append_insert_at_end= 0;
324 if (info->opt_flag & WRITE_CACHE_USED)
326 if (end_io_cache(&info->rec_cache))
328 mi_print_error(info->s, HA_ERR_CRASHED);
329 mi_mark_crashed(info);
331 info->opt_flag&= ~WRITE_CACHE_USED;
336 void mi_restore_status(
void *param)
339 info->state= &info->s->state.state;
340 info->append_insert_at_end= 0;
344 void mi_copy_status(
void*
to,
void *from)
371 my_bool mi_check_status(
void *param)
379 DBUG_PRINT(
"info",(
"dellink: %ld r_locks: %u w_locks: %u",
380 (
long) info->s->state.dellink, (uint) info->s->r_locks,
381 (uint) info->s->w_locks));
382 return (my_bool) !(info->s->state.dellink == HA_OFFSET_ERROR ||
383 (myisam_concurrent_insert == 2 && info->s->r_locks &&
384 info->s->w_locks == 1));
392 int _mi_readinfo(
register MI_INFO *info,
int lock_type,
int check_keybuffer)
394 DBUG_ENTER(
"_mi_readinfo");
396 if (info->lock_type == F_UNLCK)
399 if (!share->tot_locks)
401 if (my_lock(share->kfile,lock_type,0L,F_TO_EOF,
402 info->lock_wait | MY_SEEK_NOT_DONE))
404 if (mi_state_info_read_dsk(share->kfile, &share->state, 1))
406 int error=my_errno ? my_errno : -1;
407 (void) my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
408 MYF(MY_SEEK_NOT_DONE));
414 (void) _mi_test_if_changed(info);
415 info->invalidator=info->s->invalidator;
417 else if (lock_type == F_WRLCK && info->lock_type == F_RDLCK)
431 int _mi_writeinfo(
register MI_INFO *info, uint operation)
435 DBUG_ENTER(
"_mi_writeinfo");
436 DBUG_PRINT(
"info",(
"operation: %u tot_locks: %u", operation,
440 if (share->tot_locks == 0)
445 share->state.process= share->last_process= share->this_process;
446 share->state.unique= info->last_unique= info->this_unique;
447 share->state.update_count= info->last_loop= ++info->this_loop;
448 if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
458 if (!(operation & WRITEINFO_NO_UNLOCK) &&
459 my_lock(share->kfile,F_UNLCK,0L,F_TO_EOF,
460 MYF(MY_WME | MY_SEEK_NOT_DONE)) && !error)
473 int _mi_test_if_changed(
register MI_INFO *info)
476 if (share->state.process != share->last_process ||
477 share->state.unique != info->last_unique ||
478 share->state.update_count != info->last_loop)
480 DBUG_PRINT(
"info",(
"index file changed"));
481 if (share->state.process != share->this_process)
482 (void) flush_key_blocks(share->key_cache, share->kfile, FLUSH_RELEASE);
483 share->last_process=share->state.process;
484 info->last_unique= share->state.unique;
485 info->last_loop= share->state.update_count;
486 info->update|= HA_STATE_WRITTEN;
487 info->data_changed= 1;
490 return (!(info->update & HA_STATE_AKTIV) ||
491 (info->update & (HA_STATE_WRITTEN | HA_STATE_DELETED |
492 HA_STATE_KEY_CHANGED)));
515 int _mi_mark_file_changed(
MI_INFO *info)
519 DBUG_ENTER(
"_mi_mark_file_changed");
521 if (!(share->state.changed & STATE_CHANGED) || ! share->global_changed)
523 share->state.changed|=(STATE_CHANGED | STATE_NOT_ANALYZED |
524 STATE_NOT_OPTIMIZED_KEYS);
525 if (!share->global_changed)
527 share->global_changed=1;
528 share->state.open_count++;
530 if (!share->temporary)
532 mi_int2store(buff,share->state.open_count);
535 sizeof(share->state.header),
548 int _mi_decrement_open_count(
MI_INFO *info)
552 int lock_error=0,write_error=0;
553 if (share->global_changed)
555 uint old_lock=info->lock_type;
556 share->global_changed=0;
557 lock_error=mi_lock_database(info,F_WRLCK);
559 if (share->state.open_count > 0)
561 share->state.open_count--;
562 mi_int2store(buff,share->state.open_count);
564 sizeof(share->state.header),
568 lock_error=mi_lock_database(info,old_lock);
570 return test(lock_error || write_error);