~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/myisam/mi_test3.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2004 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
/* Test av locking */
 
17
 
 
18
#ifndef __NETWARE__
 
19
 
 
20
#include "myisam.h"
 
21
#include <sys/types.h>
 
22
#ifdef HAVE_SYS_WAIT_H
 
23
# include <sys/wait.h>
 
24
#endif
 
25
#ifndef WEXITSTATUS
 
26
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
 
27
#endif
 
28
#ifndef WIFEXITED
 
29
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
 
30
#endif
 
31
 
 
32
 
 
33
#if defined(HAVE_LRAND48)
 
34
#define rnd(X) (lrand48() % X)
 
35
#define rnd_init(X) srand48(X)
 
36
#else
 
37
#define rnd(X) (random() % X)
 
38
#define rnd_init(X) srandom(X)
 
39
#endif
 
40
 
 
41
 
 
42
const char *filename= "test3";
 
43
uint tests=10,forks=10,key_cacheing=0,use_log=0;
 
44
 
 
45
static void get_options(int argc, char *argv[]);
 
46
void start_test(int id);
 
47
int test_read(MI_INFO *,int),test_write(MI_INFO *,int,int),
 
48
    test_update(MI_INFO *,int,int),test_rrnd(MI_INFO *,int);
 
49
 
 
50
struct record {
 
51
  uchar id[8];
 
52
  uchar nr[4];
 
53
  uchar text[10];
 
54
} record;
 
55
 
 
56
 
 
57
int main(int argc,char **argv)
 
58
{
 
59
  int status,wait_ret;
 
60
  uint i=0;
 
61
  MI_KEYDEF keyinfo[10];
 
62
  MI_COLUMNDEF recinfo[10];
 
63
  HA_KEYSEG keyseg[10][2];
 
64
  MY_INIT(argv[0]);
 
65
  get_options(argc,argv);
 
66
 
 
67
  bzero((char*) keyinfo,sizeof(keyinfo));
 
68
  bzero((char*) recinfo,sizeof(recinfo));
 
69
  bzero((char*) keyseg,sizeof(keyseg));
 
70
  keyinfo[0].seg= &keyseg[0][0];
 
71
  keyinfo[0].seg[0].start=0;
 
72
  keyinfo[0].seg[0].length=8;
 
73
  keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT;
 
74
  keyinfo[0].seg[0].flag=HA_SPACE_PACK;
 
75
  keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
 
76
  keyinfo[0].keysegs=1;
 
77
  keyinfo[0].flag = (uint8) HA_PACK_KEY;
 
78
  keyinfo[0].block_length= 0;                   /* Default block length */
 
79
  keyinfo[1].seg= &keyseg[1][0];
 
80
  keyinfo[1].seg[0].start=8;
 
81
  keyinfo[1].seg[0].length=4;           /* Long is always 4 in myisam */
 
82
  keyinfo[1].seg[0].type=HA_KEYTYPE_LONG_INT;
 
83
  keyinfo[1].seg[0].flag=0;
 
84
  keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
 
85
  keyinfo[1].keysegs=1;
 
86
  keyinfo[1].flag =HA_NOSAME;
 
87
  keyinfo[1].block_length= 0;                   /* Default block length */
 
88
 
 
89
  recinfo[0].type=0;
 
90
  recinfo[0].length=sizeof(record.id);
 
91
  recinfo[1].type=0;
 
92
  recinfo[1].length=sizeof(record.nr);
 
93
  recinfo[2].type=0;
 
94
  recinfo[2].length=sizeof(record.text);
 
95
 
 
96
  puts("- Creating myisam-file");
 
97
  my_delete(filename,MYF(0));           /* Remove old locks under gdb */
 
98
  if (mi_create(filename,2,&keyinfo[0],2,&recinfo[0],0,(MI_UNIQUEDEF*) 0,
 
99
                (MI_CREATE_INFO*) 0,0))
 
100
    exit(1);
 
101
 
 
102
  rnd_init(0);
 
103
  printf("- Starting %d processes\n",forks); fflush(stdout);
 
104
  for (i=0 ; i < forks; i++)
 
105
  {
 
106
    if (!fork())
 
107
    {
 
108
      start_test(i+1);
 
109
      sleep(1);
 
110
      return 0;
 
111
    }
 
112
    VOID(rnd(1));
 
113
  }
 
114
 
 
115
  for (i=0 ; i < forks ; i++)
 
116
    while ((wait_ret=wait(&status)) && wait_ret == -1);
 
117
  return 0;
 
118
}
 
119
 
 
120
 
 
121
static void get_options(int argc, char **argv)
 
