├── Dockerfile ├── README ├── add_fkey_idx.sql ├── count.sql ├── create_table.sql ├── drop_cons.sql ├── load.sh ├── schema2 ├── add_fkey_idx.sql ├── count.sql ├── create_table.sql └── drop_cons.sql ├── scripts ├── 2instances │ └── run.sh ├── anal.full.sh ├── analyze.sh ├── analyzeR.sh ├── analyze_checkpoint.sh ├── analyze_checkpoint_xtradb.sh ├── analyze_checkpoint_xtradb1.sh ├── analyze_dirty.sh ├── analyze_evicted.sh ├── analyze_flushed.sh ├── analyze_flushed_innodb.sh ├── analyze_min.sh ├── analyze_modified.sh ├── flashcache_stat.sh ├── innodb_stat.sh ├── memlock ├── memlock.c ├── multi-instances │ └── runX.sh ├── parse_trx.py ├── remote │ └── runX.sh ├── run.sh ├── runX.sh ├── run_no_backup.sh └── virident_stat.sh ├── sources.list └── src ├── Makefile ├── delivery.c ├── driver.c ├── load.c ├── main.c ├── neword.c ├── ordstat.c ├── parse_port.h ├── payment.c ├── rthist.c ├── rthist.h ├── sequence.c ├── sequence.h ├── slev.c ├── spt_proc.c ├── spt_proc.h ├── support.c ├── tpc.h └── trans_if.h /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.10 2 | MAINTAINER SiddonTang 3 | 4 | # Use Chinese sources.list to speed up if you are in China 5 | COPY sources.list /etc/apt/sources.list 6 | 7 | RUN apt-get update && apt-get install -y gcc libc6-dev zlib1g-dev make libmysqlclient-dev \ 8 | && apt-get clean \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | ADD . /tpcc-mysql 12 | ENV PATH /tpcc-mysql:$PATH 13 | RUN cd /tpcc-mysql/src && make 14 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 1. Build binaries 2 | * cd scr ; make 3 | ( you should have mysql_config available in $PATH) 4 | 5 | 2. Load data 6 | * create database 7 | mysqladmin create tpcc1000 8 | * create tables 9 | mysql tpcc1000 < create_table.sql 10 | * create indexes and FK ( this step can be done after loading data) 11 | mysql tpcc1000 < add_fkey_idx.sql 12 | * populate data 13 | - simple step 14 | tpcc_load 127.0.0.1:33000 tpcc1000 root "" 1000 15 | |hostname:port| |dbname| |user| |password| |WAREHOUSES| 16 | ref. tpcc_load --help for all options 17 | - load data in parallel 18 | check load.sh script 19 | 20 | 3. start benchmark 21 | * ./tpcc_start -h127.0.0.1 -P33000 -dtpcc1000 -uroot -w1000 -c32 -r10 -l10800 22 | |hostname| |port| |dbname| |user| |WAREHOUSES| |CONNECTIONS| |WARMUP TIME| |BENCHMARK TIME| 23 | * ref. tpcc_start --help for all options 24 | -------------------------------------------------------------------------------- /add_fkey_idx.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | 5 | CREATE INDEX idx_customer ON customer (c_w_id,c_d_id,c_last,c_first); 6 | CREATE INDEX idx_orders ON orders (o_w_id,o_d_id,o_c_id,o_id); 7 | CREATE INDEX fkey_stock_2 ON stock (s_i_id); 8 | CREATE INDEX fkey_order_line_2 ON order_line (ol_supply_w_id,ol_i_id); 9 | 10 | ALTER TABLE district ADD CONSTRAINT fkey_district_1 FOREIGN KEY(d_w_id) REFERENCES warehouse(w_id); 11 | ALTER TABLE customer ADD CONSTRAINT fkey_customer_1 FOREIGN KEY(c_w_id,c_d_id) REFERENCES district(d_w_id,d_id); 12 | ALTER TABLE history ADD CONSTRAINT fkey_history_1 FOREIGN KEY(h_c_w_id,h_c_d_id,h_c_id) REFERENCES customer(c_w_id,c_d_id,c_id); 13 | ALTER TABLE history ADD CONSTRAINT fkey_history_2 FOREIGN KEY(h_w_id,h_d_id) REFERENCES district(d_w_id,d_id); 14 | ALTER TABLE new_orders ADD CONSTRAINT fkey_new_orders_1 FOREIGN KEY(no_w_id,no_d_id,no_o_id) REFERENCES orders(o_w_id,o_d_id,o_id); 15 | ALTER TABLE orders ADD CONSTRAINT fkey_orders_1 FOREIGN KEY(o_w_id,o_d_id,o_c_id) REFERENCES customer(c_w_id,c_d_id,c_id); 16 | ALTER TABLE order_line ADD CONSTRAINT fkey_order_line_1 FOREIGN KEY(ol_w_id,ol_d_id,ol_o_id) REFERENCES orders(o_w_id,o_d_id,o_id); 17 | ALTER TABLE order_line ADD CONSTRAINT fkey_order_line_2 FOREIGN KEY(ol_supply_w_id,ol_i_id) REFERENCES stock(s_w_id,s_i_id); 18 | ALTER TABLE stock ADD CONSTRAINT fkey_stock_1 FOREIGN KEY(s_w_id) REFERENCES warehouse(w_id); 19 | ALTER TABLE stock ADD CONSTRAINT fkey_stock_2 FOREIGN KEY(s_i_id) REFERENCES item(i_id); 20 | 21 | 22 | 23 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 24 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 25 | -------------------------------------------------------------------------------- /count.sql: -------------------------------------------------------------------------------- 1 | select count(w_id) from warehouse; 2 | select count(d_w_id) from district; 3 | select count(c_w_id) from customer; 4 | select count(h_c_id) from history; 5 | select count(no_w_id) from new_orders; 6 | select count(o_w_id) from orders; 7 | select count(ol_w_id) from order_line; 8 | select count(i_id) from item; 9 | select count(s_w_id) from stock; 10 | -------------------------------------------------------------------------------- /create_table.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | drop table if exists warehouse; 5 | 6 | create table warehouse ( 7 | w_id smallint not null, 8 | w_name varchar(10), 9 | w_street_1 varchar(20), 10 | w_street_2 varchar(20), 11 | w_city varchar(20), 12 | w_state char(2), 13 | w_zip char(9), 14 | w_tax decimal(4,2), 15 | w_ytd decimal(12,2), 16 | primary key (w_id) ) Engine=InnoDB; 17 | 18 | drop table if exists district; 19 | 20 | create table district ( 21 | d_id tinyint not null, 22 | d_w_id smallint not null, 23 | d_name varchar(10), 24 | d_street_1 varchar(20), 25 | d_street_2 varchar(20), 26 | d_city varchar(20), 27 | d_state char(2), 28 | d_zip char(9), 29 | d_tax decimal(4,2), 30 | d_ytd decimal(12,2), 31 | d_next_o_id int, 32 | primary key (d_w_id, d_id) ) Engine=InnoDB; 33 | 34 | drop table if exists customer; 35 | 36 | create table customer ( 37 | c_id int not null, 38 | c_d_id tinyint not null, 39 | c_w_id smallint not null, 40 | c_first varchar(16), 41 | c_middle char(2), 42 | c_last varchar(16), 43 | c_street_1 varchar(20), 44 | c_street_2 varchar(20), 45 | c_city varchar(20), 46 | c_state char(2), 47 | c_zip char(9), 48 | c_phone char(16), 49 | c_since datetime, 50 | c_credit char(2), 51 | c_credit_lim bigint, 52 | c_discount decimal(4,2), 53 | c_balance decimal(12,2), 54 | c_ytd_payment decimal(12,2), 55 | c_payment_cnt smallint, 56 | c_delivery_cnt smallint, 57 | c_data text, 58 | PRIMARY KEY(c_w_id, c_d_id, c_id) ) Engine=InnoDB; 59 | 60 | drop table if exists history; 61 | 62 | create table history ( 63 | h_c_id int, 64 | h_c_d_id tinyint, 65 | h_c_w_id smallint, 66 | h_d_id tinyint, 67 | h_w_id smallint, 68 | h_date datetime, 69 | h_amount decimal(6,2), 70 | h_data varchar(24) ) Engine=InnoDB; 71 | 72 | drop table if exists new_orders; 73 | 74 | create table new_orders ( 75 | no_o_id int not null, 76 | no_d_id tinyint not null, 77 | no_w_id smallint not null, 78 | PRIMARY KEY(no_w_id, no_d_id, no_o_id)) Engine=InnoDB; 79 | 80 | drop table if exists orders; 81 | 82 | create table orders ( 83 | o_id int not null, 84 | o_d_id tinyint not null, 85 | o_w_id smallint not null, 86 | o_c_id int, 87 | o_entry_d datetime, 88 | o_carrier_id tinyint, 89 | o_ol_cnt tinyint, 90 | o_all_local tinyint, 91 | PRIMARY KEY(o_w_id, o_d_id, o_id) ) Engine=InnoDB ; 92 | 93 | drop table if exists order_line; 94 | 95 | create table order_line ( 96 | ol_o_id int not null, 97 | ol_d_id tinyint not null, 98 | ol_w_id smallint not null, 99 | ol_number tinyint not null, 100 | ol_i_id int, 101 | ol_supply_w_id smallint, 102 | ol_delivery_d datetime, 103 | ol_quantity tinyint, 104 | ol_amount decimal(6,2), 105 | ol_dist_info char(24), 106 | PRIMARY KEY(ol_w_id, ol_d_id, ol_o_id, ol_number) ) Engine=InnoDB ; 107 | 108 | drop table if exists item; 109 | 110 | create table item ( 111 | i_id int not null, 112 | i_im_id int, 113 | i_name varchar(24), 114 | i_price decimal(5,2), 115 | i_data varchar(50), 116 | PRIMARY KEY(i_id) ) Engine=InnoDB; 117 | 118 | drop table if exists stock; 119 | 120 | create table stock ( 121 | s_i_id int not null, 122 | s_w_id smallint not null, 123 | s_quantity smallint, 124 | s_dist_01 char(24), 125 | s_dist_02 char(24), 126 | s_dist_03 char(24), 127 | s_dist_04 char(24), 128 | s_dist_05 char(24), 129 | s_dist_06 char(24), 130 | s_dist_07 char(24), 131 | s_dist_08 char(24), 132 | s_dist_09 char(24), 133 | s_dist_10 char(24), 134 | s_ytd decimal(8,0), 135 | s_order_cnt smallint, 136 | s_remote_cnt smallint, 137 | s_data varchar(50), 138 | PRIMARY KEY(s_w_id, s_i_id) ) Engine=InnoDB ; 139 | 140 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 141 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 142 | 143 | -------------------------------------------------------------------------------- /drop_cons.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | ALTER TABLE district DROP FOREIGN KEY fkey_district_1; 5 | ALTER TABLE customer DROP FOREIGN KEY fkey_customer_1; 6 | ALTER TABLE history DROP FOREIGN KEY fkey_history_1; 7 | ALTER TABLE history DROP FOREIGN KEY fkey_history_2; 8 | ALTER TABLE new_orders DROP FOREIGN KEY fkey_new_orders_1; 9 | ALTER TABLE orders DROP FOREIGN KEY fkey_orders_1; 10 | ALTER TABLE order_line DROP FOREIGN KEY fkey_order_line_1; 11 | ALTER TABLE order_line DROP FOREIGN KEY fkey_order_line_2; 12 | ALTER TABLE stock DROP FOREIGN KEY fkey_stock_1; 13 | ALTER TABLE stock DROP FOREIGN KEY fkey_stock_2; 14 | 15 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 16 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 17 | 18 | -------------------------------------------------------------------------------- /load.sh: -------------------------------------------------------------------------------- 1 | export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 2 | DBNAME=$1 3 | WH=$2 4 | HOST=localhost 5 | STEP=100 6 | 7 | ./tpcc_load $HOST $DBNAME root "" $WH 1 1 $WH >> 1.out & 8 | 9 | x=1 10 | 11 | while [ $x -le $WH ] 12 | do 13 | echo $x $(( $x + $STEP - 1 )) 14 | ./tpcc_load $HOST $DBNAME root "" $WH 2 $x $(( $x + $STEP - 1 )) >> 2_$x.out & 15 | ./tpcc_load $HOST $DBNAME root "" $WH 3 $x $(( $x + $STEP - 1 )) >> 3_$x.out & 16 | ./tpcc_load $HOST $DBNAME root "" $WH 4 $x $(( $x + $STEP - 1 )) >> 4_$x.out & 17 | x=$(( $x + $STEP )) 18 | done 19 | 20 | -------------------------------------------------------------------------------- /schema2/add_fkey_idx.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | 5 | ALTER TABLE district ADD CONSTRAINT fkey_district_1 FOREIGN KEY(d_w_id) REFERENCES warehouse(w_id); 6 | ALTER TABLE customer ADD CONSTRAINT fkey_customer_1 FOREIGN KEY(c_d_id, c_w_id) REFERENCES district(d_id, d_w_id); 7 | ALTER TABLE history ADD CONSTRAINT fkey_history_1 FOREIGN KEY(h_c_id, h_c_d_id, h_c_w_id) REFERENCES customer(c_id, c_d_id, c_w_id); 8 | ALTER TABLE history ADD CONSTRAINT fkey_history_2 FOREIGN KEY(h_d_id, h_w_id) REFERENCES district(d_id, d_w_id); 9 | ALTER TABLE new_orders ADD CONSTRAINT fkey_new_orders_1 FOREIGN KEY(no_o_id,no_d_id,no_w_id) REFERENCES orders(o_id, o_d_id, o_w_id); 10 | ALTER TABLE orders ADD CONSTRAINT fkey_orders_1 FOREIGN KEY(o_c_id,o_d_id,o_w_id) REFERENCES customer(c_id,c_d_id,c_w_id); 11 | ALTER TABLE order_line ADD CONSTRAINT fkey_order_line_1 FOREIGN KEY(ol_o_id,ol_d_id,ol_w_id) REFERENCES orders(o_id, o_d_id, o_w_id); 12 | ALTER TABLE order_line ADD CONSTRAINT fkey_order_line_2 FOREIGN KEY(ol_i_id,ol_supply_w_id) REFERENCES stock(s_i_id,s_w_id); 13 | ALTER TABLE stock ADD CONSTRAINT fkey_stock_1 FOREIGN KEY(s_w_id) REFERENCES warehouse(w_id); 14 | ALTER TABLE stock ADD CONSTRAINT fkey_stock_2 FOREIGN KEY(s_i_id) REFERENCES item(i_id); 15 | 16 | 17 | CREATE INDEX idx_customer ON customer (c_w_id,c_d_id,c_last,c_first); 18 | CREATE INDEX idx_orders ON orders (o_w_id,o_d_id,o_c_id,o_id); 19 | 20 | 21 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 22 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 23 | 24 | -------------------------------------------------------------------------------- /schema2/count.sql: -------------------------------------------------------------------------------- 1 | select count(w_id) from warehouse; 2 | select count(d_w_id) from district; 3 | select count(c_w_id) from customer; 4 | select count(h_c_id) from history; 5 | select count(no_w_id) from new_orders; 6 | select count(o_w_id) from orders; 7 | select count(ol_w_id) from order_line; 8 | select count(i_id) from item; 9 | select count(s_w_id) from stock; 10 | -------------------------------------------------------------------------------- /schema2/create_table.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | drop table if exists warehouse; 5 | 6 | create table warehouse ( 7 | w_id smallint not null, 8 | w_name varchar(10), 9 | w_street_1 varchar(20), 10 | w_street_2 varchar(20), 11 | w_city varchar(20), 12 | w_state char(2), 13 | w_zip char(9), 14 | w_tax decimal(4,2), 15 | w_ytd decimal(12,2) ) TYPE=InnoDB; 16 | 17 | drop table if exists district; 18 | 19 | create table district ( 20 | d_id tinyint not null, 21 | d_w_id smallint not null, 22 | d_name varchar(10), 23 | d_street_1 varchar(20), 24 | d_street_2 varchar(20), 25 | d_city varchar(20), 26 | d_state char(2), 27 | d_zip char(9), 28 | d_tax decimal(4,2), 29 | d_ytd decimal(12,2), 30 | d_next_o_id int ) TYPE=InnoDB; 31 | 32 | drop table if exists customer; 33 | 34 | create table customer ( 35 | c_id int not null, 36 | c_d_id tinyint not null, 37 | c_w_id smallint not null, 38 | c_first varchar(16), 39 | c_middle char(2), 40 | c_last varchar(16), 41 | c_street_1 varchar(20), 42 | c_street_2 varchar(20), 43 | c_city varchar(20), 44 | c_state char(2), 45 | c_zip char(9), 46 | c_phone char(16), 47 | c_since datetime, 48 | c_credit char(2), 49 | c_credit_lim bigint, 50 | c_discount decimal(4,2), 51 | c_balance decimal(12,2), 52 | c_ytd_payment decimal(12,2), 53 | c_payment_cnt smallint, 54 | c_delivery_cnt smallint, 55 | c_data text ) TYPE=InnoDB; 56 | 57 | drop table if exists history; 58 | 59 | create table history ( 60 | h_c_id int, 61 | h_c_d_id tinyint, 62 | h_c_w_id smallint, 63 | h_d_id tinyint, 64 | h_w_id smallint, 65 | h_date datetime, 66 | h_amount decimal(6,2), 67 | h_data varchar(24) ) TYPE=InnoDB; 68 | 69 | drop table if exists new_orders; 70 | 71 | create table new_orders ( 72 | no_o_id int not null, 73 | no_d_id tinyint not null, 74 | no_w_id smallint not null) TYPE=InnoDB; 75 | 76 | drop table if exists orders; 77 | 78 | create table orders ( 79 | o_id int not null, 80 | o_d_id tinyint not null, 81 | o_w_id smallint not null, 82 | o_c_id int, 83 | o_entry_d datetime, 84 | o_carrier_id tinyint, 85 | o_ol_cnt tinyint, 86 | o_all_local tinyint ) TYPE=InnoDB; 87 | 88 | drop table if exists order_line; 89 | 90 | create table order_line ( 91 | ol_o_id int not null, 92 | ol_d_id tinyint not null, 93 | ol_w_id smallint not null, 94 | ol_number tinyint not null, 95 | ol_i_id int, 96 | ol_supply_w_id smallint, 97 | ol_delivery_d datetime, 98 | ol_quantity tinyint, 99 | ol_amount decimal(6,2), 100 | ol_dist_info char(24) ) TYPE=InnoDB; 101 | 102 | drop table if exists item; 103 | 104 | create table item ( 105 | i_id int not null, 106 | i_im_id int, 107 | i_name varchar(24), 108 | i_price decimal(5,2), 109 | i_data varchar(50) ) TYPE=InnoDB; 110 | 111 | drop table if exists stock; 112 | 113 | create table stock ( 114 | s_i_id int not null, 115 | s_w_id smallint not null, 116 | s_quantity smallint, 117 | s_dist_01 char(24), 118 | s_dist_02 char(24), 119 | s_dist_03 char(24), 120 | s_dist_04 char(24), 121 | s_dist_05 char(24), 122 | s_dist_06 char(24), 123 | s_dist_07 char(24), 124 | s_dist_08 char(24), 125 | s_dist_09 char(24), 126 | s_dist_10 char(24), 127 | s_ytd decimal(8,0), 128 | s_order_cnt smallint, 129 | s_remote_cnt smallint, 130 | s_data varchar(50) ) TYPE=InnoDB; 131 | 132 | ALTER TABLE warehouse ADD CONSTRAINT pkey_warehouse PRIMARY KEY(w_id); 133 | ALTER TABLE district ADD CONSTRAINT pkey_district PRIMARY KEY(d_id, d_w_id); 134 | ALTER TABLE customer ADD CONSTRAINT pkey_customer PRIMARY KEY(c_id, c_d_id, c_w_id); 135 | ALTER TABLE new_orders ADD CONSTRAINT pkey_new_orders PRIMARY KEY(no_o_id, no_d_id, no_w_id); 136 | ALTER TABLE orders ADD CONSTRAINT pkey_orders PRIMARY KEY(o_id, o_d_id, o_w_id); 137 | ALTER TABLE order_line ADD CONSTRAINT pkey_order_line PRIMARY KEY(ol_o_id, ol_d_id, ol_w_id, ol_number); 138 | ALTER TABLE item ADD CONSTRAINT pkey_item PRIMARY KEY(i_id); 139 | ALTER TABLE stock ADD CONSTRAINT pkey_stock PRIMARY KEY(s_i_id,s_w_id); 140 | 141 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 142 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 143 | 144 | -------------------------------------------------------------------------------- /schema2/drop_cons.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | ALTER TABLE district DROP FOREIGN KEY fkey_district_1; 5 | ALTER TABLE customer DROP FOREIGN KEY fkey_customer_1; 6 | ALTER TABLE history DROP FOREIGN KEY fkey_history_1; 7 | ALTER TABLE history DROP FOREIGN KEY fkey_history_2; 8 | ALTER TABLE new_orders DROP FOREIGN KEY fkey_new_orders_1; 9 | ALTER TABLE orders DROP FOREIGN KEY fkey_orders_1; 10 | ALTER TABLE order_line DROP FOREIGN KEY fkey_order_line_1; 11 | ALTER TABLE order_line DROP FOREIGN KEY fkey_order_line_2; 12 | ALTER TABLE stock DROP FOREIGN KEY fkey_stock_1; 13 | ALTER TABLE stock DROP FOREIGN KEY fkey_stock_2; 14 | 15 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 16 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 17 | 18 | -------------------------------------------------------------------------------- /scripts/2instances/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u 3 | set -x 4 | set -e 5 | 6 | export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 7 | 8 | BD="/mnt/fio320/back/tpcc500w" 9 | DR1="/mnt/tachion/tpcc500wi1" 10 | DR2="/mnt/tachion/tpcc500wi2" 11 | 12 | BD="/mnt/tachion/back/tpcc500w" 13 | DR1="/mnt/fio320/tpcc500wi1" 14 | DR2="/mnt/fio320/tpcc500wi2" 15 | 16 | WT=10 17 | RT=10800 18 | 19 | 20 | # restore from backup 21 | 22 | function restore_backup { 23 | rm -fr $DR1 24 | rm -fr $DR2 25 | 26 | cp -r $BD $DR1 27 | cp -r $BD $DR2 28 | 29 | sync 30 | echo 3 > /proc/sys/vm/drop_caches 31 | 32 | chown mysql.mysql -R $DR1 33 | chown mysql.mysql -R $DR2 34 | 35 | } 36 | 37 | function waitm { 38 | 39 | while [ true ] 40 | do 41 | 42 | mysql -e "set global innodb_max_dirty_pages_pct=0" mysql -S /tmp/mysql$1.sock 43 | 44 | wt=`mysql -e "SHOW ENGINE INNODB STATUS\G" -S /tmp/mysql$1.sock | grep "Modified db pages" | sort -u | awk '{print $4}'` 45 | if [[ "$wt" -lt 100 ]] ; 46 | then 47 | mysql -e "set global innodb_max_dirty_pages_pct=90" mysql -S /tmp/mysql$1.sock 48 | break 49 | fi 50 | 51 | echo "mysql pages $wt" 52 | sleep 10 53 | done 54 | 55 | } 56 | 57 | function wait_for_mysql { 58 | 59 | set +e 60 | 61 | while true; 62 | do 63 | mysql -Bse "SELECT 1" mysql -S /tmp/mysql$1.sock 64 | 65 | if [ "$?" -eq 0 ] 66 | then 67 | break 68 | fi 69 | 70 | sleep 30 71 | 72 | echo -n "." 73 | done 74 | set -e 75 | 76 | } 77 | 78 | function setup_dirs { 79 | 80 | # Determine run number for selecting an output directory 81 | RUN_NUMBER=-1 82 | 83 | if [ -f ".run_number" ]; then 84 | read RUN_NUMBER < .run_number 85 | fi 86 | 87 | if [ $RUN_NUMBER -eq -1 ]; then 88 | RUN_NUMBER=0 89 | fi 90 | 91 | OUTDIR=res$RUN_NUMBER 92 | mkdir -p $OUTDIR 93 | 94 | RUN_NUMBER=`expr $RUN_NUMBER + 1` 95 | echo $RUN_NUMBER > .run_number 96 | 97 | cp /etc/my.cnf $OUTDIR 98 | 99 | } 100 | 101 | restore_backup 102 | setup_dirs 103 | 104 | #for par in 1 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 43 105 | for par in 6500MB 13GB 26GB 39GB 52GB 65GB 78GB 106 | do 107 | 108 | /usr/local/mysql/libexec/mysqld --defaults-file=/etc/my.cnf --datadir=$DR1 --port=3306 --socket=/tmp/mysql1.sock --innodb_thread_concurrency=0 --innodb-buffer-pool-size=${par} --log-error=error1.log & 109 | /usr/local/mysql/libexec/mysqld --defaults-file=/etc/my.cnf --datadir=$DR2 --port=3307 --socket=/tmp/mysql2.sock --innodb_thread_concurrency=0 --innodb-buffer-pool-size=${par} --log-error=error2.log & 110 | 111 | wait_for_mysql 1 112 | wait_for_mysql 2 113 | 114 | 115 | iostat -dmx 5 2000 >> $OUTDIR/iostat.${par}res & 116 | PID=$! 117 | vmstat 5 2000 >> $OUTDIR/vmstat.${par}res & 118 | PIDV=$! 119 | ./tpcc_start 127.0.0.1:3306 tpcc500w root "" 500 12 10 3600 | tee -a $OUTDIR/tpcc3306.bp${par}.out & 120 | ./tpcc_start 127.0.0.1:3307 tpcc500w root "" 500 12 10 3600 | tee -a $OUTDIR/tpcc3307.bp${par}.out & 121 | 122 | sleep 3700 123 | 124 | waitm 1 125 | 126 | kill -9 $PID 127 | kill -9 $PIDV 128 | 129 | 130 | mysqladmin shutdown -S /tmp/mysql1.sock 131 | mysqladmin shutdown -S /tmp/mysql2.sock 132 | 133 | done 134 | -------------------------------------------------------------------------------- /scripts/anal.full.sh: -------------------------------------------------------------------------------- 1 | cat $1 | grep LSN_ratio_expected | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/1.rr 2 | cat $1 | grep -P "LSN_ratio[\s]" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/2.rr 3 | cat $1 | grep Innodb_log_write_sleeps | awk ' BEGIN {s=0;i=0} { print i,$4-s; s=$4;i++ } ' > /tmp/3.rr 4 | cat $1 | grep -P "Innodb_log_write_sleep_prob" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/4.rr 5 | cat $1 | grep -P "Innodb_break_ratio" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/5.rr 6 | cat $1 | grep -P "Innodb_break_value" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/6.rr 7 | cat $1 | grep -P "Innodb_tacts_to_flush_dirty" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/7.rr 8 | cat $1 | grep -P "Innodb_tacts_to_fill_target" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/8.rr 9 | cat $1 | grep -P "Innodb_EMA_lsn_grow" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/9.rr 10 | cat $1 | grep -P "Innodb_EMA_ckpt_lsn_grow" | awk ' BEGIN {s=0} { print s,$4; s++ } ' > /tmp/10.rr 11 | cat $1 | grep -P "Innodb_buffer_pool_pages_flushed[\s]" | awk ' BEGIN {s=0;i=0} { print i,$4-s; s=$4;i++ } ' > /tmp/11.rr 12 | cat $1 | grep -P "Innodb_buffer_pool_pages_flushed_neighbors[\s]" | awk ' BEGIN {s=0;i=0} { print i,$4-s; s=$4;i++ } ' > /tmp/12.rr 13 | cat $2 | awk ' BEGIN {i=0;sp=0 } /Last checkpoint at/ { st=$4 ; print i, (st)/1024/1024,(st-sp)/1024/1024; i++; sp=st } ' > /tmp/13.rr 14 | 15 | join /tmp/1.rr /tmp/2.rr > /tmp/a2.rr 16 | join /tmp/a2.rr /tmp/3.rr > /tmp/a3.rr 17 | join /tmp/a3.rr /tmp/4.rr > /tmp/a4.rr 18 | join /tmp/a4.rr /tmp/5.rr > /tmp/a5.rr 19 | join /tmp/a5.rr /tmp/6.rr > /tmp/a6.rr 20 | join /tmp/a6.rr /tmp/7.rr > /tmp/a7.rr 21 | join /tmp/a7.rr /tmp/8.rr > /tmp/a8.rr 22 | join /tmp/a8.rr /tmp/9.rr > /tmp/a9.rr 23 | join /tmp/a9.rr /tmp/10.rr > /tmp/a10.rr 24 | join /tmp/a10.rr /tmp/11.rr > /tmp/a11.rr 25 | join /tmp/a11.rr /tmp/12.rr > /tmp/a12.rr 26 | join /tmp/a12.rr /tmp/13.rr > /tmp/a13.rr 27 | echo "time LSN_ratio_expected LSN_ratio sleeps sleep_prob break_ratio break_value tacts_to_flush_dirty tacts_to_fill_target EMA_lsn EMA_ckpt_lsn flushed flushed_neighbors checkpoint checkpoint_delta" 28 | cat /tmp/a13.rr 29 | -------------------------------------------------------------------------------- /scripts/analyze.sh: -------------------------------------------------------------------------------- 1 | TIMESLOT=1 2 | 3 | if [ -n "$2" ] 4 | then 5 | TIMESLOT=$2 6 | echo "Defined $2" 7 | fi 8 | 9 | cat $1 | grep -v HY000 | grep -v payment | grep -v neword | awk -v timeslot=$TIMESLOT ' BEGIN { FS="[,():]"; s=0; cntr=0; aggr=0 } /MEASURING START/ { s=1} /STOPPING THREADS/ {s=0} /0/ { if (s==1) { cntr++; aggr+=$2; } if ( cntr==timeslot ) { printf ("%d %3f\n",aggr,$5) ; cntr=0; aggr=0 } } ' 10 | 11 | -------------------------------------------------------------------------------- /scripts/analyzeR.sh: -------------------------------------------------------------------------------- 1 | TIMESLOT=1 2 | 3 | if [ -n "$2" ] 4 | then 5 | TIMESLOT=$2 6 | echo "Defined $2" 7 | fi 8 | 9 | 10 | for i in 1 2 4 8 16 32 64 11 | do 12 | cat tpcc.par$i.log4G.trx2..out | grep -v HY000 | grep -v payment | grep -v neword | awk -v timeslot=$TIMESLOT -v thr=$i ' BEGIN { FS="[,():]"; s=0; cntr=0; aggr=0 } /MEASURING START/ { s=1} /STOPPING THREADS/ {s=0} /0/ { if (s==1) { cntr++; aggr+=$2; } if ( cntr==timeslot ) { printf ("%d %d %d %3f innodb\n",thr,$1,aggr,$5) ; cntr=0; aggr=0 } } ' 13 | done 14 | 15 | -------------------------------------------------------------------------------- /scripts/analyze_checkpoint.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { } /Log sequence number/ {st=$4 } /Last checkpoint at/ { ed=$4; print (st-ed)/1024/1024 } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_checkpoint_xtradb.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { } /Checkpoint age / {st=$3 ; print (st)/1024/1024 } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_checkpoint_xtradb1.sh: -------------------------------------------------------------------------------- 1 | #cat $1 | awk ' BEGIN { } /Log sequence number/ {st=$4 ; print (st)/1024/1024 } ' 2 | cat $1 | awk ' BEGIN { } /Last checkpoint at/ {st=$4 ; print (st)/1024/1024 } ' 3 | -------------------------------------------------------------------------------- /scripts/analyze_dirty.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { dt=-1;dr=-1;df=-1 } /Innodb_buffer_pool_pages_data/ { if (dt==-1) { dt=$4} else { dt+=$4 } } /Innodb_buffer_pool_pages_dirty/ { if (dr==-1) { dr=$4} else { dr+=$4 } } /Innodb_buffer_pool_pages_free/ { if (df==-1) { df=$4} else { df+=$4 } ; print (100*dr)/(1+dt+df) } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_evicted.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { df=0 ; dl=0; } /Innodb_buffer_pool_read_ahead_evicted/ { df=$4 } /Innodb_buffer_pool_pages_LRU_flushed/ { dl=$4; print df,dl } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_flushed.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { df=0 ; dl=0; } /Innodb_buffer_pool_pages_flushed[\s]/ { df=$4 } /Innodb_buffer_pool_pages_LRU_flushed/ { dl=$4; print df,dl } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_flushed_innodb.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { df=0 ; dl=0; } /Innodb_buffer_pool_pages_flushed/ { df=$4 ; print df } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_min.sh: -------------------------------------------------------------------------------- 1 | cat $1 | grep -v HY000 | grep -v payment | grep -v neword | awk ' BEGIN { FS="[,(]"; s=0; cntr=0; aggr=0 } /MEASURING START/ { s=1} /STOPPING THREADS/ {s=0} /0/ { if (s==1) { cntr++; aggr+=$2; } if ( cntr==6 ) { printf ("%d\n",aggr) ; cntr=0; aggr=0 } } ' 2 | -------------------------------------------------------------------------------- /scripts/analyze_modified.sh: -------------------------------------------------------------------------------- 1 | cat $1 | awk ' BEGIN { } /Log sequence number/ {st=$4 } /Log flushed up to/ { ed=$5; print (st-ed) } ' 2 | -------------------------------------------------------------------------------- /scripts/flashcache_stat.sh: -------------------------------------------------------------------------------- 1 | sysctl -w dev.flashcache.zero_stats=1 2 | 3 | while [ true ] 4 | do 5 | 6 | dmsetup status flashcache 7 | sleep 10 8 | 9 | done 10 | 11 | -------------------------------------------------------------------------------- /scripts/innodb_stat.sh: -------------------------------------------------------------------------------- 1 | x=1 2 | end=$1 3 | 4 | while [ [ $x -le $end ] ] 5 | do 6 | 7 | mysql -e "SHOW ENGINE INNODB STATUS\G" 8 | sleep 10 9 | x=$(( $x + 10 )) 10 | 11 | done 12 | 13 | -------------------------------------------------------------------------------- /scripts/memlock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pingcap/tpcc-mysql/7905c313cc545ab2fc3b900334ddb808dee03547/scripts/memlock -------------------------------------------------------------------------------- /scripts/memlock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | char * 7 | alloc_workbuf(size_t size) 8 | { 9 | char *ptr; 10 | 11 | /* allocate some memory */ 12 | ptr = malloc(size); 13 | 14 | /* return NULL on failure */ 15 | if (ptr == NULL) 16 | return NULL; 17 | 18 | /* lock this buffer into RAM */ 19 | if (mlock(ptr, size)) { 20 | free(ptr); 21 | return NULL; 22 | } 23 | return ptr; 24 | } 25 | 26 | void 27 | free_workbuf(char *ptr, size_t size) 28 | { 29 | /* unlock the address range */ 30 | munlock(ptr, size); 31 | 32 | /* free the memory */ 33 | free(ptr); 34 | } 35 | 36 | int main() 37 | { 38 | 39 | char *area; 40 | size_t allocz=306535006208LLU; 41 | 42 | area=alloc_workbuf(allocz); 43 | 44 | while(1) 45 | { 46 | sleep(10); 47 | } 48 | 49 | free_workbuf(area,allocz); 50 | 51 | return 0; 52 | 53 | } 54 | -------------------------------------------------------------------------------- /scripts/multi-instances/runX.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u 3 | set -x 4 | set -e 5 | 6 | #export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 7 | export LD_LIBRARY_PATH=/usr/local/Percona-Server/lib/mysql/ 8 | MYSQLDIR=/usr/local/Percona-Server-5.5.15-rel21.0-158.Linux.x86_64/ 9 | #MYSQLDIR=/usr/local/mysql-5.6.3-m6-linux2.6-x86_64 10 | 11 | ulimit -c unlimited 12 | 13 | #DR="/mnt/fio320" 14 | DR="/data/fio/d" 15 | #IDR="/data/bench/fio/d" 16 | IDR="/data/fio/d" 17 | LR="/data/fio/d" 18 | #LR="/data/bench/fio/d" 19 | CONFIG="/etc/my.559.cnf" 20 | 21 | SERVER="R815" 22 | NINST=1 23 | MAXW=2400 24 | WH=$(($MAXW/$NINST)) 25 | BP=$((120/$NINST)) 26 | BD=/data/bench/back/tpcc$WH 27 | 28 | RT=7200 29 | 30 | 31 | log2="$DR/" 32 | 33 | # restore from backup 34 | function restore { 35 | 36 | for i in `seq 1 $NINST` 37 | do 38 | ssh $SERVER "mkdir -p $DR$i" 39 | ssh $SERVER "rm -fr $DR$i/*" 40 | 41 | ssh $SERVER "mkdir -p $LR$i" 42 | ssh $SERVER "rm -fr $LR$i/*" 43 | 44 | ssh $SERVER "mkdir -p $IDR$i" 45 | ssh $SERVER "rm -fr $IDR$i/*" 46 | 47 | ssh $SERVER "cp -r $BD/* $DR$i" 48 | 49 | ssh $SERVER "cp -r $BD/ibdata1 $IDR$i" 50 | ssh $SERVER "cp /tmp/ib_lru_dump $DR$i" 51 | ssh $SERVER "sync; echo 3 > /proc/sys/vm/drop_caches" 52 | 53 | ssh $SERVER "chown mysql.mysql -R $DR$i; chmod -R 755 $DR$i" 54 | ssh $SERVER "chown mysql.mysql -R $LR$i; chmod -R 755 $LR$i" 55 | done 56 | 57 | } 58 | 59 | function formatc { 60 | 61 | set +e 62 | ssh $SERVER "umount /data/fio" 63 | ssh $SERVER "mdadm --stop /dev/md127" 64 | ssh $SERVER "fio-detach /dev/fct0" 65 | ssh $SERVER "fio-detach /dev/fct1" 66 | ssh $SERVER "yes | fio-format -b 4096 /dev/fct0" 67 | ssh $SERVER "yes | fio-format -b 4096 /dev/fct1" 68 | ssh $SERVER "fio-attach /dev/fct0" 69 | ssh $SERVER "fio-attach /dev/fct1" 70 | ssh $SERVER "mdadm --create --verbose /dev/md127 --level=0 --raid-devices=2 --chunk=128 /dev/fioa /dev/fiob" 71 | ssh $SERVER "mkfs.xfs -s size=4096 /dev/md127" 72 | ssh $SERVER "mount /dev/md127 /data/fio -o nobarrier" 73 | set -e 74 | 75 | } 76 | 77 | 78 | function waitm { 79 | 80 | while [ true ] 81 | do 82 | 83 | mysql -e "set global innodb_max_dirty_pages_pct=0" mysql 84 | 85 | wt=`mysql -e "SHOW ENGINE INNODB STATUS\G" | grep "Modified db pages" | sort -u | awk '{print $4}'` 86 | if [[ "$wt" -lt 100 ]] ; 87 | then 88 | mysql -e "set global innodb_max_dirty_pages_pct=90" mysql 89 | break 90 | fi 91 | 92 | echo "mysql pages $wt" 93 | sleep 10 94 | done 95 | 96 | } 97 | 98 | function stratmysqld { 99 | 100 | 101 | for i in `seq 1 $NINST` 102 | do 103 | PORT=$((3305+$i)) 104 | ssh $SERVER "numactl --cpunodebind=$(( ($i-1) * 8 / $NINST ))-$((($i-1)*8/$NINST+8/$NINST-1)) --interleave=all $MYSQLDIR/bin/mysqld --defaults-file=$CONFIG --datadir=$DR$i --innodb_thread_concurrency=0 --innodb-buffer-pool-size=${BP}G --innodb-log-file-size=$logsz --innodb_flush_log_at_trx_commit=$trxv --log-error=$DR$i/mysql.error.log --socket=/tmp/mysql$PORT --port=$PORT --innodb_data_home_dir=$IDR$i --innodb_log_group_home_dir=$LR$i --basedir=$MYSQLDIR &" 105 | 106 | set +e 107 | 108 | while true; 109 | do 110 | mysql -Bse "SELECT 1" mysql -h $SERVER -P $PORT 111 | 112 | if [ "$?" -eq 0 ] 113 | then 114 | break 115 | fi 116 | 117 | sleep 30 118 | 119 | echo -n "." 120 | done 121 | set -e 122 | 123 | done 124 | 125 | } 126 | 127 | 128 | # Determine run number for selecting an output directory 129 | RUN_NUMBER=-1 130 | 131 | if [ -f ".run_number" ]; then 132 | read RUN_NUMBER < .run_number 133 | fi 134 | 135 | if [ $RUN_NUMBER -eq -1 ]; then 136 | RUN_NUMBER=0 137 | fi 138 | 139 | OUTDIR=res$RUN_NUMBER 140 | mkdir -p $OUTDIR 141 | 142 | RUN_NUMBER=`expr $RUN_NUMBER + 1` 143 | echo $RUN_NUMBER > .run_number 144 | 145 | formatc 146 | 147 | for trxv in 2 148 | do 149 | for logsz in 4G 150 | do 151 | #for par in 12 24 36 48 60 72 152 | #for par in 12 18 24 30 36 153 | #for par in 4 6 8 10 12 154 | #for par in $((36/$NINST)) $((48/$NINST)) 155 | for par in $((48/$NINST)) 156 | do 157 | 158 | runid="par$par.log$logsz.trx$trxv" 159 | 160 | restore 161 | 162 | stratmysqld 163 | 164 | sleep 30 165 | 166 | ssh -f $SERVER "iostat -dmx 10 $(($RT/10+1)) " >> $OUTDIR/iostat.$runid.res 167 | ssh -f $SERVER "dstat -t -v --nocolor 10 $(($RT/10+1))" > $OUTDIR/dstat_plain.$runid.res 168 | 169 | cp $0 $OUTDIR 170 | 171 | for i in `seq 1 $NINST` 172 | do 173 | PORT=$((3305+$i)) 174 | mysqladmin variables -h $SERVER -P$PORT >> $OUTDIR/mysql_variables.$PORT.res 175 | ./innodb_stat.sh $RT $SERVER $PORT >> $OUTDIR/innodb.${runid}.$i.res & 176 | ./tpcc_start $SERVER:$PORT tpcc$WH root "" $WH $par 10 $RT | tee -a $OUTDIR/tpcc.${runid}.$i.out & 177 | done 178 | 179 | sleep $(($RT+30)) 180 | 181 | set +e 182 | ssh $SERVER "killall -s SIGKILL mysqld" 183 | set -e 184 | 185 | sleep 60 186 | ssh $SERVER "cp ${DR}1/ib_lru_dump /tmp" 187 | 188 | 189 | 190 | done 191 | 192 | done 193 | done 194 | -------------------------------------------------------------------------------- /scripts/parse_trx.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import math 3 | import functools 4 | 5 | ins = open( sys.argv[1], "r" ) 6 | array = {} 7 | response_times= {} 8 | 9 | array_10s = {} 10 | response_times_10s = {} 11 | 12 | array_60s = {} 13 | response_times_60s = {} 14 | 15 | def calms(f_sec,f_ms,s_sec,s_ms): 16 | res=(int(f_sec)-int(s_sec))*1000 + (int(f_ms)-int(s_ms))/1000000 17 | return res 18 | 19 | def percentile(N, percent, key=lambda x:x): 20 | """ 21 | Find the percentile of a list of values. 22 | 23 | @parameter N - is a list of values. Note N MUST BE already sorted. 24 | @parameter percent - a float value from 0.0 to 1.0. 25 | @parameter key - optional key function to compute value from each element of N. 26 | 27 | @return - the percentile of the values 28 | """ 29 | if not N: 30 | return None 31 | k = (len(N)-1) * percent 32 | f = math.floor(k) 33 | c = math.ceil(k) 34 | if f == c: 35 | return key(N[int(k)]) 36 | d0 = key(N[int(f)]) * (c-k) 37 | d1 = key(N[int(c)]) * (k-f) 38 | return d0+d1 39 | 40 | if len(sys.argv)>=2: 41 | pref=sys.argv[2] 42 | else: 43 | pref="" 44 | 45 | for line in ins: 46 | data=line.split() 47 | current_sec = int(data[3]); 48 | if array.has_key(current_sec): 49 | array[current_sec] = array[current_sec]+1 50 | response_times[current_sec].append(calms(data[3],data[4],data[6],data[7])) 51 | else: 52 | array[current_sec] = 1 53 | response_times[current_sec]=[calms(data[3],data[4],data[6],data[7])] 54 | cur_10s = current_sec/10 55 | if array_10s.has_key(cur_10s): 56 | array_10s[cur_10s] = array_10s[cur_10s]+1 57 | response_times_10s[cur_10s].append(calms(data[3],data[4],data[6],data[7])) 58 | else: 59 | array_10s[cur_10s] = 1 60 | response_times_10s[cur_10s]=[calms(data[3],data[4],data[6],data[7])] 61 | # print calms(data[3],data[4],data[6],data[7]) 62 | cur_60s = current_sec/60 63 | if array_60s.has_key(cur_60s): 64 | array_60s[cur_60s] = array_60s[cur_60s]+1 65 | response_times_60s[cur_60s].append(calms(data[3],data[4],data[6],data[7])) 66 | else: 67 | array_60s[cur_60s] = 1 68 | response_times_60s[cur_60s]=[calms(data[3],data[4],data[6],data[7])] 69 | 70 | minsec=min(array.keys()) 71 | maxsec=max(array.keys()) 72 | i=minsec 73 | while i<=maxsec: 74 | if array.has_key(i): 75 | # print str(i),len(response_times[str(i)].sort()) 76 | response_times[i].sort() 77 | pct99=percentile(response_times[i],0.99) 78 | print pref,i-minsec,array[i],pct99 79 | else: 80 | print pref,i-minsec,0 81 | i=i+1 82 | 83 | print "========== 10 sec =============" 84 | 85 | minsec=min(array_10s.keys()) 86 | maxsec=max(array_10s.keys()) 87 | i=minsec 88 | while i<=maxsec: 89 | if array_10s.has_key(i): 90 | # print str(i),len(response_times[str(i)].sort()) 91 | response_times_10s[i].sort() 92 | pct99=percentile(response_times_10s[i],0.99) 93 | print pref,i-minsec,array_10s[i],pct99 94 | else: 95 | print pref,i-minsec,0 96 | i=i+1 97 | 98 | print "========== 60 sec =============" 99 | 100 | minsec=min(array_60s.keys()) 101 | maxsec=max(array_60s.keys()) 102 | i=minsec 103 | while i<=maxsec: 104 | if array_60s.has_key(i): 105 | # print str(i),len(response_times[str(i)].sort()) 106 | response_times_60s[i].sort() 107 | pct99=percentile(response_times_60s[i],0.99) 108 | print pref,i-minsec,array_60s[i],pct99 109 | else: 110 | print pref,i-minsec,0 111 | i=i+1 112 | -------------------------------------------------------------------------------- /scripts/remote/runX.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u 3 | set -x 4 | set -e 5 | 6 | #export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 7 | export LD_LIBRARY_PATH=/usr/local/Percona-Server/lib/mysql/ 8 | MYSQLDIR=/usr/local/Percona-XtraDB-Cluster-5.5.15 9 | #MYSQLDIR=/usr/local/mysql-5.6.3-m6-linux2.6-x86_64 10 | 11 | ulimit -c unlimited 12 | 13 | #DR="/mnt/fio320" 14 | DR="/data/fio/d" 15 | #IDR="/data/bench/fio/d" 16 | IDR="/data/fio/d" 17 | LR="/data/fio/d" 18 | #LR="/data/bench/fio/d" 19 | CONFIG="/etc/my.gal.55.cnf" 20 | 21 | #SERVER="10.11.12.206" 22 | SERVER="R815" 23 | NINST=1 24 | MAXW=600 25 | WH=$(($MAXW/$NINST)) 26 | BP=$((120/$NINST)) 27 | BD=/data/bench/back/tpcc$WH 28 | 29 | RT=3600 30 | 31 | 32 | log2="$DR/" 33 | 34 | # restore from backup 35 | function restore { 36 | 37 | for i in `seq 1 $NINST` 38 | do 39 | ssh $SERVER "mkdir -p $DR$i" 40 | ssh $SERVER "rm -fr $DR$i/*" 41 | 42 | ssh $SERVER "mkdir -p $LR$i" 43 | ssh $SERVER "rm -fr $LR$i/*" 44 | 45 | ssh $SERVER "mkdir -p $IDR$i" 46 | ssh $SERVER "rm -fr $IDR$i/*" 47 | 48 | ssh $SERVER "cp -r $BD/* $DR$i" 49 | 50 | ssh $SERVER "cp -r $BD/ibdata1 $IDR$i" 51 | ssh $SERVER "cp /tmp/ib_lru_dump $DR$i" 52 | ssh $SERVER "sync; echo 3 > /proc/sys/vm/drop_caches" 53 | 54 | ssh $SERVER "chown mysql.mysql -R $DR$i; chmod -R 755 $DR$i" 55 | ssh $SERVER "chown mysql.mysql -R $LR$i; chmod -R 755 $LR$i" 56 | done 57 | 58 | } 59 | 60 | function formatc { 61 | 62 | set +e 63 | ssh $SERVER "umount /data/fio" 64 | ssh $SERVER "mdadm --stop /dev/md127" 65 | ssh $SERVER "fio-detach /dev/fct0" 66 | ssh $SERVER "fio-detach /dev/fct1" 67 | ssh $SERVER "yes | fio-format -b 4096 /dev/fct0" 68 | ssh $SERVER "yes | fio-format -b 4096 /dev/fct1" 69 | ssh $SERVER "fio-attach /dev/fct0" 70 | ssh $SERVER "fio-attach /dev/fct1" 71 | ssh $SERVER "mdadm --create --verbose /dev/md127 --level=0 --raid-devices=2 --chunk=128 /dev/fioa /dev/fiob" 72 | ssh $SERVER "mkfs.xfs -s size=4096 /dev/md127" 73 | ssh $SERVER "mount /dev/md127 /data/fio -o nobarrier" 74 | set -e 75 | 76 | } 77 | 78 | 79 | function waitm { 80 | 81 | while [ true ] 82 | do 83 | 84 | mysql -e "set global innodb_max_dirty_pages_pct=0" mysql 85 | 86 | wt=`mysql -e "SHOW ENGINE INNODB STATUS\G" | grep "Modified db pages" | sort -u | awk '{print $4}'` 87 | if [[ "$wt" -lt 100 ]] ; 88 | then 89 | mysql -e "set global innodb_max_dirty_pages_pct=90" mysql 90 | break 91 | fi 92 | 93 | echo "mysql pages $wt" 94 | sleep 10 95 | done 96 | 97 | } 98 | 99 | function stratmysqld { 100 | 101 | 102 | for i in `seq 1 $NINST` 103 | do 104 | PORT=$((3305+$i)) 105 | ssh $SERVER "PATH=$PATH:/usr/local/Percona-XtraDB-Cluster-5.5.15/bin numactl --cpunodebind=$(( ($i-1) * 8 / $NINST ))-$((($i-1)*8/$NINST+8/$NINST-1)) --interleave=all $MYSQLDIR/bin/mysqld --defaults-file=$CONFIG --datadir=$DR$i --innodb_thread_concurrency=0 --innodb-buffer-pool-size=${BP}G --innodb-log-file-size=$logsz --innodb_flush_log_at_trx_commit=$trxv --log-error=$DR$i/mysql.error.log --socket=/tmp/mysql$PORT --port=$PORT --innodb_data_home_dir=$IDR$i --innodb_log_group_home_dir=$LR$i --basedir=$MYSQLDIR &" 106 | 107 | set +e 108 | 109 | while true; 110 | do 111 | mysql -Bse "SELECT 1" mysql -h $SERVER -P $PORT 112 | 113 | if [ "$?" -eq 0 ] 114 | then 115 | break 116 | fi 117 | 118 | sleep 30 119 | 120 | echo -n "." 121 | done 122 | set -e 123 | 124 | done 125 | 126 | } 127 | 128 | 129 | # Determine run number for selecting an output directory 130 | RUN_NUMBER=-1 131 | 132 | if [ -f ".run_number" ]; then 133 | read RUN_NUMBER < .run_number 134 | fi 135 | 136 | if [ $RUN_NUMBER -eq -1 ]; then 137 | RUN_NUMBER=0 138 | fi 139 | 140 | OUTDIR=res$RUN_NUMBER 141 | mkdir -p $OUTDIR 142 | 143 | RUN_NUMBER=`expr $RUN_NUMBER + 1` 144 | echo $RUN_NUMBER > .run_number 145 | 146 | formatc 147 | 148 | for trxv in 2 149 | do 150 | for logsz in 4G 151 | do 152 | #for par in 12 24 36 48 60 72 153 | #for par in 12 18 24 30 36 154 | #for par in 4 6 8 10 12 155 | #for par in $((36/$NINST)) $((48/$NINST)) 156 | for par in $((48/$NINST)) 157 | do 158 | 159 | runid="par$par.log$logsz.trx$trxv" 160 | 161 | restore 162 | 163 | #stratmysqld 164 | 165 | exit 166 | 167 | sleep 30 168 | 169 | ssh -f $SERVER "iostat -dmx 10 $(($RT/10+1)) " >> $OUTDIR/iostat.$runid.res 170 | ssh -f $SERVER "dstat -t -v --nocolor 10 $(($RT/10+1))" > $OUTDIR/dstat_plain.$runid.res 171 | 172 | cp $0 $OUTDIR 173 | 174 | for i in `seq 1 $NINST` 175 | do 176 | PORT=$((3305+$i)) 177 | mysqladmin variables -h $SERVER -P$PORT >> $OUTDIR/mysql_variables.$PORT.res 178 | ./innodb_stat.sh $RT $SERVER $PORT >> $OUTDIR/innodb.${runid}.$i.res & 179 | ./tpcc_start $SERVER:$PORT tpcc$WH root "" $WH $par 10 $RT | tee -a $OUTDIR/tpcc.${runid}.$i.out & 180 | done 181 | 182 | sleep $(($RT+30)) 183 | 184 | set +e 185 | #ssh $SERVER "killall -s SIGKILL mysqld" 186 | set -e 187 | 188 | sleep 60 189 | #ssh $SERVER "cp ${DR}1/ib_lru_dump /tmp" 190 | 191 | 192 | 193 | done 194 | 195 | done 196 | done 197 | -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u 3 | set -x 4 | set -e 5 | 6 | export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 7 | 8 | DR="/mnt/fio320/bench" 9 | BD="/data/back/fio320/bench" 10 | 11 | WT=10 12 | RT=10800 13 | 14 | ROWS=80000000 15 | 16 | #log2="/data/log/" 17 | log2="$DR/" 18 | 19 | # restore from backup 20 | 21 | rm -fr $DR/* 22 | 23 | echo $log2 24 | #for nm in ibdata1 ib_logfile0 ib_logfile1 25 | for nm in ibdata1 26 | do 27 | rm -f $log2/$nm 28 | pagecache-management.sh cp $BD/$nm $log2 29 | done 30 | 31 | 32 | cp -r $BD/mysql $DR 33 | pagecache-management.sh cp -r $BD/tpcc $DR 34 | 35 | sync 36 | echo 3 > /proc/sys/vm/drop_caches 37 | 38 | chown mysql.mysql -R $DR 39 | chown mysql.mysql -R $log2 40 | 41 | 42 | function waitm { 43 | 44 | while [ true ] 45 | do 46 | 47 | mysql -e "set global innodb_max_dirty_pages_pct=0" mysql 48 | 49 | wt=`mysql -e "SHOW ENGINE INNODB STATUS\G" | grep "Modified db pages" | sort -u | awk '{print $4}'` 50 | if [[ "$wt" -lt 100 ]] ; 51 | then 52 | mysql -e "set global innodb_max_dirty_pages_pct=90" mysql 53 | break 54 | fi 55 | 56 | echo "mysql pages $wt" 57 | sleep 10 58 | done 59 | 60 | } 61 | 62 | #for par in 1 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 43 63 | for par in 16 64 | do 65 | 66 | /usr/local/mysql/libexec/mysqld --defaults-file=/etc/my.cnf --datadir=$DR --innodb_data_home_dir=$log2 --innodb_log_group_home_dir=$log2 --innodb_thread_concurrency=0 & 67 | set +e 68 | 69 | while true; 70 | do 71 | mysql -Bse "SELECT 1" mysql 72 | 73 | if [ "$?" -eq 0 ] 74 | then 75 | break 76 | fi 77 | 78 | sleep 30 79 | 80 | echo -n "." 81 | done 82 | set -e 83 | 84 | 85 | ./tpcc_start localhost tpcc root "" 1000 $par 10 7200 | tee -a tpcc.threads${par}.out 86 | 87 | 88 | waitm 89 | 90 | 91 | mysqladmin shutdown 92 | 93 | done 94 | -------------------------------------------------------------------------------- /scripts/runX.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u 3 | set -x 4 | set -e 5 | 6 | #export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 7 | export LD_LIBRARY_PATH=/usr/local/Percona-Server/lib/mysql/ 8 | MYSQLDIR=/usr/local/mysql-5.5.15-linux2.6-x86_64 9 | 10 | ulimit -c unlimited 11 | 12 | #DR="/mnt/fio320" 13 | BD=/data/bench/back/tpc/tpc 14 | #DR=/data/db/bench 15 | DR="/data/bench/test" 16 | #DR="/mnt/tachion/tpc1000w" 17 | CONFIG="/etc/my.van.cnf" 18 | #CONFIG="/etc/my.y.558.cnf" 19 | 20 | WT=10 21 | RT=10800 22 | 23 | ROWS=80000000 24 | 25 | #log2="/tachion/system/" 26 | #log2="/data/bench/" 27 | log2="$DR/" 28 | 29 | # restore from backup 30 | function restore { 31 | 32 | #sysctl -w dev.flashcache.cache_all=0 33 | 34 | mkdir -p $DR 35 | 36 | rm -fr $DR/* 37 | rm -f $log2/ib* 38 | 39 | echo $log2 40 | #for nm in ibdata1 ib_logfile0 ib_logfile1 41 | #for nm in ibdata1 42 | #do 43 | #rm -f $log2/$nm 44 | #pagecache-management.sh cp $BD/$nm $log2 45 | #done 46 | 47 | 48 | cp -r $BD/mysql $DR 49 | cp -r $BD/tpcc $DR 50 | cp -r $BD/ibdata1 $log2 51 | 52 | sync 53 | echo 3 > /proc/sys/vm/drop_caches 54 | 55 | chown mysql.mysql -R $DR 56 | chown mysql.mysql -R $log2 57 | chmod -R 755 $DR 58 | 59 | #sysctl -w dev.flashcache.cache_all=1 60 | 61 | } 62 | 63 | 64 | function waitm { 65 | 66 | while [ true ] 67 | do 68 | 69 | mysql -e "set global innodb_max_dirty_pages_pct=0" mysql 70 | 71 | wt=`mysql -e "SHOW ENGINE INNODB STATUS\G" | grep "Modified db pages" | sort -u | awk '{print $4}'` 72 | if [[ "$wt" -lt 100 ]] ; 73 | then 74 | mysql -e "set global innodb_max_dirty_pages_pct=90" mysql 75 | break 76 | fi 77 | 78 | echo "mysql pages $wt" 79 | sleep 10 80 | done 81 | 82 | } 83 | 84 | 85 | 86 | # Determine run number for selecting an output directory 87 | RUN_NUMBER=-1 88 | 89 | if [ -f ".run_number" ]; then 90 | read RUN_NUMBER < .run_number 91 | fi 92 | 93 | if [ $RUN_NUMBER -eq -1 ]; then 94 | RUN_NUMBER=0 95 | fi 96 | 97 | OUTDIR=res$RUN_NUMBER 98 | mkdir -p $OUTDIR 99 | 100 | RUN_NUMBER=`expr $RUN_NUMBER + 1` 101 | echo $RUN_NUMBER > .run_number 102 | 103 | for trxv in 2 104 | do 105 | for logsz in 1950M 106 | do 107 | #for par in 1 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 43 108 | #for par in 13 26 39 52 65 78 109 | for par in `seq 5 10 55` 110 | #for par in 13 52 78 144 111 | #for par in 1 2 4 8 16 32 64 112 | do 113 | 114 | runid="par$par.log$logsz.trx$trxv." 115 | 116 | restore 117 | 118 | 119 | $MYSQLDIR/bin/mysqld --defaults-file=$CONFIG --datadir=$DR --innodb_data_home_dir=$log2 --innodb_log_group_home_dir=$log2 --innodb_thread_concurrency=0 --innodb-buffer-pool-size=${par}GB --innodb-log-file-size=$logsz --innodb_flush_log_at_trx_commit=$trxv --log-error=$OUTDIR/mysql.error.log & 120 | 121 | MYSQLPID=$! 122 | 123 | set +e 124 | 125 | while true; 126 | do 127 | mysql -Bse "SELECT 1" mysql 128 | 129 | if [ "$?" -eq 0 ] 130 | then 131 | break 132 | fi 133 | 134 | sleep 30 135 | 136 | echo -n "." 137 | done 138 | set -e 139 | 140 | iostat -mxt 10 $(($RT/10+1)) >> $OUTDIR/iostat.${runid}res & 141 | PID=$! 142 | vmstat 10 $(($RT/10+1)) >> $OUTDIR/vmstat.${runid}res & 143 | PIDV=$! 144 | $MYSQLDIR/bin/mysqladmin ext -i10 >> $OUTDIR/mysqladminext.${runid}res & 145 | PIDMYSQLSTAT=$! 146 | ./innodb_stat.sh $RT >> $OUTDIR/innodb.${runid}res & 147 | PIDINN=$! 148 | 149 | 150 | cp $CONFIG $OUTDIR 151 | cp $0 $OUTDIR 152 | mysqladmin variables >> $OUTDIR/mysql_variables.res 153 | sysctl -a >> $OUTDIR/sysctl.res 154 | ./tpcc_start localhost tpcc root "" 1000 32 10 $RT | tee -a $OUTDIR/tpcc.${runid}.out 155 | 156 | set +e 157 | kill -9 $PIDINN 158 | kill -9 $PIDMYSQLSTAT 159 | kill -9 `pidof mysqld` 160 | set -e 161 | 162 | 163 | 164 | 165 | done 166 | 167 | done 168 | done 169 | -------------------------------------------------------------------------------- /scripts/run_no_backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -u 3 | set -x 4 | set -e 5 | 6 | #export LD_LIBRARY_PATH=/usr/local/mysql/lib/mysql/ 7 | export LD_LIBRARY_PATH=/usr/local/Percona-Server/lib/mysql/ 8 | 9 | ulimit -c unlimited 10 | 11 | #DR="/mnt/fio320" 12 | BD=/mnt/tachion/tpc1000w 13 | #DR=/data/db/bench 14 | DR="/mnt/fio320/tpc1000w" 15 | 16 | WT=10 17 | RT=10800 18 | 19 | ROWS=80000000 20 | 21 | #log2="/data/log/" 22 | log2="$DR/" 23 | 24 | # restore from backup 25 | 26 | 27 | function waitm { 28 | 29 | while [ true ] 30 | do 31 | 32 | mysql -e "set global innodb_max_dirty_pages_pct=0" mysql 33 | 34 | wt=`mysql -e "SHOW ENGINE INNODB STATUS\G" | grep "Modified db pages" | sort -u | awk '{print $4}'` 35 | if [[ "$wt" -lt 100 ]] ; 36 | then 37 | mysql -e "set global innodb_max_dirty_pages_pct=90" mysql 38 | break 39 | fi 40 | 41 | echo "mysql pages $wt" 42 | sleep 10 43 | done 44 | 45 | } 46 | 47 | 48 | 49 | # Determine run number for selecting an output directory 50 | RUN_NUMBER=-1 51 | 52 | if [ -f ".run_number" ]; then 53 | read RUN_NUMBER < .run_number 54 | fi 55 | 56 | if [ $RUN_NUMBER -eq -1 ]; then 57 | RUN_NUMBER=0 58 | fi 59 | 60 | OUTDIR=res$RUN_NUMBER 61 | mkdir -p $OUTDIR 62 | 63 | RUN_NUMBER=`expr $RUN_NUMBER + 1` 64 | echo $RUN_NUMBER > .run_number 65 | 66 | #for par in 1 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 43 67 | for par in 13 26 39 52 65 78 68 | #for par in 24 69 | do 70 | export OS_FILE_LOG_BLOCK_SIZE=4096 71 | /usr/local/mysql/libexec/mysqld --defaults-file=/etc/my.cnf --datadir=$DR --innodb_log_group_home_dir=$log2 --innodb_thread_concurrency=0 --innodb-buffer-pool-size=${par}GB & 72 | 73 | 74 | set +e 75 | 76 | while true; 77 | do 78 | mysql -Bse "SELECT 1" mysql 79 | 80 | if [ "$?" -eq 0 ] 81 | then 82 | break 83 | fi 84 | 85 | sleep 30 86 | 87 | echo -n "." 88 | done 89 | set -e 90 | 91 | 92 | 93 | 94 | iostat -dx 5 2000 >> $OUTDIR/iostat.${par}res & 95 | PID=$! 96 | vmstat 5 2000 >> $OUTDIR/vmstat.${par}res & 97 | PIDV=$! 98 | ./tpcc_start localhost tpcc1000 root "" 1000 24 10 3600 | tee -a $OUTDIR/tpcc.${par}.out 99 | kill -9 $PID 100 | kill -9 $PIDV 101 | 102 | waitm 103 | 104 | 105 | mysqladmin shutdown 106 | rm -fr /mnt/fio320/tpc1000w ; cp -r /mnt/tachion/back/tpc1000w /mnt/fio320/ 107 | sync 108 | 109 | done 110 | -------------------------------------------------------------------------------- /scripts/virident_stat.sh: -------------------------------------------------------------------------------- 1 | echo 0 > /proc/driver/virident/vgcdrivea0/bdev 2 | 3 | while [ true ] 4 | do 5 | 6 | cat /proc/driver/virident/vgcdrivea0/bdev 7 | cat /proc/driver/virident/vgcdrivea0/gc 8 | sleep 10 9 | 10 | done 11 | 12 | -------------------------------------------------------------------------------- /sources.list: -------------------------------------------------------------------------------- 1 | deb http://mirrors.163.com/ubuntu/ utopic main restricted universe multiverse 2 | deb http://mirrors.163.com/ubuntu/ utopic-security main restricted universe multiverse 3 | deb http://mirrors.163.com/ubuntu/ utopic-updates main restricted universe multiverse 4 | deb http://mirrors.163.com/ubuntu/ utopic-proposed main restricted universe multiverse 5 | deb http://mirrors.163.com/ubuntu/ utopic-backports main restricted universe multiverse 6 | deb-src http://mirrors.163.com/ubuntu/ utopic main restricted universe multiverse 7 | deb-src http://mirrors.163.com/ubuntu/ utopic-security main restricted universe multiverse 8 | deb-src http://mirrors.163.com/ubuntu/ utopic-updates main restricted universe multiverse 9 | deb-src http://mirrors.163.com/ubuntu/ utopic-proposed main restricted universe multiverse 10 | deb-src http://mirrors.163.com/ubuntu/ utopic-backports main restricted universe multiverse 11 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # "make all" to build necessary executables. 3 | # 4 | 5 | 6 | 7 | LIBS= `mysql_config --libs_r` -lrt 8 | 9 | INC= -I. `mysql_config --include` 10 | 11 | #DEFS= -DDEBUG 12 | 13 | CFLAGS= -w -O2 -g 14 | 15 | TRANSACTIONS= neword.o payment.o ordstat.o delivery.o slev.o 16 | OBJS= main.o spt_proc.o driver.o support.o sequence.o rthist.o $(TRANSACTIONS) 17 | 18 | .SUFFIXES: 19 | .SUFFIXES: .o .c 20 | 21 | .c.o: 22 | $(CC) $(CFLAGS) $(INC) $(DEFS) -c $*.c 23 | 24 | all: ../tpcc_load ../tpcc_start 25 | 26 | ../tpcc_load : load.o support.o 27 | $(CC) load.o support.o $(LIBS) -o ../tpcc_load 28 | 29 | ../tpcc_start : $(OBJS) 30 | $(CC) $(OBJS) $(LIBS) -o ../tpcc_start 31 | 32 | clean : 33 | rm -f *.o 34 | -------------------------------------------------------------------------------- /src/delivery.c: -------------------------------------------------------------------------------- 1 | /* 2 | * -*-C-*- 3 | * delivery.pc 4 | * corresponds to A.4 in appendix A 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "spt_proc.h" 14 | #include "tpc.h" 15 | 16 | extern MYSQL **ctx; 17 | extern MYSQL_STMT ***stmt; 18 | 19 | #define NNULL ((void *)0) 20 | 21 | int delivery( int t_num, 22 | int w_id_arg, 23 | int o_carrier_id_arg 24 | ) 25 | { 26 | int w_id = w_id_arg; 27 | int o_carrier_id = o_carrier_id_arg; 28 | int d_id; 29 | int c_id; 30 | int no_o_id; 31 | float ol_total; 32 | char datetime[81]; 33 | 34 | int proceed = 0; 35 | 36 | MYSQL_STMT* mysql_stmt; 37 | MYSQL_BIND param[4]; 38 | MYSQL_BIND column[1]; 39 | 40 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 41 | 42 | gettimestamp(datetime, STRFTIME_FORMAT, TIMESTAMP_LEN); 43 | 44 | /* For each district in warehouse */ 45 | /* printf("W: %d\n", w_id); */ 46 | 47 | for (d_id = 1; d_id <= DIST_PER_WARE; d_id++) { 48 | proceed = 1; 49 | /*EXEC_SQL SELECT COALESCE(MIN(no_o_id),0) INTO :no_o_id 50 | FROM new_orders 51 | WHERE no_d_id = :d_id AND no_w_id = :w_id;*/ 52 | mysql_stmt = stmt[t_num][25]; 53 | 54 | memset(param, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 55 | param[0].buffer_type = MYSQL_TYPE_LONG; 56 | param[0].buffer = &d_id; 57 | param[1].buffer_type = MYSQL_TYPE_LONG; 58 | param[1].buffer = &w_id; 59 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 60 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 61 | 62 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 63 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 64 | column[0].buffer_type = MYSQL_TYPE_LONG; 65 | column[0].buffer = &no_o_id; 66 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 67 | switch( mysql_stmt_fetch(mysql_stmt) ) { 68 | case 0: //SUCCESS 69 | break; 70 | case 1: //ERROR 71 | case MYSQL_NO_DATA: //NO MORE DATA 72 | default: 73 | mysql_stmt_free_result(mysql_stmt); 74 | goto sqlerr; 75 | } 76 | mysql_stmt_free_result(mysql_stmt); 77 | 78 | 79 | if(no_o_id == 0) continue; 80 | proceed = 2; 81 | /*EXEC_SQL DELETE FROM new_orders WHERE no_o_id = :no_o_id AND no_d_id = :d_id 82 | AND no_w_id = :w_id;*/ 83 | mysql_stmt = stmt[t_num][26]; 84 | 85 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 86 | param[0].buffer_type = MYSQL_TYPE_LONG; 87 | param[0].buffer = &no_o_id; 88 | param[1].buffer_type = MYSQL_TYPE_LONG; 89 | param[1].buffer = &d_id; 90 | param[2].buffer_type = MYSQL_TYPE_LONG; 91 | param[2].buffer = &w_id; 92 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 93 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 94 | 95 | 96 | proceed = 3; 97 | /*EXEC_SQL SELECT o_c_id INTO :c_id FROM orders 98 | WHERE o_id = :no_o_id AND o_d_id = :d_id 99 | AND o_w_id = :w_id;*/ 100 | mysql_stmt = stmt[t_num][27]; 101 | 102 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 103 | param[0].buffer_type = MYSQL_TYPE_LONG; 104 | param[0].buffer = &no_o_id; 105 | param[1].buffer_type = MYSQL_TYPE_LONG; 106 | param[1].buffer = &d_id; 107 | param[2].buffer_type = MYSQL_TYPE_LONG; 108 | param[2].buffer = &w_id; 109 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 110 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 111 | 112 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 113 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 114 | column[0].buffer_type = MYSQL_TYPE_LONG; 115 | column[0].buffer = &c_id; 116 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 117 | switch( mysql_stmt_fetch(mysql_stmt) ) { 118 | case 0: //SUCCESS 119 | break; 120 | case 1: //ERROR 121 | case MYSQL_NO_DATA: //NO MORE DATA 122 | default: 123 | mysql_stmt_free_result(mysql_stmt); 124 | goto sqlerr; 125 | } 126 | mysql_stmt_free_result(mysql_stmt); 127 | 128 | 129 | proceed = 4; 130 | /*EXEC_SQL UPDATE orders SET o_carrier_id = :o_carrier_id 131 | WHERE o_id = :no_o_id AND o_d_id = :d_id AND 132 | o_w_id = :w_id;*/ 133 | mysql_stmt = stmt[t_num][28]; 134 | 135 | memset(param, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 136 | param[0].buffer_type = MYSQL_TYPE_LONG; 137 | param[0].buffer = &o_carrier_id; 138 | param[1].buffer_type = MYSQL_TYPE_LONG; 139 | param[1].buffer = &no_o_id; 140 | param[2].buffer_type = MYSQL_TYPE_LONG; 141 | param[2].buffer = &d_id; 142 | param[3].buffer_type = MYSQL_TYPE_LONG; 143 | param[3].buffer = &w_id; 144 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 145 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 146 | 147 | proceed = 5; 148 | /*EXEC_SQL UPDATE order_line 149 | SET ol_delivery_d = :datetime 150 | WHERE ol_o_id = :no_o_id AND ol_d_id = :d_id AND 151 | ol_w_id = :w_id;*/ 152 | mysql_stmt = stmt[t_num][29]; 153 | 154 | memset(param, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 155 | param[0].buffer_type = MYSQL_TYPE_STRING; 156 | param[0].buffer = datetime; 157 | param[0].buffer_length = strlen(datetime); 158 | param[1].buffer_type = MYSQL_TYPE_LONG; 159 | param[1].buffer = &no_o_id; 160 | param[2].buffer_type = MYSQL_TYPE_LONG; 161 | param[2].buffer = &d_id; 162 | param[3].buffer_type = MYSQL_TYPE_LONG; 163 | param[3].buffer = &w_id; 164 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 165 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 166 | 167 | proceed = 6; 168 | /*EXEC_SQL SELECT SUM(ol_amount) INTO :ol_total 169 | FROM order_line 170 | WHERE ol_o_id = :no_o_id AND ol_d_id = :d_id 171 | AND ol_w_id = :w_id;*/ 172 | mysql_stmt = stmt[t_num][30]; 173 | 174 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 175 | param[0].buffer_type = MYSQL_TYPE_LONG; 176 | param[0].buffer = &no_o_id; 177 | param[1].buffer_type = MYSQL_TYPE_LONG; 178 | param[1].buffer = &d_id; 179 | param[2].buffer_type = MYSQL_TYPE_LONG; 180 | param[2].buffer = &w_id; 181 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 182 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 183 | 184 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 185 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 186 | column[0].buffer_type = MYSQL_TYPE_FLOAT; 187 | column[0].buffer = &ol_total; 188 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 189 | switch( mysql_stmt_fetch(mysql_stmt) ) { 190 | case 0: //SUCCESS 191 | case MYSQL_DATA_TRUNCATED: 192 | break; 193 | case 1: //ERROR 194 | case MYSQL_NO_DATA: //NO MORE DATA 195 | default: 196 | mysql_stmt_free_result(mysql_stmt); 197 | goto sqlerr; 198 | } 199 | mysql_stmt_free_result(mysql_stmt); 200 | 201 | 202 | proceed = 7; 203 | /*EXEC_SQL UPDATE customer SET c_balance = c_balance + :ol_total , 204 | c_delivery_cnt = c_delivery_cnt + 1 205 | WHERE c_id = :c_id AND c_d_id = :d_id AND 206 | c_w_id = :w_id;*/ 207 | mysql_stmt = stmt[t_num][31]; 208 | 209 | memset(param, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 210 | param[0].buffer_type = MYSQL_TYPE_FLOAT; 211 | param[0].buffer = &ol_total; 212 | param[1].buffer_type = MYSQL_TYPE_LONG; 213 | param[1].buffer = &c_id; 214 | param[2].buffer_type = MYSQL_TYPE_LONG; 215 | param[2].buffer = &d_id; 216 | param[3].buffer_type = MYSQL_TYPE_LONG; 217 | param[3].buffer = &w_id; 218 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 219 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 220 | 221 | /*EXEC_SQL COMMIT WORK;*/ 222 | if( mysql_commit(ctx[t_num]) ) goto sqlerr; 223 | 224 | /* printf("D: %d, O: %d, time: %d\n", d_id, o_id, tad); */ 225 | 226 | } 227 | /*EXEC_SQL COMMIT WORK;*/ 228 | return (1); 229 | 230 | sqlerr: 231 | fprintf(stderr, "delivery %d:%d\n",t_num,proceed); 232 | error(ctx[t_num],mysql_stmt); 233 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerrerr;*/ 234 | /*EXEC_SQL ROLLBACK WORK;*/ 235 | mysql_rollback(ctx[t_num]); 236 | sqlerrerr: 237 | return (0); 238 | } 239 | -------------------------------------------------------------------------------- /src/driver.c: -------------------------------------------------------------------------------- 1 | /* 2 | * driver.c 3 | * driver for the tpcc transactions 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "tpc.h" /* prototypes for misc. functions */ 11 | #include "trans_if.h" /* prototypes for transacation interface calls */ 12 | #include "sequence.h" 13 | #include "rthist.h" 14 | 15 | static int other_ware (int home_ware); 16 | static int do_neword (int t_num); 17 | static int do_payment (int t_num); 18 | static int do_ordstat (int t_num); 19 | static int do_delivery (int t_num); 20 | static int do_slev (int t_num); 21 | 22 | extern int num_ware; 23 | extern int num_conn; 24 | extern int activate_transaction; 25 | extern int counting_on; 26 | 27 | extern int num_node; 28 | extern int time_count; 29 | extern FILE *freport_file; 30 | 31 | extern int success[]; 32 | extern int late[]; 33 | extern int retry[]; 34 | extern int failure[]; 35 | 36 | extern int* success2[]; 37 | extern int* late2[]; 38 | extern int* retry2[]; 39 | extern int* failure2[]; 40 | 41 | extern double max_rt[]; 42 | 43 | extern long clk_tck; 44 | 45 | #define MAX_RETRY 2000 46 | 47 | #define RTIME_NEWORD 5 48 | #define RTIME_PAYMENT 5 49 | #define RTIME_ORDSTAT 5 50 | #define RTIME_DELIVERY 80 51 | #define RTIME_SLEV 20 52 | 53 | int driver (int t_num) 54 | { 55 | int i, j; 56 | 57 | /* Actually, WaitTimes are needed... */ 58 | while( activate_transaction ){ 59 | switch(seq_get()){ 60 | case 0: 61 | do_neword(t_num); 62 | break; 63 | case 1: 64 | do_payment(t_num); 65 | break; 66 | case 2: 67 | do_ordstat(t_num); 68 | break; 69 | case 3: 70 | do_delivery(t_num); 71 | break; 72 | case 4: 73 | do_slev(t_num); 74 | break; 75 | default: 76 | printf("Error - Unknown sequence.\n"); 77 | } 78 | 79 | } 80 | 81 | return(0); 82 | 83 | } 84 | 85 | /* 86 | * prepare data and execute the new order transaction for one order 87 | * officially, this is supposed to be simulated terminal I/O 88 | */ 89 | static int do_neword (int t_num) 90 | { 91 | int c_num; 92 | int i,ret; 93 | clock_t clk1,clk2; 94 | double rt; 95 | struct timespec tbuf1; 96 | struct timespec tbuf2; 97 | int w_id, d_id, c_id, ol_cnt; 98 | int all_local = 1; 99 | int notfound = MAXITEMS+1; /* valid item ids are numbered consecutively 100 | [1..MAXITEMS] */ 101 | int rbk; 102 | int itemid[MAX_NUM_ITEMS]; 103 | int supware[MAX_NUM_ITEMS]; 104 | int qty[MAX_NUM_ITEMS]; 105 | 106 | if(num_node==0){ 107 | w_id = RandomNumber(1, num_ware); 108 | }else{ 109 | c_num = ((num_node * t_num)/num_conn); /* drop moduls */ 110 | w_id = RandomNumber(1 + (num_ware * c_num)/num_node, 111 | (num_ware * (c_num + 1))/num_node); 112 | } 113 | d_id = RandomNumber(1, DIST_PER_WARE); 114 | c_id = NURand(1023, 1, CUST_PER_DIST); 115 | 116 | ol_cnt = RandomNumber(5, 15); 117 | rbk = RandomNumber(1, 100); 118 | 119 | for (i = 0; i < ol_cnt; i++) { 120 | itemid[i] = NURand(8191, 1, MAXITEMS); 121 | if ((i == ol_cnt - 1) && (rbk == 1)) { 122 | itemid[i] = notfound; 123 | } 124 | if (RandomNumber(1, 100) != 1) { 125 | supware[i] = w_id; 126 | } 127 | else { 128 | supware[i] = other_ware(w_id); 129 | all_local = 0; 130 | } 131 | qty[i] = RandomNumber(1, 10); 132 | } 133 | 134 | clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 135 | for (i = 0; i < MAX_RETRY; i++) { 136 | ret = neword(t_num, w_id, d_id, c_id, ol_cnt, all_local, itemid, supware, qty); 137 | clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 138 | 139 | if(ret){ 140 | 141 | rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0); 142 | //printf("NOT : %.3f\n", rt); 143 | if (freport_file != NULL) { 144 | fprintf(freport_file,"%d %.3f\n", time_count, rt); 145 | } 146 | 147 | if(rt > max_rt[0]) 148 | max_rt[0]=rt; 149 | hist_inc(0, rt); 150 | if(counting_on){ 151 | if( rt < RTIME_NEWORD ){ 152 | success[0]++; 153 | success2[0][t_num]++; 154 | }else{ 155 | late[0]++; 156 | late2[0][t_num]++; 157 | } 158 | } 159 | 160 | return (1); /* end */ 161 | }else{ 162 | 163 | if(counting_on){ 164 | retry[0]++; 165 | retry2[0][t_num]++; 166 | } 167 | 168 | } 169 | } 170 | 171 | if(counting_on){ 172 | retry[0]--; 173 | retry2[0][t_num]--; 174 | failure[0]++; 175 | failure2[0][t_num]++; 176 | } 177 | 178 | return (0); 179 | } 180 | 181 | /* 182 | * produce the id of a valid warehouse other than home_ware 183 | * (assuming there is one) 184 | */ 185 | static int other_ware (int home_ware) 186 | { 187 | int tmp; 188 | 189 | if (num_ware == 1) return home_ware; 190 | while ((tmp = RandomNumber(1, num_ware)) == home_ware); 191 | return tmp; 192 | } 193 | 194 | /* 195 | * prepare data and execute payment transaction 196 | */ 197 | static int do_payment (int t_num) 198 | { 199 | int c_num; 200 | int byname,i,ret; 201 | clock_t clk1,clk2; 202 | double rt; 203 | struct timespec tbuf1; 204 | struct timespec tbuf2; 205 | int w_id, d_id, c_w_id, c_d_id, c_id, h_amount; 206 | char c_last[17]; 207 | 208 | if(num_node==0){ 209 | w_id = RandomNumber(1, num_ware); 210 | }else{ 211 | c_num = ((num_node * t_num)/num_conn); /* drop moduls */ 212 | w_id = RandomNumber(1 + (num_ware * c_num)/num_node, 213 | (num_ware * (c_num + 1))/num_node); 214 | } 215 | d_id = RandomNumber(1, DIST_PER_WARE); 216 | c_id = NURand(1023, 1, CUST_PER_DIST); 217 | Lastname(NURand(255,0,999), c_last); 218 | h_amount = RandomNumber(1,5000); 219 | if (RandomNumber(1, 100) <= 60) { 220 | byname = 1; /* select by last name */ 221 | }else{ 222 | byname = 0; /* select by customer id */ 223 | } 224 | if (RandomNumber(1, 100) <= 85) { 225 | c_w_id = w_id; 226 | c_d_id = d_id; 227 | }else{ 228 | c_w_id = other_ware(w_id); 229 | c_d_id = RandomNumber(1, DIST_PER_WARE); 230 | } 231 | 232 | clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 233 | for (i = 0; i < MAX_RETRY; i++) { 234 | ret = payment(t_num, w_id, d_id, byname, c_w_id, c_d_id, c_id, c_last, h_amount); 235 | clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 236 | 237 | if(ret){ 238 | 239 | rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0); 240 | if(rt > max_rt[1]) 241 | max_rt[1]=rt; 242 | hist_inc(1, rt); 243 | if(counting_on){ 244 | if( rt < RTIME_PAYMENT ){ 245 | success[1]++; 246 | success2[1][t_num]++; 247 | }else{ 248 | late[1]++; 249 | late2[1][t_num]++; 250 | } 251 | } 252 | 253 | return (1); /* end */ 254 | }else{ 255 | 256 | if(counting_on){ 257 | retry[1]++; 258 | retry2[1][t_num]++; 259 | } 260 | 261 | } 262 | } 263 | 264 | if(counting_on){ 265 | retry[1]--; 266 | retry2[1][t_num]--; 267 | failure[1]++; 268 | failure2[1][t_num]++; 269 | } 270 | 271 | return (0); 272 | } 273 | 274 | /* 275 | * prepare data and execute order status transaction 276 | */ 277 | static int do_ordstat (int t_num) 278 | { 279 | int c_num; 280 | int byname,i,ret; 281 | clock_t clk1,clk2; 282 | double rt; 283 | struct timespec tbuf1; 284 | struct timespec tbuf2; 285 | int w_id, d_id, c_id; 286 | char c_last[16]; 287 | 288 | if(num_node==0){ 289 | w_id = RandomNumber(1, num_ware); 290 | }else{ 291 | c_num = ((num_node * t_num)/num_conn); /* drop moduls */ 292 | w_id = RandomNumber(1 + (num_ware * c_num)/num_node, 293 | (num_ware * (c_num + 1))/num_node); 294 | } 295 | d_id = RandomNumber(1, DIST_PER_WARE); 296 | c_id = NURand(1023, 1, CUST_PER_DIST); 297 | Lastname(NURand(255,0,999), c_last); 298 | if (RandomNumber(1, 100) <= 60) { 299 | byname = 1; /* select by last name */ 300 | }else{ 301 | byname = 0; /* select by customer id */ 302 | } 303 | 304 | clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 305 | for (i = 0; i < MAX_RETRY; i++) { 306 | ret = ordstat(t_num, w_id, d_id, byname, c_id, c_last); 307 | clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 308 | 309 | if(ret){ 310 | 311 | rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0); 312 | if(rt > max_rt[2]) 313 | max_rt[2]=rt; 314 | hist_inc(2, rt); 315 | if(counting_on){ 316 | if( rt < RTIME_ORDSTAT ){ 317 | success[2]++; 318 | success2[2][t_num]++; 319 | }else{ 320 | late[2]++; 321 | late2[2][t_num]++; 322 | } 323 | } 324 | 325 | return (1); /* end */ 326 | }else{ 327 | 328 | if(counting_on){ 329 | retry[2]++; 330 | retry2[2][t_num]++; 331 | } 332 | 333 | } 334 | } 335 | 336 | if(counting_on){ 337 | retry[2]--; 338 | retry2[2][t_num]--; 339 | failure[2]++; 340 | failure2[2][t_num]++; 341 | } 342 | 343 | return (0); 344 | 345 | } 346 | 347 | /* 348 | * execute delivery transaction 349 | */ 350 | static int do_delivery (int t_num) 351 | { 352 | int c_num; 353 | int i,ret; 354 | clock_t clk1,clk2; 355 | double rt; 356 | struct timespec tbuf1; 357 | struct timespec tbuf2; 358 | int w_id, o_carrier_id; 359 | 360 | if(num_node==0){ 361 | w_id = RandomNumber(1, num_ware); 362 | }else{ 363 | c_num = ((num_node * t_num)/num_conn); /* drop moduls */ 364 | w_id = RandomNumber(1 + (num_ware * c_num)/num_node, 365 | (num_ware * (c_num + 1))/num_node); 366 | } 367 | o_carrier_id = RandomNumber(1, 10); 368 | 369 | clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 370 | for (i = 0; i < MAX_RETRY; i++) { 371 | ret = delivery(t_num, w_id, o_carrier_id); 372 | clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 373 | 374 | if(ret){ 375 | 376 | rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0); 377 | if(rt > max_rt[3]) 378 | max_rt[3]=rt; 379 | hist_inc(3, rt ); 380 | if(counting_on){ 381 | if( rt < RTIME_DELIVERY ){ 382 | success[3]++; 383 | success2[3][t_num]++; 384 | }else{ 385 | late[3]++; 386 | late2[3][t_num]++; 387 | } 388 | } 389 | 390 | return (1); /* end */ 391 | }else{ 392 | 393 | if(counting_on){ 394 | retry[3]++; 395 | retry2[3][t_num]++; 396 | } 397 | 398 | } 399 | } 400 | 401 | if(counting_on){ 402 | retry[3]--; 403 | retry2[3][t_num]--; 404 | failure[3]++; 405 | failure2[3][t_num]++; 406 | } 407 | 408 | return (0); 409 | 410 | } 411 | 412 | /* 413 | * prepare data and execute the stock level transaction 414 | */ 415 | static int do_slev (int t_num) 416 | { 417 | int c_num; 418 | int i,ret; 419 | clock_t clk1,clk2; 420 | double rt; 421 | struct timespec tbuf1; 422 | struct timespec tbuf2; 423 | int w_id, d_id, level; 424 | 425 | if(num_node==0){ 426 | w_id = RandomNumber(1, num_ware); 427 | }else{ 428 | c_num = ((num_node * t_num)/num_conn); /* drop moduls */ 429 | w_id = RandomNumber(1 + (num_ware * c_num)/num_node, 430 | (num_ware * (c_num + 1))/num_node); 431 | } 432 | d_id = RandomNumber(1, DIST_PER_WARE); 433 | level = RandomNumber(10, 20); 434 | 435 | clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 436 | for (i = 0; i < MAX_RETRY; i++) { 437 | ret = slev(t_num, w_id, d_id, level); 438 | clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 439 | 440 | if(ret){ 441 | 442 | rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0); 443 | if(rt > max_rt[4]) 444 | max_rt[4]=rt; 445 | hist_inc(4, rt ); 446 | if(counting_on){ 447 | if( rt < RTIME_SLEV ){ 448 | success[4]++; 449 | success2[4][t_num]++; 450 | }else{ 451 | late[4]++; 452 | late2[4][t_num]++; 453 | } 454 | } 455 | 456 | return (1); /* end */ 457 | }else{ 458 | 459 | if(counting_on){ 460 | retry[4]++; 461 | retry2[4][t_num]++; 462 | } 463 | 464 | } 465 | } 466 | 467 | if(counting_on){ 468 | retry[4]--; 469 | retry2[4][t_num]--; 470 | failure[4]++; 471 | failure2[4][t_num]++; 472 | } 473 | 474 | return (0); 475 | 476 | } 477 | -------------------------------------------------------------------------------- /src/load.c: -------------------------------------------------------------------------------- 1 | /* 2 | * corresponds to A.6 in appendix A 3 | */ 4 | 5 | /* 6 | * ==================================================================+ | Load 7 | * TPCC tables 8 | * +================================================================== 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include "spt_proc.h" 21 | #include "tpc.h" 22 | 23 | #define NNULL ((void *)0) 24 | //#undef NULL 25 | 26 | MYSQL *mysql; 27 | MYSQL_STMT *stmt[11]; 28 | 29 | /* Global SQL Variables */ 30 | char timestamp[81]; 31 | long count_ware; 32 | int fd, seed; 33 | 34 | int particle_flg = 0; /* "1" means particle mode */ 35 | int part_no = 0; /* 1:items 2:warehouse 3:customer 4:orders */ 36 | long min_ware = 1; 37 | long max_ware; 38 | 39 | /* Global Variables */ 40 | int i; 41 | int option_debug = 0; /* 1 if generating debug output */ 42 | int is_local = 1; /* "1" mean local */ 43 | 44 | #define DB_STRING_MAX 51 45 | 46 | #include "parse_port.h" 47 | 48 | int 49 | try_stmt_execute(MYSQL_STMT *mysql_stmt) 50 | { 51 | int ret = mysql_stmt_execute(mysql_stmt); 52 | if (ret) { 53 | printf("\n%d, %s, %s\n", mysql_errno(mysql), mysql_sqlstate(mysql), mysql_error(mysql) ); 54 | mysql_rollback(mysql); 55 | } 56 | return ret; 57 | } 58 | 59 | /* 60 | * ==================================================================+ | 61 | * main() | ARGUMENTS | Warehouses n [Debug] [Help] 62 | * +================================================================== 63 | */ 64 | void 65 | main(argc, argv) 66 | int argc; 67 | char *argv[]; 68 | { 69 | char arg[2]; 70 | char *ptr; 71 | 72 | char connect_string[DB_STRING_MAX]; 73 | char db_string[DB_STRING_MAX]; 74 | char db_user[DB_STRING_MAX]; 75 | char db_password[DB_STRING_MAX]; 76 | int port= 3306; 77 | 78 | int i; 79 | 80 | MYSQL* resp; 81 | 82 | /* initialize */ 83 | count_ware = 0; 84 | 85 | printf("*************************************\n"); 86 | printf("*** ###easy### TPC-C Data Loader ***\n"); 87 | printf("*************************************\n"); 88 | 89 | /* Parse args */ 90 | if (argc != 9) { 91 | if (argc != 6) { 92 | fprintf(stderr, 93 | "\n usage: tpcc_load [server] [DB] [user] [pass] [warehouse]\n" 94 | " OR\n" 95 | " tpcc_load [server] [DB] [user] [pass] [warehouse] [part] [min_wh] [max_wh]\n\n" 96 | " * [part]: 1=ITEMS 2=WAREHOUSE 3=CUSTOMER 4=ORDERS\n" 97 | ); 98 | exit(1); 99 | } 100 | }else{ 101 | particle_flg = 1; 102 | } 103 | 104 | if ( strlen(argv[1]) >= DB_STRING_MAX ) { 105 | fprintf(stderr, "\n server phrase is too long\n"); 106 | exit(1); 107 | } 108 | if ( strlen(argv[2]) >= DB_STRING_MAX ) { 109 | fprintf(stderr, "\n DBname phrase is too long\n"); 110 | exit(1); 111 | } 112 | if ( strlen(argv[3]) >= DB_STRING_MAX ) { 113 | fprintf(stderr, "\n user phrase is too long\n"); 114 | exit(1); 115 | } 116 | if ( strlen(argv[4]) >= DB_STRING_MAX ) { 117 | fprintf(stderr, "\n pass phrase is too long\n"); 118 | exit(1); 119 | } 120 | if ((count_ware = atoi(argv[5])) <= 0) { 121 | fprintf(stderr, "\n expecting positive number of warehouses\n"); 122 | exit(1); 123 | } 124 | //strcpy(connect_string, argv[1]); 125 | parse_host(connect_string, argv[1]); 126 | port= parse_port(argv[1]); 127 | strcpy( db_string, argv[2] ); 128 | strcpy( db_user, argv[3] ); 129 | strcpy( db_password, argv[4] ); 130 | 131 | if(strcmp(connect_string,"l")==0){ 132 | is_local = 1; 133 | }else{ 134 | is_local = 0; 135 | } 136 | 137 | if(particle_flg==1){ 138 | part_no = atoi(argv[6]); 139 | min_ware = atoi(argv[7]); 140 | max_ware = atoi(argv[8]); 141 | }else{ 142 | min_ware = 1; 143 | max_ware = count_ware; 144 | } 145 | 146 | printf("\n"); 147 | if(is_local==0)printf(" [server]: %s\n", connect_string); 148 | if(is_local==0)printf(" [port]: %d\n", port); 149 | printf(" [DBname]: %s\n", db_string); 150 | printf(" [user]: %s\n", db_user); 151 | printf(" [pass]: %s\n", db_password); 152 | 153 | printf(" [warehouse]: %d\n", count_ware); 154 | 155 | if(particle_flg==1){ 156 | printf(" [part(1-4)]: %d\n", part_no); 157 | printf(" [MIN WH]: %d\n", min_ware); 158 | printf(" [MAX WH]: %d\n", max_ware); 159 | } 160 | 161 | fd = open("/dev/urandom", O_RDONLY); 162 | if (fd == -1) { 163 | fd = open("/dev/random", O_RDONLY); 164 | if (fd == -1) { 165 | struct timeval tv; 166 | gettimeofday(&tv, NNULL); 167 | seed = (tv.tv_sec ^ tv.tv_usec) * tv.tv_sec * tv.tv_usec ^ tv.tv_sec; 168 | }else{ 169 | read(fd, &seed, sizeof(seed)); 170 | close(fd); 171 | } 172 | }else{ 173 | read(fd, &seed, sizeof(seed)); 174 | close(fd); 175 | } 176 | SetSeed(seed); 177 | 178 | /* Initialize timestamp (for date columns) */ 179 | gettimestamp(timestamp, STRFTIME_FORMAT, TIMESTAMP_LEN); 180 | 181 | /* EXEC SQL WHENEVER SQLERROR GOTO Error_SqlCall; */ 182 | 183 | mysql = mysql_init(NULL); 184 | if(!mysql) goto Error_SqlCall; 185 | 186 | if(is_local==1){ 187 | /* exec sql connect :connect_string; */ 188 | resp = mysql_real_connect(mysql, "localhost", db_user, db_password, db_string, port, NULL, 0); 189 | }else{ 190 | /* exec sql connect :connect_string USING :db_string; */ 191 | resp = mysql_real_connect(mysql, connect_string, db_user, db_password, db_string, port, NULL, 0); 192 | } 193 | 194 | if(resp) { 195 | mysql_autocommit(mysql, 0); 196 | mysql_query(mysql, "SET UNIQUE_CHECKS=0"); 197 | mysql_query(mysql, "SET FOREIGN_KEY_CHECKS=0"); 198 | } else { 199 | goto Error_SqlCall_close; 200 | } 201 | 202 | for( i=0; i<11; i++ ){ 203 | stmt[i] = mysql_stmt_init(mysql); 204 | if(!stmt[i]) goto Error_SqlCall_close; 205 | } 206 | 207 | if( mysql_stmt_prepare(stmt[0], 208 | "INSERT INTO item values(?,?,?,?,?)", 209 | 34) ) goto Error_SqlCall_close; 210 | if( mysql_stmt_prepare(stmt[1], 211 | "INSERT INTO warehouse values(?,?,?,?,?,?,?,?,?)", 212 | 47) ) goto Error_SqlCall_close; 213 | if( mysql_stmt_prepare(stmt[2], 214 | "INSERT INTO stock values(?,?,?,?,?,?,?,?,?,?,?,?,?,0,0,0,?)", 215 | 59) ) goto Error_SqlCall_close; 216 | if( mysql_stmt_prepare(stmt[3], 217 | "INSERT INTO district values(?,?,?,?,?,?,?,?,?,?,?)", 218 | 50) ) goto Error_SqlCall_close; 219 | if( mysql_stmt_prepare(stmt[4], 220 | "INSERT INTO customer values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?, 10.0, 1, 0,?)", 221 | 76) ) goto Error_SqlCall_close; 222 | if( mysql_stmt_prepare(stmt[5], 223 | "INSERT INTO history values(?,?,?,?,?,?,?,?)", 224 | 43) ) goto Error_SqlCall_close; 225 | if( mysql_stmt_prepare(stmt[6], 226 | "INSERT INTO orders values(?,?,?,?,?,NULL,?, 1)", 227 | 46) ) goto Error_SqlCall_close; 228 | if( mysql_stmt_prepare(stmt[7], 229 | "INSERT INTO new_orders values(?,?,?)", 230 | 36) ) goto Error_SqlCall_close; 231 | if( mysql_stmt_prepare(stmt[8], 232 | "INSERT INTO orders values(?,?,?,?,?,?,?, 1)", 233 | 43) ) goto Error_SqlCall_close; 234 | if( mysql_stmt_prepare(stmt[9], 235 | "INSERT INTO order_line values(?,?,?,?,?,?, NULL,?,?,?)", 236 | 54) ) goto Error_SqlCall_close; 237 | if( mysql_stmt_prepare(stmt[10], 238 | "INSERT INTO order_line values(?,?,?,?,?,?,?,?,?,?)", 239 | 50) ) goto Error_SqlCall_close; 240 | 241 | 242 | /* exec sql begin transaction; */ 243 | 244 | printf("TPCC Data Load Started...\n"); 245 | 246 | if(particle_flg==0){ 247 | LoadItems(); 248 | LoadWare(); 249 | LoadCust(); 250 | LoadOrd(); 251 | }else if(particle_flg==1){ 252 | switch(part_no){ 253 | case 1: 254 | LoadItems(); 255 | break; 256 | case 2: 257 | LoadWare(); 258 | break; 259 | case 3: 260 | LoadCust(); 261 | break; 262 | case 4: 263 | LoadOrd(); 264 | break; 265 | default: 266 | printf("Unknown part_no\n"); 267 | printf("1:ITEMS 2:WAREHOUSE 3:CUSTOMER 4:ORDERS\n"); 268 | } 269 | } 270 | 271 | /* EXEC SQL COMMIT WORK; */ 272 | 273 | if( mysql_commit(mysql) ) goto Error_SqlCall; 274 | 275 | for( i=0; i<11; i++ ){ 276 | mysql_stmt_close(stmt[i]); 277 | } 278 | 279 | /* EXEC SQL DISCONNECT; */ 280 | 281 | mysql_close(mysql); 282 | 283 | printf("\n...DATA LOADING COMPLETED SUCCESSFULLY.\n"); 284 | exit(0); 285 | Error_SqlCall_close: 286 | Error_SqlCall: 287 | Error(0); 288 | } 289 | 290 | /* 291 | * ==================================================================+ | 292 | * ROUTINE NAME | LoadItems | DESCRIPTION | Loads the Item table | 293 | * ARGUMENTS | none 294 | * +================================================================== 295 | */ 296 | void 297 | LoadItems() 298 | { 299 | 300 | int i_id; 301 | int i_im_id; 302 | char i_name[25]; 303 | float i_price; 304 | char i_data[51]; 305 | 306 | int idatasiz; 307 | int orig[MAXITEMS+1]; 308 | int pos; 309 | int i; 310 | int retried = 0; 311 | 312 | MYSQL_BIND param[5]; 313 | 314 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 315 | 316 | printf("Loading Item \n"); 317 | 318 | for (i = 0; i < MAXITEMS / 10; i++) 319 | orig[i] = 0; 320 | for (i = 0; i < MAXITEMS / 10; i++) { 321 | do { 322 | pos = RandomNumber(0L, MAXITEMS); 323 | } while (orig[pos]); 324 | orig[pos] = 1; 325 | } 326 | retry: 327 | if (retried) 328 | printf("Retrying ...\n"); 329 | retried = 1; 330 | for (i_id = 1; i_id <= MAXITEMS; i_id++) { 331 | 332 | /* Generate Item Data */ 333 | i_im_id = RandomNumber(1L, 10000L); 334 | 335 | i_name[ MakeAlphaString(14, 24, i_name) ] = 0; 336 | 337 | i_price = ((int) RandomNumber(100L, 10000L)) / 100.0; 338 | 339 | idatasiz = MakeAlphaString(26, 50, i_data); 340 | i_data[idatasiz] = 0; 341 | 342 | if (orig[i_id]) { 343 | pos = RandomNumber(0L, idatasiz - 8); 344 | i_data[pos] = 'o'; 345 | i_data[pos + 1] = 'r'; 346 | i_data[pos + 2] = 'i'; 347 | i_data[pos + 3] = 'g'; 348 | i_data[pos + 4] = 'i'; 349 | i_data[pos + 5] = 'n'; 350 | i_data[pos + 6] = 'a'; 351 | i_data[pos + 7] = 'l'; 352 | } 353 | if (option_debug) 354 | printf("IID = %ld, Name= %16s, Price = %5.2f\n", 355 | i_id, i_name, i_price); 356 | 357 | #if 0 358 | printf("about to exec sql\n"); 359 | fflush(stdout); 360 | #endif 361 | 362 | /* EXEC SQL INSERT INTO 363 | item 364 | values(:i_id,:i_im_id,:i_name,:i_price,:i_data); */ 365 | 366 | memset(param, 0, sizeof(MYSQL_BIND) * 5); /* initialize */ 367 | param[0].buffer_type = MYSQL_TYPE_LONG; 368 | param[0].buffer = &i_id; 369 | param[1].buffer_type = MYSQL_TYPE_LONG; 370 | param[1].buffer = &i_im_id; 371 | param[2].buffer_type = MYSQL_TYPE_STRING; 372 | param[2].buffer = i_name; 373 | param[2].buffer_length = strlen(i_name); 374 | param[3].buffer_type = MYSQL_TYPE_FLOAT; 375 | param[3].buffer = &i_price; 376 | param[4].buffer_type = MYSQL_TYPE_STRING; 377 | param[4].buffer = i_data; 378 | param[4].buffer_length = strlen(i_data); 379 | if( mysql_stmt_bind_param(stmt[0], param) ) goto sqlerr; 380 | if( try_stmt_execute(stmt[0]) ) goto retry; 381 | 382 | #if 0 383 | printf("done executing sql\n"); 384 | fflush(stdout); 385 | #endif 386 | 387 | if (!(i_id % 100)) { 388 | printf("."); 389 | fflush(stdout); 390 | 391 | if (!(i_id % 5000)) 392 | printf(" %ld\n", i_id); 393 | } 394 | } 395 | 396 | /* EXEC SQL COMMIT WORK; */ 397 | if( mysql_commit(mysql) ) goto sqlerr; 398 | 399 | printf("Item Done. \n"); 400 | return; 401 | sqlerr: 402 | Error(stmt[0]); 403 | } 404 | 405 | /* 406 | * ==================================================================+ | 407 | * ROUTINE NAME | LoadWare | DESCRIPTION | Loads the Warehouse 408 | * table | Loads Stock, District as Warehouses are created | ARGUMENTS | 409 | * none +================================================================== 410 | */ 411 | void 412 | LoadWare() 413 | { 414 | 415 | int w_id; 416 | char w_name[11]; 417 | char w_street_1[21]; 418 | char w_street_2[21]; 419 | char w_city[21]; 420 | char w_state[3]; 421 | char w_zip[10]; 422 | float w_tax; 423 | float w_ytd; 424 | 425 | int tmp; 426 | int retried = 0; 427 | 428 | MYSQL_BIND param[9]; 429 | 430 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 431 | 432 | printf("Loading Warehouse \n"); 433 | w_id = min_ware; 434 | retry: 435 | if (retried) 436 | printf("Retrying ....\n"); 437 | retried = 1; 438 | for (; w_id <= max_ware; w_id++) { 439 | 440 | /* Generate Warehouse Data */ 441 | 442 | w_name[ MakeAlphaString(6, 10, w_name) ] = 0; 443 | 444 | MakeAddress(w_street_1, w_street_2, w_city, w_state, w_zip); 445 | 446 | w_tax = ((float) RandomNumber(10L, 20L)) / 100.0; 447 | w_ytd = 3000000.00; 448 | 449 | if (option_debug) 450 | printf("WID = %ld, Name= %16s, Tax = %5.2f\n", 451 | w_id, w_name, w_tax); 452 | 453 | /*EXEC SQL INSERT INTO 454 | warehouse 455 | values(:w_id,:w_name, 456 | :w_street_1,:w_street_2,:w_city,:w_state, 457 | :w_zip,:w_tax,:w_ytd);*/ 458 | 459 | memset(param, 0, sizeof(MYSQL_BIND) * 9); /* initialize */ 460 | param[0].buffer_type = MYSQL_TYPE_LONG; 461 | param[0].buffer = &w_id; 462 | param[1].buffer_type = MYSQL_TYPE_STRING; 463 | param[1].buffer = w_name; 464 | param[1].buffer_length = strlen(w_name); 465 | param[2].buffer_type = MYSQL_TYPE_STRING; 466 | param[2].buffer = w_street_1; 467 | param[2].buffer_length = strlen(w_street_1); 468 | param[3].buffer_type = MYSQL_TYPE_STRING; 469 | param[3].buffer = w_street_2; 470 | param[3].buffer_length = strlen(w_street_2); 471 | param[4].buffer_type = MYSQL_TYPE_STRING; 472 | param[4].buffer = w_city; 473 | param[4].buffer_length = strlen(w_city); 474 | param[5].buffer_type = MYSQL_TYPE_STRING; 475 | param[5].buffer = w_state; 476 | param[5].buffer_length = strlen(w_state); 477 | param[6].buffer_type = MYSQL_TYPE_STRING; 478 | param[6].buffer = w_zip; 479 | param[6].buffer_length = strlen(w_zip); 480 | param[7].buffer_type = MYSQL_TYPE_FLOAT; 481 | param[7].buffer = &w_tax; 482 | param[8].buffer_type = MYSQL_TYPE_FLOAT; 483 | param[8].buffer = &w_ytd; 484 | if( mysql_stmt_bind_param(stmt[1], param) ) goto sqlerr; 485 | if( try_stmt_execute(stmt[1]) ) goto retry; 486 | 487 | /** Make Rows associated with Warehouse **/ 488 | if( Stock(w_id) ) goto retry; 489 | if( District(w_id) ) goto retry; 490 | 491 | /* EXEC SQL COMMIT WORK; */ 492 | if( mysql_commit(mysql) ) goto sqlerr; 493 | 494 | } 495 | 496 | return; 497 | sqlerr: 498 | Error(0); 499 | } 500 | 501 | /* 502 | * ==================================================================+ | 503 | * ROUTINE NAME | LoadCust | DESCRIPTION | Loads the Customer Table 504 | * | ARGUMENTS | none 505 | * +================================================================== 506 | */ 507 | void 508 | LoadCust() 509 | { 510 | 511 | int w_id; 512 | int d_id; 513 | 514 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 515 | 516 | for (w_id = min_ware; w_id <= max_ware; w_id++) 517 | for (d_id = 1L; d_id <= DIST_PER_WARE; d_id++) 518 | Customer(d_id, w_id); 519 | 520 | /* EXEC SQL COMMIT WORK;*/ /* Just in case */ 521 | if( mysql_commit(mysql) ) goto sqlerr; 522 | 523 | return; 524 | sqlerr: 525 | Error(0); 526 | } 527 | 528 | /* 529 | * ==================================================================+ | 530 | * ROUTINE NAME | LoadOrd | DESCRIPTION | Loads the Orders and 531 | * Order_Line Tables | ARGUMENTS | none 532 | * +================================================================== 533 | */ 534 | void 535 | LoadOrd() 536 | { 537 | 538 | int w_id; 539 | float w_tax; 540 | int d_id; 541 | float d_tax; 542 | 543 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 544 | 545 | for (w_id = min_ware; w_id <= max_ware; w_id++) 546 | for (d_id = 1L; d_id <= DIST_PER_WARE; d_id++) 547 | Orders(d_id, w_id); 548 | 549 | /* EXEC SQL COMMIT WORK; */ /* Just in case */ 550 | if( mysql_commit(mysql) ) goto sqlerr; 551 | 552 | return; 553 | sqlerr: 554 | Error(0); 555 | } 556 | 557 | /* 558 | * ==================================================================+ | 559 | * ROUTINE NAME | Stock | DESCRIPTION | Loads the Stock table | 560 | * ARGUMENTS | w_id - warehouse id 561 | * +================================================================== 562 | */ 563 | int 564 | Stock(w_id) 565 | int w_id; 566 | { 567 | 568 | int s_i_id; 569 | int s_w_id; 570 | int s_quantity; 571 | 572 | char s_dist_01[25]; 573 | char s_dist_02[25]; 574 | char s_dist_03[25]; 575 | char s_dist_04[25]; 576 | char s_dist_05[25]; 577 | char s_dist_06[25]; 578 | char s_dist_07[25]; 579 | char s_dist_08[25]; 580 | char s_dist_09[25]; 581 | char s_dist_10[25]; 582 | char s_data[51]; 583 | 584 | int sdatasiz; 585 | int orig[MAXITEMS+1]; 586 | int pos; 587 | int i; 588 | int error; 589 | 590 | MYSQL_BIND param[14]; 591 | 592 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 593 | printf("Loading Stock Wid=%ld\n", w_id); 594 | s_w_id = w_id; 595 | 596 | for (i = 0; i < MAXITEMS / 10; i++) 597 | orig[i] = 0; 598 | for (i = 0; i < MAXITEMS / 10; i++) { 599 | do { 600 | pos = RandomNumber(0L, MAXITEMS); 601 | } while (orig[pos]); 602 | orig[pos] = 1; 603 | } 604 | 605 | retry: 606 | for (s_i_id = 1; s_i_id <= MAXITEMS; s_i_id++) { 607 | 608 | /* Generate Stock Data */ 609 | s_quantity = RandomNumber(10L, 100L); 610 | 611 | s_dist_01[ MakeAlphaString(24, 24, s_dist_01) ] = 0; 612 | s_dist_02[ MakeAlphaString(24, 24, s_dist_02) ] = 0; 613 | s_dist_03[ MakeAlphaString(24, 24, s_dist_03) ] = 0; 614 | s_dist_04[ MakeAlphaString(24, 24, s_dist_04) ] = 0; 615 | s_dist_05[ MakeAlphaString(24, 24, s_dist_05) ] = 0; 616 | s_dist_06[ MakeAlphaString(24, 24, s_dist_06) ] = 0; 617 | s_dist_07[ MakeAlphaString(24, 24, s_dist_07) ] = 0; 618 | s_dist_08[ MakeAlphaString(24, 24, s_dist_08) ] = 0; 619 | s_dist_09[ MakeAlphaString(24, 24, s_dist_09) ] = 0; 620 | s_dist_10[ MakeAlphaString(24, 24, s_dist_10) ] = 0; 621 | sdatasiz = MakeAlphaString(26, 50, s_data); 622 | s_data[sdatasiz] = 0; 623 | 624 | if (orig[s_i_id]) { 625 | pos = RandomNumber(0L, sdatasiz - 8); 626 | 627 | s_data[pos] = 'o'; 628 | s_data[pos + 1] = 'r'; 629 | s_data[pos + 2] = 'i'; 630 | s_data[pos + 3] = 'g'; 631 | s_data[pos + 4] = 'i'; 632 | s_data[pos + 5] = 'n'; 633 | s_data[pos + 6] = 'a'; 634 | s_data[pos + 7] = 'l'; 635 | 636 | } 637 | /*EXEC SQL INSERT INTO 638 | stock 639 | values(:s_i_id,:s_w_id,:s_quantity, 640 | :s_dist_01,:s_dist_02,:s_dist_03,:s_dist_04,:s_dist_05, 641 | :s_dist_06,:s_dist_07,:s_dist_08,:s_dist_09,:s_dist_10, 642 | 0, 0, 0,:s_data);*/ 643 | 644 | memset(param, 0, sizeof(MYSQL_BIND) * 14); /* initialize */ 645 | param[0].buffer_type = MYSQL_TYPE_LONG; 646 | param[0].buffer = &s_i_id; 647 | param[1].buffer_type = MYSQL_TYPE_LONG; 648 | param[1].buffer = &s_w_id; 649 | param[2].buffer_type = MYSQL_TYPE_LONG; 650 | param[2].buffer = &s_quantity; 651 | param[3].buffer_type = MYSQL_TYPE_STRING; 652 | param[3].buffer = s_dist_01; 653 | param[3].buffer_length = strlen(s_dist_01); 654 | param[4].buffer_type = MYSQL_TYPE_STRING; 655 | param[4].buffer = s_dist_02; 656 | param[4].buffer_length = strlen(s_dist_02); 657 | param[5].buffer_type = MYSQL_TYPE_STRING; 658 | param[5].buffer = s_dist_03; 659 | param[5].buffer_length = strlen(s_dist_03); 660 | param[6].buffer_type = MYSQL_TYPE_STRING; 661 | param[6].buffer = s_dist_04; 662 | param[6].buffer_length = strlen(s_dist_04); 663 | param[7].buffer_type = MYSQL_TYPE_STRING; 664 | param[7].buffer = s_dist_05; 665 | param[7].buffer_length = strlen(s_dist_05); 666 | param[8].buffer_type = MYSQL_TYPE_STRING; 667 | param[8].buffer = s_dist_06; 668 | param[8].buffer_length = strlen(s_dist_06); 669 | param[9].buffer_type = MYSQL_TYPE_STRING; 670 | param[9].buffer = s_dist_07; 671 | param[9].buffer_length = strlen(s_dist_07); 672 | param[10].buffer_type = MYSQL_TYPE_STRING; 673 | param[10].buffer = s_dist_08; 674 | param[10].buffer_length = strlen(s_dist_08); 675 | param[11].buffer_type = MYSQL_TYPE_STRING; 676 | param[11].buffer = s_dist_09; 677 | param[11].buffer_length = strlen(s_dist_09); 678 | param[12].buffer_type = MYSQL_TYPE_STRING; 679 | param[12].buffer = s_dist_10; 680 | param[12].buffer_length = strlen(s_dist_10); 681 | param[13].buffer_type = MYSQL_TYPE_STRING; 682 | param[13].buffer = s_data; 683 | param[13].buffer_length = strlen(s_data); 684 | if( mysql_stmt_bind_param(stmt[2], param) ) goto sqlerr; 685 | if( (error = try_stmt_execute(stmt[2])) ) goto out; 686 | 687 | if (option_debug) 688 | printf("SID = %ld, WID = %ld, Quan = %ld\n", 689 | s_i_id, s_w_id, s_quantity); 690 | 691 | if (!(s_i_id % 100)) { 692 | printf("."); 693 | fflush(stdout); 694 | if (!(s_i_id % 5000)) 695 | printf(" %ld\n", s_i_id); 696 | } 697 | } 698 | 699 | printf(" Stock Done.\n"); 700 | out: 701 | return error; 702 | sqlerr: 703 | Error(0); 704 | } 705 | 706 | /* 707 | * ==================================================================+ | 708 | * ROUTINE NAME | District | DESCRIPTION | Loads the District table 709 | * | ARGUMENTS | w_id - warehouse id 710 | * +================================================================== 711 | */ 712 | int 713 | District(w_id) 714 | int w_id; 715 | { 716 | 717 | int d_id; 718 | int d_w_id; 719 | 720 | char d_name[11]; 721 | char d_street_1[21]; 722 | char d_street_2[21]; 723 | char d_city[21]; 724 | char d_state[3]; 725 | char d_zip[10]; 726 | 727 | float d_tax; 728 | float d_ytd; 729 | int d_next_o_id; 730 | int error; 731 | 732 | MYSQL_BIND param[11]; 733 | 734 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 735 | 736 | printf("Loading District\n"); 737 | d_w_id = w_id; 738 | d_ytd = 30000.0; 739 | d_next_o_id = 3001L; 740 | retry: 741 | for (d_id = 1; d_id <= DIST_PER_WARE; d_id++) { 742 | 743 | /* Generate District Data */ 744 | 745 | d_name[ MakeAlphaString(6L, 10L, d_name) ] = 0; 746 | MakeAddress(d_street_1, d_street_2, d_city, d_state, d_zip); 747 | 748 | d_tax = ((float) RandomNumber(10L, 20L)) / 100.0; 749 | 750 | /*EXEC SQL INSERT INTO 751 | district 752 | values(:d_id,:d_w_id,:d_name, 753 | :d_street_1,:d_street_2,:d_city,:d_state,:d_zip, 754 | :d_tax,:d_ytd,:d_next_o_id);*/ 755 | 756 | memset(param, 0, sizeof(MYSQL_BIND) * 11); /* initialize */ 757 | param[0].buffer_type = MYSQL_TYPE_LONG; 758 | param[0].buffer = &d_id; 759 | param[1].buffer_type = MYSQL_TYPE_LONG; 760 | param[1].buffer = &d_w_id; 761 | param[2].buffer_type = MYSQL_TYPE_STRING; 762 | param[2].buffer = d_name; 763 | param[2].buffer_length = strlen(d_name); 764 | param[3].buffer_type = MYSQL_TYPE_STRING; 765 | param[3].buffer = d_street_1; 766 | param[3].buffer_length = strlen(d_street_1); 767 | param[4].buffer_type = MYSQL_TYPE_STRING; 768 | param[4].buffer = d_street_2; 769 | param[4].buffer_length = strlen(d_street_2); 770 | param[5].buffer_type = MYSQL_TYPE_STRING; 771 | param[5].buffer = d_city; 772 | param[5].buffer_length = strlen(d_city); 773 | param[6].buffer_type = MYSQL_TYPE_STRING; 774 | param[6].buffer = d_state; 775 | param[6].buffer_length = strlen(d_state); 776 | param[7].buffer_type = MYSQL_TYPE_STRING; 777 | param[7].buffer = d_zip; 778 | param[7].buffer_length = strlen(d_zip); 779 | param[8].buffer_type = MYSQL_TYPE_FLOAT; 780 | param[8].buffer = &d_tax; 781 | param[9].buffer_type = MYSQL_TYPE_FLOAT; 782 | param[9].buffer = &d_ytd; 783 | param[10].buffer_type = MYSQL_TYPE_LONG; 784 | param[10].buffer = &d_next_o_id; 785 | if( mysql_stmt_bind_param(stmt[3], param) ) goto sqlerr; 786 | if( (error = try_stmt_execute(stmt[3])) ) goto out; 787 | 788 | if (option_debug) 789 | printf("DID = %ld, WID = %ld, Name = %10s, Tax = %5.2f\n", 790 | d_id, d_w_id, d_name, d_tax); 791 | 792 | } 793 | 794 | out: 795 | return error; 796 | sqlerr: 797 | Error(0); 798 | } 799 | 800 | /* 801 | * ==================================================================+ | 802 | * ROUTINE NAME | Customer | DESCRIPTION | Loads Customer Table | 803 | * Also inserts corresponding history record | ARGUMENTS | id - 804 | * customer id | d_id - district id | w_id - warehouse id 805 | * +================================================================== 806 | */ 807 | void 808 | Customer(d_id, w_id) 809 | int d_id; 810 | int w_id; 811 | { 812 | int c_id; 813 | int c_d_id; 814 | int c_w_id; 815 | 816 | char c_first[17]; 817 | char c_middle[3]; 818 | char c_last[17]; 819 | char c_street_1[21]; 820 | char c_street_2[21]; 821 | char c_city[21]; 822 | char c_state[3]; 823 | char c_zip[10]; 824 | char c_phone[17]; 825 | char c_since[12]; 826 | char c_credit[3]; 827 | 828 | int c_credit_lim; 829 | float c_discount; 830 | float c_balance; 831 | char c_data[501]; 832 | 833 | float h_amount; 834 | 835 | char h_data[25]; 836 | int retried = 0; 837 | 838 | MYSQL_BIND param[18]; 839 | 840 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 841 | 842 | printf("Loading Customer for DID=%ld, WID=%ld\n", d_id, w_id); 843 | 844 | retry: 845 | if (retried) 846 | printf("Retrying ...\n"); 847 | retried = 1; 848 | for (c_id = 1; c_id <= CUST_PER_DIST; c_id++) { 849 | 850 | /* Generate Customer Data */ 851 | c_d_id = d_id; 852 | c_w_id = w_id; 853 | 854 | c_first[ MakeAlphaString(8, 16, c_first) ] = 0; 855 | c_middle[0] = 'O'; 856 | c_middle[1] = 'E'; 857 | c_middle[2] = 0; 858 | 859 | if (c_id <= 1000) { 860 | Lastname(c_id - 1, c_last); 861 | } else { 862 | Lastname(NURand(255, 0, 999), c_last); 863 | } 864 | 865 | MakeAddress(c_street_1, c_street_2, c_city, c_state, c_zip); 866 | c_phone[ MakeNumberString(16, 16, c_phone) ] = 0; 867 | 868 | if (RandomNumber(0L, 1L)) 869 | c_credit[0] = 'G'; 870 | else 871 | c_credit[0] = 'B'; 872 | c_credit[1] = 'C'; 873 | c_credit[2] = 0; 874 | 875 | c_credit_lim = 50000; 876 | c_discount = ((float) RandomNumber(0L, 50L)) / 100.0; 877 | c_balance = -10.0; 878 | 879 | c_data[ MakeAlphaString(300, 500, c_data) ] = 0; 880 | 881 | /*EXEC SQL INSERT INTO 882 | customer 883 | values(:c_id,:c_d_id,:c_w_id, 884 | :c_first,:c_middle,:c_last, 885 | :c_street_1,:c_street_2,:c_city,:c_state, 886 | :c_zip, 887 | :c_phone, :timestamp, 888 | :c_credit, 889 | :c_credit_lim,:c_discount,:c_balance, 890 | 10.0, 1, 0,:c_data);*/ 891 | 892 | memset(param, 0, sizeof(MYSQL_BIND) * 18); /* initialize */ 893 | param[0].buffer_type = MYSQL_TYPE_LONG; 894 | param[0].buffer = &c_id; 895 | param[1].buffer_type = MYSQL_TYPE_LONG; 896 | param[1].buffer = &c_d_id; 897 | param[2].buffer_type = MYSQL_TYPE_LONG; 898 | param[2].buffer = &c_w_id; 899 | param[3].buffer_type = MYSQL_TYPE_STRING; 900 | param[3].buffer = c_first; 901 | param[3].buffer_length = strlen(c_first); 902 | param[4].buffer_type = MYSQL_TYPE_STRING; 903 | param[4].buffer = c_middle; 904 | param[4].buffer_length = strlen(c_middle); 905 | param[5].buffer_type = MYSQL_TYPE_STRING; 906 | param[5].buffer = c_last; 907 | param[5].buffer_length = strlen(c_last); 908 | param[6].buffer_type = MYSQL_TYPE_STRING; 909 | param[6].buffer = c_street_1; 910 | param[6].buffer_length = strlen(c_street_1); 911 | param[7].buffer_type = MYSQL_TYPE_STRING; 912 | param[7].buffer = c_street_2; 913 | param[7].buffer_length = strlen(c_street_2); 914 | param[8].buffer_type = MYSQL_TYPE_STRING; 915 | param[8].buffer = c_city; 916 | param[8].buffer_length = strlen(c_city); 917 | param[9].buffer_type = MYSQL_TYPE_STRING; 918 | param[9].buffer = c_state; 919 | param[9].buffer_length = strlen(c_state); 920 | param[10].buffer_type = MYSQL_TYPE_STRING; 921 | param[10].buffer = c_zip; 922 | param[10].buffer_length = strlen(c_zip); 923 | param[11].buffer_type = MYSQL_TYPE_STRING; 924 | param[11].buffer = c_phone; 925 | param[11].buffer_length = strlen(c_phone); 926 | param[12].buffer_type = MYSQL_TYPE_STRING; 927 | param[12].buffer = timestamp; 928 | param[12].buffer_length = strlen(timestamp); 929 | param[13].buffer_type = MYSQL_TYPE_STRING; 930 | param[13].buffer = c_credit; 931 | param[13].buffer_length = strlen(c_credit); 932 | param[14].buffer_type = MYSQL_TYPE_LONG; 933 | param[14].buffer = &c_credit_lim; 934 | param[15].buffer_type = MYSQL_TYPE_FLOAT; 935 | param[15].buffer = &c_discount; 936 | param[16].buffer_type = MYSQL_TYPE_FLOAT; 937 | param[16].buffer = &c_balance; 938 | param[17].buffer_type = MYSQL_TYPE_STRING; 939 | param[17].buffer = c_data; 940 | param[17].buffer_length = strlen(c_data); 941 | if( mysql_stmt_bind_param(stmt[4], param) ) goto sqlerr; 942 | if( try_stmt_execute(stmt[4]) ) goto retry; 943 | 944 | h_amount = 10.0; 945 | 946 | h_data[ MakeAlphaString(12, 24, h_data) ] = 0; 947 | 948 | /*EXEC SQL INSERT INTO 949 | history 950 | values(:c_id,:c_d_id,:c_w_id, 951 | :c_d_id,:c_w_id, :timestamp, 952 | :h_amount,:h_data);*/ 953 | 954 | memset(param, 0, sizeof(MYSQL_BIND) * 8); /* initialize */ 955 | param[0].buffer_type = MYSQL_TYPE_LONG; 956 | param[0].buffer = &c_id; 957 | param[1].buffer_type = MYSQL_TYPE_LONG; 958 | param[1].buffer = &c_d_id; 959 | param[2].buffer_type = MYSQL_TYPE_LONG; 960 | param[2].buffer = &c_w_id; 961 | param[3].buffer_type = MYSQL_TYPE_LONG; 962 | param[3].buffer = &c_d_id; 963 | param[4].buffer_type = MYSQL_TYPE_LONG; 964 | param[4].buffer = &c_w_id; 965 | param[5].buffer_type = MYSQL_TYPE_STRING; 966 | param[5].buffer = timestamp; 967 | param[5].buffer_length = strlen(timestamp); 968 | param[6].buffer_type = MYSQL_TYPE_FLOAT; 969 | param[6].buffer = &h_amount; 970 | param[7].buffer_type = MYSQL_TYPE_STRING; 971 | param[7].buffer = h_data; 972 | param[7].buffer_length = strlen(h_data); 973 | if( mysql_stmt_bind_param(stmt[5], param) ) goto sqlerr; 974 | if( try_stmt_execute(stmt[5]) ) goto retry; 975 | 976 | if (option_debug) 977 | printf("CID = %ld, LST = %s, P# = %s\n", 978 | c_id, c_last, c_phone); 979 | if (!(c_id % 100)) { 980 | printf("."); 981 | fflush(stdout); 982 | if (!(c_id % 1000)) 983 | printf(" %ld\n", c_id); 984 | } 985 | } 986 | /* EXEC SQL COMMIT WORK; */ 987 | if( mysql_commit(mysql) ) goto sqlerr; 988 | printf("Customer Done.\n"); 989 | 990 | return; 991 | sqlerr: 992 | Error(0); 993 | } 994 | 995 | /* 996 | * ==================================================================+ | 997 | * ROUTINE NAME | Orders | DESCRIPTION | Loads the Orders table | 998 | * Also loads the Order_Line table on the fly | ARGUMENTS | w_id - 999 | * warehouse id 1000 | * +================================================================== 1001 | */ 1002 | void 1003 | Orders(d_id, w_id) 1004 | int d_id, w_id; 1005 | { 1006 | 1007 | int o_id; 1008 | int o_c_id; 1009 | int o_d_id; 1010 | int o_w_id; 1011 | int o_carrier_id; 1012 | int o_ol_cnt; 1013 | int ol; 1014 | int ol_i_id; 1015 | int ol_supply_w_id; 1016 | int ol_quantity; 1017 | float ol_amount; 1018 | char ol_dist_info[25]; 1019 | float i_price; 1020 | float c_discount; 1021 | float tmp_float; 1022 | int retried = 0; 1023 | 1024 | MYSQL_BIND param[10]; 1025 | 1026 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 1027 | 1028 | printf("Loading Orders for D=%ld, W= %ld\n", d_id, w_id); 1029 | o_d_id = d_id; 1030 | o_w_id = w_id; 1031 | retry: 1032 | if (retried) 1033 | printf("Retrying ...\n"); 1034 | retried = 1; 1035 | InitPermutation(); /* initialize permutation of customer numbers */ 1036 | for (o_id = 1; o_id <= ORD_PER_DIST; o_id++) { 1037 | 1038 | /* Generate Order Data */ 1039 | o_c_id = GetPermutation(); 1040 | o_carrier_id = RandomNumber(1L, 10L); 1041 | o_ol_cnt = RandomNumber(5L, 15L); 1042 | 1043 | if (o_id > 2100) { /* the last 900 orders have not been 1044 | * delivered) */ 1045 | /*EXEC SQL INSERT INTO 1046 | orders 1047 | values(:o_id,:o_d_id,:o_w_id,:o_c_id, 1048 | :timestamp, 1049 | NULL,:o_ol_cnt, 1);*/ 1050 | 1051 | memset(param, 0, sizeof(MYSQL_BIND) * 6); /* initialize */ 1052 | param[0].buffer_type = MYSQL_TYPE_LONG; 1053 | param[0].buffer = &o_id; 1054 | param[1].buffer_type = MYSQL_TYPE_LONG; 1055 | param[1].buffer = &o_d_id; 1056 | param[2].buffer_type = MYSQL_TYPE_LONG; 1057 | param[2].buffer = &o_w_id; 1058 | param[3].buffer_type = MYSQL_TYPE_LONG; 1059 | param[3].buffer = &o_c_id; 1060 | param[4].buffer_type = MYSQL_TYPE_STRING; 1061 | param[4].buffer = timestamp; 1062 | param[4].buffer_length = strlen(timestamp); 1063 | param[5].buffer_type = MYSQL_TYPE_LONG; 1064 | param[5].buffer = &o_ol_cnt; 1065 | if( mysql_stmt_bind_param(stmt[6], param) ) goto sqlerr; 1066 | if( try_stmt_execute(stmt[6]) ) goto retry; 1067 | 1068 | /*EXEC SQL INSERT INTO 1069 | new_orders 1070 | values(:o_id,:o_d_id,:o_w_id);*/ 1071 | 1072 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 1073 | param[0].buffer_type = MYSQL_TYPE_LONG; 1074 | param[0].buffer = &o_id; 1075 | param[1].buffer_type = MYSQL_TYPE_LONG; 1076 | param[1].buffer = &o_d_id; 1077 | param[2].buffer_type = MYSQL_TYPE_LONG; 1078 | param[2].buffer = &o_w_id; 1079 | if( mysql_stmt_bind_param(stmt[7], param) ) goto sqlerr; 1080 | if( try_stmt_execute(stmt[7]) ) goto retry; 1081 | 1082 | } else { 1083 | /*EXEC SQL INSERT INTO 1084 | orders 1085 | values(:o_id,:o_d_id,:o_w_id,:o_c_id, 1086 | :timestamp, 1087 | :o_carrier_id,:o_ol_cnt, 1);*/ 1088 | 1089 | memset(param, 0, sizeof(MYSQL_BIND) * 7); /* initialize */ 1090 | param[0].buffer_type = MYSQL_TYPE_LONG; 1091 | param[0].buffer = &o_id; 1092 | param[1].buffer_type = MYSQL_TYPE_LONG; 1093 | param[1].buffer = &o_d_id; 1094 | param[2].buffer_type = MYSQL_TYPE_LONG; 1095 | param[2].buffer = &o_w_id; 1096 | param[3].buffer_type = MYSQL_TYPE_LONG; 1097 | param[3].buffer = &o_c_id; 1098 | param[4].buffer_type = MYSQL_TYPE_STRING; 1099 | param[4].buffer = timestamp; 1100 | param[4].buffer_length = strlen(timestamp); 1101 | param[5].buffer_type = MYSQL_TYPE_LONG; 1102 | param[5].buffer = &o_carrier_id; 1103 | param[6].buffer_type = MYSQL_TYPE_LONG; 1104 | param[6].buffer = &o_ol_cnt; 1105 | if( mysql_stmt_bind_param(stmt[8], param) ) goto sqlerr; 1106 | if( try_stmt_execute(stmt[8]) ) goto retry; 1107 | 1108 | } 1109 | 1110 | 1111 | if (option_debug) 1112 | printf("OID = %ld, CID = %ld, DID = %ld, WID = %ld\n", 1113 | o_id, o_c_id, o_d_id, o_w_id); 1114 | 1115 | for (ol = 1; ol <= o_ol_cnt; ol++) { 1116 | /* Generate Order Line Data */ 1117 | ol_i_id = RandomNumber(1L, MAXITEMS); 1118 | ol_supply_w_id = o_w_id; 1119 | ol_quantity = 5; 1120 | ol_amount = 0.0; 1121 | 1122 | ol_dist_info[ MakeAlphaString(24, 24, ol_dist_info) ] = 0; 1123 | 1124 | tmp_float = (float) (RandomNumber(10L, 10000L)) / 100.0; 1125 | 1126 | if (o_id > 2100) { 1127 | /*EXEC SQL INSERT INTO 1128 | order_line 1129 | values(:o_id,:o_d_id,:o_w_id,:ol, 1130 | :ol_i_id,:ol_supply_w_id, NULL, 1131 | :ol_quantity,:ol_amount,:ol_dist_info);*/ 1132 | 1133 | memset(param, 0, sizeof(MYSQL_BIND) * 9); /* initialize */ 1134 | param[0].buffer_type = MYSQL_TYPE_LONG; 1135 | param[0].buffer = &o_id; 1136 | param[1].buffer_type = MYSQL_TYPE_LONG; 1137 | param[1].buffer = &o_d_id; 1138 | param[2].buffer_type = MYSQL_TYPE_LONG; 1139 | param[2].buffer = &o_w_id; 1140 | param[3].buffer_type = MYSQL_TYPE_LONG; 1141 | param[3].buffer = &ol; 1142 | param[4].buffer_type = MYSQL_TYPE_LONG; 1143 | param[4].buffer = &ol_i_id; 1144 | param[5].buffer_type = MYSQL_TYPE_LONG; 1145 | param[5].buffer = &ol_supply_w_id; 1146 | param[6].buffer_type = MYSQL_TYPE_LONG; 1147 | param[6].buffer = &ol_quantity; 1148 | param[7].buffer_type = MYSQL_TYPE_FLOAT; 1149 | param[7].buffer = &ol_amount; 1150 | param[8].buffer_type = MYSQL_TYPE_STRING; 1151 | param[8].buffer = ol_dist_info; 1152 | param[8].buffer_length = strlen(ol_dist_info); 1153 | if( mysql_stmt_bind_param(stmt[9], param) ) goto sqlerr; 1154 | if( try_stmt_execute(stmt[9]) ) goto retry; 1155 | 1156 | } else { 1157 | /*EXEC SQL INSERT INTO 1158 | order_line 1159 | values(:o_id,:o_d_id,:o_w_id,:ol, 1160 | :ol_i_id,:ol_supply_w_id, 1161 | :timestamp, 1162 | :ol_quantity,:tmp_float,:ol_dist_info);*/ 1163 | 1164 | memset(param, 0, sizeof(MYSQL_BIND) * 10); /* initialize */ 1165 | param[0].buffer_type = MYSQL_TYPE_LONG; 1166 | param[0].buffer = &o_id; 1167 | param[1].buffer_type = MYSQL_TYPE_LONG; 1168 | param[1].buffer = &o_d_id; 1169 | param[2].buffer_type = MYSQL_TYPE_LONG; 1170 | param[2].buffer = &o_w_id; 1171 | param[3].buffer_type = MYSQL_TYPE_LONG; 1172 | param[3].buffer = &ol; 1173 | param[4].buffer_type = MYSQL_TYPE_LONG; 1174 | param[4].buffer = &ol_i_id; 1175 | param[5].buffer_type = MYSQL_TYPE_LONG; 1176 | param[5].buffer = &ol_supply_w_id; 1177 | param[6].buffer_type = MYSQL_TYPE_STRING; 1178 | param[6].buffer = timestamp; 1179 | param[6].buffer_length = strlen(timestamp); 1180 | param[7].buffer_type = MYSQL_TYPE_LONG; 1181 | param[7].buffer = &ol_quantity; 1182 | param[8].buffer_type = MYSQL_TYPE_FLOAT; 1183 | param[8].buffer = &tmp_float; 1184 | param[9].buffer_type = MYSQL_TYPE_STRING; 1185 | param[9].buffer = ol_dist_info; 1186 | param[9].buffer_length = strlen(ol_dist_info); 1187 | if( mysql_stmt_bind_param(stmt[10], param) ) goto sqlerr; 1188 | if( try_stmt_execute(stmt[10]) ) goto retry; 1189 | } 1190 | 1191 | if (option_debug) 1192 | printf("OL = %ld, IID = %ld, QUAN = %ld, AMT = %8.2f\n", 1193 | ol, ol_i_id, ol_quantity, ol_amount); 1194 | 1195 | } 1196 | if (!(o_id % 100)) { 1197 | printf("."); 1198 | fflush(stdout); 1199 | 1200 | if (!(o_id % 1000)) 1201 | printf(" %ld\n", o_id); 1202 | } 1203 | } 1204 | /*EXEC SQL COMMIT WORK;*/ 1205 | if( mysql_commit(mysql) ) goto sqlerr; 1206 | 1207 | printf("Orders Done.\n"); 1208 | return; 1209 | sqlerr: 1210 | Error(0); 1211 | } 1212 | 1213 | /* 1214 | * ==================================================================+ | 1215 | * ROUTINE NAME | MakeAddress() | DESCRIPTION | Build an Address | 1216 | * ARGUMENTS 1217 | * +================================================================== 1218 | */ 1219 | void 1220 | MakeAddress(str1, str2, city, state, zip) 1221 | char *str1; 1222 | char *str2; 1223 | char *city; 1224 | char *state; 1225 | char *zip; 1226 | { 1227 | str1[ MakeAlphaString(10, 20, str1) ] = 0; /* Street 1 */ 1228 | str2[ MakeAlphaString(10, 20, str2) ] = 0; /* Street 2 */ 1229 | city[ MakeAlphaString(10, 20, city) ] = 0; /* City */ 1230 | state[ MakeAlphaString(2, 2, state) ] = 0; /* State */ 1231 | zip[ MakeNumberString(9, 9, zip) ] = 0; /* Zip */ 1232 | } 1233 | 1234 | /* 1235 | * ==================================================================+ | 1236 | * ROUTINE NAME | Error() | DESCRIPTION | Handles an error from a 1237 | * SQL call. | ARGUMENTS 1238 | * +================================================================== 1239 | */ 1240 | void 1241 | Error(mysql_stmt) 1242 | MYSQL_STMT *mysql_stmt; 1243 | { 1244 | if(mysql_stmt) { 1245 | printf("\n%d, %s, %s", mysql_stmt_errno(mysql_stmt), 1246 | mysql_stmt_sqlstate(mysql_stmt), mysql_stmt_error(mysql_stmt) ); 1247 | } 1248 | printf("\n%d, %s, %s\n", mysql_errno(mysql), mysql_sqlstate(mysql), mysql_error(mysql) ); 1249 | 1250 | /*EXEC SQL WHENEVER SQLERROR CONTINUE;*/ 1251 | 1252 | /*EXEC SQL ROLLBACK WORK;*/ 1253 | mysql_rollback(mysql); 1254 | 1255 | /*EXEC SQL DISCONNECT;*/ 1256 | mysql_close(mysql); 1257 | 1258 | exit(-1); 1259 | } 1260 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * main.pc 3 | * driver for the tpcc transactions 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include "tpc.h" 18 | #include "trans_if.h" 19 | #include "spt_proc.h" 20 | #include "sequence.h" 21 | #include "rthist.h" 22 | 23 | /* Global SQL Variables */ 24 | MYSQL **ctx; 25 | MYSQL_STMT ***stmt; 26 | 27 | #define DB_STRING_MAX 128 28 | #define MAX_CLUSTER_SIZE 128 29 | 30 | char connect_string[DB_STRING_MAX]; 31 | 32 | char db_string[DB_STRING_MAX]; 33 | char db_host[DB_STRING_MAX]; 34 | char db_user[DB_STRING_MAX]; 35 | char db_password[DB_STRING_MAX]; 36 | char report_file[DB_STRING_MAX]=""; 37 | FILE *freport_file=NULL; 38 | char trx_file[DB_STRING_MAX]=""; 39 | FILE *ftrx_file=NULL; 40 | 41 | int num_ware; 42 | int num_conn; 43 | int lampup_time; 44 | int measure_time; 45 | 46 | int num_node; /* number of servers that consists of cluster i.e. RAC (0:normal mode)*/ 47 | #define NUM_NODE_MAX 8 48 | char node_string[NUM_NODE_MAX][DB_STRING_MAX]; 49 | 50 | int time_count; 51 | int PRINT_INTERVAL=10; 52 | 53 | int success[5]; 54 | int late[5]; 55 | int retry[5]; 56 | int failure[5]; 57 | 58 | int* success2[5]; 59 | int* late2[5]; 60 | int* retry2[5]; 61 | int* failure2[5]; 62 | 63 | int success2_sum[5]; 64 | int late2_sum[5]; 65 | int retry2_sum[5]; 66 | int failure2_sum[5]; 67 | 68 | int prev_s[5]; 69 | int prev_l[5]; 70 | 71 | double max_rt[5]; 72 | double cur_max_rt[5]; 73 | 74 | int activate_transaction; 75 | int counting_on; 76 | 77 | long clk_tck; 78 | 79 | int is_local = 0; /* "1" mean local */ 80 | int valuable_flg = 0; /* "1" mean valuable ratio */ 81 | 82 | 83 | typedef struct 84 | { 85 | int number; 86 | int port; 87 | } thread_arg; 88 | int thread_main(thread_arg*); 89 | 90 | void alarm_handler(int signum); 91 | void alarm_dummy(); 92 | 93 | 94 | int main( int argc, char *argv[] ) 95 | { 96 | int i, k, t_num, arg_offset, c; 97 | long j; 98 | float f; 99 | pthread_t *t; 100 | thread_arg *thd_arg; 101 | timer_t timer; 102 | struct itimerval itval; 103 | struct sigaction sigact; 104 | int port= 3306; 105 | int fd, seed; 106 | 107 | printf("***************************************\n"); 108 | printf("*** ###easy### TPC-C Load Generator ***\n"); 109 | printf("***************************************\n"); 110 | 111 | /* initialize */ 112 | hist_init(); 113 | activate_transaction = 1; 114 | counting_on = 0; 115 | 116 | for ( i=0; i<5; i++ ){ 117 | success[i]=0; 118 | late[i]=0; 119 | retry[i]=0; 120 | failure[i]=0; 121 | 122 | prev_s[i]=0; 123 | prev_l[i]=0; 124 | 125 | max_rt[i]=0.0; 126 | } 127 | 128 | /* dummy initialize*/ 129 | num_ware = 1; 130 | num_conn = 10; 131 | lampup_time = 10; 132 | measure_time = 20; 133 | strcpy( db_string, "tpcc" ); 134 | 135 | /* number of node (default 0) */ 136 | num_node = 0; 137 | arg_offset = 0; 138 | 139 | 140 | clk_tck = sysconf(_SC_CLK_TCK); 141 | 142 | /* Parse args */ 143 | 144 | while ( (c = getopt(argc, argv, "h:P:d:u:p:w:c:r:l:i:f:t:")) != -1) { 145 | switch (c) { 146 | case 'h': 147 | printf ("option h with value '%s'\n", optarg); 148 | strncpy(connect_string, optarg, DB_STRING_MAX); 149 | break; 150 | case 'd': 151 | printf ("option d with value '%s'\n", optarg); 152 | strncpy(db_string, optarg, DB_STRING_MAX); 153 | break; 154 | case 'u': 155 | printf ("option u with value '%s'\n", optarg); 156 | strncpy(db_user, optarg, DB_STRING_MAX); 157 | break; 158 | case 'p': 159 | printf ("option p with value '%s'\n", optarg); 160 | strncpy(db_password, optarg, DB_STRING_MAX); 161 | break; 162 | case 'f': 163 | printf ("option f with value '%s'\n", optarg); 164 | strncpy(report_file, optarg, DB_STRING_MAX); 165 | break; 166 | case 't': 167 | printf ("option t with value '%s'\n", optarg); 168 | strncpy(trx_file, optarg, DB_STRING_MAX); 169 | break; 170 | case 'w': 171 | printf ("option w with value '%s'\n", optarg); 172 | num_ware = atoi(optarg); 173 | break; 174 | case 'c': 175 | printf ("option c with value '%s'\n", optarg); 176 | num_conn = atoi(optarg); 177 | break; 178 | case 'r': 179 | printf ("option r with value '%s'\n", optarg); 180 | lampup_time = atoi(optarg); 181 | break; 182 | case 'l': 183 | printf ("option l with value '%s'\n", optarg); 184 | measure_time = atoi(optarg); 185 | break; 186 | case 'i': 187 | printf ("option i with value '%s'\n", optarg); 188 | PRINT_INTERVAL = atoi(optarg); 189 | break; 190 | case 'P': 191 | printf ("option P with value '%s'\n", optarg); 192 | port = atoi(optarg); 193 | break; 194 | case '?': 195 | printf("Usage: tpcc_start -h server_host -P port -d database_name -u mysql_user -p mysql_password -w warehouses -c connections -r warmup_time -l running_time -i report_interval -f report_file -t trx_file\n"); 196 | exit(0); 197 | default: 198 | printf ("?? getopt returned character code 0%o ??\n", c); 199 | } 200 | } 201 | if (optind < argc) { 202 | printf ("non-option ARGV-elements: "); 203 | while (optind < argc) 204 | printf ("%s ", argv[optind++]); 205 | printf ("\n"); 206 | } 207 | 208 | /* 209 | if ((num_node == 0)&&(argc == 14)) { 210 | valuable_flg = 1; 211 | } 212 | 213 | if ((num_node == 0)&&(valuable_flg == 0)&&(argc != 9)) { 214 | fprintf(stderr, "\n usage: tpcc_start [server] [DB] [user] [pass] [warehouse] [connection] [rampup] [measure]\n"); 215 | exit(1); 216 | } 217 | 218 | if ( strlen(argv[1]) >= DB_STRING_MAX ) { 219 | fprintf(stderr, "\n server phrase is too long\n"); 220 | exit(1); 221 | } 222 | if ( strlen(argv[2]) >= DB_STRING_MAX ) { 223 | fprintf(stderr, "\n DBname phrase is too long\n"); 224 | exit(1); 225 | } 226 | if ( strlen(argv[3]) >= DB_STRING_MAX ) { 227 | fprintf(stderr, "\n user phrase is too long\n"); 228 | exit(1); 229 | } 230 | if ( strlen(argv[4]) >= DB_STRING_MAX ) { 231 | fprintf(stderr, "\n pass phrase is too long\n"); 232 | exit(1); 233 | } 234 | if ((num_ware = atoi(argv[5 + arg_offset])) <= 0) { 235 | fprintf(stderr, "\n expecting positive number of warehouses\n"); 236 | exit(1); 237 | } 238 | if ((num_conn = atoi(argv[6 + arg_offset])) <= 0) { 239 | fprintf(stderr, "\n expecting positive number of connections\n"); 240 | exit(1); 241 | } 242 | if ((lampup_time = atoi(argv[7 + arg_offset])) < 0) { 243 | fprintf(stderr, "\n expecting positive number of lampup_time [sec]\n"); 244 | exit(1); 245 | } 246 | if ((measure_time = atoi(argv[8 + arg_offset])) < 0) { 247 | fprintf(stderr, "\n expecting positive number of measure_time [sec]\n"); 248 | exit(1); 249 | } 250 | 251 | if (parse_host_get_port(&port, argv[1]) < 0) { 252 | fprintf(stderr, "cannot prase the host: %s\n", argv[1]); 253 | exit(1); 254 | } 255 | strcpy( db_string, argv[2] ); 256 | strcpy( db_user, argv[3] ); 257 | strcpy( db_password, argv[4] ); 258 | */ 259 | 260 | if(strcmp(db_string,"l")==0){ 261 | is_local = 1; 262 | }else{ 263 | is_local = 0; 264 | } 265 | 266 | if(valuable_flg==1){ 267 | if( (atoi(argv[9 + arg_offset]) < 0)||(atoi(argv[10 + arg_offset]) < 0)||(atoi(argv[11 + arg_offset]) < 0) 268 | ||(atoi(argv[12 + arg_offset]) < 0)||(atoi(argv[13 + arg_offset]) < 0) ) { 269 | fprintf(stderr, "\n expecting positive number of ratio parameters\n"); 270 | exit(1); 271 | } 272 | } 273 | 274 | if( num_node > 0 ){ 275 | if( num_ware % num_node != 0 ){ 276 | fprintf(stderr, "\n [warehouse] value must be devided by [num_node].\n"); 277 | exit(1); 278 | } 279 | if( num_conn % num_node != 0 ){ 280 | fprintf(stderr, "\n [connection] value must be devided by [num_node].\n"); 281 | exit(1); 282 | } 283 | } 284 | 285 | if ( strlen(report_file) > 0 ) { 286 | freport_file=fopen(report_file,"w+"); 287 | } 288 | 289 | if ( strlen(trx_file) > 0 ) { 290 | ftrx_file=fopen(trx_file,"w+"); 291 | } 292 | 293 | 294 | printf("\n"); 295 | if(is_local==0) { 296 | printf(" [server]: "); 297 | printf("%s", connect_string); 298 | printf("\n"); 299 | } 300 | if(is_local==0)printf(" [port]: %d\n", port); 301 | printf(" [DBname]: %s\n", db_string); 302 | printf(" [user]: %s\n", db_user); 303 | printf(" [pass]: %s\n", db_password); 304 | 305 | printf(" [warehouse]: %d\n", num_ware); 306 | printf(" [connection]: %d\n", num_conn); 307 | printf(" [rampup]: %d (sec.)\n", lampup_time); 308 | printf(" [measure]: %d (sec.)\n", measure_time); 309 | 310 | if(valuable_flg==1){ 311 | printf(" [ratio]: %d:%d:%d:%d:%d\n", atoi(argv[9 + arg_offset]), atoi(argv[10 + arg_offset]), 312 | atoi(argv[11 + arg_offset]), atoi(argv[12 + arg_offset]), atoi(argv[13 + arg_offset]) ); 313 | } 314 | 315 | /* alarm initialize */ 316 | time_count = 0; 317 | itval.it_interval.tv_sec = PRINT_INTERVAL; 318 | itval.it_interval.tv_usec = 0; 319 | itval.it_value.tv_sec = PRINT_INTERVAL; 320 | itval.it_value.tv_usec = 0; 321 | sigact.sa_handler = alarm_handler; 322 | sigact.sa_flags = 0; 323 | sigemptyset(&sigact.sa_mask); 324 | 325 | /* setup handler&timer */ 326 | if( sigaction( SIGALRM, &sigact, NULL ) == -1 ) { 327 | fprintf(stderr, "error in sigaction()\n"); 328 | exit(1); 329 | } 330 | 331 | fd = open("/dev/urandom", O_RDONLY); 332 | if (fd == -1) { 333 | fd = open("/dev/random", O_RDONLY); 334 | if (fd == -1) { 335 | struct timeval tv; 336 | gettimeofday(&tv, NULL); 337 | seed = (tv.tv_sec ^ tv.tv_usec) * tv.tv_sec * tv.tv_usec ^ tv.tv_sec; 338 | }else{ 339 | read(fd, &seed, sizeof(seed)); 340 | close(fd); 341 | } 342 | }else{ 343 | read(fd, &seed, sizeof(seed)); 344 | close(fd); 345 | } 346 | SetSeed(seed); 347 | 348 | if(valuable_flg==0){ 349 | seq_init(10,10,1,1,1); /* normal ratio */ 350 | }else{ 351 | seq_init( atoi(argv[9 + arg_offset]), atoi(argv[10 + arg_offset]), atoi(argv[11 + arg_offset]), 352 | atoi(argv[12 + arg_offset]), atoi(argv[13 + arg_offset]) ); 353 | } 354 | 355 | /* set up each counter */ 356 | for ( i=0; i<5; i++ ){ 357 | success2[i] = malloc( sizeof(int) * num_conn ); 358 | late2[i] = malloc( sizeof(int) * num_conn ); 359 | retry2[i] = malloc( sizeof(int) * num_conn ); 360 | failure2[i] = malloc( sizeof(int) * num_conn ); 361 | for ( k=0; k\n"); 472 | for ( i=0; i<5; i++ ){ 473 | printf(" [%d] sc:%d lt:%d rt:%d fl:%d \n", i, success[i], late[i], retry[i], failure[i]); 474 | } 475 | printf(" in %d sec.\n", (measure_time / PRINT_INTERVAL) * PRINT_INTERVAL); 476 | 477 | printf("\n\n"); 478 | for( i=0; i<5; i++ ){ 479 | success2_sum[i] = 0; 480 | late2_sum[i] = 0; 481 | retry2_sum[i] = 0; 482 | failure2_sum[i] = 0; 483 | for( k=0; k (all must be [OK])\n [transaction percentage]\n"); 495 | for ( i=0, j=0; i<5; i++ ){ 496 | j += (success[i] + late[i]); 497 | } 498 | 499 | f = 100.0 * (float)(success[1] + late[1])/(float)j; 500 | printf(" Payment: %3.2f%% (>=43.0%%)",f); 501 | if ( f >= 43.0 ){ 502 | printf(" [OK]\n"); 503 | }else{ 504 | printf(" [NG] *\n"); 505 | } 506 | f = 100.0 * (float)(success[2] + late[2])/(float)j; 507 | printf(" Order-Status: %3.2f%% (>= 4.0%%)",f); 508 | if ( f >= 4.0 ){ 509 | printf(" [OK]\n"); 510 | }else{ 511 | printf(" [NG] *\n"); 512 | } 513 | f = 100.0 * (float)(success[3] + late[3])/(float)j; 514 | printf(" Delivery: %3.2f%% (>= 4.0%%)",f); 515 | if ( f >= 4.0 ){ 516 | printf(" [OK]\n"); 517 | }else{ 518 | printf(" [NG] *\n"); 519 | } 520 | f = 100.0 * (float)(success[4] + late[4])/(float)j; 521 | printf(" Stock-Level: %3.2f%% (>= 4.0%%)",f); 522 | if ( f >= 4.0 ){ 523 | printf(" [OK]\n"); 524 | }else{ 525 | printf(" [NG] *\n"); 526 | } 527 | 528 | printf(" [response time (at least 90%% passed)]\n"); 529 | f = 100.0 * (float)success[0]/(float)(success[0] + late[0]); 530 | printf(" New-Order: %3.2f%% ",f); 531 | if ( f >= 90.0 ){ 532 | printf(" [OK]\n"); 533 | }else{ 534 | printf(" [NG] *\n"); 535 | } 536 | f = 100.0 * (float)success[1]/(float)(success[1] + late[1]); 537 | printf(" Payment: %3.2f%% ",f); 538 | if ( f >= 90.0 ){ 539 | printf(" [OK]\n"); 540 | }else{ 541 | printf(" [NG] *\n"); 542 | } 543 | f = 100.0 * (float)success[2]/(float)(success[2] + late[2]); 544 | printf(" Order-Status: %3.2f%% ",f); 545 | if ( f >= 90.0 ){ 546 | printf(" [OK]\n"); 547 | }else{ 548 | printf(" [NG] *\n"); 549 | } 550 | f = 100.0 * (float)success[3]/(float)(success[3] + late[3]); 551 | printf(" Delivery: %3.2f%% ",f); 552 | if ( f >= 90.0 ){ 553 | printf(" [OK]\n"); 554 | }else{ 555 | printf(" [NG] *\n"); 556 | } 557 | f = 100.0 * (float)success[4]/(float)(success[4] + late[4]); 558 | printf(" Stock-Level: %3.2f%% ",f); 559 | if ( f >= 90.0 ){ 560 | printf(" [OK]\n"); 561 | }else{ 562 | printf(" [NG] *\n"); 563 | } 564 | 565 | printf("\n\n"); 566 | f = (float)(success[0] + late[0]) * 60.0 567 | / (float)((measure_time / PRINT_INTERVAL) * PRINT_INTERVAL); 568 | printf(" %.3f TpmC\n",f); 569 | exit(0); 570 | 571 | sqlerr: 572 | fprintf(stdout, "error at main\n"); 573 | error(ctx[i],0); 574 | exit(1); 575 | 576 | } 577 | 578 | 579 | void alarm_handler(int signum) 580 | { 581 | int i; 582 | int s[5],l[5]; 583 | double rt90[5]; 584 | 585 | for( i=0; i<5; i++ ){ 586 | s[i] = success[i]; 587 | l[i] = late[i]; 588 | rt90[i] = hist_ckp(i); 589 | } 590 | 591 | time_count += PRINT_INTERVAL; 592 | printf("%4d, %d(%d):%.3f|%.3f, %d(%d):%.3f|%.3f, %d(%d):%.3f|%.3f, %d(%d):%.3f|%.3f, %d(%d):%.3f|%.3f\n", 593 | time_count, 594 | ( s[0] + l[0] - prev_s[0] - prev_l[0] ), 595 | ( l[0] - prev_l[0] ), 596 | rt90[0],(double)cur_max_rt[0], 597 | ( s[1] + l[1] - prev_s[1] - prev_l[1] ), 598 | ( l[1] - prev_l[1] ), 599 | rt90[1],(double)cur_max_rt[1], 600 | ( s[2] + l[2] - prev_s[2] - prev_l[2] ), 601 | ( l[2] - prev_l[2] ), 602 | rt90[2],(double)cur_max_rt[2], 603 | ( s[3] + l[3] - prev_s[3] - prev_l[3] ), 604 | ( l[3] - prev_l[3] ), 605 | rt90[3],(double)cur_max_rt[3], 606 | ( s[4] + l[4] - prev_s[4] - prev_l[4] ), 607 | ( l[4] - prev_l[4] ), 608 | rt90[4],(double)cur_max_rt[4] 609 | ); 610 | fflush(stdout); 611 | 612 | for( i=0; i<5; i++ ){ 613 | prev_s[i] = s[i]; 614 | prev_l[i] = l[i]; 615 | cur_max_rt[i]=0.0; 616 | } 617 | } 618 | 619 | void alarm_dummy() 620 | { 621 | int i; 622 | int s[5],l[5]; 623 | float rt90[5]; 624 | 625 | for( i=0; i<5; i++ ){ 626 | s[i] = success[i]; 627 | l[i] = late[i]; 628 | rt90[i] = hist_ckp(i); 629 | } 630 | 631 | time_count += PRINT_INTERVAL; 632 | printf("%4d, %d(%d):%.2f, %d(%d):%.2f, %d(%d):%.2f, %d(%d):%.2f, %d(%d):%.2f\n", 633 | time_count, 634 | ( s[0] + l[0] - prev_s[0] - prev_l[0] ), 635 | ( l[0] - prev_l[0] ), 636 | rt90[0], 637 | ( s[1] + l[1] - prev_s[1] - prev_l[1] ), 638 | ( l[1] - prev_l[1] ), 639 | rt90[1], 640 | ( s[2] + l[2] - prev_s[2] - prev_l[2] ), 641 | ( l[2] - prev_l[2] ), 642 | rt90[2], 643 | ( s[3] + l[3] - prev_s[3] - prev_l[3] ), 644 | ( l[3] - prev_l[3] ), 645 | rt90[3], 646 | ( s[4] + l[4] - prev_s[4] - prev_l[4] ), 647 | ( l[4] - prev_l[4] ), 648 | rt90[4] 649 | ); 650 | fflush(stdout); 651 | 652 | for( i=0; i<5; i++ ){ 653 | prev_s[i] = s[i]; 654 | prev_l[i] = l[i]; 655 | } 656 | } 657 | 658 | int thread_main (thread_arg* arg) 659 | { 660 | int t_num= arg->number; 661 | int port= arg->port; 662 | int r,i; 663 | 664 | char *db_string_ptr; 665 | MYSQL* resp; 666 | 667 | db_string_ptr = db_string; 668 | 669 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 670 | 671 | if(num_node > 0){ /* RAC mode */ 672 | db_string_ptr = node_string[((num_node * t_num)/num_conn)]; 673 | } 674 | 675 | if(is_local==1){ 676 | /* exec sql connect :connect_string; */ 677 | resp = mysql_real_connect(ctx[t_num], "localhost", db_user, db_password, db_string, port, NULL, 0); 678 | }else{ 679 | /* exec sql connect :connect_string USING :db_string; */ 680 | resp = mysql_real_connect(ctx[t_num], connect_string, db_user, db_password, db_string, port, NULL, 0); 681 | } 682 | 683 | if(resp) { 684 | mysql_autocommit(ctx[t_num], 0); 685 | } else { 686 | mysql_close(ctx[t_num]); 687 | goto sqlerr; 688 | } 689 | 690 | for(i=0;i<40;i++){ 691 | stmt[t_num][i] = mysql_stmt_init(ctx[t_num]); 692 | if(!stmt[t_num][i]) goto sqlerr; 693 | } 694 | 695 | /* Prepare ALL of SQLs */ 696 | 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; 697 | 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; 698 | 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; 699 | 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; 700 | 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; 701 | if( mysql_stmt_prepare(stmt[t_num][5], "SELECT i_price, i_name, i_data FROM item WHERE i_id = ?", 55) ) goto sqlerr; 702 | 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; 703 | if( mysql_stmt_prepare(stmt[t_num][7], "UPDATE stock SET s_quantity = ? WHERE s_i_id = ? AND s_w_id = ?", 63) ) goto sqlerr; 704 | 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; 705 | if( mysql_stmt_prepare(stmt[t_num][9], "UPDATE warehouse SET w_ytd = w_ytd + ? WHERE w_id = ?", 53) ) goto sqlerr; 706 | 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; 707 | 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; 708 | 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; 709 | 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; 710 | 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; 711 | 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; 712 | 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; 713 | 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; 714 | 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; 715 | 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; 716 | 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; 717 | 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; 718 | 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; 719 | 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; 720 | 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; 721 | 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; 722 | 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; 723 | 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; 724 | 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; 725 | 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; 726 | 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; 727 | 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; 728 | 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; 729 | 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; 730 | 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; 731 | 732 | r = driver(t_num); 733 | 734 | /* EXEC SQL COMMIT WORK; */ 735 | if( mysql_commit(ctx[t_num]) ) goto sqlerr; 736 | 737 | for(i=0;i<40;i++){ 738 | mysql_stmt_free_result(stmt[t_num][i]); 739 | mysql_stmt_close(stmt[t_num][i]); 740 | } 741 | 742 | /* EXEC SQL DISCONNECT; */ 743 | mysql_close(ctx[t_num]); 744 | 745 | printf("."); 746 | fflush(stdout); 747 | 748 | return(r); 749 | 750 | sqlerr: 751 | fprintf(stdout, "error at thread_main\n"); 752 | error(ctx[t_num],0); 753 | return(0); 754 | 755 | } 756 | -------------------------------------------------------------------------------- /src/neword.c: -------------------------------------------------------------------------------- 1 | /* 2 | * -*-C-*- 3 | * neword.pc 4 | * corresponds to A.1 in appendix A 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "spt_proc.h" 14 | #include "tpc.h" 15 | 16 | #define pick_dist_info(ol_dist_info,ol_supply_w_id) \ 17 | switch(ol_supply_w_id) { \ 18 | case 1: strncpy(ol_dist_info, s_dist_01, 25); break; \ 19 | case 2: strncpy(ol_dist_info, s_dist_02, 25); break; \ 20 | case 3: strncpy(ol_dist_info, s_dist_03, 25); break; \ 21 | case 4: strncpy(ol_dist_info, s_dist_04, 25); break; \ 22 | case 5: strncpy(ol_dist_info, s_dist_05, 25); break; \ 23 | case 6: strncpy(ol_dist_info, s_dist_06, 25); break; \ 24 | case 7: strncpy(ol_dist_info, s_dist_07, 25); break; \ 25 | case 8: strncpy(ol_dist_info, s_dist_08, 25); break; \ 26 | case 9: strncpy(ol_dist_info, s_dist_09, 25); break; \ 27 | case 10: strncpy(ol_dist_info, s_dist_10, 25); break; \ 28 | } 29 | 30 | extern MYSQL **ctx; 31 | extern MYSQL_STMT ***stmt; 32 | 33 | extern FILE *ftrx_file; 34 | 35 | #define NNULL ((void *)0) 36 | 37 | /* 38 | * the new order transaction 39 | */ 40 | int neword( int t_num, 41 | int w_id_arg, /* warehouse id */ 42 | int d_id_arg, /* district id */ 43 | int c_id_arg, /* customer id */ 44 | int o_ol_cnt_arg, /* number of items */ 45 | int o_all_local_arg, /* are all order lines local */ 46 | int itemid[], /* ids of items to be ordered */ 47 | int supware[], /* warehouses supplying items */ 48 | int qty[] /* quantity of each item */ 49 | ) 50 | { 51 | 52 | int w_id = w_id_arg; 53 | int d_id = d_id_arg; 54 | int c_id = c_id_arg; 55 | int o_ol_cnt = o_ol_cnt_arg; 56 | int o_all_local = o_all_local_arg; 57 | float c_discount; 58 | char c_last[17]; 59 | char c_credit[3]; 60 | float w_tax; 61 | int d_next_o_id; 62 | float d_tax; 63 | char datetime[81]; 64 | int o_id; 65 | char i_name[25]; 66 | float i_price; 67 | char i_data[51]; 68 | int ol_i_id; 69 | int s_quantity; 70 | char s_data[51]; 71 | char s_dist_01[25]; 72 | char s_dist_02[25]; 73 | char s_dist_03[25]; 74 | char s_dist_04[25]; 75 | char s_dist_05[25]; 76 | char s_dist_06[25]; 77 | char s_dist_07[25]; 78 | char s_dist_08[25]; 79 | char s_dist_09[25]; 80 | char s_dist_10[25]; 81 | char ol_dist_info[25]; 82 | int ol_supply_w_id; 83 | float ol_amount; 84 | int ol_number; 85 | int ol_quantity; 86 | 87 | char iname[MAX_NUM_ITEMS][MAX_ITEM_LEN]; 88 | char bg[MAX_NUM_ITEMS]; 89 | float amt[MAX_NUM_ITEMS]; 90 | float price[MAX_NUM_ITEMS]; 91 | int stock[MAX_NUM_ITEMS]; 92 | float total = 0.0; 93 | 94 | int min_num; 95 | int i,j,tmp,swp; 96 | int ol_num_seq[MAX_NUM_ITEMS]; 97 | 98 | int proceed = 0; 99 | struct timespec tbuf1,tbuf_start; 100 | clock_t clk1,clk_start; 101 | 102 | 103 | MYSQL_STMT* mysql_stmt; 104 | MYSQL_BIND param[9]; 105 | MYSQL_BIND column[12]; 106 | 107 | /* EXEC SQL WHENEVER NOT FOUND GOTO sqlerr;*/ 108 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 109 | 110 | /*EXEC SQL CONTEXT USE :ctx[t_num];*/ 111 | 112 | gettimestamp(datetime, STRFTIME_FORMAT, TIMESTAMP_LEN); 113 | clk_start = clock_gettime(CLOCK_REALTIME, &tbuf_start ); 114 | 115 | proceed = 1; 116 | /*EXEC_SQL SELECT c_discount, c_last, c_credit, w_tax 117 | INTO :c_discount, :c_last, :c_credit, :w_tax 118 | FROM customer, warehouse 119 | WHERE w_id = :w_id 120 | AND c_w_id = w_id 121 | AND c_d_id = :d_id 122 | AND c_id = :c_id;*/ 123 | mysql_stmt = stmt[t_num][0]; 124 | 125 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 126 | param[0].buffer_type = MYSQL_TYPE_LONG; 127 | param[0].buffer = &w_id; 128 | param[1].buffer_type = MYSQL_TYPE_LONG; 129 | param[1].buffer = &d_id; 130 | param[2].buffer_type = MYSQL_TYPE_LONG; 131 | param[2].buffer = &c_id; 132 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 133 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 134 | 135 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 136 | memset(column, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 137 | column[0].buffer_type = MYSQL_TYPE_FLOAT; 138 | column[0].buffer = &c_discount; 139 | column[1].buffer_type = MYSQL_TYPE_STRING; 140 | column[1].buffer = c_last; 141 | column[1].buffer_length = sizeof(c_last); 142 | column[2].buffer_type = MYSQL_TYPE_STRING; 143 | column[2].buffer = c_credit; 144 | column[2].buffer_length = sizeof(c_credit); 145 | column[3].buffer_type = MYSQL_TYPE_FLOAT; 146 | column[3].buffer = &w_tax; 147 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 148 | switch( mysql_stmt_fetch(mysql_stmt) ) { 149 | case 0: //SUCCESS 150 | case MYSQL_DATA_TRUNCATED: 151 | break; 152 | case 1: //ERROR 153 | case MYSQL_NO_DATA: //NO MORE DATA 154 | default: 155 | mysql_stmt_free_result(mysql_stmt); 156 | goto sqlerr; 157 | } 158 | mysql_stmt_free_result(mysql_stmt); 159 | 160 | 161 | #ifdef DEBUG 162 | printf("n %d\n",proceed); 163 | #endif 164 | 165 | proceed = 2; 166 | /*EXEC_SQL SELECT d_next_o_id, d_tax INTO :d_next_o_id, :d_tax 167 | FROM district 168 | WHERE d_id = :d_id 169 | AND d_w_id = :w_id 170 | FOR UPDATE;*/ 171 | mysql_stmt = stmt[t_num][1]; 172 | 173 | memset(param, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 174 | param[0].buffer_type = MYSQL_TYPE_LONG; 175 | param[0].buffer = &d_id; 176 | param[1].buffer_type = MYSQL_TYPE_LONG; 177 | param[1].buffer = &w_id; 178 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 179 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 180 | 181 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 182 | memset(column, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 183 | column[0].buffer_type = MYSQL_TYPE_LONG; 184 | column[0].buffer = &d_next_o_id; 185 | column[1].buffer_type = MYSQL_TYPE_FLOAT; 186 | column[1].buffer = &d_tax; 187 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 188 | switch( mysql_stmt_fetch(mysql_stmt) ) { 189 | case 0: //SUCCESS 190 | case MYSQL_DATA_TRUNCATED: 191 | break; 192 | case 1: //ERROR 193 | case MYSQL_NO_DATA: //NO MORE DATA 194 | default: 195 | mysql_stmt_free_result(mysql_stmt); 196 | goto sqlerr; 197 | } 198 | mysql_stmt_free_result(mysql_stmt); 199 | 200 | 201 | proceed = 3; 202 | /*EXEC_SQL UPDATE district SET d_next_o_id = :d_next_o_id + 1 203 | WHERE d_id = :d_id 204 | AND d_w_id = :w_id;*/ 205 | mysql_stmt = stmt[t_num][2]; 206 | 207 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 208 | param[0].buffer_type = MYSQL_TYPE_LONG; 209 | param[0].buffer = &d_next_o_id; 210 | param[1].buffer_type = MYSQL_TYPE_LONG; 211 | param[1].buffer = &d_id; 212 | param[2].buffer_type = MYSQL_TYPE_LONG; 213 | param[2].buffer = &w_id; 214 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 215 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 216 | 217 | o_id = d_next_o_id; 218 | 219 | #ifdef DEBUG 220 | printf("n %d\n",proceed); 221 | #endif 222 | 223 | proceed = 4; 224 | /*EXEC_SQL INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, 225 | o_entry_d, o_ol_cnt, o_all_local) 226 | VALUES(:o_id, :d_id, :w_id, :c_id, 227 | :datetime, 228 | :o_ol_cnt, :o_all_local);*/ 229 | mysql_stmt = stmt[t_num][3]; 230 | 231 | memset(param, 0, sizeof(MYSQL_BIND) * 7); /* initialize */ 232 | param[0].buffer_type = MYSQL_TYPE_LONG; 233 | param[0].buffer = &o_id; 234 | param[1].buffer_type = MYSQL_TYPE_LONG; 235 | param[1].buffer = &d_id; 236 | param[2].buffer_type = MYSQL_TYPE_LONG; 237 | param[2].buffer = &w_id; 238 | param[3].buffer_type = MYSQL_TYPE_LONG; 239 | param[3].buffer = &c_id; 240 | param[4].buffer_type = MYSQL_TYPE_STRING; 241 | param[4].buffer = datetime; 242 | param[4].buffer_length = strlen(datetime); 243 | param[5].buffer_type = MYSQL_TYPE_LONG; 244 | param[5].buffer = &o_ol_cnt; 245 | param[6].buffer_type = MYSQL_TYPE_LONG; 246 | param[6].buffer = &o_all_local; 247 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 248 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 249 | 250 | 251 | #ifdef DEBUG 252 | printf("n %d\n",proceed); 253 | #endif 254 | 255 | proceed = 5; 256 | /* EXEC_SQL INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) 257 | VALUES (:o_id,:d_id,:w_id); */ 258 | mysql_stmt = stmt[t_num][4]; 259 | 260 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 261 | param[0].buffer_type = MYSQL_TYPE_LONG; 262 | param[0].buffer = &o_id; 263 | param[1].buffer_type = MYSQL_TYPE_LONG; 264 | param[1].buffer = &d_id; 265 | param[2].buffer_type = MYSQL_TYPE_LONG; 266 | param[2].buffer = &w_id; 267 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 268 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 269 | 270 | /* sort orders to avoid DeadLock */ 271 | for (i = 0; i < o_ol_cnt; i++) { 272 | ol_num_seq[i]=i; 273 | } 274 | for (i = 0; i < (o_ol_cnt - 1); i++) { 275 | tmp = (MAXITEMS + 1) * supware[ol_num_seq[i]] + itemid[ol_num_seq[i]]; 276 | min_num = i; 277 | for ( j = i+1; j < o_ol_cnt; j++) { 278 | if ( (MAXITEMS + 1) * supware[ol_num_seq[j]] + itemid[ol_num_seq[j]] < tmp ){ 279 | tmp = (MAXITEMS + 1) * supware[ol_num_seq[j]] + itemid[ol_num_seq[j]]; 280 | min_num = j; 281 | } 282 | } 283 | if ( min_num != i ){ 284 | swp = ol_num_seq[min_num]; 285 | ol_num_seq[min_num] = ol_num_seq[i]; 286 | ol_num_seq[i] = swp; 287 | } 288 | } 289 | 290 | 291 | for (ol_number = 1; ol_number <= o_ol_cnt; ol_number++) { 292 | ol_supply_w_id = supware[ol_num_seq[ol_number - 1]]; 293 | ol_i_id = itemid[ol_num_seq[ol_number - 1]]; 294 | ol_quantity = qty[ol_num_seq[ol_number - 1]]; 295 | 296 | /* EXEC SQL WHENEVER NOT FOUND GOTO invaliditem; */ 297 | proceed = 6; 298 | /*EXEC_SQL SELECT i_price, i_name, i_data 299 | INTO :i_price, :i_name, :i_data 300 | FROM item 301 | WHERE i_id = :ol_i_id;*/ 302 | mysql_stmt = stmt[t_num][5]; 303 | 304 | memset(param, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 305 | param[0].buffer_type = MYSQL_TYPE_LONG; 306 | param[0].buffer = &ol_i_id; 307 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 308 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 309 | 310 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 311 | memset(column, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 312 | column[0].buffer_type = MYSQL_TYPE_FLOAT; 313 | column[0].buffer = &i_price; 314 | column[1].buffer_type = MYSQL_TYPE_STRING; 315 | column[1].buffer = i_name; 316 | column[1].buffer_length = sizeof(i_name); 317 | column[2].buffer_type = MYSQL_TYPE_STRING; 318 | column[2].buffer = i_data; 319 | column[2].buffer_length = sizeof(i_data); 320 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 321 | switch( mysql_stmt_fetch(mysql_stmt) ) { 322 | case 0: //SUCCESS 323 | case MYSQL_DATA_TRUNCATED: 324 | break; 325 | 326 | case MYSQL_NO_DATA: //NO MORE DATA 327 | mysql_stmt_free_result(mysql_stmt); 328 | goto invaliditem; 329 | 330 | case 1: //ERROR 331 | default: 332 | mysql_stmt_free_result(mysql_stmt); 333 | goto sqlerr; 334 | } 335 | mysql_stmt_free_result(mysql_stmt); 336 | 337 | 338 | price[ol_num_seq[ol_number - 1]] = i_price; 339 | strncpy(iname[ol_num_seq[ol_number - 1]], i_name, 25); 340 | 341 | /* EXEC SQL WHENEVER NOT FOUND GOTO sqlerr; */ 342 | 343 | #ifdef DEBUG 344 | printf("n %d\n",proceed); 345 | #endif 346 | 347 | proceed = 7; 348 | /*EXEC_SQL SELECT s_quantity, s_data, s_dist_01, s_dist_02, 349 | s_dist_03, s_dist_04, s_dist_05, s_dist_06, 350 | s_dist_07, s_dist_08, s_dist_09, s_dist_10 351 | INTO :s_quantity, :s_data, :s_dist_01, :s_dist_02, 352 | :s_dist_03, :s_dist_04, :s_dist_05, :s_dist_06, 353 | :s_dist_07, :s_dist_08, :s_dist_09, :s_dist_10 354 | FROM stock 355 | WHERE s_i_id = :ol_i_id 356 | AND s_w_id = :ol_supply_w_id 357 | FOR UPDATE;*/ 358 | mysql_stmt = stmt[t_num][6]; 359 | 360 | memset(param, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 361 | param[0].buffer_type = MYSQL_TYPE_LONG; 362 | param[0].buffer = &ol_i_id; 363 | param[1].buffer_type = MYSQL_TYPE_LONG; 364 | param[1].buffer = &ol_supply_w_id; 365 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 366 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 367 | 368 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 369 | memset(column, 0, sizeof(MYSQL_BIND) * 12); /* initialize */ 370 | column[0].buffer_type = MYSQL_TYPE_LONG; 371 | column[0].buffer = &s_quantity; 372 | column[1].buffer_type = MYSQL_TYPE_STRING; 373 | column[1].buffer = s_data; 374 | column[1].buffer_length = sizeof(s_data); 375 | column[2].buffer_type = MYSQL_TYPE_STRING; 376 | column[2].buffer = s_dist_01; 377 | column[2].buffer_length = sizeof(s_dist_01); 378 | column[3].buffer_type = MYSQL_TYPE_STRING; 379 | column[3].buffer = s_dist_02; 380 | column[3].buffer_length = sizeof(s_dist_02); 381 | column[4].buffer_type = MYSQL_TYPE_STRING; 382 | column[4].buffer = s_dist_03; 383 | column[4].buffer_length = sizeof(s_dist_03); 384 | column[5].buffer_type = MYSQL_TYPE_STRING; 385 | column[5].buffer = s_dist_04; 386 | column[5].buffer_length = sizeof(s_dist_04); 387 | column[6].buffer_type = MYSQL_TYPE_STRING; 388 | column[6].buffer = s_dist_05; 389 | column[6].buffer_length = sizeof(s_dist_05); 390 | column[7].buffer_type = MYSQL_TYPE_STRING; 391 | column[7].buffer = s_dist_06; 392 | column[7].buffer_length = sizeof(s_dist_06); 393 | column[8].buffer_type = MYSQL_TYPE_STRING; 394 | column[8].buffer = s_dist_07; 395 | column[8].buffer_length = sizeof(s_dist_07); 396 | column[9].buffer_type = MYSQL_TYPE_STRING; 397 | column[9].buffer = s_dist_08; 398 | column[9].buffer_length = sizeof(s_dist_08); 399 | column[10].buffer_type = MYSQL_TYPE_STRING; 400 | column[10].buffer = s_dist_09; 401 | column[10].buffer_length = sizeof(s_dist_09); 402 | column[11].buffer_type = MYSQL_TYPE_STRING; 403 | column[11].buffer = s_dist_10; 404 | column[11].buffer_length = sizeof(s_dist_10); 405 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 406 | switch( mysql_stmt_fetch(mysql_stmt) ) { 407 | case 0: //SUCCESS 408 | break; 409 | case 1: //ERROR 410 | case MYSQL_NO_DATA: //NO MORE DATA 411 | default: 412 | mysql_stmt_free_result(mysql_stmt); 413 | goto sqlerr; 414 | } 415 | mysql_stmt_free_result(mysql_stmt); 416 | 417 | 418 | pick_dist_info(ol_dist_info, d_id); /* pick correct 419 | * s_dist_xx */ 420 | 421 | stock[ol_num_seq[ol_number - 1]] = s_quantity; 422 | 423 | if ((strstr(i_data, "original") != NULL) && 424 | (strstr(s_data, "original") != NULL)) 425 | bg[ol_num_seq[ol_number - 1]] = 'B'; 426 | else 427 | bg[ol_num_seq[ol_number - 1]] = 'G'; 428 | 429 | if (s_quantity > ol_quantity) 430 | s_quantity = s_quantity - ol_quantity; 431 | else 432 | s_quantity = s_quantity - ol_quantity + 91; 433 | 434 | #ifdef DEBUG 435 | printf("n %d\n",proceed); 436 | #endif 437 | 438 | proceed = 8; 439 | /*EXEC_SQL UPDATE stock SET s_quantity = :s_quantity 440 | WHERE s_i_id = :ol_i_id 441 | AND s_w_id = :ol_supply_w_id;*/ 442 | mysql_stmt = stmt[t_num][7]; 443 | 444 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 445 | param[0].buffer_type = MYSQL_TYPE_LONG; 446 | param[0].buffer = &s_quantity; 447 | param[1].buffer_type = MYSQL_TYPE_LONG; 448 | param[1].buffer = &ol_i_id; 449 | param[2].buffer_type = MYSQL_TYPE_LONG; 450 | param[2].buffer = &ol_supply_w_id; 451 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 452 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 453 | 454 | 455 | ol_amount = ol_quantity * i_price * (1 + w_tax + d_tax) * (1 - c_discount); 456 | amt[ol_num_seq[ol_number - 1]] = ol_amount; 457 | total += ol_amount; 458 | 459 | #ifdef DEBUG 460 | printf("n %d\n",proceed); 461 | #endif 462 | 463 | proceed = 9; 464 | /*EXEC_SQL INSERT INTO order_line (ol_o_id, ol_d_id, ol_w_id, 465 | ol_number, ol_i_id, 466 | ol_supply_w_id, ol_quantity, 467 | ol_amount, ol_dist_info) 468 | VALUES (:o_id, :d_id, :w_id, :ol_number, :ol_i_id, 469 | :ol_supply_w_id, :ol_quantity, :ol_amount, 470 | :ol_dist_info);*/ 471 | mysql_stmt = stmt[t_num][8]; 472 | 473 | memset(param, 0, sizeof(MYSQL_BIND) * 9); /* initialize */ 474 | param[0].buffer_type = MYSQL_TYPE_LONG; 475 | param[0].buffer = &o_id; 476 | param[1].buffer_type = MYSQL_TYPE_LONG; 477 | param[1].buffer = &d_id; 478 | param[2].buffer_type = MYSQL_TYPE_LONG; 479 | param[2].buffer = &w_id; 480 | param[3].buffer_type = MYSQL_TYPE_LONG; 481 | param[3].buffer = &ol_number; 482 | param[4].buffer_type = MYSQL_TYPE_LONG; 483 | param[4].buffer = &ol_i_id; 484 | param[5].buffer_type = MYSQL_TYPE_LONG; 485 | param[5].buffer = &ol_supply_w_id; 486 | param[6].buffer_type = MYSQL_TYPE_LONG; 487 | param[6].buffer = &ol_quantity; 488 | param[7].buffer_type = MYSQL_TYPE_FLOAT; 489 | param[7].buffer = &ol_amount; 490 | param[8].buffer_type = MYSQL_TYPE_STRING; 491 | param[8].buffer = ol_dist_info; 492 | param[8].buffer_length = strlen(ol_dist_info); 493 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 494 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 495 | 496 | 497 | } /* End Order Lines */ 498 | 499 | #ifdef DEBUG 500 | printf("insert 3\n"); 501 | fflush(stdout); 502 | #endif 503 | 504 | /*EXEC_SQL COMMIT WORK;*/ 505 | if( mysql_commit(ctx[t_num]) ) goto sqlerr; 506 | clk1 = clock_gettime(CLOCK_REALTIME, &tbuf1 ); 507 | if (ftrx_file) { 508 | fprintf(ftrx_file,"t_num: %d finish: %lu %lu start: %lu %lu\n",t_num, tbuf1.tv_sec, tbuf1.tv_nsec, 509 | tbuf_start.tv_sec, tbuf_start.tv_nsec); 510 | } 511 | 512 | return (1); 513 | 514 | invaliditem: 515 | /*EXEC_SQL ROLLBACK WORK;*/ 516 | mysql_rollback(ctx[t_num]); 517 | 518 | /* printf("Item number is not valid\n"); */ 519 | return (1); /* OK? */ 520 | 521 | sqlerr: 522 | fprintf(stderr,"neword %d:%d\n",t_num,proceed); 523 | error(ctx[t_num],mysql_stmt); 524 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerrerr;*/ 525 | /*EXEC_SQL ROLLBACK WORK;*/ 526 | mysql_rollback(ctx[t_num]); 527 | sqlerrerr: 528 | return (0); 529 | } 530 | 531 | -------------------------------------------------------------------------------- /src/ordstat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * -*-C-*- 3 | * ordstat.pc 4 | * corresponds to A.3 in appendix A 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "spt_proc.h" 13 | #include "tpc.h" 14 | 15 | extern MYSQL **ctx; 16 | extern MYSQL_STMT ***stmt; 17 | 18 | /* 19 | * the order status transaction 20 | */ 21 | int ordstat( int t_num, 22 | int w_id_arg, /* warehouse id */ 23 | int d_id_arg, /* district id */ 24 | int byname, /* select by c_id or c_last? */ 25 | int c_id_arg, /* customer id */ 26 | char c_last_arg[] /* customer last name, format? */ 27 | ) 28 | { 29 | int w_id = w_id_arg; 30 | int d_id = d_id_arg; 31 | int c_id = c_id_arg; 32 | int c_d_id = d_id; 33 | int c_w_id = w_id; 34 | char c_first[17]; 35 | char c_middle[3]; 36 | char c_last[17]; 37 | float c_balance; 38 | int o_id; 39 | char o_entry_d[25]; 40 | int o_carrier_id; 41 | int ol_i_id; 42 | int ol_supply_w_id; 43 | int ol_quantity; 44 | float ol_amount; 45 | char ol_delivery_d[25]; 46 | int namecnt; 47 | 48 | int n; 49 | int proceed = 0; 50 | 51 | MYSQL_STMT* mysql_stmt; 52 | MYSQL_BIND param[6]; 53 | MYSQL_BIND column[5]; 54 | 55 | /*EXEC SQL WHENEVER NOT FOUND GOTO sqlerr;*/ 56 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 57 | 58 | if (byname) { 59 | strcpy(c_last, c_last_arg); 60 | proceed = 1; 61 | /*EXEC_SQL SELECT count(c_id) 62 | INTO :namecnt 63 | FROM customer 64 | WHERE c_w_id = :c_w_id 65 | AND c_d_id = :c_d_id 66 | AND c_last = :c_last;*/ 67 | mysql_stmt = stmt[t_num][20]; 68 | 69 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 70 | param[0].buffer_type = MYSQL_TYPE_LONG; 71 | param[0].buffer = &c_w_id; 72 | param[1].buffer_type = MYSQL_TYPE_LONG; 73 | param[1].buffer = &c_d_id; 74 | param[2].buffer_type = MYSQL_TYPE_STRING; 75 | param[2].buffer = c_last; 76 | param[2].buffer_length = strlen(c_last); 77 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 78 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 79 | 80 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 81 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 82 | column[0].buffer_type = MYSQL_TYPE_LONG; 83 | column[0].buffer = &namecnt; 84 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 85 | switch( mysql_stmt_fetch(mysql_stmt) ) { 86 | case 0: //SUCCESS 87 | break; 88 | case 1: //ERROR 89 | case MYSQL_NO_DATA: //NO MORE DATA 90 | default: 91 | mysql_stmt_free_result(mysql_stmt); 92 | goto sqlerr; 93 | } 94 | mysql_stmt_free_result(mysql_stmt); 95 | 96 | 97 | proceed = 2; 98 | /*EXEC_SQL DECLARE c_byname_o CURSOR FOR 99 | SELECT c_balance, c_first, c_middle, c_last 100 | FROM customer 101 | WHERE c_w_id = :c_w_id 102 | AND c_d_id = :c_d_id 103 | AND c_last = :c_last 104 | ORDER BY c_first; 105 | proceed = 3; 106 | EXEC_SQL OPEN c_byname_o;*/ 107 | mysql_stmt = stmt[t_num][21]; 108 | 109 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 110 | param[0].buffer_type = MYSQL_TYPE_LONG; 111 | param[0].buffer = &c_w_id; 112 | param[1].buffer_type = MYSQL_TYPE_LONG; 113 | param[1].buffer = &c_d_id; 114 | param[2].buffer_type = MYSQL_TYPE_STRING; 115 | param[2].buffer = c_last; 116 | param[2].buffer_length = strlen(c_last); 117 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 118 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 119 | 120 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 121 | memset(column, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 122 | column[0].buffer_type = MYSQL_TYPE_FLOAT; 123 | column[0].buffer = &c_balance; 124 | column[1].buffer_type = MYSQL_TYPE_STRING; 125 | column[1].buffer = c_first; 126 | column[1].buffer_length = sizeof(c_first); 127 | column[2].buffer_type = MYSQL_TYPE_STRING; 128 | column[2].buffer = c_middle; 129 | column[2].buffer_length = sizeof(c_middle); 130 | column[3].buffer_type = MYSQL_TYPE_STRING; 131 | column[3].buffer = c_last; 132 | column[3].buffer_length = sizeof(c_last); 133 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 134 | 135 | if (namecnt % 2) 136 | namecnt++; /* Locate midpoint customer; */ 137 | 138 | for (n = 0; n < namecnt / 2; n++) { 139 | proceed = 4; 140 | /*EXEC_SQL FETCH c_byname_o 141 | INTO :c_balance, :c_first, :c_middle, :c_last;*/ 142 | switch( mysql_stmt_fetch(mysql_stmt) ) { 143 | case 0: //SUCCESS 144 | case MYSQL_DATA_TRUNCATED: 145 | break; 146 | case 1: //ERROR 147 | case MYSQL_NO_DATA: //NO MORE DATA 148 | default: 149 | mysql_stmt_free_result(mysql_stmt); 150 | goto sqlerr; 151 | } 152 | } 153 | proceed = 5; 154 | /*EXEC_SQL CLOSE c_byname_o;*/ 155 | mysql_stmt_free_result(mysql_stmt); 156 | 157 | 158 | } else { /* by number */ 159 | proceed = 6; 160 | /*EXEC_SQL SELECT c_balance, c_first, c_middle, c_last 161 | INTO :c_balance, :c_first, :c_middle, :c_last 162 | FROM customer 163 | WHERE c_w_id = :c_w_id 164 | AND c_d_id = :c_d_id 165 | AND c_id = :c_id;*/ 166 | mysql_stmt = stmt[t_num][22]; 167 | 168 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 169 | param[0].buffer_type = MYSQL_TYPE_LONG; 170 | param[0].buffer = &c_w_id; 171 | param[1].buffer_type = MYSQL_TYPE_LONG; 172 | param[1].buffer = &c_d_id; 173 | param[2].buffer_type = MYSQL_TYPE_LONG; 174 | param[2].buffer = &c_id; 175 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 176 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 177 | 178 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 179 | memset(column, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 180 | column[0].buffer_type = MYSQL_TYPE_FLOAT; 181 | column[0].buffer = &c_balance; 182 | column[1].buffer_type = MYSQL_TYPE_STRING; 183 | column[1].buffer = c_first; 184 | column[1].buffer_length = sizeof(c_first); 185 | column[2].buffer_type = MYSQL_TYPE_STRING; 186 | column[2].buffer = c_middle; 187 | column[2].buffer_length = sizeof(c_middle); 188 | column[3].buffer_type = MYSQL_TYPE_STRING; 189 | column[3].buffer = c_last; 190 | column[3].buffer_length = sizeof(c_last); 191 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 192 | switch( mysql_stmt_fetch(mysql_stmt) ) { 193 | case 0: //SUCCESS 194 | case MYSQL_DATA_TRUNCATED: 195 | break; 196 | case 1: //ERROR 197 | case MYSQL_NO_DATA: //NO MORE DATA 198 | default: 199 | mysql_stmt_free_result(mysql_stmt); 200 | goto sqlerr; 201 | } 202 | mysql_stmt_free_result(mysql_stmt); 203 | 204 | } 205 | 206 | /* find the most recent order for this customer */ 207 | 208 | proceed = 7; 209 | /*EXEC_SQL SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) 210 | INTO :o_id, :o_entry_d, :o_carrier_id 211 | FROM orders 212 | WHERE o_w_id = :c_w_id 213 | AND o_d_id = :c_d_id 214 | AND o_c_id = :c_id 215 | AND o_id = (SELECT MAX(o_id) 216 | FROM orders 217 | WHERE o_w_id = :c_w_id 218 | AND o_d_id = :c_d_id 219 | AND o_c_id = :c_id);*/ 220 | mysql_stmt = stmt[t_num][23]; 221 | 222 | memset(param, 0, sizeof(MYSQL_BIND) * 6); /* initialize */ 223 | param[0].buffer_type = MYSQL_TYPE_LONG; 224 | param[0].buffer = &c_w_id; 225 | param[1].buffer_type = MYSQL_TYPE_LONG; 226 | param[1].buffer = &c_d_id; 227 | param[2].buffer_type = MYSQL_TYPE_LONG; 228 | param[2].buffer = &c_id; 229 | param[3].buffer_type = MYSQL_TYPE_LONG; 230 | param[3].buffer = &c_w_id; 231 | param[4].buffer_type = MYSQL_TYPE_LONG; 232 | param[4].buffer = &c_d_id; 233 | param[5].buffer_type = MYSQL_TYPE_LONG; 234 | param[5].buffer = &c_id; 235 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 236 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 237 | 238 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 239 | memset(column, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 240 | column[0].buffer_type = MYSQL_TYPE_LONG; 241 | column[0].buffer = &o_id; 242 | column[1].buffer_type = MYSQL_TYPE_STRING; 243 | column[1].buffer = o_entry_d; 244 | column[1].buffer_length = sizeof(o_entry_d); 245 | column[2].buffer_type = MYSQL_TYPE_LONG; 246 | column[2].buffer = &o_carrier_id; 247 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 248 | switch( mysql_stmt_fetch(mysql_stmt) ) { 249 | case 0: //SUCCESS 250 | break; 251 | case 1: //ERROR 252 | case MYSQL_NO_DATA: //NO MORE DATA 253 | default: 254 | mysql_stmt_free_result(mysql_stmt); 255 | goto sqlerr; 256 | } 257 | mysql_stmt_free_result(mysql_stmt); 258 | 259 | 260 | /* find all the items in this order */ 261 | proceed = 8; 262 | /*EXEC_SQL DECLARE c_items CURSOR FOR 263 | SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, 264 | ol_delivery_d 265 | FROM order_line 266 | WHERE ol_w_id = :c_w_id 267 | AND ol_d_id = :c_d_id 268 | AND ol_o_id = :o_id;*/ 269 | mysql_stmt = stmt[t_num][24]; 270 | 271 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 272 | param[0].buffer_type = MYSQL_TYPE_LONG; 273 | param[0].buffer = &c_w_id; 274 | param[1].buffer_type = MYSQL_TYPE_LONG; 275 | param[1].buffer = &c_d_id; 276 | param[2].buffer_type = MYSQL_TYPE_LONG; 277 | param[2].buffer = &o_id; 278 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 279 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 280 | 281 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 282 | memset(column, 0, sizeof(MYSQL_BIND) * 5); /* initialize */ 283 | column[0].buffer_type = MYSQL_TYPE_LONG; 284 | column[0].buffer = &ol_i_id; 285 | column[1].buffer_type = MYSQL_TYPE_LONG; 286 | column[1].buffer = &ol_supply_w_id; 287 | column[2].buffer_type = MYSQL_TYPE_LONG; 288 | column[2].buffer = &ol_quantity; 289 | column[3].buffer_type = MYSQL_TYPE_FLOAT; 290 | column[3].buffer = &ol_amount; 291 | column[4].buffer_type = MYSQL_TYPE_STRING; 292 | column[4].buffer = ol_delivery_d; 293 | column[4].buffer_length = sizeof(ol_delivery_d); 294 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 295 | 296 | /*proceed = 9; 297 | EXEC_SQL OPEN c_items; 298 | 299 | EXEC SQL WHENEVER NOT FOUND GOTO done;*/ 300 | 301 | for (;;) { 302 | proceed = 10; 303 | /*EXEC_SQL FETCH c_items 304 | INTO :ol_i_id, :ol_supply_w_id, :ol_quantity, 305 | :ol_amount, :ol_delivery_d;*/ 306 | switch( mysql_stmt_fetch(mysql_stmt) ) { 307 | case 0: //SUCCESS 308 | case MYSQL_DATA_TRUNCATED: 309 | break; 310 | case MYSQL_NO_DATA: //NO MORE DATA 311 | mysql_stmt_free_result(mysql_stmt); 312 | goto done; 313 | case 1: //ERROR 314 | default: 315 | mysql_stmt_free_result(mysql_stmt); 316 | goto sqlerr; 317 | } 318 | } 319 | 320 | done: 321 | /*EXEC_SQL CLOSE c_items;*/ 322 | /*EXEC_SQL COMMIT WORK;*/ 323 | if( mysql_commit(ctx[t_num]) ) goto sqlerr; 324 | 325 | return (1); 326 | 327 | sqlerr: 328 | fprintf(stderr, "ordstat %d:%d\n",t_num,proceed); 329 | error(ctx[t_num],mysql_stmt); 330 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerrerr;*/ 331 | /*EXEC_SQL ROLLBACK WORK;*/ 332 | mysql_rollback(ctx[t_num]); 333 | sqlerrerr: 334 | return (0); 335 | } 336 | 337 | -------------------------------------------------------------------------------- /src/parse_port.h: -------------------------------------------------------------------------------- 1 | inline void parse_host(char* host, const char* from) 2 | { 3 | const char* port= rindex(from,':'); 4 | size_t length; 5 | if(NULL == port) 6 | length= strlen(from); 7 | else 8 | length= (port - from); 9 | memcpy(host,from, length); 10 | host[length] = '\0'; 11 | } 12 | inline int parse_port(const char* from) 13 | { 14 | const char* port= rindex(from,':'); 15 | if(NULL == port) 16 | return 3306; 17 | else 18 | { 19 | const char* end= NULL; 20 | int result= strtol(port+1,&end,10); 21 | if( (0 == *end) && (0 <= result) && (result <= 0xFFFF) ) 22 | return result; 23 | else 24 | { 25 | printf(stderr,"Incorrect port value: %s\n",end); 26 | exit(-1); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/payment.c: -------------------------------------------------------------------------------- 1 | /* 2 | * -*-C-*- 3 | * payment.pc 4 | * corresponds to A.2 in appendix A 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "spt_proc.h" 14 | #include "tpc.h" 15 | 16 | extern MYSQL **ctx; 17 | extern MYSQL_STMT ***stmt; 18 | 19 | #define NNULL ((void *)0) 20 | 21 | /* 22 | * the payment transaction 23 | */ 24 | int payment( int t_num, 25 | int w_id_arg, /* warehouse id */ 26 | int d_id_arg, /* district id */ 27 | int byname, /* select by c_id or c_last? */ 28 | int c_w_id_arg, 29 | int c_d_id_arg, 30 | int c_id_arg, /* customer id */ 31 | char c_last_arg[], /* customer last name */ 32 | float h_amount_arg /* payment amount */ 33 | ) 34 | { 35 | int w_id = w_id_arg; 36 | int d_id = d_id_arg; 37 | int c_id = c_id_arg; 38 | char w_name[11]; 39 | char w_street_1[21]; 40 | char w_street_2[21]; 41 | char w_city[21]; 42 | char w_state[3]; 43 | char w_zip[10]; 44 | int c_d_id = c_d_id_arg; 45 | int c_w_id = c_w_id_arg; 46 | char c_first[17]; 47 | char c_middle[3]; 48 | char c_last[17]; 49 | char c_street_1[21]; 50 | char c_street_2[21]; 51 | char c_city[21]; 52 | char c_state[3]; 53 | char c_zip[10]; 54 | char c_phone[17]; 55 | char c_since[20]; 56 | char c_credit[4]; 57 | int c_credit_lim; 58 | float c_discount; 59 | float c_balance; 60 | char c_data[502]; 61 | char c_new_data[502]; 62 | float h_amount = h_amount_arg; 63 | char h_data[26]; 64 | char d_name[11]; 65 | char d_street_1[21]; 66 | char d_street_2[21]; 67 | char d_city[21]; 68 | char d_state[3]; 69 | char d_zip[10]; 70 | int namecnt; 71 | char datetime[81]; 72 | 73 | int n; 74 | int proceed = 0; 75 | 76 | MYSQL_STMT* mysql_stmt; 77 | MYSQL_BIND param[8]; 78 | MYSQL_BIND column[14]; 79 | 80 | /* EXEC SQL WHENEVER NOT FOUND GOTO sqlerr; */ 81 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 82 | 83 | gettimestamp(datetime, STRFTIME_FORMAT, TIMESTAMP_LEN); 84 | 85 | proceed = 1; 86 | /*EXEC_SQL UPDATE warehouse SET w_ytd = w_ytd + :h_amount 87 | WHERE w_id =:w_id;*/ 88 | mysql_stmt = stmt[t_num][9]; 89 | 90 | memset(param, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 91 | param[0].buffer_type = MYSQL_TYPE_FLOAT; 92 | param[0].buffer = &h_amount; 93 | param[1].buffer_type = MYSQL_TYPE_LONG; 94 | param[1].buffer = &w_id; 95 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 96 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 97 | 98 | 99 | proceed = 2; 100 | /*EXEC_SQL SELECT w_street_1, w_street_2, w_city, w_state, w_zip, 101 | w_name 102 | INTO :w_street_1, :w_street_2, :w_city, :w_state, 103 | :w_zip, :w_name 104 | FROM warehouse 105 | WHERE w_id = :w_id;*/ 106 | mysql_stmt = stmt[t_num][10]; 107 | 108 | memset(param, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 109 | param[0].buffer_type = MYSQL_TYPE_LONG; 110 | param[0].buffer = &w_id; 111 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 112 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 113 | 114 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 115 | memset(column, 0, sizeof(MYSQL_BIND) * 6); /* initialize */ 116 | column[0].buffer_type = MYSQL_TYPE_STRING; 117 | column[0].buffer = w_street_1; 118 | column[0].buffer_length = sizeof(w_street_1); 119 | column[1].buffer_type = MYSQL_TYPE_STRING; 120 | column[1].buffer = w_street_2; 121 | column[1].buffer_length = sizeof(w_street_2); 122 | column[2].buffer_type = MYSQL_TYPE_STRING; 123 | column[2].buffer = w_city; 124 | column[2].buffer_length = sizeof(w_city); 125 | column[3].buffer_type = MYSQL_TYPE_STRING; 126 | column[3].buffer = w_state; 127 | column[3].buffer_length = sizeof(w_state); 128 | column[4].buffer_type = MYSQL_TYPE_STRING; 129 | column[4].buffer = w_zip; 130 | column[4].buffer_length = sizeof(w_zip); 131 | column[5].buffer_type = MYSQL_TYPE_STRING; 132 | column[5].buffer = w_name; 133 | column[5].buffer_length = sizeof(w_name); 134 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 135 | switch( mysql_stmt_fetch(mysql_stmt) ) { 136 | case 0: //SUCCESS 137 | break; 138 | case 1: //ERROR 139 | case MYSQL_NO_DATA: //NO MORE DATA 140 | default: 141 | mysql_stmt_free_result(mysql_stmt); 142 | goto sqlerr; 143 | } 144 | mysql_stmt_free_result(mysql_stmt); 145 | 146 | 147 | proceed = 3; 148 | /*EXEC_SQL UPDATE district SET d_ytd = d_ytd + :h_amount 149 | WHERE d_w_id = :w_id 150 | AND d_id = :d_id;*/ 151 | mysql_stmt = stmt[t_num][11]; 152 | 153 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 154 | param[0].buffer_type = MYSQL_TYPE_FLOAT; 155 | param[0].buffer = &h_amount; 156 | param[1].buffer_type = MYSQL_TYPE_LONG; 157 | param[1].buffer = &w_id; 158 | param[2].buffer_type = MYSQL_TYPE_LONG; 159 | param[2].buffer = &d_id; 160 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 161 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 162 | 163 | 164 | proceed = 4; 165 | /*EXEC_SQL SELECT d_street_1, d_street_2, d_city, d_state, d_zip, 166 | d_name 167 | INTO :d_street_1, :d_street_2, :d_city, :d_state, 168 | :d_zip, :d_name 169 | FROM district 170 | WHERE d_w_id = :w_id 171 | AND d_id = :d_id;*/ 172 | mysql_stmt = stmt[t_num][12]; 173 | 174 | memset(param, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 175 | param[0].buffer_type = MYSQL_TYPE_LONG; 176 | param[0].buffer = &w_id; 177 | param[1].buffer_type = MYSQL_TYPE_LONG; 178 | param[1].buffer = &d_id; 179 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 180 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 181 | 182 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 183 | memset(column, 0, sizeof(MYSQL_BIND) * 6); /* initialize */ 184 | column[0].buffer_type = MYSQL_TYPE_STRING; 185 | column[0].buffer = d_street_1; 186 | column[0].buffer_length = sizeof(d_street_1); 187 | column[1].buffer_type = MYSQL_TYPE_STRING; 188 | column[1].buffer = d_street_2; 189 | column[1].buffer_length = sizeof(d_street_2); 190 | column[2].buffer_type = MYSQL_TYPE_STRING; 191 | column[2].buffer = d_city; 192 | column[2].buffer_length = sizeof(d_city); 193 | column[3].buffer_type = MYSQL_TYPE_STRING; 194 | column[3].buffer = d_state; 195 | column[3].buffer_length = sizeof(d_state); 196 | column[4].buffer_type = MYSQL_TYPE_STRING; 197 | column[4].buffer = d_zip; 198 | column[4].buffer_length = sizeof(d_zip); 199 | column[5].buffer_type = MYSQL_TYPE_STRING; 200 | column[5].buffer = d_name; 201 | column[5].buffer_length = sizeof(d_name); 202 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 203 | switch( mysql_stmt_fetch(mysql_stmt) ) { 204 | case 0: //SUCCESS 205 | break; 206 | case 1: //ERROR 207 | case MYSQL_NO_DATA: //NO MORE DATA 208 | default: 209 | mysql_stmt_free_result(mysql_stmt); 210 | goto sqlerr; 211 | } 212 | mysql_stmt_free_result(mysql_stmt); 213 | 214 | 215 | if (byname) { 216 | strcpy(c_last, c_last_arg); 217 | 218 | proceed = 5; 219 | /*EXEC_SQL SELECT count(c_id) 220 | INTO :namecnt 221 | FROM customer 222 | WHERE c_w_id = :c_w_id 223 | AND c_d_id = :c_d_id 224 | AND c_last = :c_last;*/ 225 | mysql_stmt = stmt[t_num][13]; 226 | 227 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 228 | param[0].buffer_type = MYSQL_TYPE_LONG; 229 | param[0].buffer = &c_w_id; 230 | param[1].buffer_type = MYSQL_TYPE_LONG; 231 | param[1].buffer = &c_d_id; 232 | param[2].buffer_type = MYSQL_TYPE_STRING; 233 | param[2].buffer = c_last; 234 | param[2].buffer_length = strlen(c_last); 235 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 236 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 237 | 238 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 239 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 240 | column[0].buffer_type = MYSQL_TYPE_LONG; 241 | column[0].buffer = &namecnt; 242 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 243 | switch( mysql_stmt_fetch(mysql_stmt) ) { 244 | case 0: //SUCCESS 245 | break; 246 | case 1: //ERROR 247 | case MYSQL_NO_DATA: //NO MORE DATA 248 | default: 249 | mysql_stmt_free_result(mysql_stmt); 250 | goto sqlerr; 251 | } 252 | mysql_stmt_free_result(mysql_stmt); 253 | 254 | /*EXEC_SQL DECLARE c_byname_p CURSOR FOR 255 | SELECT c_id 256 | FROM customer 257 | WHERE c_w_id = :c_w_id 258 | AND c_d_id = :c_d_id 259 | AND c_last = :c_last 260 | ORDER BY c_first; 261 | 262 | EXEC_SQL OPEN c_byname_p;*/ 263 | mysql_stmt = stmt[t_num][14]; 264 | 265 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 266 | param[0].buffer_type = MYSQL_TYPE_LONG; 267 | param[0].buffer = &c_w_id; 268 | param[1].buffer_type = MYSQL_TYPE_LONG; 269 | param[1].buffer = &c_d_id; 270 | param[2].buffer_type = MYSQL_TYPE_STRING; 271 | param[2].buffer = c_last; 272 | param[2].buffer_length = strlen(c_last); 273 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 274 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 275 | 276 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 277 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 278 | column[0].buffer_type = MYSQL_TYPE_LONG; 279 | column[0].buffer = &c_id; 280 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 281 | 282 | if (namecnt % 2) 283 | namecnt++; /* Locate midpoint customer; */ 284 | for (n = 0; n < namecnt / 2; n++) { 285 | /*EXEC_SQL FETCH c_byname_p 286 | INTO :c_id;*/ 287 | switch( mysql_stmt_fetch(mysql_stmt) ) { 288 | case 0: //SUCCESS 289 | break; 290 | case 1: //ERROR 291 | case MYSQL_NO_DATA: //NO MORE DATA 292 | default: 293 | mysql_stmt_free_result(mysql_stmt); 294 | goto sqlerr; 295 | } 296 | } 297 | 298 | /*EXEC_SQL CLOSE c_byname_p; */ 299 | mysql_stmt_free_result(mysql_stmt); 300 | 301 | } 302 | 303 | proceed = 6; 304 | /*EXEC_SQL SELECT c_first, c_middle, c_last, c_street_1, 305 | c_street_2, c_city, c_state, c_zip, c_phone, 306 | c_credit, c_credit_lim, c_discount, c_balance, 307 | c_since 308 | INTO :c_first, :c_middle, :c_last, :c_street_1, 309 | :c_street_2, :c_city, :c_state, :c_zip, :c_phone, 310 | :c_credit, :c_credit_lim, :c_discount, :c_balance, 311 | :c_since 312 | FROM customer 313 | WHERE c_w_id = :c_w_id 314 | AND c_d_id = :c_d_id 315 | AND c_id = :c_id 316 | FOR UPDATE;*/ 317 | mysql_stmt = stmt[t_num][15]; 318 | 319 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 320 | param[0].buffer_type = MYSQL_TYPE_LONG; 321 | param[0].buffer = &c_w_id; 322 | param[1].buffer_type = MYSQL_TYPE_LONG; 323 | param[1].buffer = &c_d_id; 324 | param[2].buffer_type = MYSQL_TYPE_LONG; 325 | param[2].buffer = &c_id; 326 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 327 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 328 | 329 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 330 | memset(column, 0, sizeof(MYSQL_BIND) * 14); /* initialize */ 331 | column[0].buffer_type = MYSQL_TYPE_STRING; 332 | column[0].buffer = c_first; 333 | column[0].buffer_length = sizeof(c_first); 334 | column[1].buffer_type = MYSQL_TYPE_STRING; 335 | column[1].buffer = c_middle; 336 | column[1].buffer_length = sizeof(c_middle); 337 | column[2].buffer_type = MYSQL_TYPE_STRING; 338 | column[2].buffer = c_last; 339 | column[2].buffer_length = sizeof(c_last); 340 | column[3].buffer_type = MYSQL_TYPE_STRING; 341 | column[3].buffer = c_street_1; 342 | column[3].buffer_length = sizeof(c_street_1); 343 | column[4].buffer_type = MYSQL_TYPE_STRING; 344 | column[4].buffer = c_street_2; 345 | column[4].buffer_length = sizeof(c_street_2); 346 | column[5].buffer_type = MYSQL_TYPE_STRING; 347 | column[5].buffer = c_city; 348 | column[5].buffer_length = sizeof(c_city); 349 | column[6].buffer_type = MYSQL_TYPE_STRING; 350 | column[6].buffer = c_state; 351 | column[6].buffer_length = sizeof(c_state); 352 | column[7].buffer_type = MYSQL_TYPE_STRING; 353 | column[7].buffer = c_zip; 354 | column[7].buffer_length = sizeof(c_zip); 355 | column[8].buffer_type = MYSQL_TYPE_STRING; 356 | column[8].buffer = c_phone; 357 | column[8].buffer_length = sizeof(c_phone); 358 | column[9].buffer_type = MYSQL_TYPE_STRING; 359 | column[9].buffer = c_credit; 360 | column[9].buffer_length = sizeof(c_credit); 361 | column[10].buffer_type = MYSQL_TYPE_LONG; 362 | column[10].buffer = &c_credit_lim; 363 | column[11].buffer_type = MYSQL_TYPE_FLOAT; 364 | column[11].buffer = &c_discount; 365 | column[12].buffer_type = MYSQL_TYPE_FLOAT; 366 | column[12].buffer = &c_balance; 367 | column[13].buffer_type = MYSQL_TYPE_STRING; 368 | column[13].buffer = c_since; 369 | column[13].buffer_length = sizeof(c_since); 370 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 371 | switch( mysql_stmt_fetch(mysql_stmt) ) { 372 | case 0: //SUCCESS 373 | case MYSQL_DATA_TRUNCATED: 374 | break; 375 | case 1: //ERROR 376 | case MYSQL_NO_DATA: //NO MORE DATA 377 | default: 378 | mysql_stmt_free_result(mysql_stmt); 379 | goto sqlerr; 380 | } 381 | mysql_stmt_free_result(mysql_stmt); 382 | 383 | 384 | 385 | c_balance += h_amount; 386 | c_credit[2] = '\0'; 387 | if (strstr(c_credit, "BC")) { 388 | proceed = 7; 389 | /*EXEC_SQL SELECT c_data 390 | INTO :c_data 391 | FROM customer 392 | WHERE c_w_id = :c_w_id 393 | AND c_d_id = :c_d_id 394 | AND c_id = :c_id; */ 395 | mysql_stmt = stmt[t_num][16]; 396 | 397 | memset(param, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 398 | param[0].buffer_type = MYSQL_TYPE_LONG; 399 | param[0].buffer = &c_w_id; 400 | param[1].buffer_type = MYSQL_TYPE_LONG; 401 | param[1].buffer = &c_d_id; 402 | param[2].buffer_type = MYSQL_TYPE_LONG; 403 | param[2].buffer = &c_id; 404 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 405 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 406 | 407 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 408 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 409 | column[0].buffer_type = MYSQL_TYPE_STRING; 410 | column[0].buffer = c_data; 411 | column[0].buffer_length = sizeof(c_data); 412 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 413 | switch( mysql_stmt_fetch(mysql_stmt) ) { 414 | case 0: //SUCCESS 415 | break; 416 | case 1: //ERROR 417 | case MYSQL_NO_DATA: //NO MORE DATA 418 | default: 419 | mysql_stmt_free_result(mysql_stmt); 420 | goto sqlerr; 421 | } 422 | mysql_stmt_free_result(mysql_stmt); 423 | 424 | 425 | sprintf(c_new_data, 426 | "| %4d %2d %4d %2d %4d $%7.2f %12c %24c", 427 | c_id, c_d_id, c_w_id, d_id, 428 | w_id, h_amount, 429 | datetime, c_data); 430 | 431 | strncat(c_new_data, c_data, 432 | 500 - strlen(c_new_data)); 433 | 434 | c_new_data[500] = '\0'; 435 | 436 | proceed = 8; 437 | /*EXEC_SQL UPDATE customer 438 | SET c_balance = :c_balance, c_data = :c_new_data 439 | WHERE c_w_id = :c_w_id 440 | AND c_d_id = :c_d_id 441 | AND c_id = :c_id;*/ 442 | mysql_stmt = stmt[t_num][17]; 443 | 444 | memset(param, 0, sizeof(MYSQL_BIND) * 5); /* initialize */ 445 | param[0].buffer_type = MYSQL_TYPE_FLOAT; 446 | param[0].buffer = &c_balance; 447 | param[1].buffer_type = MYSQL_TYPE_STRING; 448 | param[1].buffer = c_data; 449 | param[1].buffer_length = strlen(c_data); 450 | param[2].buffer_type = MYSQL_TYPE_LONG; 451 | param[2].buffer = &c_w_id; 452 | param[3].buffer_type = MYSQL_TYPE_LONG; 453 | param[3].buffer = &c_d_id; 454 | param[4].buffer_type = MYSQL_TYPE_LONG; 455 | param[4].buffer = &c_id; 456 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 457 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 458 | } else { 459 | proceed = 9; 460 | /*EXEC_SQL UPDATE customer 461 | SET c_balance = :c_balance 462 | WHERE c_w_id = :c_w_id 463 | AND c_d_id = :c_d_id 464 | AND c_id = :c_id;*/ 465 | mysql_stmt = stmt[t_num][18]; 466 | 467 | memset(param, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 468 | param[0].buffer_type = MYSQL_TYPE_FLOAT; 469 | param[0].buffer = &c_balance; 470 | param[1].buffer_type = MYSQL_TYPE_LONG; 471 | param[1].buffer = &c_w_id; 472 | param[2].buffer_type = MYSQL_TYPE_LONG; 473 | param[2].buffer = &c_d_id; 474 | param[3].buffer_type = MYSQL_TYPE_LONG; 475 | param[3].buffer = &c_id; 476 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 477 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 478 | } 479 | strncpy(h_data, w_name, 10); 480 | h_data[10] = '\0'; 481 | strncat(h_data, d_name, 10); 482 | h_data[20] = ' '; 483 | h_data[21] = ' '; 484 | h_data[22] = ' '; 485 | h_data[23] = ' '; 486 | h_data[24] = '\0'; 487 | 488 | proceed = 10; 489 | /*EXEC_SQL INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, 490 | h_w_id, h_date, h_amount, h_data) 491 | VALUES(:c_d_id, :c_w_id, :c_id, :d_id, 492 | :w_id, 493 | :datetime, 494 | :h_amount, :h_data);*/ 495 | mysql_stmt = stmt[t_num][19]; 496 | 497 | memset(param, 0, sizeof(MYSQL_BIND) * 8); /* initialize */ 498 | param[0].buffer_type = MYSQL_TYPE_LONG; 499 | param[0].buffer = &c_d_id; 500 | param[1].buffer_type = MYSQL_TYPE_LONG; 501 | param[1].buffer = &c_w_id; 502 | param[2].buffer_type = MYSQL_TYPE_LONG; 503 | param[2].buffer = &c_id; 504 | param[3].buffer_type = MYSQL_TYPE_LONG; 505 | param[3].buffer = &d_id; 506 | param[4].buffer_type = MYSQL_TYPE_LONG; 507 | param[4].buffer = &w_id; 508 | param[5].buffer_type = MYSQL_TYPE_STRING; 509 | param[5].buffer = datetime; 510 | param[5].buffer_length = strlen(datetime); 511 | param[6].buffer_type = MYSQL_TYPE_FLOAT; 512 | param[6].buffer = &h_amount; 513 | param[7].buffer_type = MYSQL_TYPE_STRING; 514 | param[7].buffer = h_data; 515 | param[7].buffer_length = strlen(h_data); 516 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 517 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 518 | 519 | /*EXEC_SQL COMMIT WORK;*/ 520 | if( mysql_commit(ctx[t_num]) ) goto sqlerr; 521 | 522 | return (1); 523 | 524 | sqlerr: 525 | fprintf(stderr, "payment %d:%d\n",t_num,proceed); 526 | error(ctx[t_num],mysql_stmt); 527 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerrerr;*/ 528 | /*EXEC_SQL ROLLBACK WORK;*/ 529 | mysql_rollback(ctx[t_num]); 530 | sqlerrerr: 531 | return (0); 532 | } 533 | -------------------------------------------------------------------------------- /src/rthist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * rthist.c 3 | * RT-histgram 4 | */ 5 | 6 | #include 7 | #include 8 | 9 | #define MAXREC 20 10 | #define REC_PER_SEC 1000 11 | 12 | extern double max_rt[]; 13 | extern double cur_max_rt[]; 14 | 15 | int total_hist[5][MAXREC * REC_PER_SEC]; 16 | int cur_hist[5][MAXREC * REC_PER_SEC]; 17 | 18 | /* initialize */ 19 | void hist_init() 20 | { 21 | int i,j; 22 | 23 | for( i=0; i<5; i++){ 24 | for( j=0; j<(MAXREC * REC_PER_SEC); j++){ 25 | total_hist[i][j] = cur_hist[i][j] = 0; 26 | } 27 | } 28 | } 29 | 30 | /* incliment matched one */ 31 | void hist_inc( int transaction, double rtclk ) 32 | { 33 | int i; 34 | 35 | i = ( rtclk * (double)REC_PER_SEC ); 36 | if(i >= (MAXREC * REC_PER_SEC)){ 37 | i = (MAXREC * REC_PER_SEC) - 1; 38 | } 39 | if (rtclk > cur_max_rt[transaction]) cur_max_rt[transaction] = rtclk; 40 | ++cur_hist[transaction][i]; 41 | //printf("In: %.3f, trx: %d, Added %d\n", rtclk, transaction, i); 42 | } 43 | 44 | /* check point, add on total histgram, return 90% line */ 45 | double hist_ckp( int transaction ) 46 | { 47 | int i; 48 | int total,tmp,line,line_set; 49 | 50 | total = tmp = line_set = 0; 51 | line = MAXREC * REC_PER_SEC; 52 | for( i=0; i<(MAXREC * REC_PER_SEC); i++){ 53 | total += cur_hist[transaction][i]; 54 | //total += i; 55 | } 56 | for( i=0; i<(MAXREC * REC_PER_SEC); i++){ 57 | tmp += cur_hist[transaction][i]; 58 | //tmp += i; 59 | total_hist[transaction][i] += cur_hist[transaction][i]; 60 | cur_hist[transaction][i] = 0; 61 | if (( tmp >= (total*99/100) ) && (line_set ==0)){ 62 | line = i; 63 | line_set=1; 64 | } 65 | } 66 | //printf("CKP: trx: %d line: %d total: %d tmp: %d ret: %.3f\n", transaction, line, total, tmp,(double)(line)/(double)(REC_PER_SEC)); 67 | return ( (double)(line)/(double)(REC_PER_SEC) ); 68 | } 69 | 70 | void hist_report() 71 | { 72 | int i,j; 73 | int total[5],tmp[5],line[5]; 74 | 75 | for( j=0; j<5; j++){ 76 | total[j] = tmp[j] = 0; 77 | line[j] = MAXREC * REC_PER_SEC; 78 | for( i=0; i<(MAXREC * REC_PER_SEC); i++){ 79 | total[j] += total_hist[j][i]; 80 | } 81 | for( i=(MAXREC * REC_PER_SEC)-1; i >= 0 ; i--){ 82 | tmp[j] += total_hist[j][i]; 83 | if( (tmp[j] * 10) <= total[j] ){ 84 | line[j] = i; 85 | } 86 | } 87 | } 88 | 89 | printf("\n\n"); 90 | 91 | for( j=0; j<5; j++){ 92 | switch(j){ 93 | case 0: 94 | printf("\n1.New-Order\n\n"); 95 | break; 96 | case 1: 97 | printf("\n2.Payment\n\n"); 98 | break; 99 | case 2: 100 | printf("\n3.Order-Status\n\n"); 101 | break; 102 | case 3: 103 | printf("\n4.Delivery\n\n"); 104 | break; 105 | case 4: 106 | printf("\n5.Stock-Level\n\n"); 107 | } 108 | for( i=0; (i<(MAXREC * REC_PER_SEC))&&(i <= line[j]*4); i++){ 109 | printf("%3.2f, %6d\n",(double)(i+1)/(double)(REC_PER_SEC),total_hist[j][i]); 110 | } 111 | printf("\n"); 112 | } 113 | 114 | printf("\n<90th Percentile RT (MaxRT)>\n"); 115 | for( j=0; j<5; j++){ 116 | switch(j){ 117 | case 0: 118 | printf(" New-Order : "); 119 | break; 120 | case 1: 121 | printf(" Payment : "); 122 | break; 123 | case 2: 124 | printf("Order-Status : "); 125 | break; 126 | case 3: 127 | printf(" Delivery : "); 128 | break; 129 | case 4: 130 | printf(" Stock-Level : "); 131 | } 132 | printf("%3.2f (%.2f)\n",(double)(line[j])/(double)(REC_PER_SEC),max_rt[j]); 133 | } 134 | 135 | } 136 | 137 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /src/rthist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * rthist.h 3 | */ 4 | 5 | void hist_init(); 6 | void hist_inc( int transaction, double rtclk ); 7 | double hist_ckp( int transaction ); 8 | void hist_report(); 9 | -------------------------------------------------------------------------------- /src/sequence.c: -------------------------------------------------------------------------------- 1 | /* 2 | * sequence.c 3 | * manage sequence shared by threads 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /* weight */ 11 | static int no; 12 | static int py; 13 | static int os; 14 | static int dl; 15 | static int sl; 16 | static int total; 17 | 18 | static pthread_mutex_t mutex; 19 | static int *seq; 20 | static int next_num; 21 | 22 | static void shuffle() 23 | { 24 | int i,j,rnd,tmp; 25 | 26 | for( i=0, j=0; i < no ; i++, j++ ){ 27 | seq[j]=0; 28 | } 29 | for( i=0; i < py ; i++, j++){ 30 | seq[j]=1; 31 | } 32 | for( i=0; i < os ; i++, j++){ 33 | seq[j]=2; 34 | } 35 | for( i=0; i < dl ; i++, j++){ 36 | seq[j]=3; 37 | } 38 | for( i=0; i < sl ; i++, j++){ 39 | seq[j]=4; 40 | } 41 | for( i=0, j = total - 1; j>0; i++, j--){ 42 | rnd = rand()%(j+1); 43 | tmp = seq[rnd+i]; 44 | seq[rnd+i] = seq[i]; 45 | seq[i] = tmp; 46 | } 47 | } 48 | 49 | void seq_init( int n, int p, int o, int d, int s ) 50 | { 51 | pthread_mutex_init( &mutex, NULL ); 52 | no = n; 53 | py = p; 54 | os = o; 55 | dl = d; 56 | sl = s; 57 | total = n + p + o + d + s; 58 | seq = malloc( sizeof(int) * total ); 59 | shuffle(); 60 | next_num = 0; 61 | } 62 | 63 | 64 | int seq_get() 65 | { 66 | int retval; 67 | 68 | pthread_mutex_lock( &mutex ); 69 | 70 | if(next_num >= total){ 71 | shuffle(); 72 | next_num = 0; 73 | } 74 | 75 | retval = seq[next_num]; 76 | ++next_num; 77 | 78 | pthread_mutex_unlock( &mutex ); 79 | 80 | return(retval); 81 | } 82 | -------------------------------------------------------------------------------- /src/sequence.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sequence.h 3 | */ 4 | 5 | void seq_init( int n, int p, int o, int d, int s ); 6 | int seq_get(); 7 | -------------------------------------------------------------------------------- /src/slev.c: -------------------------------------------------------------------------------- 1 | /* 2 | * -*-C-*- 3 | * slev.pc 4 | * corresponds to A.5 in appendix A 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | #include "spt_proc.h" 13 | #include "tpc.h" 14 | 15 | extern MYSQL **ctx; 16 | extern MYSQL_STMT ***stmt; 17 | 18 | /* 19 | * the stock level transaction 20 | */ 21 | int slev( int t_num, 22 | int w_id_arg, /* warehouse id */ 23 | int d_id_arg, /* district id */ 24 | int level_arg /* stock level */ 25 | ) 26 | { 27 | int w_id = w_id_arg; 28 | int d_id = d_id_arg; 29 | int level = level_arg; 30 | int d_next_o_id; 31 | int i_count; 32 | int ol_i_id; 33 | 34 | MYSQL_STMT* mysql_stmt; 35 | MYSQL_BIND param[4]; 36 | MYSQL_BIND column[1]; 37 | MYSQL_STMT* mysql_stmt2; 38 | MYSQL_BIND param2[3]; 39 | MYSQL_BIND column2[1]; 40 | 41 | /*EXEC SQL WHENEVER NOT FOUND GOTO sqlerr;*/ 42 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 43 | 44 | /* find the next order id */ 45 | #ifdef DEBUG 46 | printf("select 1\n"); 47 | #endif 48 | /*EXEC_SQL SELECT d_next_o_id 49 | INTO :d_next_o_id 50 | FROM district 51 | WHERE d_id = :d_id 52 | AND d_w_id = :w_id;*/ 53 | mysql_stmt = stmt[t_num][32]; 54 | 55 | memset(param, 0, sizeof(MYSQL_BIND) * 2); /* initialize */ 56 | param[0].buffer_type = MYSQL_TYPE_LONG; 57 | param[0].buffer = &d_id; 58 | param[1].buffer_type = MYSQL_TYPE_LONG; 59 | param[1].buffer = &w_id; 60 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 61 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 62 | 63 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 64 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 65 | column[0].buffer_type = MYSQL_TYPE_LONG; 66 | column[0].buffer = &d_next_o_id; 67 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 68 | switch( mysql_stmt_fetch(mysql_stmt) ) { 69 | case 0: //SUCCESS 70 | break; 71 | case 1: //ERROR 72 | case MYSQL_NO_DATA: //NO MORE DATA 73 | default: 74 | mysql_stmt_free_result(mysql_stmt); 75 | goto sqlerr; 76 | } 77 | mysql_stmt_free_result(mysql_stmt); 78 | 79 | /* find the most recent 20 orders for this district */ 80 | /*EXEC_SQL DECLARE ord_line CURSOR FOR 81 | SELECT DISTINCT ol_i_id 82 | FROM order_line 83 | WHERE ol_w_id = :w_id 84 | AND ol_d_id = :d_id 85 | AND ol_o_id < :d_next_o_id 86 | AND ol_o_id >= (:d_next_o_id - 20); 87 | 88 | EXEC_SQL OPEN ord_line; 89 | 90 | EXEC SQL WHENEVER NOT FOUND GOTO done;*/ 91 | mysql_stmt = stmt[t_num][33]; 92 | 93 | memset(param, 0, sizeof(MYSQL_BIND) * 4); /* initialize */ 94 | param[0].buffer_type = MYSQL_TYPE_LONG; 95 | param[0].buffer = &w_id; 96 | param[1].buffer_type = MYSQL_TYPE_LONG; 97 | param[1].buffer = &d_id; 98 | param[2].buffer_type = MYSQL_TYPE_LONG; 99 | param[2].buffer = &d_next_o_id; 100 | param[3].buffer_type = MYSQL_TYPE_LONG; 101 | param[3].buffer = &d_next_o_id; 102 | if( mysql_stmt_bind_param(mysql_stmt, param) ) goto sqlerr; 103 | if( mysql_stmt_execute(mysql_stmt) ) goto sqlerr; 104 | 105 | if( mysql_stmt_store_result(mysql_stmt) ) goto sqlerr; 106 | memset(column, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 107 | column[0].buffer_type = MYSQL_TYPE_LONG; 108 | column[0].buffer = &ol_i_id; 109 | if( mysql_stmt_bind_result(mysql_stmt, column) ) goto sqlerr; 110 | 111 | for (;;) { 112 | #ifdef DEBUG 113 | printf("fetch 1\n"); 114 | #endif 115 | /*EXEC_SQL FETCH ord_line INTO :ol_i_id;*/ 116 | switch( mysql_stmt_fetch(mysql_stmt) ) { 117 | case 0: //SUCCESS 118 | break; 119 | case MYSQL_NO_DATA: //NO MORE DATA 120 | mysql_stmt_free_result(mysql_stmt); 121 | goto done; 122 | case 1: //ERROR 123 | default: 124 | mysql_stmt_free_result(mysql_stmt); 125 | goto sqlerr; 126 | } 127 | 128 | #ifdef DEBUG 129 | printf("select 2\n"); 130 | #endif 131 | 132 | /*EXEC_SQL SELECT count(*) INTO :i_count 133 | FROM stock 134 | WHERE s_w_id = :w_id 135 | AND s_i_id = :ol_i_id 136 | AND s_quantity < :level;*/ 137 | mysql_stmt2 = stmt[t_num][34]; 138 | 139 | memset(param2, 0, sizeof(MYSQL_BIND) * 3); /* initialize */ 140 | param2[0].buffer_type = MYSQL_TYPE_LONG; 141 | param2[0].buffer = &w_id; 142 | param2[1].buffer_type = MYSQL_TYPE_LONG; 143 | param2[1].buffer = &ol_i_id; 144 | param2[2].buffer_type = MYSQL_TYPE_LONG; 145 | param2[2].buffer = &level; 146 | if( mysql_stmt_bind_param(mysql_stmt2, param2) ) goto sqlerr2; 147 | if( mysql_stmt_execute(mysql_stmt2) ) goto sqlerr2; 148 | 149 | if( mysql_stmt_store_result(mysql_stmt2) ) goto sqlerr2; 150 | memset(column2, 0, sizeof(MYSQL_BIND) * 1); /* initialize */ 151 | column2[0].buffer_type = MYSQL_TYPE_LONG; 152 | column2[0].buffer = &i_count; 153 | if( mysql_stmt_bind_result(mysql_stmt2, column2) ) goto sqlerr2; 154 | switch( mysql_stmt_fetch(mysql_stmt2) ) { 155 | case 0: //SUCCESS 156 | break; 157 | case 1: //ERROR 158 | case MYSQL_NO_DATA: //NO MORE DATA 159 | default: 160 | mysql_stmt_free_result(mysql_stmt2); 161 | goto sqlerr2; 162 | } 163 | mysql_stmt_free_result(mysql_stmt2); 164 | 165 | } 166 | 167 | done: 168 | /*EXEC_SQL CLOSE ord_line;*/ 169 | /*EXEC_SQL COMMIT WORK;*/ 170 | if( mysql_commit(ctx[t_num]) ) goto sqlerr; 171 | 172 | return (1); 173 | 174 | sqlerr: 175 | fprintf(stderr,"slev\n"); 176 | error(ctx[t_num],mysql_stmt); 177 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerrerr;*/ 178 | /*EXEC_SQL ROLLBACK WORK;*/ 179 | mysql_rollback(ctx[t_num]); 180 | sqlerrerr: 181 | return (0); 182 | 183 | sqlerr2: 184 | fprintf(stderr,"slev\n"); 185 | error(ctx[t_num],mysql_stmt2); 186 | /*EXEC SQL WHENEVER SQLERROR GOTO sqlerrerr;*/ 187 | /*EXEC_SQL ROLLBACK WORK;*/ 188 | mysql_stmt_free_result(mysql_stmt); 189 | mysql_rollback(ctx[t_num]); 190 | return (0); 191 | } 192 | -------------------------------------------------------------------------------- /src/spt_proc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * spt_proc.pc 3 | * support routines for the proc tpcc implementation 4 | */ 5 | 6 | #include 7 | 8 | #include 9 | 10 | /* 11 | * report error 12 | */ 13 | int error( 14 | MYSQL *mysql, 15 | MYSQL_STMT *mysql_stmt 16 | ) 17 | { 18 | /* 19 | if(mysql_stmt) { 20 | printf("\n%d, %s, %s", mysql_stmt_errno(mysql_stmt), 21 | mysql_stmt_sqlstate(mysql_stmt), mysql_stmt_error(mysql_stmt) ); 22 | } 23 | */ 24 | if(mysql){ 25 | fprintf(stderr, "%d, %s, %s\n", mysql_errno(mysql), mysql_sqlstate(mysql), mysql_error(mysql) ); 26 | } 27 | return (0); 28 | } 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/spt_proc.h: -------------------------------------------------------------------------------- 1 | int error(MYSQL *mysql, MYSQL_STMT *mysql_stmt); 2 | 3 | #define TIMESTAMP_LEN 80 4 | #define STRFTIME_FORMAT "%Y-%m-%d %H:%M:%S" 5 | 6 | -------------------------------------------------------------------------------- /src/support.c: -------------------------------------------------------------------------------- 1 | /* 2 | * support.c 3 | * routines needed for the tpcc loading and transaction programs 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "tpc.h" 13 | 14 | static int nums[CUST_PER_DIST]; 15 | static int perm_count; 16 | 17 | void SetSeed (int seed) 18 | { 19 | srand(seed); 20 | } 21 | 22 | /* 23 | * return number uniformly distributed b/w min and max, inclusive 24 | */ 25 | int RandomNumber (int min, int max) 26 | { 27 | return min + (rand() % ((max - min) + 1)); 28 | } 29 | 30 | /* 31 | * non uniform random -- see p. 15 32 | * 33 | * the constant C depends on which value of A is passed, but the same 34 | * value of C should be used for all calls with the same value of 35 | * A. however, we know in advance which values of A will be used. 36 | */ 37 | int NURand (unsigned A, unsigned x, unsigned y) 38 | { 39 | static int first = 1; 40 | unsigned C, C_255, C_1023, C_8191; 41 | 42 | if (first) { 43 | C_255 = RandomNumber(0, 255); 44 | C_1023 = RandomNumber(0, 1023); 45 | C_8191 = RandomNumber(0, 8191); 46 | first = 0; 47 | } 48 | 49 | switch (A) { 50 | case 255: C = C_255; break; 51 | case 1023: C = C_1023; break; 52 | case 8191: C = C_8191; break; 53 | default: 54 | fprintf(stderr, 55 | "NURand: unexpected value (%d) of A used\n", 56 | A); 57 | abort(); 58 | } 59 | 60 | return (int) 61 | (((RandomNumber(0, A) | RandomNumber(x, y)) + C) % (y-x+1)) + x; 62 | } 63 | 64 | /* 65 | * p. 54 66 | * 67 | * make a ``random a-string'': a string of random alphanumeric 68 | * characters of a random length of minimum x, maximum y, and 69 | * mean (y+x)/2 70 | */ 71 | int MakeAlphaString (int x, int y, char str[]) 72 | { 73 | static char *alphanum = "0123456789" 74 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 75 | "abcdefghijklmnopqrstuvwxyz"; 76 | int arrmax = 61; /* index of last array element */ 77 | register int i, len; 78 | 79 | len = RandomNumber(x, y); 80 | 81 | for (i = 0; i < len; i++) 82 | str[i] = alphanum[RandomNumber(0, arrmax)]; 83 | 84 | return len; 85 | } 86 | 87 | /* 88 | * like MakeAlphaString, only numeric characters only 89 | */ 90 | int MakeNumberString (int x, int y, char str[]) 91 | { 92 | static char *numeric = "0123456789"; 93 | int arrmax = 9; 94 | register int i, len; 95 | 96 | len = RandomNumber(x, y); 97 | 98 | for (i = 0; i < len; i++) 99 | str[i] = numeric[RandomNumber(0, arrmax)]; 100 | 101 | return len; 102 | } 103 | 104 | /* 105 | * turn system time into database format 106 | * the format argument should be a strftime() format string that produces 107 | * a datetime string acceptable to the database 108 | */ 109 | void gettimestamp (char str[], char *format, size_t len) 110 | { 111 | time_t t; 112 | struct tm *datetime; 113 | 114 | t = time(NULL); 115 | datetime = localtime(&t); 116 | 117 | if ( !strftime(str, len, format, datetime) ) { 118 | fprintf(stderr, "error writing timestamp to string\n"); 119 | abort(); 120 | } 121 | } 122 | 123 | /* 124 | * permute the list of customer ids for the order table 125 | */ 126 | void InitPermutation (void) 127 | { 128 | int *cur; 129 | int i,j; 130 | 131 | perm_count = 0; 132 | 133 | /* initialize with consecutive values [1..ORD_PER_DIST] */ 134 | for (i = 0, cur = nums; i < ORD_PER_DIST; i++, cur++) { 135 | *cur = i + 1; 136 | } 137 | 138 | /* now, shuffle */ 139 | for (i = 0; i < ORD_PER_DIST-1; i++) { 140 | j = (int)RandomNumber(i+1, ORD_PER_DIST-1); 141 | swap_int(nums[i], nums[j]); 142 | } 143 | } 144 | 145 | int GetPermutation (void) 146 | { 147 | if ( perm_count >= ORD_PER_DIST ) { 148 | fprintf(stderr, "GetPermutation: past end of list!\n"); 149 | abort(); 150 | } 151 | return nums[perm_count++]; 152 | } 153 | 154 | /*==================================================================+ 155 | | ROUTINE NAME 156 | | Lastname 157 | | DESCRIPTION 158 | | TPC-C Lastname Function. 159 | | ARGUMENTS 160 | | num - non-uniform random number 161 | | name - last name string 162 | +==================================================================*/ 163 | void Lastname(num, name) 164 | int num; 165 | char *name; 166 | { 167 | static char *n[] = 168 | {"BAR", "OUGHT", "ABLE", "PRI", "PRES", 169 | "ESE", "ANTI", "CALLY", "ATION", "EING"}; 170 | 171 | strcpy(name,n[num/100]); 172 | strcat(name,n[(num/10)%10]); 173 | strcat(name,n[num%10]); 174 | 175 | return; 176 | } 177 | 178 | -------------------------------------------------------------------------------- /src/tpc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * tpc.h 3 | * definitions for tpcc loading program && transactions 4 | */ 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* 11 | * correct values 12 | */ 13 | #define MAXITEMS 100000 14 | #define CUST_PER_DIST 3000 15 | #define DIST_PER_WARE 10 16 | #define ORD_PER_DIST 3000 17 | /* 18 | */ 19 | 20 | /* 21 | * small values 22 | 23 | #define MAXITEMS 1000 24 | #define CUST_PER_DIST 30 25 | #define DIST_PER_WARE 3 26 | #define ORD_PER_DIST 30 27 | 28 | */ 29 | 30 | /* definitions for new order transaction */ 31 | #define MAX_NUM_ITEMS 15 32 | #define MAX_ITEM_LEN 24 33 | 34 | #define swap_int(a,b) {int tmp; tmp=a; a=b; b=tmp;} 35 | 36 | /* 37 | * hack MakeAddress() into a macro so that we can pass Oracle 38 | * VARCHARs instead of char *s 39 | */ 40 | #define MakeAddressMacro(str1,str2,city,state,zip) \ 41 | {int tmp; \ 42 | tmp = MakeAlphaString(10,20,str1.arr); \ 43 | str1.len = tmp; \ 44 | tmp = MakeAlphaString(10,20,str2.arr); \ 45 | str2.len = tmp; \ 46 | tmp = MakeAlphaString(10,20,city.arr); \ 47 | city.len = tmp; \ 48 | tmp = MakeAlphaString(2,2,state.arr); \ 49 | state.len = tmp; \ 50 | tmp = MakeNumberString(9,9,zip.arr); \ 51 | zip.len = tmp;} 52 | 53 | /* 54 | * while we're at it, wrap MakeAlphaString() and MakeNumberString() 55 | * in a similar way 56 | */ 57 | #define MakeAlphaStringMacro(x,y,str) \ 58 | {int tmp; tmp = MakeAlphaString(x,y,str.arr); str.len = tmp;} 59 | #define MakeNumberStringMacro(x,y,str) \ 60 | {int tmp; tmp = MakeNumberString(x,y,str.arr); str.len = tmp;} 61 | 62 | /* 63 | * likewise, for Lastname() 64 | * counts on Lastname() producing null-terminated strings 65 | */ 66 | #define LastnameMacro(num,str) \ 67 | {Lastname(num, str.arr); str.len = strlen(str.arr);} 68 | 69 | extern long count_ware; 70 | 71 | /* Functions */ 72 | 73 | void LoadItems(); 74 | void LoadWare(); 75 | void LoadCust(); 76 | void LoadOrd(); 77 | void LoadNewOrd(); 78 | int Stock(); 79 | int District(); 80 | void Customer(); 81 | void Orders(); 82 | void New_Orders(); 83 | void MakeAddress(); 84 | void Error(); 85 | 86 | #ifdef __STDC__ 87 | void SetSeed (int seed); 88 | int RandomNumber (int min, int max); 89 | int NURand (unsigned A, unsigned x, unsigned y); 90 | int MakeAlphaString (int x, int y, char str[]); 91 | int MakeNumberString (int x, int y, char str[]); 92 | void gettimestamp (char str[], char *format, size_t n); 93 | void InitPermutation (void); 94 | int GetPermutation (void); 95 | void Lastname(int num, char* name); 96 | 97 | #endif /* __STDC__ */ 98 | 99 | #ifdef __cplusplus 100 | } 101 | #endif 102 | -------------------------------------------------------------------------------- /src/trans_if.h: -------------------------------------------------------------------------------- 1 | /* 2 | * trans_if.h 3 | * 4 | * prototypes for the transaction interface calls 5 | */ 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | int driver (int t_num); 12 | int neword (int t_num, int w_id_arg, int d_id_arg, int c_id_arg, 13 | int o_ol_cnt_arg, int o_all_local_arg, int itemid[], 14 | int supware[], int qty[]); 15 | int payment (int t_num, int w_id_arg, int d_id_arg, int byname, 16 | int c_w_id_arg, int c_d_id_arg, 17 | int c_id_arg, char c_last_arg[], float h_amount_arg); 18 | int ordstat (int t_num, int w_id, int d_id, int byname, int c_id, 19 | char c_last[]); 20 | int slev (int t_num, int w_id, int d_id, int level); 21 | int delivery (int t_num, int w_id_arg, int o_carrier_id_arg); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | --------------------------------------------------------------------------------