3
* driver for the tpcc transactions
23
/* Global SQL Variables */
27
#define DB_STRING_MAX 51
29
char connect_string[DB_STRING_MAX];
30
char db_string[DB_STRING_MAX];
31
char db_user[DB_STRING_MAX];
32
char db_password[DB_STRING_MAX];
39
int num_node; /* number of servers that consists of cluster i.e. RAC (0:normal mode)*/
40
#define NUM_NODE_MAX 8
41
char node_string[NUM_NODE_MAX][DB_STRING_MAX];
44
#define PRINT_INTERVAL 10
66
int activate_transaction;
71
int is_local = 0; /* "1" mean local */
72
int valuable_flg = 0; /* "1" mean valuable ratio */
75
int thread_main(int t_num);
77
void alarm_handler(int signum);
80
int main( int argc, char *argv[] )
82
int i, k, t_num, arg_offset;
87
struct itimerval itval;
88
struct sigaction sigact;
92
printf("***************************************\n");
93
printf("*** ###easy### TPC-C Load Generator ***\n");
94
printf("***************************************\n");
98
activate_transaction = 1;
101
for ( i=0; i<5; i++ ){
113
/* dummy initialize*/
118
strcpy( connect_string, "tpcc/tpcc" );
119
strcpy( db_string, "tpcc" );
121
/* number of node (default 0) */
125
/* alarm initialize */
127
itval.it_interval.tv_sec = PRINT_INTERVAL;
128
itval.it_interval.tv_usec = 0;
129
itval.it_value.tv_sec = PRINT_INTERVAL;
130
itval.it_value.tv_usec = 0;
131
sigact.sa_handler = alarm_handler;
133
sigemptyset(&sigact.sa_mask);
135
/* setup handler&timer */
136
if( sigaction( SIGALRM, &sigact, NULL ) == -1 ) {
137
fprintf(stderr, "error in sigaction()\n");
141
clk_tck = sysconf(_SC_CLK_TCK);
145
if ((num_node == 0)&&(argc == 14)) { /* hidden mode */
149
if ((num_node == 0)&&(valuable_flg == 0)&&(argc != 9)) {
150
fprintf(stderr, "\n usage: tpcc_start [server] [DB] [user] [pass] [warehouse] [connection] [rampup] [measure]\n");
154
if ( strlen(argv[1]) >= DB_STRING_MAX ) {
155
fprintf(stderr, "\n server phrase is too long\n");
158
if ( strlen(argv[2]) >= DB_STRING_MAX ) {
159
fprintf(stderr, "\n DBname phrase is too long\n");
162
if ( strlen(argv[3]) >= DB_STRING_MAX ) {
163
fprintf(stderr, "\n user phrase is too long\n");
166
if ( strlen(argv[4]) >= DB_STRING_MAX ) {
167
fprintf(stderr, "\n pass phrase is too long\n");
170
if ((num_ware = atoi(argv[5 + arg_offset])) <= 0) {
171
fprintf(stderr, "\n expecting positive number of warehouses\n");
174
if ((num_conn = atoi(argv[6 + arg_offset])) <= 0) {
175
fprintf(stderr, "\n expecting positive number of connections\n");
178
if ((lampup_time = atoi(argv[7 + arg_offset])) < 0) {
179
fprintf(stderr, "\n expecting positive number of lampup_time [sec]\n");
182
if ((measure_time = atoi(argv[8 + arg_offset])) < 0) {
183
fprintf(stderr, "\n expecting positive number of measure_time [sec]\n");
186
strcpy( connect_string, argv[1] );
187
strcpy( db_string, argv[2] );
188
strcpy( db_user, argv[3] );
189
strcpy( db_password, argv[4] );
190
if(strcmp(db_string,"l")==0){
197
if( (atoi(argv[9 + arg_offset]) < 0)||(atoi(argv[10 + arg_offset]) < 0)||(atoi(argv[11 + arg_offset]) < 0)
198
||(atoi(argv[12 + arg_offset]) < 0)||(atoi(argv[13 + arg_offset]) < 0) ) {
199
fprintf(stderr, "\n expecting positive number of ratio parameters\n");
205
if( num_ware % num_node != 0 ){
206
fprintf(stderr, "\n [warehouse] value must be devided by [num_node].\n");
209
if( num_conn % num_node != 0 ){
210
fprintf(stderr, "\n [connection] value must be devided by [num_node].\n");
215
printf("<Parameters>\n");
216
if(is_local==0)printf(" [server]: %s\n", connect_string);
217
printf(" [DBname]: %s\n", db_string);
218
printf(" [user]: %s\n", db_user);
219
printf(" [pass]: %s\n", db_password);
221
printf(" [warehouse]: %d\n", num_ware);
222
printf(" [connection]: %d\n", num_conn);
223
printf(" [rampup]: %d (sec.)\n", lampup_time);
224
printf(" [measure]: %d (sec.)\n", measure_time);
227
printf(" [ratio]: %d:%d:%d:%d:%d\n", atoi(argv[9 + arg_offset]), atoi(argv[10 + arg_offset]),
228
atoi(argv[11 + arg_offset]), atoi(argv[12 + arg_offset]), atoi(argv[13 + arg_offset]) );
231
fd = open("/dev/urandom", O_RDONLY);
233
fd = open("/dev/random", O_RDONLY);
236
gettimeofday(&tv, NULL);
237
seed = (tv.tv_sec ^ tv.tv_usec) * tv.tv_sec * tv.tv_usec ^ tv.tv_sec;
239
read(fd, &seed, sizeof(seed));
243
read(fd, &seed, sizeof(seed));
249
seq_init(10,10,1,1,1); /* normal ratio */
251
seq_init( atoi(argv[9 + arg_offset]), atoi(argv[10 + arg_offset]), atoi(argv[11 + arg_offset]),
252
atoi(argv[12 + arg_offset]), atoi(argv[13 + arg_offset]) );
255
/* set up each counter */
256
for ( i=0; i<5; i++ ){
257
success2[i] = malloc( sizeof(int) * num_conn );
258
late2[i] = malloc( sizeof(int) * num_conn );
259
retry2[i] = malloc( sizeof(int) * num_conn );
260
failure2[i] = malloc( sizeof(int) * num_conn );
261
for ( k=0; k<num_conn; k++ ){
271
t = malloc( sizeof(pthread_t) * num_conn );
273
fprintf(stderr, "error at malloc(pthread_t)\n");
277
ctx = malloc( sizeof(MYSQL *) * num_conn );
278
stmt = malloc( sizeof(MYSQL_STMT **) * num_conn );
279
for( i=0; i < num_conn; i++ ){
280
stmt[i] = malloc( sizeof(MYSQL_STMT *) * 40 );
284
fprintf(stderr, "error at malloc(sql_context)\n");
288
/* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */
290
for( i=0; i < num_conn; i++ ){
291
ctx[i] = mysql_init(NULL);
292
if(!ctx[i]) goto sqlerr;
295
for( t_num=0; t_num < num_conn; t_num++ ){
296
pthread_create( &t[t_num], NULL, (void *)thread_main, (void *)t_num );
300
printf("\nRAMP-UP TIME.(%d sec.)\n",lampup_time);
303
printf("\nMEASURING START.\n\n");
306
/* sleep(measure_time); */
310
if( setitimer(ITIMER_REAL, &itval, NULL) == -1 ) {
311
fprintf(stderr, "error in setitimer()\n");
317
for(i = 0; i < (measure_time / PRINT_INTERVAL); i++ ) {
321
sleep(PRINT_INTERVAL);
329
itval.it_interval.tv_sec = 0;
330
itval.it_interval.tv_usec = 0;
331
itval.it_value.tv_sec = 0;
332
itval.it_value.tv_usec = 0;
333
if( setitimer(ITIMER_REAL, &itval, NULL) == -1 ) {
334
fprintf(stderr, "error in setitimer()\n");
338
printf("\nSTOPPING THREADS");
339
activate_transaction = 0;
341
/* wait threads' ending and close connections*/
342
for( i=0; i < num_conn; i++ ){
343
pthread_join( t[i], NULL );
349
for( i=0; i < num_conn; i++ ){
358
printf("\n<Raw Results>\n");
359
for ( i=0; i<5; i++ ){
360
printf(" [%d] sc:%d lt:%d rt:%d fl:%d \n", i, success[i], late[i], retry[i], failure[i]);
362
printf(" in %d sec.\n", (measure_time / PRINT_INTERVAL) * PRINT_INTERVAL);
364
printf("\n<Raw Results2(sum ver.)>\n");
365
for( i=0; i<5; i++ ){
370
for( k=0; k<num_conn; k++ ){
371
success2_sum[i] += success2[i][k];
372
late2_sum[i] += late2[i][k];
373
retry2_sum[i] += retry2[i][k];
374
failure2_sum[i] += failure2[i][k];
377
for ( i=0; i<5; i++ ){
378
printf(" [%d] sc:%d lt:%d rt:%d fl:%d \n", i, success2_sum[i], late2_sum[i], retry2_sum[i], failure2_sum[i]);
381
printf("\n<Constraint Check> (all must be [OK])\n [transaction percentage]\n");
382
for ( i=0, j=0; i<5; i++ ){
383
j += (success[i] + late[i]);
386
f = 100.0 * (float)(success[1] + late[1])/(float)j;
387
printf(" Payment: %3.2f%% (>=43.0%%)",f);
393
f = 100.0 * (float)(success[2] + late[2])/(float)j;
394
printf(" Order-Status: %3.2f%% (>= 4.0%%)",f);
400
f = 100.0 * (float)(success[3] + late[3])/(float)j;
401
printf(" Delivery: %3.2f%% (>= 4.0%%)",f);
407
f = 100.0 * (float)(success[4] + late[4])/(float)j;
408
printf(" Stock-Level: %3.2f%% (>= 4.0%%)",f);
415
printf(" [response time (at least 90%% passed)]\n");
416
f = 100.0 * (float)success[0]/(float)(success[0] + late[0]);
417
printf(" New-Order: %3.2f%% ",f);
423
f = 100.0 * (float)success[1]/(float)(success[1] + late[1]);
424
printf(" Payment: %3.2f%% ",f);
430
f = 100.0 * (float)success[2]/(float)(success[2] + late[2]);
431
printf(" Order-Status: %3.2f%% ",f);
437
f = 100.0 * (float)success[3]/(float)(success[3] + late[3]);
438
printf(" Delivery: %3.2f%% ",f);
444
f = 100.0 * (float)success[4]/(float)(success[4] + late[4]);
445
printf(" Stock-Level: %3.2f%% ",f);
452
printf("\n<TpmC>\n");
453
f = (float)(success[0] + late[0]) * 60.0
454
/ (float)((measure_time / PRINT_INTERVAL) * PRINT_INTERVAL);
455
printf(" %.3f TpmC\n",f);
459
fprintf(stdout, "error at main\n");
466
void alarm_handler(int signum)
472
for( i=0; i<5; i++ ){
475
rt90[i] = hist_ckp(i);
478
time_count += PRINT_INTERVAL;
479
printf("%4d, %d(%d):%.1f, %d(%d):%.1f, %d(%d):%.1f, %d(%d):%.1f, %d(%d):%.1f\n",
481
( s[0] + l[0] - prev_s[0] - prev_l[0] ),
482
( l[0] - prev_l[0] ),
484
( s[1] + l[1] - prev_s[1] - prev_l[1] ),
485
( l[1] - prev_l[1] ),
487
( s[2] + l[2] - prev_s[2] - prev_l[2] ),
488
( l[2] - prev_l[2] ),
490
( s[3] + l[3] - prev_s[3] - prev_l[3] ),
491
( l[3] - prev_l[3] ),
493
( s[4] + l[4] - prev_s[4] - prev_l[4] ),
494
( l[4] - prev_l[4] ),
499
for( i=0; i<5; i++ ){
511
for( i=0; i<5; i++ ){
514
rt90[i] = hist_ckp(i);
517
time_count += PRINT_INTERVAL;
518
printf("%4d, %d(%d):%.1f, %d(%d):%.1f, %d(%d):%.1f, %d(%d):%.1f, %d(%d):%.1f\n",
520
( s[0] + l[0] - prev_s[0] - prev_l[0] ),
521
( l[0] - prev_l[0] ),
523
( s[1] + l[1] - prev_s[1] - prev_l[1] ),
524
( l[1] - prev_l[1] ),
526
( s[2] + l[2] - prev_s[2] - prev_l[2] ),
527
( l[2] - prev_l[2] ),
529
( s[3] + l[3] - prev_s[3] - prev_l[3] ),
530
( l[3] - prev_l[3] ),
532
( s[4] + l[4] - prev_s[4] - prev_l[4] ),
533
( l[4] - prev_l[4] ),
538
for( i=0; i<5; i++ ){
544
int thread_main (int t_num)
551
db_string_ptr = db_string;
553
/* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/
555
if(num_node > 0){ /* RAC mode */
556
db_string_ptr = node_string[((num_node * t_num)/num_conn)];
560
/* exec sql connect :connect_string; */
561
resp = mysql_real_connect(ctx[t_num], "localhost", db_user, db_password, db_string, 3306, NULL, 0);
563
/* exec sql connect :connect_string USING :db_string; */
564
resp = mysql_real_connect(ctx[t_num], connect_string, db_user, db_password, db_string, 3306, NULL, 0);
568
mysql_autocommit(ctx[t_num], 0);
570
mysql_close(ctx[t_num]);
575
stmt[t_num][i] = mysql_stmt_init(ctx[t_num]);
576
if(!stmt[t_num][i]) goto sqlerr;
579
/* Prepare ALL of SQLs */
580
if( mysql_stmt_prepare(stmt[t_num][0], "SELECT c_discount, c_last, c_credit, w_tax FROM customer, warehouse WHERE w_id = ? AND c_w_id = w_id AND c_d_id = ? AND c_id = ?", 128) ) goto sqlerr;
581
if( mysql_stmt_prepare(stmt[t_num][1], "SELECT d_next_o_id, d_tax FROM district WHERE d_id = ? AND d_w_id = ? FOR UPDATE", 80) ) goto sqlerr;
582
if( mysql_stmt_prepare(stmt[t_num][2], "UPDATE district SET d_next_o_id = ? + 1 WHERE d_id = ? AND d_w_id = ?", 69) ) goto sqlerr;
583
if( mysql_stmt_prepare(stmt[t_num][3], "INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) VALUES(?, ?, ?, ?, ?, ?, ?)", 111) ) goto sqlerr;
584
if( mysql_stmt_prepare(stmt[t_num][4], "INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) VALUES (?,?,?)", 65) ) goto sqlerr;
585
if( mysql_stmt_prepare(stmt[t_num][5], "SELECT i_price, i_name, i_data FROM item WHERE i_id = ?", 55) ) goto sqlerr;
586
if( mysql_stmt_prepare(stmt[t_num][6], "SELECT s_quantity, s_data, s_dist_01, s_dist_02, s_dist_03, s_dist_04, s_dist_05, s_dist_06, s_dist_07, s_dist_08, s_dist_09, s_dist_10 FROM stock WHERE s_i_id = ? AND s_w_id = ? FOR UPDATE", 189) ) goto sqlerr;
587
if( mysql_stmt_prepare(stmt[t_num][7], "UPDATE stock SET s_quantity = ? WHERE s_i_id = ? AND s_w_id = ?", 63) ) goto sqlerr;
588
if( mysql_stmt_prepare(stmt[t_num][8], "INSERT INTO order_line (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", 159) ) goto sqlerr;
589
if( mysql_stmt_prepare(stmt[t_num][9], "UPDATE warehouse SET w_ytd = w_ytd + ? WHERE w_id = ?", 53) ) goto sqlerr;
590
if( mysql_stmt_prepare(stmt[t_num][10], "SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse WHERE w_id = ?", 91) ) goto sqlerr;
591
if( mysql_stmt_prepare(stmt[t_num][11], "UPDATE district SET d_ytd = d_ytd + ? WHERE d_w_id = ? AND d_id = ?", 67) ) goto sqlerr;
592
if( mysql_stmt_prepare(stmt[t_num][12], "SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district WHERE d_w_id = ? AND d_id = ?", 105) ) goto sqlerr;
593
if( mysql_stmt_prepare(stmt[t_num][13], "SELECT count(c_id) FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ?", 79) ) goto sqlerr;
594
if( mysql_stmt_prepare(stmt[t_num][14], "SELECT c_id FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first", 89) ) goto sqlerr;
595
if( mysql_stmt_prepare(stmt[t_num][15], "SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ? FOR UPDATE", 215) ) goto sqlerr;
596
if( mysql_stmt_prepare(stmt[t_num][16], "SELECT c_data FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?", 72) ) goto sqlerr;
597
if( mysql_stmt_prepare(stmt[t_num][17], "UPDATE customer SET c_balance = ?, c_data = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?", 90) ) goto sqlerr;
598
if( mysql_stmt_prepare(stmt[t_num][18], "UPDATE customer SET c_balance = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?", 78) ) goto sqlerr;
599
if( mysql_stmt_prepare(stmt[t_num][19], "INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) VALUES(?, ?, ?, ?, ?, ?, ?, ?)", 120) ) goto sqlerr;
600
if( mysql_stmt_prepare(stmt[t_num][20], "SELECT count(c_id) FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ?", 79) ) goto sqlerr;
601
if( mysql_stmt_prepare(stmt[t_num][21], "SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first", 121) ) goto sqlerr;
602
if( mysql_stmt_prepare(stmt[t_num][22], "SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?", 102) ) goto sqlerr;
603
if( mysql_stmt_prepare(stmt[t_num][23], "SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ? AND o_id = (SELECT MAX(o_id) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ?)", 196) ) goto sqlerr;
604
if( mysql_stmt_prepare(stmt[t_num][24], "SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id = ?", 135) ) goto sqlerr;
605
if( mysql_stmt_prepare(stmt[t_num][25], "SELECT COALESCE(MIN(no_o_id),0) FROM new_orders WHERE no_d_id = ? AND no_w_id = ?", 81) ) goto sqlerr;
606
if( mysql_stmt_prepare(stmt[t_num][26], "DELETE FROM new_orders WHERE no_o_id = ? AND no_d_id = ? AND no_w_id = ?", 72) ) goto sqlerr;
607
if( mysql_stmt_prepare(stmt[t_num][27], "SELECT o_c_id FROM orders WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?", 70) ) goto sqlerr;
608
if( mysql_stmt_prepare(stmt[t_num][28], "UPDATE orders SET o_carrier_id = ? WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?", 79) ) goto sqlerr;
609
if( mysql_stmt_prepare(stmt[t_num][29], "UPDATE order_line SET ol_delivery_d = ? WHERE ol_o_id = ? AND ol_d_id = ? AND ol_w_id = ?", 89) ) goto sqlerr;
610
if( mysql_stmt_prepare(stmt[t_num][30], "SELECT SUM(ol_amount) FROM order_line WHERE ol_o_id = ? AND ol_d_id = ? AND ol_w_id = ?", 87) ) goto sqlerr;
611
if( mysql_stmt_prepare(stmt[t_num][31], "UPDATE customer SET c_balance = c_balance + ? , c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = ? AND c_d_id = ? AND c_w_id = ?", 128) ) goto sqlerr;
612
if( mysql_stmt_prepare(stmt[t_num][32], "SELECT d_next_o_id FROM district WHERE d_id = ? AND d_w_id = ?", 62) ) goto sqlerr;
613
if( mysql_stmt_prepare(stmt[t_num][33], "SELECT DISTINCT ol_i_id FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id < ? AND ol_o_id >= (? - 20)", 113) ) goto sqlerr;
614
if( mysql_stmt_prepare(stmt[t_num][34], "SELECT count(*) FROM stock WHERE s_w_id = ? AND s_i_id = ? AND s_quantity < ?", 77) ) goto sqlerr;
618
/* EXEC SQL COMMIT WORK; */
619
if( mysql_commit(ctx[t_num]) ) goto sqlerr;
622
mysql_stmt_free_result(stmt[t_num][i]);
623
mysql_stmt_close(stmt[t_num][i]);
626
/* EXEC SQL DISCONNECT; */
627
mysql_close(ctx[t_num]);
635
fprintf(stdout, "error at thread_main\n");