LTP GCOV extension - code coverage report
Current view: directory - storage/maria - ma_extra.c
Test: maria-unit-test.html
Date: 2009-03-04 Instrumented lines: 262
Code covered: 27.5 % Executed lines: 72

       1                 : /* Copyright (C) 2006 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; version 2 of the License.
       6                 : 
       7                 :    This program is distributed in the hope that it will be useful,
       8                 :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9                 :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10                 :    GNU General Public License for more details.
      11                 : 
      12                 :    You should have received a copy of the GNU General Public License
      13                 :    along with this program; if not, write to the Free Software
      14                 :    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
      15                 : 
      16                 : #include "maria_def.h"
      17                 : #ifdef HAVE_SYS_MMAN_H
      18                 : #include <sys/mman.h>
      19                 : #endif
      20                 : #include "ma_blockrec.h"
      21                 : 
      22                 : static void maria_extra_keyflag(MARIA_HA *info,
      23                 :                                 enum ha_extra_function function);
      24                 : 
      25                 : /**
      26                 :    @brief Set options and buffers to optimize table handling
      27                 : 
      28                 :    @param  name             table's name
      29                 :    @param  info             open table
      30                 :    @param  function         operation
      31                 :    @param  extra_arg        Pointer to extra argument (normally pointer to
      32                 :                             ulong); used when function is one of:
      33                 :                             HA_EXTRA_WRITE_CACHE
      34                 :                             HA_EXTRA_CACHE
      35                 : 
      36                 :    @return Operation status
      37                 :      @retval 0      ok
      38                 :      @retval !=0    error
      39                 : */
      40                 : 
      41                 : int maria_extra(MARIA_HA *info, enum ha_extra_function function,
      42                 :                 void *extra_arg)
      43             458 : {
      44             458 :   int error= 0;
      45                 :   ulong cache_size;
      46             458 :   MARIA_SHARE *share= info->s;
      47             458 :   my_bool block_records= share->data_file_type == BLOCK_RECORD;
      48             458 :   DBUG_ENTER("maria_extra");
      49             458 :   DBUG_PRINT("enter",("function: %d",(int) function));
      50                 : 
      51             458 :   switch (function) {
      52                 :   case HA_EXTRA_RESET_STATE:            /* Reset state (don't free buffers) */
      53               0 :     info->lastinx= 0;                        /* Use first index as def */
      54               0 :     info->last_search_keypage= info->cur_row.lastpos= HA_OFFSET_ERROR;
      55               0 :     info->page_changed= 1;
      56                 :                                         /* Next/prev gives first/last */
      57               0 :     if (info->opt_flag & READ_CACHE_USED)
      58                 :     {
      59               0 :       reinit_io_cache(&info->rec_cache,READ_CACHE,0,
      60                 :                       (pbool) (info->lock_type != F_UNLCK),
      61                 :                       (pbool) test(info->update & HA_STATE_ROW_CHANGED)
      62                 :                       );
      63                 :     }
      64               0 :     info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
      65                 :                    HA_STATE_PREV_FOUND);
      66               0 :     break;
      67                 :   case HA_EXTRA_CACHE:
      68             151 :     if (block_records)
      69              49 :       break;                                    /* Not supported */
      70                 : 
      71              49 :     if (info->lock_type == F_UNLCK &&
      72                 :         (share->options & HA_OPTION_PACK_RECORD))
      73                 :     {
      74               5 :       error= 1;                 /* Not possibly if not locked */
      75               5 :       my_errno= EACCES;
      76               5 :       break;
      77                 :     }
      78              44 :     if (info->s->file_map) /* Don't use cache if mmap */
      79              44 :       break;
      80                 : #if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
      81              44 :     if ((share->options & HA_OPTION_COMPRESS_RECORD))
      82                 :     {
      83               0 :       pthread_mutex_lock(&share->intern_lock);
      84               0 :       if (_ma_memmap_file(info))
      85                 :       {
      86                 :         /* We don't nead MADV_SEQUENTIAL if small file */
      87               0 :         madvise((char*) share->file_map, share->state.state.data_file_length,
      88                 :                 share->state.state.data_file_length <= RECORD_CACHE_SIZE*16 ?
      89                 :                 MADV_RANDOM : MADV_SEQUENTIAL);
      90               0 :         pthread_mutex_unlock(&share->intern_lock);
      91               0 :         break;
      92                 :       }
      93               0 :       pthread_mutex_unlock(&share->intern_lock);
      94                 :     }
      95                 : #endif
      96              44 :     if (info->opt_flag & WRITE_CACHE_USED)
      97                 :     {
      98               0 :       info->opt_flag&= ~WRITE_CACHE_USED;
      99               0 :       if ((error= end_io_cache(&info->rec_cache)))
     100              44 :         break;
     101                 :     }
     102              44 :     if (!(info->opt_flag &
     103                 :           (READ_CACHE_USED | WRITE_CACHE_USED | MEMMAP_USED)))
     104                 :     {
     105              44 :       cache_size= (extra_arg ? *(ulong*) extra_arg :
     106                 :                    my_default_record_cache_size);
     107              44 :       if (!(init_io_cache(&info->rec_cache, info->dfile.file,
     108                 :                          (uint) min(share->state.state.data_file_length+1,
     109                 :                                     cache_size),
     110                 :                           READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
     111                 :                           MYF(share->write_flag & MY_WAIT_IF_FULL))))
     112                 :       {
     113              44 :         info->opt_flag|= READ_CACHE_USED;
     114              44 :         info->update&=   ~HA_STATE_ROW_CHANGED;
     115                 :       }
     116              44 :       if (share->non_transactional_concurrent_insert)
     117               0 :         info->rec_cache.end_of_file= info->state->data_file_length;
     118                 :     }
     119                 :     break;
     120                 :   case HA_EXTRA_REINIT_CACHE:
     121               0 :     if (info->opt_flag & READ_CACHE_USED)
     122                 :     {
     123               0 :       reinit_io_cache(&info->rec_cache, READ_CACHE, info->cur_row.nextpos,
     124                 :                       (pbool) (info->lock_type != F_UNLCK),
     125                 :                       (pbool) test(info->update & HA_STATE_ROW_CHANGED));
     126               0 :       info->update&= ~HA_STATE_ROW_CHANGED;
     127               0 :       if (share->non_transactional_concurrent_insert)
     128               0 :         info->rec_cache.end_of_file= info->state->data_file_length;
     129                 :     }
     130                 :     break;
     131                 :   case HA_EXTRA_WRITE_CACHE:
     132              63 :     if (info->lock_type == F_UNLCK)
     133                 :     {
     134               0 :       error= 1;                         /* Not possibly if not locked */
     135               0 :       break;
     136                 :     }
     137              63 :     if (block_records)
     138               7 :       break;                            /* Not supported */
     139                 : 
     140               7 :     cache_size= (extra_arg ? *(ulong*) extra_arg :
     141                 :                  my_default_record_cache_size);
     142               7 :     if (!(info->opt_flag &
     143                 :           (READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
     144                 :         !share->state.header.uniques)
     145               7 :       if (!(init_io_cache(&info->rec_cache, info->dfile.file, cache_size,
     146                 :                          WRITE_CACHE,share->state.state.data_file_length,
     147                 :                           (pbool) (info->lock_type != F_UNLCK),
     148                 :                           MYF(share->write_flag & MY_WAIT_IF_FULL))))
     149                 :       {
     150               7 :         info->opt_flag|= WRITE_CACHE_USED;
     151               7 :         info->update&=   ~(HA_STATE_ROW_CHANGED |
     152                 :                            HA_STATE_WRITE_AT_END |
     153                 :                            HA_STATE_EXTEND_BLOCK);
     154                 :       }
     155                 :     break;
     156                 :   case HA_EXTRA_PREPARE_FOR_UPDATE:
     157               0 :     if (info->s->data_file_type != DYNAMIC_RECORD)
     158             244 :       break;
     159                 :     /* Remove read/write cache if dynamic rows */
     160                 :   case HA_EXTRA_NO_CACHE:
     161             244 :     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
     162                 :     {
     163              51 :       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
     164              51 :       error= end_io_cache(&info->rec_cache);
     165                 :       /* Sergei will insert full text index caching here */
     166                 :     }
     167                 : #if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
     168             244 :     if (info->opt_flag & MEMMAP_USED)
     169               0 :       madvise((char*) share->file_map, share->state.state.data_file_length,
     170                 :               MADV_RANDOM);
     171                 : #endif
     172                 :     break;
     173                 :   case HA_EXTRA_FLUSH_CACHE:
     174               0 :     if (info->opt_flag & WRITE_CACHE_USED)
     175                 :     {
     176               0 :       if ((error= flush_io_cache(&info->rec_cache)))
     177                 :       {
     178               0 :         maria_print_error(info->s, HA_ERR_CRASHED);
     179               0 :         maria_mark_crashed(info);                       /* Fatal error found */
     180                 :       }
     181                 :     }
     182                 :     break;
     183                 :   case HA_EXTRA_NO_READCHECK:
     184               0 :     info->opt_flag&= ~READ_CHECK_USED;           /* No readcheck */
     185               0 :     break;
     186                 :   case HA_EXTRA_READCHECK:
     187               0 :     info->opt_flag|= READ_CHECK_USED;
     188               0 :     break;
     189                 :   case HA_EXTRA_KEYREAD:                        /* Read only keys to record */
     190                 :   case HA_EXTRA_REMEMBER_POS:
     191               0 :     info->opt_flag|= REMEMBER_OLD_POS;
     192               0 :     bmove(info->last_key.data + share->base.max_key_length*2,
     193                 :           info->last_key.data,
     194                 :           info->last_key.data_length + info->last_key.ref_length);
     195               0 :     info->save_update=       info->update;
     196               0 :     info->save_lastinx= info->lastinx;
     197               0 :     info->save_lastpos= info->cur_row.lastpos;
     198               0 :     info->save_lastkey_data_length= info->last_key.data_length;
     199               0 :     info->save_lastkey_ref_length= info->last_key.ref_length;
     200               0 :     if (function == HA_EXTRA_REMEMBER_POS)
     201               0 :       break;
     202                 :     /* fall through */
     203                 :   case HA_EXTRA_KEYREAD_CHANGE_POS:
     204               0 :     info->opt_flag|= KEY_READ_USED;
     205               0 :     info->read_record= _ma_read_key_record;
     206               0 :     break;
     207                 :   case HA_EXTRA_NO_KEYREAD:
     208                 :   case HA_EXTRA_RESTORE_POS:
     209               0 :     if (info->opt_flag & REMEMBER_OLD_POS)
     210                 :     {
     211               0 :       bmove(info->last_key.data,
     212                 :             info->last_key.data + share->base.max_key_length*2,
     213                 :             info->save_lastkey_data_length + info->save_lastkey_ref_length);
     214               0 :       info->update=  info->save_update | HA_STATE_WRITTEN;
     215               0 :       info->lastinx= info->save_lastinx;
     216               0 :       info->cur_row.lastpos= info->save_lastpos;
     217               0 :       info->last_key.data_length= info->save_lastkey_data_length;
     218               0 :       info->last_key.ref_length= info->save_lastkey_ref_length;
     219               0 :       info->last_key.flag= 0;
     220                 :     }
     221               0 :     info->read_record=       share->read_record;
     222               0 :     info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
     223               0 :     break;
     224                 :   case HA_EXTRA_NO_USER_CHANGE: /* Database is somehow locked agains changes */
     225               0 :     info->lock_type= F_EXTRA_LCK; /* Simulate as locked */
     226               0 :     break;
     227                 :   case HA_EXTRA_WAIT_LOCK:
     228               0 :     info->lock_wait= 0;
     229               0 :     break;
     230                 :   case HA_EXTRA_NO_WAIT_LOCK:
     231               0 :     info->lock_wait= MY_SHORT_WAIT;
     232               0 :     break;
     233                 :   case HA_EXTRA_NO_KEYS:
     234                 :     /* we're going to modify pieces of the state, stall Checkpoint */
     235               0 :     pthread_mutex_lock(&share->intern_lock);
     236               0 :     if (info->lock_type == F_UNLCK)
     237                 :     {
     238               0 :       pthread_mutex_unlock(&share->intern_lock);
     239               0 :       error= 1;                                 /* Not possibly if not lock */
     240               0 :       break;
     241                 :     }
     242               0 :     if (maria_is_any_key_active(share->state.key_map))
     243                 :     {
     244               0 :       MARIA_KEYDEF *key= share->keyinfo;
     245                 :       uint i;
     246               0 :       for (i =0 ; i < share->base.keys ; i++,key++)
     247                 :       {
     248               0 :         if (!(key->flag & HA_NOSAME) && info->s->base.auto_key != i+1)
     249                 :         {
     250               0 :           maria_clear_key_active(share->state.key_map, i);
     251               0 :           info->update|= HA_STATE_CHANGED;
     252                 :         }
     253                 :       }
     254                 : 
     255               0 :       if (!share->changed)
     256                 :       {
     257               0 :         share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
     258               0 :         share->changed= 1;                   /* Update on close */
     259               0 :         if (!share->global_changed)
     260                 :         {
     261               0 :           share->global_changed= 1;
     262               0 :           share->state.open_count++;
     263                 :         }
     264                 :       }
     265               0 :       if (!share->now_transactional)
     266               0 :         share->state.state= *info->state;
     267                 :       /*
     268                 :         That state write to disk must be done, even for transactional tables;
     269                 :         indeed the table's share is going to be lost (there was a
     270                 :         HA_EXTRA_FORCE_REOPEN before, which set share->last_version to
     271                 :         0), and so the only way it leaves information (share->state.key_map)
     272                 :         for the posterity is by writing it to disk.
     273                 :       */
     274               0 :       DBUG_ASSERT(!maria_in_recovery);
     275               0 :       error= _ma_state_info_write(share,
     276                 :                                   MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET |
     277                 :                                   MA_STATE_INFO_WRITE_FULL_INFO);
     278                 :     }
     279               0 :     pthread_mutex_unlock(&share->intern_lock);
     280               0 :     break;
     281                 :   case HA_EXTRA_FORCE_REOPEN:
     282                 :     /*
     283                 :       MySQL uses this case after it has closed all other instances
     284                 :       of this table.
     285                 :       We however do a flush here for additional safety.
     286                 :     */
     287                 :     /** @todo consider porting these flush-es to MyISAM */
     288               0 :     DBUG_ASSERT(share->reopen == 1);
     289               0 :     error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
     290                 :                                  FLUSH_FORCE_WRITE, FLUSH_FORCE_WRITE);
     291               0 :     if (!error && share->changed)
     292                 :     {
     293               0 :       pthread_mutex_lock(&share->intern_lock);
     294               0 :       if (!(error= _ma_state_info_write(share,
     295                 :                                         MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET|
     296                 :                                         MA_STATE_INFO_WRITE_FULL_INFO)))
     297               0 :         share->changed= 0;
     298               0 :       pthread_mutex_unlock(&share->intern_lock);
     299                 :     }
     300               0 :     pthread_mutex_lock(&THR_LOCK_maria);
     301               0 :     pthread_mutex_lock(&share->intern_lock); /* protect against Checkpoint */
     302                 :     /* this makes the share not be re-used next time the table is opened */
     303               0 :     share->last_version= 0L;                 /* Impossible version */
     304               0 :     pthread_mutex_unlock(&share->intern_lock);
     305               0 :     pthread_mutex_unlock(&THR_LOCK_maria);
     306               0 :     break;
     307                 :   case HA_EXTRA_PREPARE_FOR_DROP:
     308                 :   case HA_EXTRA_PREPARE_FOR_RENAME:
     309                 :   {
     310               0 :     my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP);
     311                 :     enum flush_type type;
     312               0 :     pthread_mutex_lock(&THR_LOCK_maria);
     313                 :     /*
     314                 :       This share, to have last_version=0, needs to save all its data/index
     315                 :       blocks to disk if this is not for a DROP TABLE. Otherwise they would be
     316                 :       invisible to future openers; and they could even go to disk late and
     317                 :       cancel the work of future openers.
     318                 :     */
     319               0 :     if (info->lock_type != F_UNLCK && !info->was_locked)
     320                 :     {
     321               0 :       info->was_locked= info->lock_type;
     322               0 :       if (maria_lock_database(info, F_UNLCK))
     323               0 :         error= my_errno;
     324               0 :       info->lock_type= F_UNLCK;
     325                 :     }
     326               0 :     if (share->kfile.file >= 0)
     327               0 :       _ma_decrement_open_count(info);
     328               0 :     pthread_mutex_lock(&share->intern_lock);
     329               0 :     if (info->trn)
     330                 :     {
     331               0 :       _ma_remove_table_from_trnman(share, info->trn);
     332                 :       /* Ensure we don't point to the deleted data in trn */
     333               0 :       info->state= info->state_start= &share->state.state;
     334                 :     }
     335                 : 
     336               0 :     type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED;
     337               0 :     if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
     338                 :                               type, type))
     339                 :     {
     340               0 :       error=my_errno;
     341               0 :       share->changed= 1;
     342                 :     }
     343               0 :     if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
     344                 :     {
     345               0 :       info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
     346               0 :       if (end_io_cache(&info->rec_cache))
     347               0 :         error= 1;
     348                 :     }
     349               0 :     if (share->kfile.file >= 0)
     350                 :     {
     351               0 :       if (do_flush)
     352                 :       {
     353                 :         /* Save the state so that others can find it from disk. */
     354               0 :         if ((share->changed &&
     355                 :              _ma_state_info_write(share,
     356                 :                                   MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET |
     357                 :                                   MA_STATE_INFO_WRITE_FULL_INFO)) ||
     358                 :             my_sync(share->kfile.file, MYF(0)))
     359               0 :           error= my_errno;
     360                 :         else
     361               0 :           share->changed= 0;
     362                 :       }
     363                 :       else
     364                 :       {
     365                 :         /* be sure that state is not tried for write as file may be closed */
     366               0 :         share->changed= 0;
     367                 :       }
     368                 :     }
     369               0 :     if (share->data_file_type == BLOCK_RECORD &&
     370                 :         share->bitmap.file.file >= 0)
     371                 :     {
     372               0 :       if (do_flush && my_sync(share->bitmap.file.file, MYF(0)))
     373               0 :         error= my_errno;
     374                 :     }
     375                 :     /* For protection against Checkpoint, we set under intern_lock: */
     376               0 :     share->last_version= 0L;                 /* Impossible version */
     377               0 :     pthread_mutex_unlock(&share->intern_lock);
     378               0 :     pthread_mutex_unlock(&THR_LOCK_maria);
     379               0 :     break;
     380                 :   }
     381                 :   case HA_EXTRA_PREPARE_FOR_FORCED_CLOSE:
     382               0 :     if (info->trn)
     383                 :     {
     384               0 :       pthread_mutex_lock(&share->intern_lock);
     385               0 :       _ma_remove_table_from_trnman(share, info->trn);
     386                 :       /* Ensure we don't point to the deleted data in trn */
     387               0 :       info->state= info->state_start= &share->state.state;
     388               0 :       pthread_mutex_unlock(&share->intern_lock);    
     389                 :     }
     390                 :     break;
     391                 :   case HA_EXTRA_FLUSH:
     392               0 :     if (!share->temporary)
     393               0 :       error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
     394                 :                                    FLUSH_KEEP, FLUSH_KEEP);
     395                 : #ifdef HAVE_PWRITE
     396                 :     _ma_decrement_open_count(info);
     397                 : #endif
     398               0 :     if (share->not_flushed)
     399                 :     {
     400               0 :       share->not_flushed= 0;
     401               0 :       if (_ma_sync_table_files(info))
     402               0 :         error= my_errno;
     403               0 :       if (error)
     404                 :       {
     405               0 :         share->changed= 1;
     406               0 :         maria_print_error(info->s, HA_ERR_CRASHED);
     407               0 :         maria_mark_crashed(info);                       /* Fatal error found */
     408                 :       }
     409                 :     }
     410                 :     break;
     411                 :   case HA_EXTRA_NORMAL:                         /* Theese isn't in use */
     412               0 :     info->quick_mode= 0;
     413               0 :     break;
     414                 :   case HA_EXTRA_QUICK:
     415               0 :     info->quick_mode= 1;
     416               0 :     break;
     417                 :   case HA_EXTRA_NO_ROWS:
     418               0 :     if (!share->state.header.uniques)
     419               0 :       info->opt_flag|= OPT_NO_ROWS;
     420                 :     break;
     421                 :   case HA_EXTRA_PRELOAD_BUFFER_SIZE:
     422               0 :     info->preload_buff_size= *((ulong *) extra_arg);
     423               0 :     break;
     424                 :   case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
     425                 :   case HA_EXTRA_CHANGE_KEY_TO_DUP:
     426               0 :     maria_extra_keyflag(info, function);
     427               0 :     break;
     428                 :   case HA_EXTRA_MMAP:
     429                 : #ifdef HAVE_MMAP
     430               0 :     if (block_records)
     431               0 :       break;                                    /* Not supported */
     432               0 :     pthread_mutex_lock(&share->intern_lock);
     433                 :     /*
     434                 :       Memory map the data file if it is not already mapped. It is safe
     435                 :       to memory map a file while other threads are using file I/O on it.
     436                 :       Assigning a new address to a function pointer is an atomic
     437                 :       operation. intern_lock prevents that two or more mappings are done
     438                 :       at the same time.
     439                 :     */
     440               0 :     if (!share->file_map)
     441                 :     {
     442               0 :       if (_ma_dynmap_file(info, share->state.state.data_file_length))
     443                 :       {
     444               0 :         DBUG_PRINT("warning",("mmap failed: errno: %d",errno));
     445               0 :         error= my_errno= errno;
     446                 :       }
     447                 :       else
     448                 :       {
     449               0 :         share->file_read=  _ma_mmap_pread;
     450               0 :         share->file_write= _ma_mmap_pwrite;
     451                 :       }
     452                 :     }
     453               0 :     pthread_mutex_unlock(&share->intern_lock);
     454                 : #endif
     455               0 :     break;
     456                 :   case HA_EXTRA_MARK_AS_LOG_TABLE:
     457               0 :     pthread_mutex_lock(&share->intern_lock);
     458               0 :     share->is_log_table= TRUE;
     459               0 :     pthread_mutex_unlock(&share->intern_lock);
     460                 :     break;
     461                 :   case HA_EXTRA_KEY_CACHE:
     462                 :   case HA_EXTRA_NO_KEY_CACHE:
     463                 :   default:
     464                 :     break;
     465                 :   }
     466             458 :   DBUG_RETURN(error);
     467                 : } /* maria_extra */
     468                 : 
     469                 : 
     470                 : /*
     471                 :   Start/Stop Inserting Duplicates Into a Table, WL#1648.
     472                 : */
     473                 : 
     474                 : static void maria_extra_keyflag(MARIA_HA *info,
     475                 :                                 enum ha_extra_function function)
     476               0 : {
     477                 :   uint  idx;
     478                 : 
     479               0 :   for (idx= 0; idx< info->s->base.keys; idx++)
     480                 :   {
     481               0 :     switch (function) {
     482                 :     case HA_EXTRA_CHANGE_KEY_TO_UNIQUE:
     483               0 :       info->s->keyinfo[idx].flag|= HA_NOSAME;
     484               0 :       break;
     485                 :     case HA_EXTRA_CHANGE_KEY_TO_DUP:
     486               0 :       info->s->keyinfo[idx].flag&= ~(HA_NOSAME);
     487                 :       break;
     488                 :     default:
     489                 :       break;
     490                 :     }
     491                 :   }
     492                 : }
     493                 : 
     494                 : 
     495                 : int maria_reset(MARIA_HA *info)
     496             232 : {
     497             232 :   int error= 0;
     498             232 :   MARIA_SHARE *share= info->s;
     499             232 :   DBUG_ENTER("maria_reset");
     500                 :   /*
     501                 :     Free buffers and reset the following flags:
     502                 :     EXTRA_CACHE, EXTRA_WRITE_CACHE, EXTRA_KEYREAD, EXTRA_QUICK
     503                 : 
     504                 :     If the row buffer cache is large (for dynamic tables), reduce it
     505                 :     to save memory.
     506                 :   */
     507             232 :   if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
     508                 :   {
     509               0 :     info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
     510               0 :     error= end_io_cache(&info->rec_cache);
     511                 :   }
     512                 :   /* Free memory used for keeping blobs */
     513             232 :   if (share->base.blobs)
     514                 :   {
     515              60 :     if (info->rec_buff_size > share->base.default_rec_buff_size)
     516                 :     {
     517               8 :       info->rec_buff_size= 1;                 /* Force realloc */
     518               8 :       _ma_alloc_buffer(&info->rec_buff, &info->rec_buff_size,
     519                 :                        share->base.default_rec_buff_size);
     520                 :     }
     521              60 :     if (info->blob_buff_size > MARIA_SMALL_BLOB_BUFFER)
     522                 :     {
     523              52 :       info->blob_buff_size= 1;                 /* Force realloc */
     524              52 :       _ma_alloc_buffer(&info->blob_buff, &info->blob_buff_size,
     525                 :                        MARIA_SMALL_BLOB_BUFFER);
     526                 :     }
     527                 :   }
     528                 : #if defined(HAVE_MMAP) && defined(HAVE_MADVISE)
     529             232 :   if (info->opt_flag & MEMMAP_USED)
     530               0 :     madvise((char*) share->file_map, share->state.state.data_file_length,
     531                 :             MADV_RANDOM);
     532                 : #endif
     533             232 :   info->opt_flag&= ~(KEY_READ_USED | REMEMBER_OLD_POS);
     534             232 :   info->quick_mode= 0;
     535             232 :   info->lastinx= 0;                  /* Use first index as def */
     536             232 :   info->last_search_keypage= info->cur_row.lastpos= HA_OFFSET_ERROR;
     537             232 :   info->page_changed= 1;
     538             232 :   info->update= ((info->update & HA_STATE_CHANGED) | HA_STATE_NEXT_FOUND |
     539                 :                  HA_STATE_PREV_FOUND);
     540             232 :   DBUG_RETURN(error);
     541                 : }
     542                 : 
     543                 : 
     544                 : int _ma_sync_table_files(const MARIA_HA *info)
     545               2 : {
     546               2 :   return (my_sync(info->dfile.file, MYF(MY_WME)) ||
     547                 :           my_sync(info->s->kfile.file, MYF(MY_WME)));
     548                 : }
     549                 : 
     550                 : 
     551                 : /**
     552                 :    @brief flushes the data and/or index file of a table
     553                 : 
     554                 :    This is useful when one wants to read a table using OS syscalls (like
     555                 :    my_copy()) and first wants to be sure that MySQL-level caches go down to
     556                 :    the OS so that OS syscalls can see all data. It can flush rec_cache,
     557                 :    bitmap, pagecache of data file, pagecache of index file.
     558                 : 
     559                 :    @param  info                table
     560                 :    @param  flush_data_or_index one or two of these flags:
     561                 :                                MARIA_FLUSH_DATA, MARIA_FLUSH_INDEX
     562                 :    @param  flush_type_for_data
     563                 :    @param  flush_type_for_index
     564                 : 
     565                 :    @note does not sync files (@see _ma_sync_table_files()).
     566                 :    @note Progressively this function will be used in all places where we flush
     567                 :    the index but not the data file (probable bugs).
     568                 : 
     569                 :    @return Operation status
     570                 :      @retval 0      OK
     571                 :      @retval 1      Error
     572                 : */
     573                 : 
     574                 : int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
     575                 :                           enum flush_type flush_type_for_data,
     576                 :                           enum flush_type flush_type_for_index)
     577            1358 : {
     578            1358 :   int error= 0;
     579            1358 :   MARIA_SHARE *share= info->s;
     580                 :   /* flush data file first because it's more critical */
     581            1358 :   if (flush_data_or_index & MARIA_FLUSH_DATA)
     582                 :   {
     583            1358 :     if ((info->opt_flag & WRITE_CACHE_USED) &&
     584                 :         flush_type_for_data != FLUSH_IGNORE_CHANGED &&
     585                 :         flush_io_cache(&info->rec_cache))
     586               0 :       error= 1;
     587            1358 :     if (share->data_file_type == BLOCK_RECORD)
     588                 :     {
     589             853 :       if (flush_type_for_data != FLUSH_IGNORE_CHANGED)
     590                 :       {
     591             853 :         if (_ma_bitmap_flush(share))
     592               0 :           error= 1;
     593                 :       }
     594                 :       else
     595                 :       {
     596               0 :         pthread_mutex_lock(&share->bitmap.bitmap_lock);
     597               0 :         share->bitmap.changed= 0;
     598               0 :         pthread_mutex_unlock(&share->bitmap.bitmap_lock);
     599                 :       }
     600             853 :       if (flush_pagecache_blocks(share->pagecache, &info->dfile,
     601                 :                                  flush_type_for_data))
     602               0 :         error= 1;
     603                 :     }
     604                 :   }
     605            1358 :   if ((flush_data_or_index & MARIA_FLUSH_INDEX) &&
     606                 :       flush_pagecache_blocks(share->pagecache, &share->kfile,
     607                 :                              flush_type_for_index))
     608               0 :     error= 1;
     609            1358 :   if (!error)
     610            1358 :     return 0;
     611                 : 
     612               0 :   maria_print_error(info->s, HA_ERR_CRASHED);
     613               0 :   maria_mark_crashed(info);
     614               0 :   return 1;
     615                 : }

Generated by: LTP GCOV extension version 1.4