122
{
 
123
  char *pos,*progname;
 
124
 
 
125
  progname= argv[0];
 
126
 
 
127
  while (--argc >0 && *(pos = *(++argv)) == '-' ) {
 
128
    switch(*++pos) {
 
129
    case 'l':
 
130
      use_log=1;
 
131
      break;
 
132
    case 'f':
 
133
      forks=atoi(++pos);
 
134
      break;
 
135
    case 't':
 
136
      tests=atoi(++pos);
 
137
      break;
 
138
    case 'K':                           /* Use key cacheing */
 
139
      key_cacheing=1;
 
140
      break;
 
141
    case 'A':                           /* All flags */
 
142
      use_log=key_cacheing=1;
 
143
      break;
 
144
   case '?':
 
145
    case 'I':
 
146
    case 'V':
 
147
      printf("%s  Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
 
148
      puts("By Monty, for your professional use\n");
 
149
      puts("Test av locking with threads\n");
 
150
      printf("Usage: %s [-?lKA] [-f#] [-t#]\n",progname);
 
151
      exit(0);
 
152
    case '#':
 
153
      DBUG_PUSH (++pos);
 
154
      break;
 
155
    default:
 
156
      printf("Illegal option: '%c'\n",*pos);
 
157
      break;
 
158
    }
 
159
  }
 
160
  return;
 
161
}
 
162
 
 
163
 
 
164
void start_test(int id)
 
165
{
 
166
  uint i;
 
167
  int error,lock_type;
 
168
  MI_ISAMINFO isam_info;
 
169
  MI_INFO *file,*file1,*file2=0,*lock;
 
170
 
 
171
  if (use_log)
 
172
    mi_log(1);
 
173
  if (!(file1=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED)) ||
 
174
      !(file2=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED)))
 
175
  {
 
176
    fprintf(stderr,"Can't open isam-file: %s\n",filename);
 
177
    exit(1);
 
178
  }
 
179
  if (key_cacheing && rnd(2) == 0)
 
180
    init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0);
 
181
  printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
 
182
 
 
183
  for (error=i=0 ; i < tests && !error; i++)
 
184
  {
 
185
    file= (rnd(2) == 1) ? file1 : file2;
 
186
    lock=0 ; lock_type=0;
 
187
    if (rnd(10) == 0)
 
188
    {
 
189
      if (mi_lock_database(lock=(rnd(2) ? file1 : file2),
 
190
                           lock_type=(rnd(2) == 0 ? F_RDLCK : F_WRLCK)))
 
191
      {
 
192
        fprintf(stderr,"%2d: start: Can't lock table %d\n",id,my_errno);
 
193
        error=1;
 
194
        break;
 
195
      }
 
196
    }
 
197
    switch (rnd(4)) {
 
198
    case 0: error=test_read(file,id); break;
 
199
    case 1: error=test_rrnd(file,id); break;
 
200
    case 2: error=test_write(file,id,lock_type); break;
 
201
    case 3: error=test_update(file,id,lock_type); break;
 
202
    }
 
203
    if (lock)
 
204
      mi_lock_database(lock,F_UNLCK);
 
205
  }
 
206
  if (!error)
 
207
  {
 
208
    mi_status(file1,&isam_info,HA_STATUS_VARIABLE);
 
209
    printf("%2d: End of test.  Records:  %ld  Deleted:  %ld\n",
 
210
           id,(long) isam_info.records, (long) isam_info.deleted);
 
211
    fflush(stdout);
 
212
  }
 
213
 
 
214
  mi_close(file1);
 
215
  mi_close(file2);
 
216
  if (use_log)
 
217
    mi_log(0);
 
218
  if (error)
 
219
  {
 
220
    printf("%2d: Aborted\n",id); fflush(stdout);
 
221
    exit(1);
 
222
  }
 
223
}
 
224
 
 
225
 
 
226
int test_read(MI_INFO *file,int id)
 
