29
29
#ifdef HAVE_SYS_MMAN_H
30
30
#include <sys/mman.h>
32
#include <drizzled/util/test.h>
32
SET_STACK_SIZE(9000) /* Minimum stack size for program */
34
#define my_raid_create(A,B,C,D,E,F,G) my_create(A,B,C,G)
35
#define my_raid_delete(A,B,C) my_delete(A,B)
34
37
#include "myisamdef.h"
36
static uint32_t decode_bits;
39
static uint decode_bits;
37
40
static char **default_argv;
38
41
static const char *load_default_groups[]= { "myisamchk", 0 };
39
42
static const char *set_collation_name, *opt_tmpdir;
69
72
static int myisamchk(MI_CHECK *param, char *filename);
70
73
static void descript(MI_CHECK *param, register MI_INFO *info, char * name);
71
74
static int mi_sort_records(MI_CHECK *param, register MI_INFO *info,
72
char * name, uint32_t sort_key,
75
char * name, uint sort_key,
73
76
bool write_info, bool update_index);
74
77
static int sort_record_index(MI_SORT_PARAM *sort_param, MI_INFO *info,
75
78
MI_KEYDEF *keyinfo,
76
my_off_t page,unsigned char *buff,uint32_t sortkey,
79
my_off_t page,uchar *buff,uint sortkey,
77
80
File new_file, bool update_index);
79
82
MI_CHECK check_param;
97
100
int new_error=myisamchk(&check_param, *(argv++));
98
101
if ((check_param.testflag & T_REP_ANY) != T_REP)
99
102
check_param.testflag&= ~T_REP;
103
VOID(fflush(stdout));
104
VOID(fflush(stderr));
102
105
if ((check_param.error_printed | check_param.warning_printed) &&
103
106
(check_param.testflag & T_FORCE_CREATE) &&
104
107
(!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS |
107
uint32_t old_testflag=check_param.testflag;
110
uint old_testflag=check_param.testflag;
108
111
if (!(check_param.testflag & T_REP))
109
112
check_param.testflag|= T_REP_BY_SORT;
110
113
check_param.testflag&= ~T_EXTEND; /* Don't needed */
111
114
error|=myisamchk(&check_param, argv[-1]);
112
115
check_param.testflag= old_testflag;
116
VOID(fflush(stdout));
117
VOID(fflush(stderr));
117
120
error|=new_error;
118
121
if (argc && (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO))
120
123
puts("\n---------\n");
124
VOID(fflush(stdout));
124
127
if (check_param.total_files > 1)
432
435
-b, --block-search=#\n\
433
436
Find a record, a block at given offset belongs to.");
435
print_defaults("drizzle", load_default_groups);
438
print_defaults("my", load_default_groups);
436
439
my_print_variables(my_long_options);
439
442
const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
440
"nulls_ignored", NULL};
443
"nulls_ignored", NullS};
441
444
TYPELIB myisam_stats_method_typelib= {
442
445
array_elements(myisam_stats_method_names) - 1, "",
443
446
myisam_stats_method_names, NULL};
667
670
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
669
672
default: assert(0); /* Impossible */
670
fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
673
674
check_param.stats_method= method_conv;
696
load_defaults("drizzle", load_default_groups, argc, argv);
697
load_defaults("my", load_default_groups, argc, argv);
697
698
default_argv= *argv;
698
699
if (isatty(fileno(stdout)))
699
700
check_param.testflag|=T_WRITE_LOOP;
715
716
if ((check_param.testflag & T_UNPACK) &&
716
717
(check_param.testflag & (T_QUICK | T_SORT_RECORDS)))
719
"%s: --unpack can't be used with --quick or --sort-records\n",
720
"%s: --unpack can't be used with --quick or --sort-records\n",
723
724
if ((check_param.testflag & T_READONLY) &&
725
726
(T_REP_ANY | T_STATISTICS | T_AUTO_INC |
726
727
T_SORT_RECORDS | T_SORT_INDEX | T_FORCE_CREATE)))
729
"%s: Can't use --readonly when repairing or sorting\n",
730
"%s: Can't use --readonly when repairing or sorting\n",
754
755
int error,lock_type,recreate;
755
756
int rep_quick= param->testflag & (T_QUICK | T_FORCE_UNIQUENESS);
756
uint32_t raid_chunks;
759
760
char llbuff[22],llbuff2[22];
880
881
param->language= set_collation->number;
881
882
if (recreate_table(param, &info,filename))
884
"MyISAM-table '%s' is not fixed because of errors\n",
885
"MyISAM-table '%s' is not fixed because of errors\n",
1031
1032
!(param->testflag & (T_FAST | T_FORCE_CREATE)))
1033
1034
if (param->testflag & (T_EXTEND | T_MEDIUM))
1034
init_key_cache(dflt_key_cache,opt_key_cache_block_size,
1035
param->use_buffers, 0, 0);
1036
init_io_cache(¶m->read_cache,datafile,
1037
(uint) param->read_buffer_length,
1039
(param->start_check_pos ?
1040
param->start_check_pos :
1041
share->pack.header_length),
1035
VOID(init_key_cache(dflt_key_cache,opt_key_cache_block_size,
1036
param->use_buffers, 0, 0));
1037
VOID(init_io_cache(¶m->read_cache,datafile,
1038
(uint) param->read_buffer_length,
1040
(param->start_check_pos ?
1041
param->start_check_pos :
1042
share->pack.header_length),
1044
1045
lock_memory(param);
1045
1046
if ((info->s->options & (HA_OPTION_PACK_RECORD |
1046
1047
HA_OPTION_COMPRESS_RECORD)) ||
1047
1048
(param->testflag & (T_EXTEND | T_MEDIUM)))
1048
1049
error|=chk_data_link(param, info, param->testflag & T_EXTEND);
1049
1050
error|=flush_blocks(param, share->key_cache, share->kfile);
1050
end_io_cache(¶m->read_cache);
1051
VOID(end_io_cache(¶m->read_cache));
1100
1101
error|=change_to_newfile(filename,MI_NAME_IEXT,INDEX_TMP_EXT,0,
1103
fflush(stdout); fflush(stderr);
1104
VOID(fflush(stdout)); VOID(fflush(stderr));
1104
1105
if (param->error_printed)
1106
1107
if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX))
1109
"MyISAM-table '%s' is not fixed because of errors\n",
1109
VOID(fprintf(stderr,
1110
"MyISAM-table '%s' is not fixed because of errors\n",
1111
1112
if (param->testflag & T_REP_ANY)
1113
"Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag\n");
1113
VOID(fprintf(stderr,
1114
"Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag\n"));
1115
1116
else if (!(param->error_printed & 2) &&
1116
1117
!(param->testflag & T_FORCE_CREATE))
1118
"MyISAM-table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n",
1118
VOID(fprintf(stderr,
1119
"MyISAM-table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n",
1121
1122
else if (param->warning_printed &&
1122
1123
! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
1123
1124
T_FORCE_CREATE)))
1124
fprintf(stderr, "MyISAM-table '%s' is usable but should be fixed\n",
1125
VOID(fprintf(stderr, "MyISAM-table '%s' is usable but should be fixed\n",
1127
VOID(fflush(stderr));
1128
1129
} /* myisamchk */
1133
1134
static void descript(MI_CHECK *param, register MI_INFO *info, char * name)
1135
uint32_t key,keyseg_nr,field,start;
1136
uint key,keyseg_nr,field,start;
1136
1137
register MI_KEYDEF *keyinfo;
1137
1138
register HA_KEYSEG *keyseg;
1138
1139
register const char *text;
1171
1172
if (share->state.changed & STATE_CRASHED)
1172
my_stpcpy(buff,"crashed");
1173
stpcpy(buff,"crashed");
1175
1176
if (share->state.open_count)
1176
pos=my_stpcpy(pos,"open,");
1177
pos=stpcpy(pos,"open,");
1177
1178
if (share->state.changed & STATE_CHANGED)
1178
pos=my_stpcpy(pos,"changed,");
1179
pos=stpcpy(pos,"changed,");
1180
pos=my_stpcpy(pos,"checked,");
1181
pos=stpcpy(pos,"checked,");
1181
1182
if (!(share->state.changed & STATE_NOT_ANALYZED))
1182
pos=my_stpcpy(pos,"analyzed,");
1183
pos=stpcpy(pos,"analyzed,");
1183
1184
if (!(share->state.changed & STATE_NOT_OPTIMIZED_KEYS))
1184
pos=my_stpcpy(pos,"optimized keys,");
1185
pos=stpcpy(pos,"optimized keys,");
1185
1186
if (!(share->state.changed & STATE_NOT_SORTED_PAGES))
1186
pos=my_stpcpy(pos,"sorted index pages,");
1187
pos=stpcpy(pos,"sorted index pages,");
1187
1188
pos[-1]=0; /* Remove extra ',' */
1189
1190
printf("Status: %s\n",buff);
1193
1194
share->base.auto_key,
1194
1195
llstr(share->state.auto_increment,llbuff));
1197
if (share->base.raid_type)
1199
printf("RAID: Type: %u Chunks: %u Chunksize: %lu\n",
1200
share->base.raid_type,
1201
share->base.raid_chunks,
1202
share->base.raid_chunksize);
1196
1204
if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
1197
1205
printf("Checksum: %23s\n",llstr(info->state->checksum,llbuff));
1242
1250
printf("Key Start Len Index Type");
1243
1251
if (param->testflag & T_VERBOSE)
1244
1252
printf(" Rec/key Root Blocksize");
1253
VOID(putchar('\n'));
1247
1255
for (key=keyseg_nr=0, keyinfo= &share->keyinfo[0] ;
1248
1256
key < share->base.keys;
1256
1264
if (keyseg->flag & HA_REVERSE_SORT)
1258
pos=my_stpcpy(pos,type_names[keyseg->type]);
1266
pos=stpcpy(pos,type_names[keyseg->type]);
1261
1269
if (keyinfo->flag & HA_PACK_KEY)
1262
pos=my_stpcpy(pos,prefix_packed_txt);
1270
pos=stpcpy(pos,prefix_packed_txt);
1263
1271
if (keyinfo->flag & HA_BINARY_PACK_KEY)
1264
pos=my_stpcpy(pos,bin_packed_txt);
1272
pos=stpcpy(pos,bin_packed_txt);
1265
1273
if (keyseg->flag & HA_SPACE_PACK)
1266
pos=my_stpcpy(pos,diff_txt);
1274
pos=stpcpy(pos,diff_txt);
1267
1275
if (keyseg->flag & HA_BLOB_PART)
1268
pos=my_stpcpy(pos,blob_txt);
1276
pos=stpcpy(pos,blob_txt);
1269
1277
if (keyseg->flag & HA_NULL_PART)
1270
pos=my_stpcpy(pos,null_txt);
1278
pos=stpcpy(pos,null_txt);
1273
1281
printf("%-4d%-6ld%-3d %-8s%-21s",
1280
1288
printf("%11lu %12s %10d",
1281
1289
share->state.rec_per_key_part[keyseg_nr++],
1282
1290
buff,keyinfo->block_length);
1291
VOID(putchar('\n'));
1284
1292
while ((++keyseg)->type != HA_KEYTYPE_END)
1287
1295
if (keyseg->flag & HA_REVERSE_SORT)
1289
pos=my_stpcpy(pos,type_names[keyseg->type]);
1297
pos=stpcpy(pos,type_names[keyseg->type]);
1291
1299
if (keyseg->flag & HA_SPACE_PACK)
1292
pos=my_stpcpy(pos,diff_txt);
1300
pos=stpcpy(pos,diff_txt);
1293
1301
if (keyseg->flag & HA_BLOB_PART)
1294
pos=my_stpcpy(pos,blob_txt);
1302
pos=stpcpy(pos,blob_txt);
1295
1303
if (keyseg->flag & HA_NULL_PART)
1296
pos=my_stpcpy(pos,null_txt);
1304
pos=stpcpy(pos,null_txt);
1298
1306
printf(" %-6ld%-3d %-21s",
1299
1307
(long) keyseg->start+1,keyseg->length,buff);
1300
1308
if (param->testflag & T_VERBOSE)
1301
1309
printf("%11lu", share->state.rec_per_key_part[keyseg_nr++]);
1310
VOID(putchar('\n'));
1345
1353
type=share->rec[field].base_type;
1347
1355
type=(enum en_fieldtype) share->rec[field].type;
1348
end=my_stpcpy(buff,field_pack[type]);
1356
end=stpcpy(buff,field_pack[type]);
1349
1357
if (share->options & HA_OPTION_COMPRESS_RECORD)
1351
1359
if (share->rec[field].pack_type & PACK_TYPE_SELECTED)
1352
end=my_stpcpy(end,", not_always");
1360
end=stpcpy(end,", not_always");
1353
1361
if (share->rec[field].pack_type & PACK_TYPE_SPACE_FIELDS)
1354
end=my_stpcpy(end,", no empty");
1362
end=stpcpy(end,", no empty");
1355
1363
if (share->rec[field].pack_type & PACK_TYPE_ZERO_FILL)
1357
1365
sprintf(end,", zerofill(%d)",share->rec[field].space_length_bits);
1389
1397
static int mi_sort_records(MI_CHECK *param,
1390
1398
register MI_INFO *info, char * name,
1392
1400
bool write_info,
1393
1401
bool update_index)
1397
1405
MI_KEYDEF *keyinfo;
1399
unsigned char *temp_buff;
1400
1408
ha_rows old_record_count;
1401
1409
MYISAM_SHARE *share=info->s;
1402
1410
char llbuff[22],llbuff2[22];
1446
1454
info->opt_flag|=WRITE_CACHE_USED;
1448
if (!(temp_buff=(unsigned char*) my_alloca((uint) keyinfo->block_length)))
1456
if (!(temp_buff=(uchar*) my_alloca((uint) keyinfo->block_length)))
1450
1458
mi_check_print_error(param,"Not enough memory for key block");
1459
1467
fn_format(param->temp_filename,name,"", MI_NAME_DEXT,2+4+32);
1460
new_file=my_create(fn_format(param->temp_filename,
1461
param->temp_filename,"",
1463
0,param->tmpfile_createflag,
1468
new_file=my_raid_create(fn_format(param->temp_filename,
1469
param->temp_filename,"",
1471
0,param->tmpfile_createflag,
1472
share->base.raid_type,
1473
share->base.raid_chunks,
1474
share->base.raid_chunksize,
1465
1476
if (new_file < 0)
1467
1478
mi_check_print_error(param,"Can't create new tempfile: '%s'",
1478
1489
for (key=0 ; key < share->base.keys ; key++)
1479
1490
share->keyinfo[key].flag|= HA_SORT_ALLOWS_SAME;
1481
if (my_pread(share->kfile,(unsigned char*) temp_buff,
1492
if (my_pread(share->kfile,(uchar*) temp_buff,
1482
1493
(uint) keyinfo->block_length,
1483
1494
share->state.key_root[sort_key],
1484
1495
MYF(MY_NABP+MY_WME)))
1516
my_close(info->dfile,MYF(MY_WME));
1527
VOID(my_close(info->dfile,MYF(MY_WME)));
1517
1528
param->out_flag|=O_NEW_DATA; /* Data in new file */
1518
1529
info->dfile=new_file; /* Use new datafile */
1519
1530
info->state->del=0;
1528
1539
if (param->testflag & T_WRITE_LOOP)
1530
fputs(" \r",stdout); fflush(stdout);
1541
VOID(fputs(" \r",stdout)); VOID(fflush(stdout));
1535
1546
if (got_error && new_file >= 0)
1537
end_io_cache(&info->rec_cache);
1548
VOID(end_io_cache(&info->rec_cache));
1538
1549
(void) my_close(new_file,MYF(MY_WME));
1539
(void) my_delete(param->temp_filename, MYF(MY_WME));
1550
(void) my_raid_delete(param->temp_filename, share->base.raid_chunks,
1543
my_afree((unsigned char*) temp_buff);
1555
my_afree((uchar*) temp_buff);
1545
void * rec_buff_ptr= mi_get_rec_buff_ptr(info, sort_param.record);
1546
if (rec_buff_ptr != NULL)
1557
my_free(mi_get_rec_buff_ptr(info, sort_param.record),
1558
MYF(MY_ALLOW_ZERO_PTR));
1549
1559
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
1550
end_io_cache(&info->rec_cache);
1551
free(sort_info.buff);
1560
VOID(end_io_cache(&info->rec_cache));
1561
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
1552
1562
sort_info.buff=0;
1553
1563
share->state.sortkey=sort_key;
1554
1564
return(flush_blocks(param, share->key_cache, share->kfile) |
1561
1571
static int sort_record_index(MI_SORT_PARAM *sort_param,MI_INFO *info,
1562
1572
MI_KEYDEF *keyinfo,
1563
my_off_t page, unsigned char *buff, uint32_t sort_key,
1573
my_off_t page, uchar *buff, uint sort_key,
1564
1574
File new_file,bool update_index)
1566
1576
uint nod_flag,used_length,key_length;
1567
unsigned char *temp_buff,*keypos,*endpos;
1577
uchar *temp_buff,*keypos,*endpos;
1568
1578
my_off_t next_page,rec_pos;
1569
unsigned char lastkey[MI_MAX_KEY_BUFF];
1579
uchar lastkey[MI_MAX_KEY_BUFF];
1570
1580
char llbuff[22];
1571
1581
SORT_INFO *sort_info= sort_param->sort_info;
1572
1582
MI_CHECK *param=sort_info->param;
1592
1602
next_page=_mi_kpos(nod_flag,keypos);
1593
if (my_pread(info->s->kfile,(unsigned char*) temp_buff,
1603
if (my_pread(info->s->kfile,(uchar*) temp_buff,
1594
1604
(uint) keyinfo->block_length, next_page,
1595
1605
MYF(MY_NABP+MY_WME)))
1630
1640
/* Clear end of block to get better compression if the table is backuped */
1631
1641
memset(buff+used_length, 0, keyinfo->block_length-used_length);
1632
if (my_pwrite(info->s->kfile,(unsigned char*) buff,(uint) keyinfo->block_length,
1642
if (my_pwrite(info->s->kfile,(uchar*) buff,(uint) keyinfo->block_length,
1633
1643
page,param->myf_rw))
1635
1645
mi_check_print_error(param,"%d when updating keyblock",my_errno);
1639
my_afree((unsigned char*) temp_buff);
1649
my_afree((uchar*) temp_buff);
1643
my_afree((unsigned char*) temp_buff);
1653
my_afree((uchar*) temp_buff);
1645
1655
} /* sort_record_index */
1670
1680
va_start(args,fmt);
1671
vfprintf(stdout, fmt, args);
1681
VOID(vfprintf(stdout, fmt, args));
1682
VOID(fputc('\n',stdout));
1690
1700
param->warning_printed=1;
1691
1701
va_start(args,fmt);
1692
1702
fprintf(stderr,"%s: warning: ",my_progname_short);
1693
vfprintf(stderr, fmt, args);
1703
VOID(vfprintf(stderr, fmt, args));
1704
VOID(fputc('\n',stderr));
1695
1705
fflush(stderr);
1713
1723
param->error_printed|=1;
1714
1724
va_start(args,fmt);
1715
1725
fprintf(stderr,"%s: error: ",my_progname_short);
1716
vfprintf(stderr, fmt, args);
1726
VOID(vfprintf(stderr, fmt, args));
1727
VOID(fputc('\n',stderr));
1718
1728
fflush(stderr);