~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/maria/ma_delete_all.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/* Remove all rows from a MARIA table */
 
17
/* This clears the status information and truncates files */
 
18
 
 
19
#include "maria_def.h"
 
20
#include "trnman.h"
 
21
 
 
22
/**
 
23
   @brief deletes all rows from a table
 
24
 
 
25
   @param  info             Maria handler
 
26
 
 
27
   @note It is important that this function does not rely on the state
 
28
   information, as it may be called by ma_apply_undo_bulk_insert() on an
 
29
   inconsistent table left by a crash.
 
30
 
 
31
   @return Operation status
 
32
     @retval 0      ok
 
33
     @retval 1      error
 
34
*/
 
35
 
 
36
int maria_delete_all_rows(MARIA_HA *info)
 
37
{
 
38
  MARIA_SHARE *share= info->s;
 
39
  my_bool log_record;
 
40
  LSN lsn;
 
41
  DBUG_ENTER("maria_delete_all_rows");
 
42
 
 
43
  if (share->options & HA_OPTION_READ_ONLY_DATA)
 
44
  {
 
45
    DBUG_RETURN(my_errno=EACCES);
 
46
  }
 
47
  /**
 
48
     @todo LOCK take X-lock on table here.
 
49
     When we have versioning, if some other thread is looking at this table,
 
50
     we cannot shrink the file like this.
 
51
  */
 
52
  if (_ma_readinfo(info,F_WRLCK,1))
 
53
    DBUG_RETURN(my_errno);
 
54
  log_record= share->now_transactional && !share->temporary;
 
55
  if (_ma_mark_file_changed(info))
 
56
    goto err;
 
57
 
 
58
  if (log_record)
 
59
  {
 
60
    /*
 
61
      This record will be used by Recovery to finish the deletion if it
 
62
      crashed. We force it to have a complete history in the log.
 
63
    */
 
64
    LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
 
65
    uchar log_data[FILEID_STORE_SIZE];
 
66
    log_array[TRANSLOG_INTERNAL_PARTS + 0].str=    log_data;
 
67
    log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
 
68
    if (unlikely(translog_write_record(&lsn, LOGREC_REDO_DELETE_ALL,
 
69
                                       info->trn, info, 0,
 
70
                                       sizeof(log_array)/sizeof(log_array[0]),
 
71
                                       log_array, log_data, NULL) ||
 
72
                 translog_flush(lsn)))
 
73
      goto err;
 
74
    /*
 
75
      If we fail in this function after this point, log and table will be
 
76
      inconsistent.
 
77
    */
 
78
  }
 
79
  else
 
80
  {
 
81
    /* Other branch called function below when writing log record, in hook */
 
82
    _ma_reset_status(info);
 
83
  }
 
84
  /* Remove old history as the table is now empty for everyone */
 
85
  _ma_reset_state(info);
 
86
 
 
87
  /*
 
88
    If we are using delayed keys or if the user has done changes to the tables
 
89
    since it was locked then there may be key blocks in the page cache. Or
 
90
    there may be data blocks there. We need to throw them away or they may
 
91
    re-enter the emptied table or another table later.
 
92
  */
 
93
 
 
94
#ifdef HAVE_MMAP
 
95
  if (share->file_map)
 
96
    _ma_unmap_file(info);
 
97
#endif
 
98
 
 
99
  if (_ma_flush_table_files(info, MARIA_FLUSH_DATA|MARIA_FLUSH_INDEX,
 
100
                            FLUSH_IGNORE_CHANGED, FLUSH_IGNORE_CHANGED) ||
 
101
      my_chsize(info->dfile.file, 0, 0, MYF(MY_WME)) ||
 
102
      my_chsize(share->kfile.file, share->base.keystart, 0, MYF(MY_WME)))
 
103
    goto err;
 
104
 
 
105
  if (_ma_initialize_data_file(share, info->dfile.file))
 
106
    goto err;
 
107
 
 
108
  if (log_record)
 
109
  {
 
110
    /*
 
111
      Because LOGREC_REDO_DELETE_ALL does not operate on pages, it has the
 
112
      following problem:
 
113
      delete_all; inserts (redo_insert); all pages get flushed; checkpoint:
 
114
      the dirty pages list will be empty. In recovery, delete_all is executed,
 
115
      but redo_insert are skipped (dirty pages list is empty).
 
116
      To avoid this, we need to set skip_redo_lsn now, and thus need to sync
 
117
      files.
 
118
    */
 
119
    my_bool error= _ma_state_info_write(share, 1|4) ||
 
120
      _ma_update_state_lsns(share, lsn, trnman_get_min_trid(), FALSE, FALSE) ||
 
121
      _ma_sync_table_files(info);
 
122
    info->trn->rec_lsn= LSN_IMPOSSIBLE;
 
123
    if (error)
 
124
      goto err;
 
125
  }
 
126
 
 
127
  (void)(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
 
128
#ifdef HAVE_MMAP
 
129
  /* Map again */
 
130
  if (share->file_map)
 
131
    _ma_dynmap_file(info, (my_off_t) 0);
 
132
#endif
 
133
  allow_break();                        /* Allow SIGHUP & SIGINT */
 
134
  DBUG_RETURN(0);
 
135
 
 
136
err:
 
137
  {
 
138
    int save_errno=my_errno;
 
139
    (void)(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
 
140
    info->update|=HA_STATE_WRITTEN;     /* Buffer changed */
 
141
    allow_break();                      /* Allow SIGHUP & SIGINT */
 
142
    DBUG_RETURN(my_errno=save_errno);
 
143
  }
 
144
} /* maria_delete_all_rows */
 
145
 
 
146
 
 
147
/*
 
148
  Reset status information
 
149
 
 
150
  SYNOPSIS
 
151
    _ma_reset_status()
 
152
    maria       Maria handler
 
153
 
 
154
  DESCRIPTION
 
155
    Resets data and index file information as if the file would be empty
 
156
    Files are not touched.
 
157
*/
 
158
 
 
159
void _ma_reset_status(MARIA_HA *info)
 
160
{
 
161
  MARIA_SHARE *share= info->s;
 
162
  MARIA_STATE_INFO *state= &share->state;
 
163
  uint i;
 
164
  DBUG_ENTER("_ma_reset_status");
 
165
 
 
166
  state->split= 0;
 
167
  state->state.records= state->state.del= 0;
 
168
  state->changed=  0;                            /* File is optimized */
 
169
  state->dellink= HA_OFFSET_ERROR;
 
170
  state->sortkey=  (ushort) ~0;
 
171
  state->state.key_file_length= share->base.keystart;
 
172
  state->state.data_file_length= 0;
 
173
  state->state.empty= state->state.key_empty= 0;
 
174
  state->state.checksum= 0;
 
175
 
 
176
  *info->state= state->state;
 
177
 
 
178
  /* Drop the delete key chain. */
 
179
  state->key_del= HA_OFFSET_ERROR;
 
180
  /* Clear all keys */
 
181
  for (i=0 ; i < share->base.keys ; i++)
 
182
    state->key_root[i]= HA_OFFSET_ERROR;
 
183
  DBUG_VOID_RETURN;
 
184
}