227
{
 
228
  uint i,lock,found,next,prev;
 
229
  ulong find;
 
230
 
 
231
  lock=0;
 
232
  if (rnd(2) == 0)
 
233
  {
 
234
    lock=1;
 
235
    if (mi_lock_database(file,F_RDLCK))
 
236
    {
 
237
      fprintf(stderr,"%2d: Can't lock table %d\n",id,my_errno);
 
238
      return 1;
 
239
    }
 
240
  }
 
241
 
 
242
  found=next=prev=0;
 
243
  for (i=0 ; i < 100 ; i++)
 
244
  {
 
245
    find=rnd(100000);
 
246
    if (!mi_rkey(file,record.id,1,(uchar*) &find, HA_WHOLE_KEY,
 
247
                 HA_READ_KEY_EXACT))
 
248
      found++;
 
249
    else
 
250
    {
 
251
      if (my_errno != HA_ERR_KEY_NOT_FOUND)
 
252
      {
 
253
        fprintf(stderr,"%2d: Got error %d from read in read\n",id,my_errno);
 
254
        return 1;
 
255
      }
 
256
      else if (!mi_rnext(file,record.id,1))
 
257
        next++;
 
258
      else
 
259
      {
 
260
        if (my_errno != HA_ERR_END_OF_FILE)
 
261
        {
 
262
          fprintf(stderr,"%2d: Got error %d from rnext in read\n",id,my_errno);
 
263
          return 1;
 
264
        }
 
265
        else if (!mi_rprev(file,record.id,1))
 
266
          prev++;
 
267
        else
 
268
        {
 
269
          if (my_errno != HA_ERR_END_OF_FILE)
 
270
          {
 
271
            fprintf(stderr,"%2d: Got error %d from rnext in read\n",
 
272
                    id,my_errno);
 
273
            return 1;
 
274
          }
 
275
        }
 
276
      }
 
277
    }
 
278
  }
 
279
  if (lock)
 
280
  {
 
281
    if (mi_lock_database(file,F_UNLCK))
 
282
    {
 
283
      fprintf(stderr,"%2d: Can't unlock table\n",id);
 
284
      return 1;
 
285
    }
 
286
  }
 
287
  printf("%2d: read:   found: %5d  next: %5d   prev: %5d\n",
 
288
         id,found,next,prev);
 
289
  fflush(stdout);
 
290
  return 0;
 
291
}
 
292
 
 
293
 
 
294
int test_rrnd(MI_INFO *file,int id)
 
295
{
 
296
  uint count,lock;
 
297
 
 
298
  lock=0;
 
299
  if (rnd(2) == 0)
 
300
  {
 
301
    lock=1;
 
302
    if (mi_lock_database(file,F_RDLCK))
 
303
    {
 
304
      fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
 
305
      mi_close(file);
 
306
      return 1;
 
307
    }
 
308
    if (rnd(2) == 0)
 
309
      mi_extra(file,HA_EXTRA_CACHE,0);
 
310
  }
 
311
 
 
312
  count=0;
 
313
  if (mi_rrnd(file,record.id,0L))
 
314
  {
 
315
    if (my_errno == HA_ERR_END_OF_FILE)
 
316
      goto end;
 
317
    fprintf(stderr,"%2d: Can't read first record (%d)\n",id,my_errno);
 
318
    return 1;
 
319
  }
 
320
  for (count=1 ; !mi_rrnd(file,record.id,HA_OFFSET_ERROR) ;count++) ;
 
321
  if (my_errno != HA_ERR_END_OF_FILE)
 
322
  {
 
323
    fprintf(stderr,"%2d: Got error %d from rrnd\n",id,my_errno);
 
324
    return 1;
 
325
  }
 
326
 
 
327
end:
 
328
  if (lock)
 
329
  {
 
330
    mi_extra(file,HA_EXTRA_NO_CACHE,0);
 
331
    if (mi_lock_database(file,F_UNLCK))
 
332
    {
 
333
      fprintf(stderr,"%2d: Can't unlock table\n",id);
 
334
      exit(0);
 
335
    }
 
336
  }
 
337
  printf("%2d: rrnd:   %5d\n",id,count); fflush(stdout);
 
338
  return 0;
 
339
}
 
340
 
 
341
 
 
342
int test_write(MI_INFO *file,int id,int lock_type)
 
343
{
 
344
  uint i,tries,count,lock;
 
345
 
 
346
  lock=0;
 
347
  if (rnd(2) == 0 || lock_type == F_RDLCK)
 
348
  {
 
349
    lock=1;
 
350
    if (mi_lock_database(file,F_WRLCK))
 
351
    {
 
352
      if (lock_type == F_RDLCK && my_errno == EDEADLK)
 
353
      {
 
354
        printf("%2d: write:  deadlock\n",id); fflush(stdout);
 
355
        return 0;
 
356
      }
 
357
      fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
 
358
      mi_close(file);
 
359
      return 1;
 
360
    }
 
361
    if (rnd(2) == 0)
 
362
      mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
 
363
  }
 
364
 
 
365
  sprintf((char*) record.id,"%7d",getpid());
 
366
  strnmov((char*) record.text,"Testing...", sizeof(record.text));
 
367
 
 
368
  tries=(uint) rnd(100)+10;
 
369
  for (i=count=0 ; i < tries ; i++)
 
370
  {
 
371
    uint32 tmp=rnd(80000)+20000;
 
372
    int4store(record.nr,tmp);
 
373
    if (!mi_write(file,record.id))
 
374
      count++;
 
375
    else
 
376
    {
 
377
      if (my_errno != HA_ERR_FOUND_DUPP_KEY)
 
378
      {
 
379
        fprintf(stderr,"%2d: Got error %d (errno %d) from write\n",id,my_errno,
 
380
                errno);
 
381
        return 1;
 
382
      }
 
383
    }
 
384
  }
 
385
  if (lock)
 
386
  {
 
387
    mi_extra(file,HA_EXTRA_NO_CACHE,0);
 
388
    if (mi_lock_database(file,F_UNLCK))
 
389
    {
 
390
      fprintf(stderr,"%2d: Can't unlock table\n",id);
 
391
      exit(0);
 
392
    }
 
393
  }
 
394
  printf("%2d: write:  %5d\n",id,count); fflush(stdout);
 
395
  return 0;
 
396
}
 
