summaryrefslogtreecommitdiff
path: root/storage/maria/ma_delete_all.c
blob: fccd29b15f108801fe695413fb68a7a9deb3fe4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* Remove all rows from a MARIA table */
/* This clears the status information and truncates files */

#include "maria_def.h"

int maria_delete_all_rows(MARIA_HA *info)
{
  uint i;
  MARIA_SHARE *share=info->s;
  MARIA_STATE_INFO *state=&share->state;
  DBUG_ENTER("maria_delete_all_rows");

  if (share->options & HA_OPTION_READ_ONLY_DATA)
  {
    DBUG_RETURN(my_errno=EACCES);
  }
  /* LOCKTODO take X-lock on table here */
  if (_ma_readinfo(info,F_WRLCK,1))
    DBUG_RETURN(my_errno);
  if (_ma_mark_file_changed(info))
    goto err;

  info->state->records=info->state->del=state->split=0;
  state->dellink = HA_OFFSET_ERROR;
  state->sortkey=  (ushort) ~0;
  info->state->key_file_length=share->base.keystart;
  info->state->data_file_length=0;
  info->state->empty=info->state->key_empty=0;
  info->state->checksum=0;

  for (i=share->base.max_key_block_length/MARIA_MIN_KEY_BLOCK_LENGTH ; i-- ; )
    state->key_del[i]= HA_OFFSET_ERROR;
  for (i=0 ; i < share->base.keys ; i++)
    state->key_root[i]= HA_OFFSET_ERROR;

  /*
    If we are using delayed keys or if the user has done changes to the tables
    since it was locked then there may be key blocks in the key cache
  */
  flush_key_blocks(share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED);
  /*
    RECOVERYTODO Log the two chsize and header modifications and force the
    log. So that if crash between the two chsize, we finish the work at
    Recovery. For this scenario:
    "TRUNCATE TABLE t1; DROP TABLE t1; RENAME TABLE t2 to t1; crash;"
    Recovery mustn't truncate the new t1, so the log records of TRUNCATE
    should be applied only if t1 exists and its ZeroDirtyPagesLSN is smaller
    than the records'. See more comments below.
  */
  if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
      my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME))  )
    goto err;
  /*
    RECOVERYTODO Consider updating ZeroDirtyPagesLSN here. It is
    not a necessity (it is one only in RENAME commands) but an optional
    optimization which will allow some REDO skipping at Recovery.
  */
  VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
#ifdef HAVE_MMAP
  /* Resize mmaped area */
  rw_wrlock(&info->s->mmap_lock);
  _ma_remap_file(info, (my_off_t)0);
  rw_unlock(&info->s->mmap_lock);
#endif
  /*
    RECOVERYTODO Until we have the TRUNCATE log record and take it into
    account for log-low-water-mark calculation and use it in Recovery, we need
    to sync.
  */
  if (_ma_sync_table_files(info))
    goto err;
  allow_break();			/* Allow SIGHUP & SIGINT */
  DBUG_RETURN(0);

err:
  {
    int save_errno=my_errno;
    /* RECOVERYTODO log the header modifications */
    VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
    info->update|=HA_STATE_WRITTEN;	/* Buffer changed */
    /* RECOVERYTODO until we log above we have to sync */
    if (_ma_sync_table_files(info) && !save_errno)
      save_errno= my_errno;
    allow_break();			/* Allow SIGHUP & SIGINT */
    DBUG_RETURN(my_errno=save_errno);
  }
} /* maria_delete */