43 #define STAT_MAX_DIFF_TIME (60000) 44 #define SORT_BUF_MAX (4096) 45 #define BIND_STR_BUF_SIZE (4096) 46 #define SQL_INFO_TITLE_LEN (128) 48 #define CCI_ERR_FILE_NAME "replay.err" 49 #define PASS_SQL_FILE_NAME "skip.sql" 51 #define DEFAULT_DIFF_TIME_LOWER (0.01) 52 #define DEFAULT_BREAK_TIME (0.01) 54 #define INVALID_PORT_NUM (-1) 56 #define free_and_init(ptr) \ 107 static int log_prepare (FILE * cci_err, FILE * pass_sql,
int con,
char *sql_log,
T_SQL_INFO * sql_info,
110 static int log_bind_value (
int req,
T_STRING * linebuf,
char *sql_log,
char *output_result,
int remain_bind_buf);
111 static int log_execute (
int con_h,
int req,
char *sql_log,
double *execute_time);
119 static void print_result (FILE * outfp,
double max_diff_time,
double min_diff_time,
int tmp_line_len_max);
125 static int print_result_with_sort (FILE * outfp,
int print_diff_time_lower,
int num_query,
int read_buf_max);
129 static int open_file (
char *
infilename,
char *outfilename, FILE ** infp, FILE ** outfp, FILE ** cci_errfp,
131 static void close_file (FILE * infp, FILE * outfp, FILE * cci_errfp, FILE * skip_sqlfp);
169 int remain_bind_buf = 0;
173 int bind_str_offset = 0;
174 int temp_line_len = 0;
175 int temp_line_len_max = 0;
176 FILE *cci_errfp =
NULL;
177 FILE *skip_sqlfp =
NULL;
180 struct timeval begin, end;
181 double program_run_time;
187 gettimeofday (&begin,
NULL);
195 fprintf (stderr,
"cci connect error. url [%s]\n", conn_url);
199 result = cci_set_autocommit (con_h, CCI_AUTOCOMMIT_FALSE);
202 fprintf (stderr,
"cannot set autocommit mode\n");
206 if (
open_file (infilename, outfilename, &infp, &outfp, &cci_errfp, &skip_sqlfp) < 0)
213 last_offset = lseek (fileno (infp), (off_t) 0, SEEK_END);
215 fseek (infp, (off_t) 0, SEEK_SET);
218 if (linebuf_tstr ==
NULL)
220 fprintf (stderr,
"memory allocation failed\n");
247 if (strncmp (msg_p,
"execute", 7) != 0)
252 memset (&sql_info,
'\0',
sizeof (
T_SQL_INFO));
254 req =
log_prepare (cci_errfp, skip_sqlfp, con_h, msg_p, &sql_info, &summary);
275 if (strncmp (msg_p,
"bind ", 5) == 0)
279 memset (bind_str_buf,
'\0',
sizeof (bind_str_buf));
281 remain_bind_buf =
sizeof (bind_str_buf);
285 if (bind_str_offset < 0)
287 fprintf (stderr,
"log bind error [line:%d]\n", lineno);
290 sql_info.
bind_str += bind_str_offset;
291 remain_bind_buf -= bind_str_offset;
293 else if (strncmp (msg_p,
"execute", 7) == 0)
298 fprintf (cci_errfp,
"cci execute error\n");
301 fprintf (cci_errfp,
"rewrite sql[%s]\n", sql_info.
rewrite_sql);
303 fprintf (cci_errfp,
"sql[%s]\n", sql_info.
sql);
306 fprintf (cci_errfp,
"bind[%s]\n", bind_str_buf);
309 cci_close_req_handle (req);
312 cci_close_req_handle (req);
316 msg_p = strstr (msg_p,
"time");
343 temp_line_len_max = MAX (temp_line_len_max, temp_line_len);
363 gettimeofday (&end,
NULL);
366 fprintf (stdout,
"\n%s: %f sec\n",
"cubrid_replay run time", program_run_time);
369 cci_disconnect (con_h, &err_buf);
371 close_file (infp, outfp, cci_errfp, skip_sqlfp);
398 cur_offset = ftell (infp);
399 if (cur_offset >= last_offset)
406 fprintf (stderr,
"memory allocation failed\n");
415 if (linebuf[
strlen (linebuf) - 1] ==
'\n')
417 linebuf[
strlen (linebuf) - 1] =
'\0';
434 char *sql_stmt =
NULL, *
p;
435 char *result_sql =
NULL;
437 const char *query_header_str =
"Query stmt:";
439 if (cci_get_query_plan (req, &plan) < 0)
450 p = strstr (p, query_header_str);
456 p +=
strlen (query_header_str);
459 if (sql_stmt ==
NULL)
464 sql_stmt +=
strlen (query_header_str);
467 if (*sql_stmt ==
'\0')
472 rewrite_sql_len = (int)
strlen (sql_stmt);
474 result_sql = (
char *) malloc (rewrite_sql_len);
477 p = strstr (sql_stmt,
"class ");
480 snprintf (result_sql, rewrite_sql_len,
"%s", sql_stmt);
481 cci_query_info_free (plan);
497 snprintf (result_sql, rewrite_sql_len,
"select 1 %s", p);
501 fprintf (stderr,
"memory allocation failed\n");
504 cci_query_info_free (plan);
513 cci_query_info_free (plan);
533 int prepare_flag, execute_flag;
546 if (strncmp (sql_log,
"srv_h_id ", 9) != 0)
551 result =
str_to_int32 (&exec_h_id, &endp, (sql_log + 9), 10);
561 req = cci_prepare (con, sql_log, prepare_flag, &err_buf);
565 fprintf (cci_errfp,
"cci prepare error [sql:%s]\n", sql_log);
569 (void) cci_get_result_info (req, &cmd_type,
NULL);
574 if (rewrite_query ==
NULL)
577 fprintf (pass_sql,
"skip sql [%s]\n", sql_log);
578 cci_close_req_handle (req);
582 cci_close_req_handle (req);
584 req = cci_prepare (con, rewrite_query, prepare_flag, &err_buf);
588 fprintf (cci_errfp,
"cci prepare error [sql:%s]\n", rewrite_query);
595 (void) cci_get_result_info (req, &cmd_type,
NULL);
601 cci_close_req_handle (req);
608 fprintf (stderr,
"memory allocation failed\n");
625 if (strcmp (p,
"NULL") == 0)
627 type = CCI_U_TYPE_NULL;
629 else if (strcmp (p,
"CHAR") == 0)
631 type = CCI_U_TYPE_CHAR;
633 else if (strcmp (p,
"VARCHAR") == 0)
635 type = CCI_U_TYPE_STRING;
637 else if (strcmp (p,
"NCHAR") == 0)
639 type = CCI_U_TYPE_NCHAR;
641 else if (strcmp (p,
"VARNCHAR") == 0)
643 type = CCI_U_TYPE_VARNCHAR;
645 else if (strcmp (p,
"BIT") == 0)
647 type = CCI_U_TYPE_BIT;
649 else if (strcmp (p,
"VARBIT") == 0)
651 type = CCI_U_TYPE_VARBIT;
653 else if (strcmp (p,
"NUMERIC") == 0)
655 type = CCI_U_TYPE_NUMERIC;
657 else if (strcmp (p,
"UBIGINT") == 0)
659 type = CCI_U_TYPE_UBIGINT;
661 else if (strcmp (p,
"BIGINT") == 0)
663 type = CCI_U_TYPE_BIGINT;
665 else if (strcmp (p,
"UINT") == 0)
667 type = CCI_U_TYPE_UINT;
669 else if (strcmp (p,
"INT") == 0)
671 type = CCI_U_TYPE_INT;
673 else if (strcmp (p,
"USHORT") == 0)
675 type = CCI_U_TYPE_USHORT;
677 else if (strcmp (p,
"SHORT") == 0)
679 type = CCI_U_TYPE_SHORT;
681 else if (strcmp (p,
"MONETARY") == 0)
683 type = CCI_U_TYPE_MONETARY;
685 else if (strcmp (p,
"FLOAT") == 0)
687 type = CCI_U_TYPE_FLOAT;
689 else if (strcmp (p,
"DOUBLE") == 0)
691 type = CCI_U_TYPE_DOUBLE;
693 else if (strcmp (p,
"DATE") == 0)
695 type = CCI_U_TYPE_DATE;
697 else if (strcmp (p,
"TIME") == 0)
699 type = CCI_U_TYPE_TIME;
701 else if (strcmp (p,
"TIMESTAMP") == 0)
703 type = CCI_U_TYPE_TIMESTAMP;
705 else if (strcmp (p,
"DATETIME") == 0)
707 type = CCI_U_TYPE_DATETIME;
709 else if (strcmp (p,
"OBJECT") == 0)
711 type = CCI_U_TYPE_OBJECT;
713 else if (strcmp (p,
"BLOB") == 0)
715 type = CCI_U_TYPE_NULL;
717 else if (strcmp (p,
"CLOB") == 0)
719 type = CCI_U_TYPE_NULL;
721 else if (strcmp (p,
"ENUM") == 0)
723 type = CCI_U_TYPE_ENUM;
725 else if (strcmp (p,
"JSON") == 0)
727 type = CCI_U_TYPE_JSON;
765 fprintf (stderr,
"invalid bind index\n");
769 p = strchr (sql_log,
':');
778 if (strcmp (p,
"NULL") == 0)
780 value_p = (
char *)
"";
809 if (type == CCI_U_TYPE_NULL)
811 value_p = (
char *)
"";
815 fprintf (stderr,
"unknown cci type\n");
819 if ((type == CCI_U_TYPE_VARBIT) || (type == CCI_U_TYPE_BIT))
822 memset ((
char *) &vptr, 0x00,
sizeof (T_CCI_BIT));
823 vptr.size = bind_len;
824 vptr.buf = (
char *) value_p;
825 res = cci_bind_param (req, bind_idx, CCI_A_TYPE_BIT, (
void *) &(vptr), (T_CCI_U_TYPE) type, CCI_BIND_PTR);
829 cci_bind_param (req, bind_idx, CCI_A_TYPE_STR, value_p, (T_CCI_U_TYPE) type, 0);
832 if (remain_bind_buf <= 0)
839 offset = snprintf (output_result, remain_bind_buf,
"%d: '%s',END", bind_idx, value_p);
843 offset = snprintf (output_result, remain_bind_buf,
"%d: %s,END", bind_idx, value_p);
858 log_execute (
int con_h,
int req,
char *sql_log,
double *execute_time)
864 struct timeval begin, end;
865 T_CCI_ERROR cci_error;
866 CCI_AUTOCOMMIT_MODE
mode;
872 mode = cci_get_autocommit (con_h);
873 if (mode == CCI_AUTOCOMMIT_TRUE)
875 res = cci_set_autocommit (con_h, CCI_AUTOCOMMIT_FALSE);
878 fprintf (stderr,
"cannot set autocommit mode\n");
889 gettimeofday (&begin,
NULL);
891 res = cci_execute (req, (
char) execute_flag, 0, &cci_error);
901 gettimeofday (&end,
NULL);
904 res = cci_end_tran (con_h, CCI_TRAN_ROLLBACK, &cci_error);
946 diff_in_msec = (int) (diff_time * 1000);
952 else if (diff_in_msec >= 0)
962 assert (diff_in_msec < 0);
987 if (rewrite_sql !=
NULL)
989 line_len += fprintf (
br_tmpfp,
"REWRITE:%s", rewrite_sql);
991 if (bind_str !=
NULL)
993 bind_len =
strlen (bind_str);
996 line_len += fprintf (
br_tmpfp,
"BIND:%s", bind_str);
1000 line_len += fprintf (
br_tmpfp,
"\n");
1036 double avg_diff_time = 0;
1044 fprintf (stdout,
"------------------- Result Summary --------------------------\n");
1045 fprintf (stdout,
"* %-40s : %d\n",
"Total queries", summary->
num_total_query);
1046 fprintf (stdout,
"* %-40s : %d\n",
"Skipped queries (see skip.sql)", summary->
num_skip_query);
1047 fprintf (stdout,
"* %-40s : %d\n",
"Failed queries (see replay.err)", summary->
num_err_query);
1050 fprintf (stdout,
"* %-40s : %.3f\n",
"Max execution time diff", summary->
max_diff_time);
1051 fprintf (stdout,
"* %-40s : %.3f\n",
"Avg execution time diff", avg_diff_time);
1070 int res, offset = 0;
1079 p = strstr (sql,
"REWRITE:");
1088 p = strstr (endp,
"BIND:");
1097 snprintf (sql_info, buf_size,
"EXEC TIME (REPLAY / SQL_LOG / DIFF): %.3f / %.3f / %.3f\n" "SQL: %s\n",
1098 ((
double) exec_time) / 1000, ((
double) sql_log_time) / 1000, ((
double) diff_time) / 1000, sql);
1100 if (rewrite_sql && (buf_size - offset) > 0)
1102 offset += snprintf (sql_info + offset, (buf_size - offset),
"REWRITE SQL: %s\n", rewrite_sql);
1105 if (bind_str ==
NULL)
1110 while ((buf_size - offset) > 0)
1112 p = strstr (bind_str,
",END");
1116 offset += snprintf (sql_info + offset, (buf_size - offset),
"BIND %s\n", bind_str);
1144 return (diff_time2 - diff_time1);
1161 p = fgets (read_buf, read_buf_size,
br_tmpfp);
1170 p = strchr (read_buf,
'\n');
1204 next_tmp_fp = tmpfile ();
1205 if (next_tmp_fp ==
NULL)
1207 fprintf (stderr,
"cannot open temp file\n");
1211 read_buf = (
char *) malloc (read_buf_max);
1212 if (read_buf ==
NULL)
1214 fprintf (stderr,
"memory allocation failed\n");
1215 fclose (next_tmp_fp);
1219 fseek (
br_tmpfp, (off_t) 0, SEEK_SET);
1232 if (diff_time < print_diff_time_lower)
1234 fprintf (next_tmp_fp,
"%s\n", read_buf);
1241 fprintf (stderr,
"memory allocation failed\n");
1242 fclose (next_tmp_fp);
1249 fprintf (outfp,
"%s\n", result.
sql_info);
1255 fflush (next_tmp_fp);
1279 char *read_buf =
NULL;
1288 next_tmp_fp = tmpfile ();
1289 if (next_tmp_fp ==
NULL)
1291 fprintf (stderr,
"cannot open temp file\n");
1298 fprintf (stderr,
"memory allocation failed\n");
1299 fclose (next_tmp_fp);
1302 memset (result,
'\0',
sizeof (
T_SQL_RESULT) * num_query);
1304 read_buf = (
char *) malloc (read_buf_max);
1305 if (read_buf ==
NULL)
1307 fprintf (stderr,
"memory allocation failed\n");
1311 fseek (
br_tmpfp, (off_t) 0, SEEK_SET);
1324 if (diff_time >= print_diff_time_lower)
1327 if (result[i].sql_info ==
NULL)
1329 fprintf (stderr,
"memory allocation failed\n");
1343 fprintf (next_tmp_fp,
"%s\n", read_buf);
1351 for (i = 0; i < num_query; i++)
1353 fprintf (outfp,
"%s\n", result[i].sql_info);
1364 fflush (next_tmp_fp);
1377 for (i = 0; i < num_query; i++)
1381 fclose (next_tmp_fp);
1394 print_result (FILE * outfp,
double max_diff_time,
double min_diff_time,
int temp_line_len_max)
1396 int i, num_sort = 0;
1397 int max_diff_in_msec = (int) (max_diff_time * 1000) + 1;
1398 int min_diff_in_msec = (int) (min_diff_time * 1000) - 1;
1403 for (i = max_diff_in_msec; i >= 0; i--)
1425 for (i = -1; i >= min_diff_in_msec; i--)
1468 c =
getopt (argc, argv,
"rd:u:p:I:P:F:T:h:D:");
1500 break_time_in_sec = atof (
optarg);
1508 goto date_format_err;
1515 goto date_format_err;
1524 break_time = (int) (break_time_in_sec * 1000);
1526 num_file_arg = argc -
optind;
1527 if (num_file_arg != 2)
1541 "usage : %s -I broker_host -P broker_port -d database_name infile outfile [OPTION] \n" "\n" 1542 "valid options:\n" " -u user name\n" " -p user password\n" 1543 " -h break time between query execute; default: %.3f(sec)\n" 1544 " -r enable to rewrite update/delete query to select query\n" 1545 " -D minimum value of time difference make print result; default: %.3f(sec)\n" 1546 " -F datetime when start to replay sql_log\n" " -T datetime when end to replay sql_log\n", argv[0],
1551 fprintf (stderr,
"invalid date. valid date format is yy-mm-dd hh:mm:ss.\n");
1566 open_file (
char *
infilename,
char *outfilename, FILE ** infp, FILE ** outfp, FILE ** cci_errfp, FILE ** skip_sqlfp)
1568 *infp = fopen (infilename,
"r");
1571 fprintf (stderr,
"cannot open input file '%s'\n", infilename);
1575 *outfp = fopen (outfilename,
"w");
1578 fprintf (stderr,
"cannot open output file '%s'\n", outfilename);
1585 fprintf (stderr,
"cannot open temp file\n");
1590 if (*cci_errfp ==
NULL)
1597 if (*skip_sqlfp ==
NULL)
1606 close_file (*infp, *outfp, *cci_errfp, *skip_sqlfp);
1619 close_file (FILE * infp, FILE * outfp, FILE * cci_errfp, FILE * skip_sqlfp)
1636 if (cci_errfp !=
NULL)
1641 if (skip_sqlfp !=
NULL)
1643 fclose (skip_sqlfp);
1654 char *outfilename =
NULL;
1663 assert (start_arg < argc);
1665 infilename = argv[start_arg];
1667 outfilename = argv[start_arg + 1];
#define SLEEP_MILISEC(sec, msec)
static int open_file(char *infilename, char *outfilename, FILE **infp, FILE **outfp, FILE **cci_errfp, FILE **skip_sqlfp)
static int print_temp_result(char *sql_log, T_SQL_INFO *info)
static int log_replay(char *infilename, char *outfilename)
static int print_result_without_sort(FILE *outfp, int print_diff_time_lower, int read_buf_max)
char * get_msg_start_ptr(char *linebuf)
int getopt(int, char *const *, const char *)
#define BIND_STR_BUF_SIZE
int parse_int(int *ret_p, const char *str_p, int base)
static int log_execute(int con_h, int req, char *sql_log, double *execute_time)
static char * get_query_stmt_from_plan(int req)
static void update_summary_info(T_SUMMARY_INFO *summary, T_SQL_INFO *sql_info)
static double print_result_diff_time_lower
static char check_date_flag
#define PASS_SQL_FILE_NAME
int t_string_len(T_STRING *t_str)
static void get_sql_time_info(char *sql_log, T_SQL_INFO *info)
static unsigned int num_faster_queries[STAT_MAX_DIFF_TIME]
static int result_sort_func(const void *arg1, const void *arg2)
static READ_RESULT get_temp_file_line(char *read_buf, unsigned int read_buf_size, int *diff_time, char **endp)
char * t_string_str(T_STRING *t_str)
#define free_and_init(ptr)
static int get_args(int argc, char *argv[])
#define STAT_MAX_DIFF_TIME
static void update_diff_time_statistics(double diff_time)
static enum scanner_mode mode
static void print_result(FILE *outfp, double max_diff_time, double min_diff_time, int tmp_line_len_max)
static char rewrite_query_flag
int is_cas_log(char *str)
static char * make_sql_info(char *info_buf, char *start_p, int diff_time, int buf_size)
int str_to_int32(int *ret_p, char **end_p, const char *str_p, int base)
#define GET_CUR_DATE_STR(BUF, LINEBUF)
static int log_bind_value(int req, T_STRING *linebuf, char *sql_log, char *output_result, int remain_bind_buf)
int t_string_bind_len(T_STRING *t_str)
static char * get_next_log_line(FILE *infp, T_STRING *linebuf_tstr, const off_t last_offset, int *lineno)
int main(int argc, char *argv[])
int ut_check_log_valid_time(const char *log_date, const char *from_date, const char *to_date)
#define DEFAULT_BREAK_TIME
static void error(const char *msg)
static void print_summary_info(T_SUMMARY_INFO *summary)
static unsigned int num_slower_queries[STAT_MAX_DIFF_TIME]
enum temp_read_result READ_RESULT
static int print_result_with_sort(FILE *outfp, int print_diff_time_lower, int num_query, int read_buf_max)
double ut_diff_time(struct timeval *begin, struct timeval *end)
static char from_date[128]
T_STRING * t_string_make(int init_size)
#define DEFAULT_DIFF_TIME_LOWER
static int get_cci_type(char *p)
char * strdup(const char *str)
char * ut_get_execute_type(char *msg_p, int *prepare_flag, int *execute_flag)
static int log_prepare(FILE *cci_err, FILE *pass_sql, int con, char *sql_log, T_SQL_INFO *sql_info, T_SUMMARY_INFO *summary)
static void close_file(FILE *infp, FILE *outfp, FILE *cci_errfp, FILE *skip_sqlfp)
#define SQL_INFO_TITLE_LEN
int ut_get_line(FILE *fp, T_STRING *t_str, char **out_str, int *lineno)
#define CCI_ERR_FILE_NAME
int str_to_log_date_format(char *str, char *date_format_str)