397
 
 
398
 
 
399
int test_update(MI_INFO *file,int id,int lock_type)
 
400
{
 
401
  uint i,lock,found,next,prev,update;
 
402
  uint32 tmp;
 
403
  char find[4];
 
404
  struct record new_record;
 
405
 
 
406
  lock=0;
 
407
  if (rnd(2) == 0 || lock_type == F_RDLCK)
 
408
  {
 
409
    lock=1;
 
410
    if (mi_lock_database(file,F_WRLCK))
 
411
    {
 
412
      if (lock_type == F_RDLCK && my_errno == EDEADLK)
 
413
      {
 
414
        printf("%2d: write:  deadlock\n",id); fflush(stdout);
 
415
        return 0;
 
416
      }
 
417
      fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
 
418
      return 1;
 
419
    }
 
420
  }
 
421
  bzero((char*) &new_record,sizeof(new_record));
 
422
  strmov((char*) new_record.text,"Updated");
 
423
 
 
424
  found=next=prev=update=0;
 
425
  for (i=0 ; i < 100 ; i++)
 
426
  {
 
427
    tmp=rnd(100000);
 
428
    int4store(find,tmp);
 
429
    if (!mi_rkey(file,record.id,1,(uchar*) find, HA_WHOLE_KEY,
 
430
                 HA_READ_KEY_EXACT))
 
431
      found++;
 
432
    else
 
433
    {
 
434
      if (my_errno != HA_ERR_KEY_NOT_FOUND)
 
435
      {
 
436
        fprintf(stderr,"%2d: Got error %d from read in update\n",id,my_errno);
 
437
        return 1;
 
438
      }
 
439
      else if (!mi_rnext(file,record.id,1))
 
440
        next++;
 
441
      else
 
442
      {
 
443
        if (my_errno != HA_ERR_END_OF_FILE)
 
444
        {
 
445
          fprintf(stderr,"%2d: Got error %d from rnext in update\n",
 
446
                  id,my_errno);
 
447
          return 1;
 
448
        }
 
449
        else if (!mi_rprev(file,record.id,1))
 
450
          prev++;
 
451
        else
 
452
        {
 
453
          if (my_errno != HA_ERR_END_OF_FILE)
 
454
          {
 
455
            fprintf(stderr,"%2d: Got error %d from rnext in update\n",
 
456
                    id,my_errno);
 
457
            return 1;
 
458
          }
 
459
          continue;
 
460
        }
 
461
      }
 
462
    }
 
463
    memcpy_fixed(new_record.id,record.id,sizeof(record.id));
 
464
    tmp=rnd(20000)+40000;
 
465
    int4store(new_record.nr,tmp);
 
466
    if (!mi_update(file,record.id,new_record.id))
 
467
      update++;
 
468
    else
 
469
    {
 
470
      if (my_errno != HA_ERR_RECORD_CHANGED &&
 
471
          my_errno != HA_ERR_RECORD_DELETED &&
 
472
          my_errno != HA_ERR_FOUND_DUPP_KEY)
 
473
      {
 
474
        fprintf(stderr,"%2d: Got error %d from update\n",id,my_errno);
 
475
        return 1;
 
476
      }
 
477
    }
 
478
  }
 
479
  if (lock)
 
480
  {
 
481
    if (mi_lock_database(file,F_UNLCK))
 
482
    {
 
483
      fprintf(stderr,"Can't unlock table,id, error%d\n",my_errno);
 
484
      return 1;
 
485
    }
 
486
  }
 
487
  printf("%2d: update: %5d\n",id,update); fflush(stdout);
 
488
  return 0;
 
489
}
 
490
 
 
491
#else /* __NETWARE__ */
 
492
 
 
493
#include <stdio.h>
 
494
 
 
495
main()
 
496
{
 
497
        fprintf(stderr,"this test has not been ported to NetWare\n");
 
498
        return 0;
 
499
}
 
500
 
 
501
#endif /* __NETWARE__ */