16
16
/* Describe, check and repair of MyISAM tables */
18
#include <drizzled/global.h>
18
#include "myisamdef.h"
20
21
#include <mystrings/m_ctype.h>
22
22
#include <mysys/my_getopt.h>
23
23
#include <mysys/my_bit.h>
25
24
#include <mystrings/m_string.h>
26
27
#ifdef HAVE_SYS_VADVICE_H
27
28
#include <sys/vadvise.h>
29
30
#ifdef HAVE_SYS_MMAN_H
30
31
#include <sys/mman.h>
33
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
34
#define my_raid_delete(A,B,C) my_delete(A,B)
36
#include "myisamdef.h"
33
#include <drizzled/util/test.h>
36
pthread_mutex_t THR_LOCK_myisam= PTHREAD_MUTEX_INITIALIZER;
38
38
static uint32_t decode_bits;
39
39
static char **default_argv;
161
161
"Make a backup of the .MYD file as 'filename-time.BAK'.",
162
162
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
163
{"character-sets-dir", OPT_CHARSETS_DIR,
164
"Directory where character sets are.",
165
(char**) &charsets_dir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
167
164
"Check table for errors.",
168
165
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
291
288
(char**) &check_param.read_buffer_length,
292
289
(char**) &check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
293
290
(long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
294
INT32_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
291
SIZE_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
295
292
{ "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
296
293
(char**) &check_param.write_buffer_length,
297
294
(char**) &check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
298
295
(long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
299
INT32_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
296
SIZE_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
300
297
{ "sort_buffer_size", OPT_SORT_BUFFER_SIZE, "",
301
298
(char**) &check_param.sort_buffer_length,
302
299
(char**) &check_param.sort_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
303
300
(long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD),
304
INT32_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
301
SIZE_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
305
302
{ "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
306
303
(char**) &check_param.sort_key_blocks,
307
304
(char**) &check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG,
1171
1162
if (share->state.changed & STATE_CRASHED)
1172
my_stpcpy(buff,"crashed");
1163
strcpy(buff,"crashed");
1175
1166
if (share->state.open_count)
1176
pos=my_stpcpy(pos,"open,");
1167
pos= strcpy(pos,"open,")+5;
1177
1168
if (share->state.changed & STATE_CHANGED)
1178
pos=my_stpcpy(pos,"changed,");
1169
pos= strcpy(pos,"changed,")+8;
1180
pos=my_stpcpy(pos,"checked,");
1171
pos= strcpy(pos,"checked,")+8;
1181
1172
if (!(share->state.changed & STATE_NOT_ANALYZED))
1182
pos=my_stpcpy(pos,"analyzed,");
1173
pos= strcpy(pos,"analyzed,")+9;
1183
1174
if (!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))
1184
pos=my_stpcpy(pos,"optimized keys,");
1175
pos= strcpy(pos,"optimized keys,")+15;
1185
1176
if (!(share->state.changed & STATE_NOT_SORTED_PAGES))
1186
pos=my_stpcpy(pos,"sorted index pages,");
1177
pos= strcpy(pos,"sorted index pages,")+19;
1187
1178
pos[-1]=0; /* Remove extra ',' */
1189
1180
printf("Status: %s\n",buff);
1190
1181
if (share->base.auto_key)
1218
1202
printf("Init-relocation: %13s\n",llstr(share->base.reloc,llbuff));
1220
1204
printf("Datafile parts: %13s Deleted data: %13s\n",
1221
llstr(share->state.split,llbuff),
1222
llstr(info->state->empty,llbuff2));
1205
llstr(share->state.split,llbuff),
1206
llstr(info->state->empty,llbuff2));
1223
1207
printf("Datafile pointer (bytes):%9d Keyfile pointer (bytes):%9d\n",
1224
share->rec_reflength,share->base.key_reflength);
1208
share->rec_reflength,share->base.key_reflength);
1225
1209
printf("Datafile length: %13s Keyfile length: %13s\n",
1226
llstr(info->state->data_file_length,llbuff),
1227
llstr(info->state->key_file_length,llbuff2));
1210
llstr(info->state->data_file_length,llbuff),
1211
llstr(info->state->key_file_length,llbuff2));
1229
1213
if (info->s->base.reloc == 1L && info->s->base.records == 1L)
1230
1214
puts("This is a one-record table");
1233
1217
if (share->base.max_data_file_length != HA_OFFSET_ERROR ||
1234
share->base.max_key_file_length != HA_OFFSET_ERROR)
1235
printf("Max datafile length: %13s Max keyfile length: %13s\n",
1236
llstr(share->base.max_data_file_length-1,llbuff),
1237
llstr(share->base.max_key_file_length-1,llbuff2));
1218
share->base.max_key_file_length != HA_OFFSET_ERROR)
1219
printf("Max datafile length: %13s Max keyfile length: %13s\n",
1220
llstr(share->base.max_data_file_length-1,llbuff),
1221
llstr(share->base.max_key_file_length-1,llbuff2));
1263
1247
if (keyseg->flag & HA_REVERSE_SORT)
1265
pos=my_stpcpy(pos,type_names[keyseg->type]);
1249
pos= strcpy(pos,type_names[keyseg->type]);
1250
pos+= strlen(type_names[keyseg->type]);
1268
1253
if (keyinfo->flag & HA_PACK_KEY)
1269
pos=my_stpcpy(pos,prefix_packed_txt);
1254
pos= strcpy(pos,prefix_packed_txt) + strlen(prefix_packed_txt);
1270
1255
if (keyinfo->flag & HA_BINARY_PACK_KEY)
1271
pos=my_stpcpy(pos,bin_packed_txt);
1256
pos= strcpy(pos,bin_packed_txt) + strlen(bin_packed_txt);
1272
1257
if (keyseg->flag & HA_SPACE_PACK)
1273
pos=my_stpcpy(pos,diff_txt);
1258
pos= strcpy(pos,diff_txt) + strlen(diff_txt);
1274
1259
if (keyseg->flag & HA_BLOB_PART)
1275
pos=my_stpcpy(pos,blob_txt);
1260
pos= strcpy(pos,blob_txt) + strlen(blob_txt);
1276
1261
if (keyseg->flag & HA_NULL_PART)
1277
pos=my_stpcpy(pos,null_txt);
1262
pos= strcpy(pos,null_txt) + strlen(null_txt);
1280
1265
printf("%-4d%-6ld%-3d %-8s%-21s",
1281
key+1,(long) keyseg->start+1,keyseg->length,text,buff);
1266
key+1,(long) keyseg->start+1,keyseg->length,text,buff);
1282
1267
if (share->state.key_root[key] != HA_OFFSET_ERROR)
1283
1268
llstr(share->state.key_root[key],buff);
1286
1271
if (param->testflag & T_VERBOSE)
1287
1272
printf("%11lu %12s %10d",
1288
share->state.rec_per_key_part[keyseg_nr++],
1289
buff,keyinfo->block_length);
1273
share->state.rec_per_key_part[keyseg_nr++],
1274
buff,keyinfo->block_length);
1291
1276
while ((++keyseg)->type != HA_KEYTYPE_END)
1294
1279
if (keyseg->flag & HA_REVERSE_SORT)
1296
pos=my_stpcpy(pos,type_names[keyseg->type]);
1281
pos= strcpy(pos,type_names[keyseg->type]);
1282
pos+= strlen(type_names[keyseg->type]);
1298
1284
if (keyseg->flag & HA_SPACE_PACK)
1299
pos=my_stpcpy(pos,diff_txt);
1285
pos= strcpy(pos,diff_txt) + strlen(diff_txt);
1300
1286
if (keyseg->flag & HA_BLOB_PART)
1301
pos=my_stpcpy(pos,blob_txt);
1287
pos= strcpy(pos,blob_txt) + strlen(blob_txt);
1302
1288
if (keyseg->flag & HA_NULL_PART)
1303
pos=my_stpcpy(pos,null_txt);
1289
pos= strcpy(pos,null_txt) + strlen(null_txt);
1305
1291
printf(" %-6ld%-3d %-21s",
1306
1292
(long) keyseg->start+1,keyseg->length,buff);
1307
1293
if (param->testflag & T_VERBOSE)
1308
printf("%11lu", share->state.rec_per_key_part[keyseg_nr++]);
1294
printf("%11lu", share->state.rec_per_key_part[keyseg_nr++]);
1315
1301
MI_UNIQUEDEF *uniqueinfo;
1316
1302
puts("\nUnique Key Start Len Nullpos Nullbit Type");
1317
1303
for (key=0,uniqueinfo= &share->uniqueinfo[0] ;
1318
key < share->state.header.uniques; key++, uniqueinfo++)
1304
key < share->state.header.uniques; key++, uniqueinfo++)
1320
1306
bool new_row=0;
1321
1307
char null_bit[8],null_pos[8];
1322
1308
printf("%-8d%-5d",key+1,uniqueinfo->key+1);
1323
1309
for (keyseg=uniqueinfo->seg ; keyseg->type != HA_KEYTYPE_END ; keyseg++)
1327
null_bit[0]=null_pos[0]=0;
1328
if (keyseg->null_bit)
1330
sprintf(null_bit,"%d",keyseg->null_bit);
1331
sprintf(null_pos,"%ld",(long) keyseg->null_pos+1);
1333
printf("%-7ld%-5d%-9s%-10s%-30s\n",
1334
(long) keyseg->start+1,keyseg->length,
1336
type_names[keyseg->type]);
1313
null_bit[0]=null_pos[0]=0;
1314
if (keyseg->null_bit)
1316
sprintf(null_bit,"%d",keyseg->null_bit);
1317
sprintf(null_pos,"%ld",(long) keyseg->null_pos+1);
1319
printf("%-7ld%-5d%-9s%-10s%-30s\n",
1320
(long) keyseg->start+1,keyseg->length,
1322
type_names[keyseg->type]);
1349
1335
for (field=0 ; field < share->base.fields ; field++)
1351
1337
if (share->options & HA_OPTION_COMPRESS_RECORD)
1352
type=share->rec[field].base_type;
1338
type=share->rec[field].base_type;
1354
type=(enum en_fieldtype) share->rec[field].type;
1355
end=my_stpcpy(buff,field_pack[type]);
1340
type=(enum en_fieldtype) share->rec[field].type;
1341
end= strcpy(buff, field_pack[type]);
1342
end+= strlen(field_pack[type]);
1356
1343
if (share->options & HA_OPTION_COMPRESS_RECORD)
1358
if (share->rec[field].pack_type & PACK_TYPE_SELECTED)
1359
end=my_stpcpy(end,", not_always");
1360
if (share->rec[field].pack_type & PACK_TYPE_SPACE_FIELDS)
1361
end=my_stpcpy(end,", no empty");
1362
if (share->rec[field].pack_type & PACK_TYPE_ZERO_FILL)
1364
sprintf(end,", zerofill(%d)",share->rec[field].space_length_bits);
1365
end= strchr(end, '\0');
1345
if (share->rec[field].pack_type & PACK_TYPE_SELECTED)
1346
end= strcpy(end,", not_always")+12;
1347
if (share->rec[field].pack_type & PACK_TYPE_SPACE_FIELDS)
1348
end= strcpy(end,", no empty")+10;
1349
if (share->rec[field].pack_type & PACK_TYPE_ZERO_FILL)
1351
sprintf(end,", zerofill(%d)",share->rec[field].space_length_bits);
1352
end= strchr(end, '\0');
1368
1355
if (buff[0] == ',')
1369
my_stpcpy(buff,buff+2);
1356
strcpy(buff,buff+2);
1370
1357
int10_to_str((long) share->rec[field].length,length,10);
1371
1358
null_bit[0]=null_pos[0]=0;
1372
1359
if (share->rec[field].null_bit)
1374
sprintf(null_bit,"%d",share->rec[field].null_bit);
1375
sprintf(null_pos,"%d",share->rec[field].null_pos+1);
1361
sprintf(null_bit,"%d",share->rec[field].null_bit);
1362
sprintf(null_pos,"%d",share->rec[field].null_pos+1);
1377
1364
printf("%-6d%-6d%-7s%-8s%-8s%-35s",field+1,start,length,
1378
1365
null_pos, null_bit, buff);
1453
1440
info->opt_flag|=WRITE_CACHE_USED;
1455
if (!(temp_buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
1442
if (!(temp_buff=(unsigned char*) malloc(keyinfo->block_length)))
1457
1444
mi_check_print_error(param,"Not enough memory for key block");
1461
if (!mi_alloc_rec_buff(info, -1, &sort_param.record))
1448
if (!mi_alloc_rec_buff(info, (ulong)-1, &sort_param.record))
1463
1450
mi_check_print_error(param,"Not enough memory for record");
1466
1453
fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
1467
new_file=my_raid_create(fn_format(param->temp_filename,
1468
param->temp_filename,"",
1470
0,param->tmpfile_createflag,
1471
share->base.raid_type,
1472
share->base.raid_chunks,
1473
share->base.raid_chunksize,
1454
new_file=my_create(fn_format(param->temp_filename,
1455
param->temp_filename,"",
1457
0,param->tmpfile_createflag,
1475
1459
if (new_file < 0)
1477
1461
mi_check_print_error(param,"Can't create new tempfile: '%s'",
1547
1531
end_io_cache(&info->rec_cache);
1548
1532
(void) my_close(new_file,MYF(MY_WME));
1549
(void) my_raid_delete(param->temp_filename, share->base.raid_chunks,
1533
(void) my_delete(param->temp_filename, MYF(MY_WME));
1554
my_afree((unsigned char*) temp_buff);
1537
free((unsigned char*) temp_buff);
1556
1539
void * rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
1557
1540
if (rec_buff_ptr != NULL)