~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to storage/maria/maria_read_log.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) 2007 MySQL 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
#include "ma_recovery.h"
 
18
#include <my_getopt.h>
 
19
 
 
20
#define LOG_FLAGS 0
 
21
 
 
22
static const char *load_default_groups[]= { "maria_read_log",0 };
 
23
static void get_options(int *argc,char * * *argv);
 
24
#ifndef DBUG_OFF
 
25
#if defined(__WIN__)
 
26
const char *default_dbug_option= "d:t:i:O,\\maria_read_log.trace";
 
27
#else
 
28
const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace";
 
29
#endif
 
30
#endif /* DBUG_OFF */
 
31
static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent;
 
32
static my_bool opt_check;
 
33
static const char *opt_tmpdir;
 
34
static ulong opt_page_buffer_size;
 
35
static ulonglong opt_start_from_lsn;
 
36
static MY_TMPDIR maria_chk_tmpdir;
 
37
 
 
38
 
 
39
int main(int argc, char **argv)
 
40
{
 
41
  LSN lsn;
 
42
  char **default_argv;
 
43
  uint warnings_count;
 
44
  MY_INIT(argv[0]);
 
45
 
 
46
  load_defaults("my", load_default_groups, &argc, &argv);
 
47
  default_argv= argv;
 
48
  maria_data_root= (char *)".";
 
49
  get_options(&argc, &argv);
 
50
 
 
51
  maria_in_recovery= TRUE;
 
52
 
 
53
  if (maria_init())
 
54
  {
 
55
    fprintf(stderr, "Can't init Maria engine (%d)\n", errno);
 
56
    goto err;
 
57
  }
 
58
  /* we don't want to create a control file, it MUST exist */
 
59
  if (ma_control_file_open(FALSE, TRUE))
 
60
  {
 
61
    fprintf(stderr, "Can't open control file (%d)\n", errno);
 
62
    goto err;
 
63
  }
 
64
  if (last_logno == FILENO_IMPOSSIBLE)
 
65
  {
 
66
    fprintf(stderr, "Can't find any log\n");
 
67
    goto err;
 
68
  }
 
69
  if (init_pagecache(maria_pagecache, opt_page_buffer_size, 0, 0,
 
70
                     TRANSLOG_PAGE_SIZE, MY_WME) == 0)
 
71
  {
 
72
    fprintf(stderr, "Got error in init_pagecache() (errno: %d)\n", errno);
 
73
    goto err;
 
74
  }
 
75
  /*
 
76
    If log handler does not find the "last_logno" log it will return error,
 
77
    which is good.
 
78
    But if it finds a log and this log was crashed, it will create a new log,
 
79
    which is useless. TODO: start log handler in read-only mode.
 
80
  */
 
81
  if (init_pagecache(maria_log_pagecache,
 
82
                     TRANSLOG_PAGECACHE_SIZE, 0, 0,
 
83
                     TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
 
84
      translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
 
85
                    0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS,
 
86
                    opt_display_only))
 
87
  {
 
88
    fprintf(stderr, "Can't init loghandler (%d)\n", errno);
 
89
    goto err;
 
90
  }
 
91
 
 
92
  if (opt_display_only)
 
93
    printf("You are using --display-only, NOTHING will be written to disk\n");
 
94
 
 
95
  /* LSN could be also --start-from-lsn=# */
 
96
  lsn= translog_first_lsn_in_log();
 
97
  if (lsn == LSN_ERROR)
 
98
  {
 
99
    fprintf(stderr, "Opening transaction log failed\n");
 
100
    goto end;
 
101
  }
 
102
  if (lsn == LSN_IMPOSSIBLE)
 
103
  {
 
104
     fprintf(stdout, "The transaction log is empty\n");
 
105
  }
 
106
  fprintf(stdout, "The transaction log starts from lsn (%lu,0x%lx)\n",
 
107
          LSN_IN_PARTS(lsn));
 
108
 
 
109
  if (opt_start_from_lsn)
 
110
  {
 
111
    if (opt_start_from_lsn < (ulonglong) lsn)
 
112
    {
 
113
      fprintf(stderr, "start_from_lsn is too small. Aborting\n");
 
114
      maria_end();
 
115
      goto err;
 
116
    }
 
117
    lsn= (LSN) opt_start_from_lsn;
 
118
    fprintf(stdout, "Starting reading log from lsn (%lu,0x%lx)\n",
 
119
            LSN_IN_PARTS(lsn));
 
120
  }
 
121
 
 
122
  fprintf(stdout, "TRACE of the last maria_read_log\n");
 
123
  if (maria_apply_log(lsn, opt_apply ?  MARIA_LOG_APPLY :
 
124
                      (opt_check ? MARIA_LOG_CHECK :
 
125
                       MARIA_LOG_DISPLAY_HEADER), opt_silent ? NULL : stdout,
 
126
                      opt_apply_undo, FALSE, FALSE, &warnings_count))
 
127
    goto err;
 
128
  if (warnings_count == 0)
 
129
    fprintf(stdout, "%s: SUCCESS\n", my_progname_short);
 
130
  else
 
131
    fprintf(stdout, "%s: DOUBTFUL (%u warnings, check previous output)\n",
 
132
            my_progname_short, warnings_count);
 
133
 
 
134
end:
 
135
  maria_end();
 
136
  free_tmpdir(&maria_chk_tmpdir);
 
137
  free_defaults(default_argv);
 
138
  my_end(0);
 
139
  exit(0);
 
140
  return 0;                             /* No compiler warning */
 
141
 
 
142
err:
 
143
  /* don't touch anything more, in case we hit a bug */
 
144
  fprintf(stderr, "%s: FAILED\n", my_progname_short);
 
145
  free_tmpdir(&maria_chk_tmpdir);
 
146
  free_defaults(default_argv);
 
147
  exit(1);
 
148
}
 
