mi_extra.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2 of the License, or
  6.    (at your option) any later version.
  7.    
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  16. /* Extra functions we want to do with a database */
  17. /* - Set flags for quicker databasehandler */
  18. /* - Set databasehandler to normal */
  19. /* - Reset recordpointers as after open database */
  20. #include "myisamdef.h"
  21. #ifdef HAVE_MMAP
  22. #include <sys/mman.h>
  23. #endif
  24. #ifdef __WIN__
  25. #include <errno.h>
  26. #endif
  27. /* set extra flags for database */
  28. int mi_extra(MI_INFO *info, enum ha_extra_function function)
  29. {
  30.   int error=0;
  31.   MYISAM_SHARE *share=info->s;
  32.   DBUG_ENTER("mi_extra");
  33.   switch (function) {
  34.   case HA_EXTRA_RESET:
  35.     /*
  36.       Free buffers and reset the following flags:
  37.       EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
  38.     */
  39.     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
  40.     {
  41.       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
  42.       error=end_io_cache(&info->rec_cache);
  43.     }
  44. #if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
  45.     if (info->opt_flag & MEMMAP_USED)
  46.       madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
  47. #endif
  48.     info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);    
  49.     info->quick_mode=0;
  50.     /* Fall through */
  51.   case HA_EXTRA_RESET_STATE: /* Reset state (don't free buffers) */
  52.     info->lastinx= 0; /* Use first index as def */
  53.     info->last_search_keypage=info->lastpos= HA_OFFSET_ERROR;
  54.     info->page_changed=1;
  55. /* Next/prev gives first/last */
  56.     if (info->opt_flag & READ_CACHE_USED)
  57.     {
  58.       reinit_io_cache(&info->rec_cache,READ_CACHE,0,
  59.       (pbool) (info->lock_type != F_UNLCK),
  60.       (pbool) test(info->update & HA_STATE_ROW_CHANGED)
  61.       );
  62.     }
  63.     info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
  64.    HA_STATE_PREV_FOUND);
  65.     break;
  66.   case HA_EXTRA_CACHE:
  67.     if (info->lock_type == F_UNLCK &&
  68. (share->options & HA_OPTION_PACK_RECORD))
  69.     {
  70.       error=1; /* Not possibly if not locked */
  71.       my_errno=EACCES;
  72.       break;
  73.     }
  74. #if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
  75.     if ((share->options & HA_OPTION_COMPRESS_RECORD))
  76.     {
  77.       pthread_mutex_lock(&share->intern_lock);
  78.       if (_mi_memmap_file(info))
  79.       {
  80. /* We don't nead MADV_SEQUENTIAL if small file */
  81. madvise(share->file_map,share->state.state.data_file_length,
  82. share->state.state.data_file_length <= RECORD_CACHE_SIZE*16 ?
  83. MADV_RANDOM : MADV_SEQUENTIAL);
  84. pthread_mutex_unlock(&share->intern_lock);
  85. break;
  86.       }
  87.       pthread_mutex_unlock(&share->intern_lock);
  88.     }
  89. #endif
  90.     if (info->opt_flag & WRITE_CACHE_USED)
  91.     {
  92.       info->opt_flag&= ~WRITE_CACHE_USED;
  93.       if ((error=end_io_cache(&info->rec_cache)))
  94. break;
  95.     }
  96.     if (!(info->opt_flag &
  97.   (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
  98.     {
  99.       if (!(init_io_cache(&info->rec_cache,info->dfile,
  100.  (uint) min(info->state->data_file_length+1,
  101.     my_default_record_cache_size),
  102.  READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
  103.  MYF(share->write_flag & MY_WAIT_IF_FULL))))
  104.       {
  105. info->opt_flag|=READ_CACHE_USED;
  106. info->update&= ~HA_STATE_ROW_CHANGED;
  107.       }
  108.       if (share->concurrent_insert)
  109. info->rec_cache.end_of_file=info->state->data_file_length;
  110.     }
  111.     break;
  112.   case HA_EXTRA_REINIT_CACHE:
  113.     if (info->opt_flag & READ_CACHE_USED)
  114.     {
  115.       reinit_io_cache(&info->rec_cache,READ_CACHE,info->nextpos,
  116.       (pbool) (info->lock_type != F_UNLCK),
  117.       (pbool) test(info->update & HA_STATE_ROW_CHANGED));
  118.       info->update&= ~HA_STATE_ROW_CHANGED;
  119.       if (share->concurrent_insert)
  120. info->rec_cache.end_of_file=info->state->data_file_length;
  121.     }
  122.     break;
  123.   case HA_EXTRA_WRITE_CACHE:
  124.     if (info->lock_type == F_UNLCK)
  125.     {
  126.       error=1; /* Not possibly if not locked */
  127.       break;
  128.     }
  129.     if (!(info->opt_flag &
  130.   (READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
  131. !share->state.header.uniques)
  132.       if (!(init_io_cache(&info->rec_cache,info->dfile,0,
  133.  WRITE_CACHE,info->state->data_file_length,
  134.   (pbool) (info->lock_type != F_UNLCK),
  135.   MYF(share->write_flag & MY_WAIT_IF_FULL))))
  136.       {
  137. info->opt_flag|=WRITE_CACHE_USED;
  138. info->update&= ~(HA_STATE_ROW_CHANGED |
  139.  HA_STATE_WRITE_AT_END |
  140.  HA_STATE_EXTEND_BLOCK);
  141.       }
  142.     break;
  143.   case HA_EXTRA_NO_CACHE:
  144.     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
  145.     {
  146.       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
  147.       error=end_io_cache(&info->rec_cache);
  148.       /* Sergei will insert full text index caching here */
  149.     }
  150. #if defined(HAVE_MMAP) && defined(HAVE_MADVICE)
  151.     if (info->opt_flag & MEMMAP_USED)
  152.       madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM);
  153. #endif
  154.     break;
  155.   case HA_EXTRA_FLUSH_CACHE:
  156.     if (info->opt_flag & WRITE_CACHE_USED)
  157.     {
  158.       if ((error=flush_io_cache(&info->rec_cache)))
  159. mi_mark_crashed(info); /* Fatal error found */
  160.     }
  161.     break;
  162.   case HA_EXTRA_NO_READCHECK:
  163.     info->opt_flag&= ~READ_CHECK_USED; /* No readcheck */
  164.     break;
  165.   case HA_EXTRA_READCHECK:
  166.     info->opt_flag|= READ_CHECK_USED;
  167.     break;
  168.   case HA_EXTRA_KEYREAD: /* Read only keys to record */
  169.   case HA_EXTRA_REMEMBER_POS:
  170.     info->opt_flag |= REMEMBER_OLD_POS;
  171.     bmove((byte*) info->lastkey+share->base.max_key_length*2,
  172.   (byte*) info->lastkey,info->lastkey_length);
  173.     info->save_update= info->update;
  174.     info->save_lastinx= info->lastinx;
  175.     info->save_lastpos= info->lastpos;
  176.     info->save_lastkey_length=info->lastkey_length;
  177.     if (function == HA_EXTRA_REMEMBER_POS)
  178.       break;
  179.     /* fall through */
  180.   case HA_EXTRA_KEYREAD_CHANGE_POS:
  181.     info->opt_flag |= KEY_READ_USED;
  182.     info->read_record=_mi_read_key_record;
  183.     break;
  184.   case HA_EXTRA_NO_KEYREAD:
  185.   case HA_EXTRA_RESTORE_POS:
  186.     if (info->opt_flag & REMEMBER_OLD_POS)
  187.     {
  188.       bmove((byte*) info->lastkey,
  189.     (byte*) info->lastkey+share->base.max_key_length*2,
  190.     info->save_lastkey_length);
  191.       info->update= info->save_update | HA_STATE_WRITTEN;
  192.       info->lastinx= info->save_lastinx;
  193.       info->lastpos= info->save_lastpos;
  194.       info->lastkey_length=info->save_lastkey_length;
  195.     }
  196.     info->read_record= share->read_record;
  197.     info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
  198.     break;
  199.   case HA_EXTRA_NO_USER_CHANGE: /* Database is somehow locked agains changes */
  200.     info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
  201.     break;
  202.   case HA_EXTRA_WAIT_LOCK:
  203.     info->lock_wait=0;
  204.     break;
  205.   case HA_EXTRA_NO_WAIT_LOCK:
  206.     info->lock_wait=MY_DONT_WAIT;
  207.     break;
  208.   case HA_EXTRA_NO_KEYS:
  209.     if (info->lock_type == F_UNLCK)
  210.     {
  211.       error=1; /* Not possibly if not lock */
  212.       break;
  213.     }
  214.     if (share->state.key_map)
  215.     {
  216.       share->state.key_map=0;
  217.       info->state->key_file_length=share->state.state.key_file_length=
  218. share->base.keystart;
  219.       if (!share->changed)
  220.       {
  221. share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
  222. share->changed=1; /* Update on close */
  223. if (!share->global_changed)
  224. {
  225.   share->global_changed=1;
  226.   share->state.open_count++;
  227. }
  228.       }
  229.       share->state.state= *info->state;
  230.       error=mi_state_info_write(share->kfile,&share->state,1 | 2);
  231.     }
  232.     break;
  233.   case HA_EXTRA_FORCE_REOPEN:
  234.     pthread_mutex_lock(&THR_LOCK_myisam);
  235.     share->last_version= 0L; /* Impossible version */
  236. #ifdef __WIN__
  237.     /* Close the isam and data files as Win32 can't drop an open table */
  238.     pthread_mutex_lock(&share->intern_lock);
  239.     if (flush_key_blocks(share->kfile,FLUSH_RELEASE))
  240.     {
  241.       error=my_errno;
  242.       share->changed=1;
  243.       mi_mark_crashed(info); /* Fatal error found */
  244.     }
  245.     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
  246.     {
  247.       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
  248.       error=end_io_cache(&info->rec_cache);
  249.     }
  250.     if (info->lock_type != F_UNLCK && ! info->was_locked)
  251.     {
  252.       info->was_locked=info->lock_type;
  253.       if (mi_lock_database(info,F_UNLCK))
  254. error=my_errno;
  255.       info->lock_type = F_UNLCK;
  256.     }
  257.     if (share->kfile >= 0)
  258.       _mi_decrement_open_count(info);
  259.     if (share->kfile >= 0 && my_close(share->kfile,MYF(0)))
  260.       error=my_errno;
  261.     {
  262.       LIST *list_element ;
  263.       for (list_element=myisam_open_list ;
  264.    list_element ;
  265.    list_element=list_element->next)
  266.       {
  267. MI_INFO *tmpinfo=(MI_INFO*) list_element->data;
  268. if (tmpinfo->s == info->s)
  269. {
  270.   if (tmpinfo->dfile >= 0 && my_close(tmpinfo->dfile,MYF(0)))
  271.     error = my_errno;
  272.   tmpinfo->dfile= -1;
  273. }
  274.       }
  275.     }
  276.     share->kfile= -1; /* Files aren't open anymore */
  277.     pthread_mutex_unlock(&share->intern_lock);
  278. #endif
  279.     pthread_mutex_unlock(&THR_LOCK_myisam);
  280.     break;
  281.   case HA_EXTRA_FLUSH:
  282.     if (!share->temporary)
  283.       flush_key_blocks(share->kfile,FLUSH_KEEP);
  284. #ifdef HAVE_PWRITE
  285.     _mi_decrement_open_count(info);
  286. #endif
  287.     if (share->not_flushed)
  288.     {
  289.       share->not_flushed=0;
  290. #if defined(__WIN__)
  291.       if (_commit(share->kfile))
  292. error=errno;
  293.       if (_commit(info->dfile))
  294. error=errno;
  295. #elif defined(HAVE_FDATASYNC)
  296.       if (fdatasync(share->kfile))
  297. error=errno;
  298.       if (fdatasync(share->dfile))
  299. error=errno;
  300. #elif defined(HAVE_FSYNC)
  301.       if ( fsync(share->kfile))
  302. error=errno;
  303.       if (fsync(share->dfile))
  304. error=errno;
  305. #endif
  306.       if (error)
  307.       {
  308. share->changed=1;
  309. mi_mark_crashed(info); /* Fatal error found */
  310.       }
  311.     }
  312.     if (share->base.blobs)
  313.     {
  314.       my_free(info->rec_alloc,MYF(MY_ALLOW_ZERO_PTR));
  315.       info->rec_alloc=info->rec_buff=0;
  316.     }
  317.     break;
  318.   case HA_EXTRA_NORMAL: /* Theese isn't in use */
  319.     info->quick_mode=0;
  320.     break;
  321.   case HA_EXTRA_QUICK:
  322.     info->quick_mode=1;
  323.     break;
  324.   case HA_EXTRA_NO_ROWS:
  325.     if (!share->state.header.uniques)
  326.       info->opt_flag|= OPT_NO_ROWS;
  327.     break;
  328.   case HA_EXTRA_KEY_CACHE:
  329.   case HA_EXTRA_NO_KEY_CACHE:
  330.   default:
  331.     break;
  332.   }
  333.   {
  334.     char tmp[1];
  335.     tmp[0]=function;
  336.     myisam_log_command(MI_LOG_EXTRA,info,(byte*) tmp,1,error);
  337.   }
  338.   DBUG_RETURN(error);
  339. } /* mi_extra */