int main(int argc,char *argv[]) { int error=0; uint keylen, keylen2=0, inx, doc_cnt=0; float weight= 1.0; double gws, min_gws=0, avg_gws=0; MARIA_HA *info; char buf[MAX_LEN], buf2[MAX_LEN], buf_maxlen[MAX_LEN], buf_min_gws[MAX_LEN]; ulong total=0, maxlen=0, uniq=0, max_doc_cnt=0; struct { MARIA_HA *info; } aio0, *aio=&aio0; /* for GWS_IN_USE */ MY_INIT(argv[0]); if ((error= handle_options(&argc, &argv, my_long_options, get_one_option))) exit(error); maria_init(); if (count || dump) verbose=0; if (!count && !dump && !lstats && !query) stats=1; if (verbose) setbuf(stdout,NULL); if (argc < 2) usage(); { char *end; inx= (uint) strtoll(argv[1], &end, 10); if (*end) usage(); } init_pagecache(maria_pagecache, PAGE_BUFFER_INIT, 0, 0, MARIA_KEY_BLOCK_LENGTH, 0, MY_WME); if (!(info=maria_open(argv[0], O_RDONLY, HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER))) { error=my_errno; goto err; } *buf2=0; aio->info=info; if ((inx >= info->s->base.keys) || !(info->s->keyinfo[inx].flag & HA_FULLTEXT)) { printf("Key %d in table %s is not a FULLTEXT key\n", inx, info->s->open_file_name.str); goto err; } maria_lock_database(info, F_EXTRA_LCK); info->cur_row.lastpos= HA_OFFSET_ERROR; info->update|= HA_STATE_PREV_FOUND; while (!(error=maria_rnext(info,NULL,inx))) { FT_WEIGTH subkeys; keylen=*(info->lastkey_buff); subkeys.i= ft_sintXkorr(info->lastkey_buff + keylen + 1); if (subkeys.i >= 0) weight= subkeys.f; #ifdef HAVE_SNPRINTF snprintf(buf,MAX_LEN,"%.*s",(int) keylen,info->lastkey_buff+1); #else sprintf(buf,"%.*s",(int) keylen,info->lastkey_buff+1); #endif my_casedn_str(default_charset_info,buf); total++; lengths[keylen]++; if (count || stats) { if (strcmp(buf, buf2)) { if (*buf2) { uniq++; avg_gws+=gws=GWS_IN_USE; if (count) printf("%9u %20.7f %s\n",doc_cnt,gws,buf2); if (maxlen<keylen2) { maxlen=keylen2; strmov(buf_maxlen, buf2); } if (max_doc_cnt < doc_cnt) { max_doc_cnt=doc_cnt; strmov(buf_min_gws, buf2); min_gws=gws; } } strmov(buf2, buf); keylen2=keylen; doc_cnt=0; } doc_cnt+= (subkeys.i >= 0 ? 1 : -subkeys.i); } if (dump) { if (subkeys.i >= 0) printf("%9lx %20.7f %s\n", (long) info->cur_row.lastpos,weight,buf); else printf("%9lx => %17d %s\n",(long) info->cur_row.lastpos,-subkeys.i, buf); } if (verbose && (total%HOW_OFTEN_TO_WRITE)==0) printf("%10ld\r",total); } maria_lock_database(info, F_UNLCK); if (count || stats) { if (*buf2) { uniq++; avg_gws+=gws=GWS_IN_USE; if (count) printf("%9u %20.7f %s\n",doc_cnt,gws,buf2); if (maxlen<keylen2) { maxlen=keylen2; strmov(buf_maxlen, buf2); } if (max_doc_cnt < doc_cnt) { max_doc_cnt=doc_cnt; strmov(buf_min_gws, buf2); min_gws=gws; } } } if (stats) { count=0; for (inx=0;inx<256;inx++) { count+=lengths[inx]; if ((ulong) count >= total/2) break; } printf("Total rows: %lu\nTotal words: %lu\n" "Unique words: %lu\nLongest word: %lu chars (%s)\n" "Median length: %u\n" "Average global weight: %f\n" "Most common word: %lu times, weight: %f (%s)\n", (long) info->state->records, total, uniq, maxlen, buf_maxlen, inx, avg_gws/uniq, max_doc_cnt, min_gws, buf_min_gws); } if (lstats) { count=0; for (inx=0; inx<256; inx++) { count+=lengths[inx]; if (count && lengths[inx]) printf("%3u: %10lu %5.2f%% %20lu %4.1f%%\n", inx, (ulong) lengths[inx],100.0*lengths[inx]/total,(ulong) count, 100.0*count/total); } } err: if (error && error != HA_ERR_END_OF_FILE) printf("got error %d\n",my_errno); if (info) maria_close(info); maria_end(); return 0; }
int main(int argc, char **argv) { LSN lsn; char **default_argv; uint warnings_count; MY_INIT(argv[0]); maria_data_root= (char *)"."; load_defaults("my", load_default_groups, &argc, &argv); default_argv= argv; get_options(&argc, &argv); maria_in_recovery= TRUE; if (maria_init()) { fprintf(stderr, "Can't init Aria engine (%d)\n", errno); goto err; } maria_block_size= 0; /* Use block size from file */ /* we don't want to create a control file, it MUST exist */ if (ma_control_file_open(FALSE, TRUE)) { fprintf(stderr, "Can't open control file (%d)\n", errno); goto err; } if (last_logno == FILENO_IMPOSSIBLE) { fprintf(stderr, "Can't find any log\n"); goto err; } if (init_pagecache(maria_pagecache, opt_page_buffer_size, 0, 0, maria_block_size, MY_WME) == 0) { fprintf(stderr, "Got error in init_pagecache() (errno: %d)\n", errno); goto err; } /* If log handler does not find the "last_logno" log it will return error, which is good. But if it finds a log and this log was crashed, it will create a new log, which is useless. TODO: start log handler in read-only mode. */ if (init_pagecache(maria_log_pagecache, opt_translog_buffer_size, 0, 0, TRANSLOG_PAGE_SIZE, MY_WME) == 0 || translog_init(maria_data_root, TRANSLOG_FILE_SIZE, 0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS, opt_display_only)) { fprintf(stderr, "Can't init loghandler (%d)\n", errno); goto err; } if (opt_display_only) printf("You are using --display-only, NOTHING will be written to disk\n"); lsn= translog_first_lsn_in_log(); if (lsn == LSN_ERROR) { fprintf(stderr, "Opening transaction log failed\n"); goto end; } if (lsn == LSN_IMPOSSIBLE) { fprintf(stdout, "The transaction log is empty\n"); } if (opt_start_from_checkpoint && !opt_start_from_lsn && last_checkpoint_lsn != LSN_IMPOSSIBLE) { lsn= LSN_IMPOSSIBLE; /* LSN set in maria_apply_log() */ fprintf(stdout, "Starting from checkpoint (%lu,0x%lx)\n", LSN_IN_PARTS(last_checkpoint_lsn)); } else fprintf(stdout, "The transaction log starts from lsn (%lu,0x%lx)\n", LSN_IN_PARTS(lsn)); if (opt_start_from_lsn) { if (opt_start_from_lsn < (ulonglong) lsn) { fprintf(stderr, "start_from_lsn is too small. Aborting\n"); maria_end(); goto err; } lsn= (LSN) opt_start_from_lsn; fprintf(stdout, "Starting reading log from lsn (%lu,0x%lx)\n", LSN_IN_PARTS(lsn)); } if (opt_end_lsn != LSN_IMPOSSIBLE) { /* We can't apply undo if we use end_lsn */ opt_apply_undo= 0; } fprintf(stdout, "TRACE of the last aria_read_log\n"); if (maria_apply_log(lsn, opt_end_lsn, opt_apply ? MARIA_LOG_APPLY : (opt_check ? MARIA_LOG_CHECK : MARIA_LOG_DISPLAY_HEADER), opt_silent ? NULL : stdout, opt_apply_undo, FALSE, FALSE, &warnings_count)) goto err; if (warnings_count == 0) fprintf(stdout, "%s: SUCCESS\n", my_progname_short); else fprintf(stdout, "%s: DOUBTFUL (%u warnings, check previous output)\n", my_progname_short, warnings_count); end: maria_end(); free_tmpdir(&maria_chk_tmpdir); free_defaults(default_argv); my_end(0); exit(0); return 0; /* No compiler warning */ err: /* don't touch anything more, in case we hit a bug */ fprintf(stderr, "%s: FAILED\n", my_progname_short); free_tmpdir(&maria_chk_tmpdir); free_defaults(default_argv); exit(1); }
static int run_test(const char *filename) { MARIA_HA *file; int i,j= 0,error,deleted,rec_length,uniques=0; uint offset_to_key; ha_rows found,row_count; uchar record[MAX_REC_LENGTH],key[MAX_REC_LENGTH],read_record[MAX_REC_LENGTH]; MARIA_UNIQUEDEF uniquedef; MARIA_CREATE_INFO create_info; if (die_in_middle_of_transaction) null_fields= 1; bzero((char*) recinfo,sizeof(recinfo)); bzero((char*) &create_info,sizeof(create_info)); /* First define 2 columns */ create_info.null_bytes= 1; recinfo[0].type= key_field; recinfo[0].length= (key_field == FIELD_BLOB ? 4+portable_sizeof_char_ptr : key_length); if (key_field == FIELD_VARCHAR) recinfo[0].length+= HA_VARCHAR_PACKLENGTH(key_length); recinfo[1].type=extra_field; recinfo[1].length= (extra_field == FIELD_BLOB ? 4 + portable_sizeof_char_ptr : 24); if (extra_field == FIELD_VARCHAR) recinfo[1].length+= HA_VARCHAR_PACKLENGTH(recinfo[1].length); recinfo[1].null_bit= null_fields ? 2 : 0; if (opt_unique) { recinfo[2].type=FIELD_CHECK; recinfo[2].length=MARIA_UNIQUE_HASH_LENGTH; } rec_length= recinfo[0].length + recinfo[1].length + recinfo[2].length + create_info.null_bytes; if (key_type == HA_KEYTYPE_VARTEXT1 && key_length > 255) key_type= HA_KEYTYPE_VARTEXT2; /* Define a key over the first column */ keyinfo[0].seg=keyseg; keyinfo[0].keysegs=1; keyinfo[0].block_length= 0; /* Default block length */ keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].seg[0].type= key_type; keyinfo[0].seg[0].flag= pack_seg; keyinfo[0].seg[0].start=1; keyinfo[0].seg[0].length=key_length; keyinfo[0].seg[0].null_bit= null_fields ? 2 : 0; keyinfo[0].seg[0].null_pos=0; keyinfo[0].seg[0].language= default_charset_info->number; if (pack_seg & HA_BLOB_PART) { keyinfo[0].seg[0].bit_start=4; /* Length of blob length */ } keyinfo[0].flag = (uint8) (pack_keys | unique_key); bzero((uchar*) flags,sizeof(flags)); if (opt_unique) { uint start; uniques=1; bzero((char*) &uniquedef,sizeof(uniquedef)); bzero((char*) uniqueseg,sizeof(uniqueseg)); uniquedef.seg=uniqueseg; uniquedef.keysegs=2; /* Make a unique over all columns (except first NULL fields) */ for (i=0, start=1 ; i < 2 ; i++) { uniqueseg[i].start=start; start+=recinfo[i].length; uniqueseg[i].length=recinfo[i].length; uniqueseg[i].language= default_charset_info->number; } uniqueseg[0].type= key_type; uniqueseg[0].null_bit= null_fields ? 2 : 0; uniqueseg[1].type= HA_KEYTYPE_TEXT; if (extra_field == FIELD_BLOB) { uniqueseg[1].length=0; /* The whole blob */ uniqueseg[1].bit_start=4; /* long blob */ uniqueseg[1].flag|= HA_BLOB_PART; } else if (extra_field == FIELD_VARCHAR) { uniqueseg[1].flag|= HA_VAR_LENGTH_PART; uniqueseg[1].type= (HA_VARCHAR_PACKLENGTH(recinfo[1].length-1) == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2); } } else uniques=0; offset_to_key= MY_TEST(null_fields); if (key_field == FIELD_BLOB || key_field == FIELD_VARCHAR) offset_to_key+= 2; if (!silent) printf("- Creating maria file\n"); create_info.max_rows=(ulong) (rec_pointer_size ? (1L << (rec_pointer_size*8))/40 : 0); create_info.transactional= transactional; if (maria_create(filename, record_type, 1, keyinfo,2+opt_unique,recinfo, uniques, &uniquedef, &create_info, create_flag)) goto err; if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) goto err; if (!silent) printf("- Writing key:s\n"); if (maria_begin(file)) goto err; if (opt_versioning) maria_versioning(file, 1); my_errno=0; row_count=deleted=0; for (i=49 ; i>=1 ; i-=2 ) { if (insert_count-- == 0) { if (testflag) break; maria_close(file); exit(0); } j=i%25 +1; create_record(record,j); error=maria_write(file,record); if (!error) row_count++; flags[j]=1; if (verbose || error) printf("J= %2d maria_write: %d errno: %d\n", j,error,my_errno); } if (maria_commit(file) || maria_begin(file)) goto err; if (checkpoint == 1 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) goto err; if (testflag == 1) goto end; /* Insert 2 rows with null values */ if (null_fields) { create_record(record,0); error=maria_write(file,record); if (!error) row_count++; if (verbose || error) printf("J= NULL maria_write: %d errno: %d\n", error,my_errno); error=maria_write(file,record); if (!error) row_count++; if (verbose || error) printf("J= NULL maria_write: %d errno: %d\n", error,my_errno); flags[0]=2; } if (checkpoint == 2 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) goto err; if (testflag == 2) { printf("Terminating after inserts\n"); goto end; } if (maria_commit(file) || maria_begin(file)) goto err; if (!skip_update) { if (opt_unique) { if (!silent) printf("- Checking unique constraint\n"); create_record(record,j); /* Check last created row */ if (!maria_write(file,record) || my_errno != HA_ERR_FOUND_DUPP_UNIQUE) { printf("unique check failed\n"); } } if (!silent) printf("- Updating rows\n"); /* Update first last row to force extend of file */ if (maria_rsame(file,read_record,-1)) { printf("Can't find last row with maria_rsame\n"); } else { memcpy(record,read_record,rec_length); update_record(record); if (maria_update(file,read_record,record)) { printf("Can't update last row: %.*s\n", keyinfo[0].seg[0].length,read_record+1); } } /* Read through all rows and update them */ maria_scan_init(file); found=0; while ((error= maria_scan(file,read_record)) == 0) { if (--update_count == 0) { maria_close(file); exit(0) ; } memcpy(record,read_record,rec_length); update_record(record); if (maria_update(file,read_record,record)) { printf("Can't update row: %.*s, error: %d\n", keyinfo[0].seg[0].length,record+1,my_errno); } found++; } if (found != row_count) printf("Found %ld of %ld rows\n", (ulong) found, (ulong) row_count); maria_scan_end(file); } if (checkpoint == 3 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) goto err; if (testflag == 3) { printf("Terminating after updates\n"); goto end; } if (!silent) printf("- Reopening file\n"); if (maria_commit(file)) goto err; if (maria_close(file)) goto err; if (!(file=maria_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) goto err; if (maria_begin(file)) goto err; if (opt_versioning) maria_versioning(file, 1); if (!skip_delete) { if (!silent) printf("- Removing keys\n"); for (i=0 ; i <= 10 ; i++) { /* If you want to debug the problem in ma_test_recovery with BLOBs (see @todo there), you can break out of the loop after just one delete, it is enough, like this: if (i==1) break; */ /* testing */ if (remove_count-- == 0) { fprintf(stderr, "delete-rows number of rows deleted; Going down hard!\n"); goto end; } j=i*2; if (!flags[j]) continue; create_key(key,j); my_errno=0; if ((error = maria_rkey(file, read_record, 0, key, HA_WHOLE_KEY, HA_READ_KEY_EXACT))) { if (verbose || (flags[j] >= 1 || (error && my_errno != HA_ERR_KEY_NOT_FOUND))) printf("key: '%.*s' maria_rkey: %3d errno: %3d\n", (int) key_length,key+offset_to_key,error,my_errno); } else { error=maria_delete(file,read_record); if (verbose || error) printf("key: '%.*s' maria_delete: %3d errno: %3d\n", (int) key_length, key+offset_to_key, error, my_errno); if (! error) { deleted++; flags[j]--; } } } } if (checkpoint == 4 && ma_checkpoint_execute(CHECKPOINT_MEDIUM, FALSE)) goto err; if (testflag == 4) { printf("Terminating after deletes\n"); goto end; } if (!silent) printf("- Reading rows with key\n"); record[1]= 0; /* For nicer printf */ if (record_type == NO_RECORD) maria_extra(file, HA_EXTRA_KEYREAD, 0); for (i=0 ; i <= 25 ; i++) { create_key(key,i); my_errno=0; error=maria_rkey(file,read_record,0,key,HA_WHOLE_KEY,HA_READ_KEY_EXACT); if (verbose || (error == 0 && flags[i] == 0 && unique_key) || (error && (flags[i] != 0 || my_errno != HA_ERR_KEY_NOT_FOUND))) { printf("key: '%.*s' maria_rkey: %3d errno: %3d record: %s\n", (int) key_length,key+offset_to_key,error,my_errno,record+1); } } if (record_type == NO_RECORD) { maria_extra(file, HA_EXTRA_NO_KEYREAD, 0); goto end; } if (!silent) printf("- Reading rows with position\n"); if (maria_scan_init(file)) { fprintf(stderr, "maria_scan_init failed\n"); goto err; } for (i=1,found=0 ; i <= 30 ; i++) { my_errno=0; if ((error= maria_scan(file, read_record)) == HA_ERR_END_OF_FILE) { if (found != row_count-deleted) printf("Found only %ld of %ld rows\n", (ulong) found, (ulong) (row_count - deleted)); break; } if (!error) found++; if (verbose || (error != 0 && error != HA_ERR_RECORD_DELETED && error != HA_ERR_END_OF_FILE)) { printf("pos: %2d maria_rrnd: %3d errno: %3d record: %s\n", i-1,error,my_errno,read_record+1); } } maria_scan_end(file); end: if (die_in_middle_of_transaction) { /* As commit record is not done, UNDO entries needs to be rolled back */ switch (die_in_middle_of_transaction) { case 1: /* Flush changed pages go to disk. That will also flush log. Recovery will skip REDOs and apply UNDOs. */ _ma_flush_table_files(file, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX, FLUSH_RELEASE, FLUSH_RELEASE); break; case 2: /* Just flush log. Pages are likely to not be on disk. Recovery will then execute REDOs and UNDOs. */ if (translog_flush(file->trn->undo_lsn)) goto err; break; case 3: /* Flush nothing. Pages and log are likely to not be on disk. Recovery will then do nothing. */ break; case 4: /* Flush changed data pages go to disk. Changed index pages are not flushed. Recovery will skip some REDOs and apply UNDOs. */ _ma_flush_table_files(file, MARIA_FLUSH_DATA, FLUSH_RELEASE, FLUSH_RELEASE); /* We have to flush log separately as the redo for the last key page may not be flushed */ if (translog_flush(file->trn->undo_lsn)) goto err; break; } printf("Dying on request without maria_commit()/maria_close()\n"); sf_leaking_memory= 1; exit(0); } if (maria_commit(file)) goto err; if (maria_close(file)) goto err; maria_end(); my_uuid_end(); my_end(MY_CHECK_ERROR); return (0); err: printf("got error: %3d when using maria-database\n",my_errno); return 1; /* skip warning */ }
int main(int argc,char **argv) { int status,wait_ret; uint i=0; MARIA_KEYDEF keyinfo[10]; MARIA_COLUMNDEF recinfo[10]; HA_KEYSEG keyseg[10][2]; MY_INIT(argv[0]); get_options(argc,argv); fprintf(stderr, "WARNING! this program is to test 'external locking'" " (when several processes share a table through file locking)" " which is not supported by Maria at all; expect errors." " We may soon remove this program.\n"); maria_init(); bzero((char*) keyinfo,sizeof(keyinfo)); bzero((char*) recinfo,sizeof(recinfo)); bzero((char*) keyseg,sizeof(keyseg)); keyinfo[0].seg= &keyseg[0][0]; keyinfo[0].seg[0].start=0; keyinfo[0].seg[0].length=8; keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT; keyinfo[0].seg[0].flag=HA_SPACE_PACK; keyinfo[0].key_alg=HA_KEY_ALG_BTREE; keyinfo[0].keysegs=1; keyinfo[0].flag = (uint8) HA_PACK_KEY; keyinfo[0].block_length= 0; /* Default block length */ keyinfo[1].seg= &keyseg[1][0]; keyinfo[1].seg[0].start=8; keyinfo[1].seg[0].length=4; /* Long is always 4 in maria */ keyinfo[1].seg[0].type=HA_KEYTYPE_LONG_INT; keyinfo[1].seg[0].flag=0; keyinfo[1].key_alg=HA_KEY_ALG_BTREE; keyinfo[1].keysegs=1; keyinfo[1].flag =HA_NOSAME; keyinfo[1].block_length= 0; /* Default block length */ recinfo[0].type=0; recinfo[0].length=sizeof(record.id); recinfo[1].type=0; recinfo[1].length=sizeof(record.nr); recinfo[2].type=0; recinfo[2].length=sizeof(record.text); puts("- Creating maria-file"); my_delete(filename,MYF(0)); /* Remove old locks under gdb */ if (maria_create(filename,BLOCK_RECORD, 2, &keyinfo[0],2,&recinfo[0],0, (MARIA_UNIQUEDEF*) 0, (MARIA_CREATE_INFO*) 0,0)) exit(1); rnd_init(0); printf("- Starting %d processes\n",forks); fflush(stdout); for (i=0 ; i < forks; i++) { if (!fork()) { start_test(i+1); sleep(1); return 0; } rnd(1); } for (i=0 ; i < forks ; i++) while ((wait_ret=wait(&status)) && wait_ret == -1); maria_end(); return 0; }