149
 
 
150
 
 
151
static struct my_option my_long_options[] =
 
152
{
 
153
  {"apply", 'a',
 
154
   "Apply log to tables: modifies tables! you should make a backup first! "
 
155
   " Displays a lot of information if not run with --silent",
 
156
   (uchar **) &opt_apply, (uchar **) &opt_apply, 0,
 
157
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
158
  {"check", 'c',
 
159
   "if --display-only, check if record is fully readable (for debugging)",
 
160
   (uchar **) &opt_check, (uchar **) &opt_check, 0,
 
161
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
162
#ifndef DBUG_OFF
 
163
  {"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.",
 
164
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
165
#endif
 
166
  {"help", '?', "Display this help and exit.",
 
167
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
168
  {"display-only", 'd', "display brief info read from records' header",
 
169
   (uchar **) &opt_display_only, (uchar **) &opt_display_only, 0, GET_BOOL,
 
170
   NO_ARG,0, 0, 0, 0, 0, 0},
 
171
  {"maria_log_dir_path", 'l',
 
172
    "Path to the directory where to store transactional log",
 
173
    (uchar **) &maria_data_root, (uchar **) &maria_data_root, 0,
 
174
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
175
  { "page_buffer_size", 'P', "",
 
176
    (uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0,
 
177
    GET_ULONG, REQUIRED_ARG, (long) USE_BUFFER_INIT,
 
178
    (long) USE_BUFFER_INIT, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
 
179
    (long) IO_SIZE, 0},
 
180
  { "start_from_lsn", 'o', "Start reading log from this lsn",
 
181
    (uchar**) &opt_start_from_lsn, (uchar**) &opt_start_from_lsn,
 
182
    0, GET_ULL, REQUIRED_ARG, 0, 0, ~(longlong) 0, 0, 0, 0 },
 
183
  {"silent", 's', "Print less information during apply/undo phase",
 
184
   (uchar **) &opt_silent, (uchar **) &opt_silent, 0,
 
185
   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 
186
  {"tmpdir", 't', "Path for temporary files. Multiple paths can be specified, "
 
187
   "separated by "
 
188
#if defined( __WIN__) || defined(__NETWARE__)
 
189
   "semicolon (;)"
 
190
#else
 
191
   "colon (:)"
 
192
#endif
 
193
   , (uchar**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
194
  {"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)",
 
195
   (uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0,
 
196
   GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
 
197
  {"version", 'V', "Print version and exit.",
 
198
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
199
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
200
};
 
201
 
 
202
#include <help_start.h>
 
203
 
 
204
static void print_version(void)
 
205
{
 
206
  (void)(printf("%s Ver 1.2 for %s on %s\n",
 
207
              my_progname_short, SYSTEM_TYPE, MACHINE_TYPE));
 
208
  NETWARE_SET_SCREEN_MODE(1);
 
209
}
 
210
 
 
211
 
 
212
static void usage(void)
 
213
{
 
214
  print_version();
 
215
  puts("Copyright (C) 2007 MySQL AB");
 
216
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
 
217
  puts("and you are welcome to modify and redistribute it under the GPL license\n");
 
218
 
 
219
  puts("Display and apply log records from a MARIA transaction log");
 
220
  puts("found in the current directory (for now)");
 
221
#ifndef IDENTICAL_PAGES_AFTER_RECOVERY
 
222
  puts("\nNote: Maria is compiled without -DIDENTICAL_PAGES_AFTER_RECOVERY\n"
 
223
       "which means that the table files are not byte-to-byte identical to\n"
 
224
       "files created during normal execution. This should be ok, except for\n"
 
225
       "test scripts that tries to compare files before and after recovery.");
 
226
#endif
 
227
  (void)(printf("\nUsage: %s OPTIONS\n", my_progname_short));
 
228
  puts("You need to use one of -d or -a");
 
229
  my_print_help(my_long_options);
 
230
  print_defaults("my", load_default_groups);
 
231
  my_print_variables(my_long_options);
 
232
}
 
233
 
 
234
#include <help_end.h>
 
235
 
 
236
static my_bool
 
237
get_one_option(int optid __attribute__((unused)),
 
238
               const struct my_option *opt __attribute__((unused)),
 
239
               char *argument __attribute__((unused)))
 
240
{
 
241
  switch (optid) {
 
242
  case '?':
 
243
    usage();
 
244
    exit(0);
 
245
  case 'V':
 
246
    print_version();
 
247
    exit(0);
 
248
#ifndef DBUG_OFF
 
249
  case '#':
 
250
    DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
 
251
    break;
 
252
#endif
 
253
  }
 
254
  return 0;
 
255
}
 
256
 
 
257
static void get_options(int *argc,char ***argv)
 
258
{
 
259
  int ho_error;
 
260
 
 
261
  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
 
262
    exit(ho_error);
 
263
 
 
264
  if (!opt_apply)
 
265
    opt_apply_undo= FALSE;
 
266
 
 
267
  if (((opt_display_only + opt_apply) != 1) || (*argc > 0))
 
268
  {
 
269
    usage();
 
270
    exit(1);
 
271
  }
 
272
  if (init_tmpdir(&maria_chk_tmpdir, opt_tmpdir))
 
273
    exit(1);
 
274
  maria_tmpdir= &maria_chk_tmpdir;
 
275
}
 
276
 
 
277
#define MA_CHECK_STANDALONE 1
 
278
#include "ma_check_standalone.h"
 
279
#undef MA_CHECK_STANDALONE