CUBRID Engine  latest
broker_log_replay.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * broker_log_replay.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #if defined(WINDOWS)
30 #include <io.h>
31 #else /* WINDOWS */
32 #include <unistd.h>
33 #endif /* !WINDOWS */
34 #include <assert.h>
35 
36 #include "cubrid_getopt.h"
37 #include "cas_common.h"
38 #include "cas_cci.h"
39 #include "broker_log_util.h"
40 #include "porting.h"
41 #include "error_code.h"
42 
43 #define STAT_MAX_DIFF_TIME (60000) /* 60 * 1000 : 10 min */
44 #define SORT_BUF_MAX (4096)
45 #define BIND_STR_BUF_SIZE (4096)
46 #define SQL_INFO_TITLE_LEN (128)
47 
48 #define CCI_ERR_FILE_NAME "replay.err"
49 #define PASS_SQL_FILE_NAME "skip.sql"
50 
51 #define DEFAULT_DIFF_TIME_LOWER (0.01) /* 10 millisecond */
52 #define DEFAULT_BREAK_TIME (0.01) /* 10 millisecond */
53 
54 #define INVALID_PORT_NUM (-1)
55 
56 #define free_and_init(ptr) \
57  do { \
58  if ((ptr)) { \
59  free ((ptr)); \
60  (ptr) = NULL; \
61  } \
62  } while (0)
63 
65 {
66  READ_STOP = -1,
69 };
71 
72 typedef struct t_sql_info T_SQL_INFO;
73 struct t_sql_info
74 {
75  char *sql;
76  char *rewrite_sql;
77  char *bind_str;
78  double exec_time;
79  double sql_log_time;
80  double diff_time;
81 };
82 
85 {
91  double sum_diff_time;
92  double max_diff_time;
93  double min_diff_time;
94 };
95 
96 typedef struct t_sql_result T_SQL_RESULT;
98 {
99  int diff_time;
100  char *sql_info;
101 };
102 
103 static int log_replay (char *infilename, char *outfilename);
104 static char *get_next_log_line (FILE * infp, T_STRING * linebuf_tstr, const off_t last_offset, int *lineno);
105 
106 static char *get_query_stmt_from_plan (int req);
107 static int log_prepare (FILE * cci_err, FILE * pass_sql, int con, char *sql_log, T_SQL_INFO * sql_info,
108  T_SUMMARY_INFO * summary);
109 static int get_cci_type (char *p);
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);
112 
113 static void get_sql_time_info (char *sql_log, T_SQL_INFO * info);
114 static void update_diff_time_statistics (double diff_time);
115 
116 static int print_temp_result (char *sql_log, T_SQL_INFO * info);
117 static void update_summary_info (T_SUMMARY_INFO * summary, T_SQL_INFO * sql_info);
118 static void print_summary_info (T_SUMMARY_INFO * summary);
119 static void print_result (FILE * outfp, double max_diff_time, double min_diff_time, int tmp_line_len_max);
120 
121 static char *make_sql_info (char *info_buf, char *start_p, int diff_time, int buf_size);
122 static int result_sort_func (const void *arg1, const void *arg2);
123 static READ_RESULT get_temp_file_line (char *read_buf, unsigned int read_buf_size, int *diff_time, char **endp);
124 static int print_result_without_sort (FILE * outfp, int print_diff_time_lower, int read_buf_max);
125 static int print_result_with_sort (FILE * outfp, int print_diff_time_lower, int num_query, int read_buf_max);
126 
127 static int get_args (int argc, char *argv[]);
128 
129 static int open_file (char *infilename, char *outfilename, FILE ** infp, FILE ** outfp, FILE ** cci_errfp,
130  FILE ** skip_sqlfp);
131 static void close_file (FILE * infp, FILE * outfp, FILE * cci_errfp, FILE * skip_sqlfp);
132 
133 static char *host = NULL;
135 static char *dbname = NULL;
136 static char *dbuser = NULL;
137 static char *dbpasswd = NULL;
138 
139 static char from_date[128] = "";
140 static char to_date[128] = "";
141 static char check_date_flag = 0;
142 
143 static char rewrite_query_flag = 0;
144 
145 static int break_time = 0;
147 
148 static FILE *br_tmpfp = NULL;
149 
150 static unsigned int num_slower_queries[STAT_MAX_DIFF_TIME] = { 0 };
151 static unsigned int num_faster_queries[STAT_MAX_DIFF_TIME] = { 0 };
152 
153 /*
154  * log_replay() - log_replay main routine
155  * return: NO_ERROR or ER_FAILED
156  * infp(in): input file pointer
157  * outfp(in): output file pointer
158  * last_offset(in): last offset of input file
159  */
160 static int
161 log_replay (char *infilename, char *outfilename)
162 {
163  char *linebuf;
164  int lineno = 0;
165  char *msg_p;
166  T_STRING *linebuf_tstr = NULL;
167  char date_str[DATE_STR_LEN + 1];
168  char bind_str_buf[BIND_STR_BUF_SIZE];
169  int remain_bind_buf = 0;
170  char conn_url[1024];
171  int con_h, req;
172  int result = 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;
178  FILE *outfp = NULL;
179  FILE *infp = NULL;
180  struct timeval begin, end;
181  double program_run_time;
182  off_t last_offset;
183  T_SQL_INFO sql_info;
184  T_SUMMARY_INFO summary;
185  T_CCI_ERROR err_buf;
186 
187  gettimeofday (&begin, NULL);
188 
189  memset (&summary, 0, sizeof (T_SUMMARY_INFO));
190 
191  snprintf (conn_url, sizeof (conn_url), "cci:cubrid:%s:%u:%s:::", host, broker_port, dbname);
192  con_h = cci_connect_with_url (conn_url, dbuser, dbpasswd);
193  if (con_h < 0)
194  {
195  fprintf (stderr, "cci connect error. url [%s]\n", conn_url);
196  return ER_FAILED;
197  }
198 
199  result = cci_set_autocommit (con_h, CCI_AUTOCOMMIT_FALSE);
200  if (result < 0)
201  {
202  fprintf (stderr, "cannot set autocommit mode\n");
203  goto end;
204  }
205 
206  if (open_file (infilename, outfilename, &infp, &outfp, &cci_errfp, &skip_sqlfp) < 0)
207  {
208  result = ER_FAILED;
209  goto end;
210  }
211 
212  assert (infp != NULL);
213  last_offset = lseek (fileno (infp), (off_t) 0, SEEK_END);
214 
215  fseek (infp, (off_t) 0, SEEK_SET);
216 
217  linebuf_tstr = t_string_make (1024);
218  if (linebuf_tstr == NULL)
219  {
220  fprintf (stderr, "memory allocation failed\n");
221  result = ER_FAILED;
222  goto end;
223  }
224 
225  while (1)
226  {
227  linebuf = get_next_log_line (infp, linebuf_tstr, last_offset, &lineno);
228  if (linebuf == NULL)
229  {
230  break;
231  }
232  if (is_cas_log (linebuf) == 0)
233  {
234  continue;
235  }
236 
237  if (check_date_flag == 1)
238  {
239  GET_CUR_DATE_STR (date_str, linebuf);
240  if (ut_check_log_valid_time (date_str, from_date, to_date) < 0)
241  {
242  continue;
243  }
244  }
245 
246  msg_p = get_msg_start_ptr (linebuf);
247  if (strncmp (msg_p, "execute", 7) != 0)
248  {
249  continue;
250  }
251 
252  memset (&sql_info, '\0', sizeof (T_SQL_INFO));
253 
254  req = log_prepare (cci_errfp, skip_sqlfp, con_h, msg_p, &sql_info, &summary);
255  if (req < 0)
256  {
257  free_and_init (sql_info.sql);
258  free_and_init (sql_info.rewrite_sql);
259  continue;
260  }
261 
262  while (1)
263  {
264  linebuf = get_next_log_line (infp, linebuf_tstr, last_offset, &lineno);
265  if (linebuf == NULL)
266  {
267  break;
268  }
269  if (is_cas_log (linebuf) == 0)
270  {
271  continue;
272  }
273 
274  msg_p = get_msg_start_ptr (linebuf);
275  if (strncmp (msg_p, "bind ", 5) == 0)
276  {
277  if (sql_info.bind_str == NULL)
278  {
279  memset (bind_str_buf, '\0', sizeof (bind_str_buf));
280  sql_info.bind_str = bind_str_buf;
281  remain_bind_buf = sizeof (bind_str_buf);
282  }
283 
284  bind_str_offset = log_bind_value (req, linebuf_tstr, msg_p, sql_info.bind_str, remain_bind_buf);
285  if (bind_str_offset < 0)
286  {
287  fprintf (stderr, "log bind error [line:%d]\n", lineno);
288  break;
289  }
290  sql_info.bind_str += bind_str_offset;
291  remain_bind_buf -= bind_str_offset;
292  }
293  else if (strncmp (msg_p, "execute", 7) == 0)
294  {
295  result = log_execute (con_h, req, msg_p, &sql_info.exec_time);
296  if (result < 0)
297  {
298  fprintf (cci_errfp, "cci execute error\n");
299  if (sql_info.rewrite_sql)
300  {
301  fprintf (cci_errfp, "rewrite sql[%s]\n", sql_info.rewrite_sql);
302  }
303  fprintf (cci_errfp, "sql[%s]\n", sql_info.sql);
304  if (sql_info.bind_str)
305  {
306  fprintf (cci_errfp, "bind[%s]\n", bind_str_buf);
307  }
308  summary.num_err_query++;
309  cci_close_req_handle (req);
310  break;
311  }
312  cci_close_req_handle (req);
313 
314  summary.num_exec_query++;
315 
316  msg_p = strstr (msg_p, "time");
317  if (msg_p == NULL)
318  {
319  /* unexpected sql log. pass this sql to write result */
320  break;
321  }
322 
323  if (sql_info.bind_str != NULL)
324  {
325  /* restore bind_str with first address of bind string buffer */
326  sql_info.bind_str = bind_str_buf;
327  }
328 
329  get_sql_time_info (msg_p + 5, &sql_info);
330 
331  update_summary_info (&summary, &sql_info);
332 
334  {
335  break;
336  }
337 
339 
340  /* we write result in temp file to order after all sql_log execute */
341  temp_line_len = print_temp_result (msg_p, &sql_info);
342 
343  temp_line_len_max = MAX (temp_line_len_max, temp_line_len);
344 
345  break;
346  }
347  else
348  {
349  break;
350  }
351  }
352 
353  free_and_init (sql_info.sql);
354  free_and_init (sql_info.rewrite_sql);
355  }
356 
357  fflush (br_tmpfp);
358 
359  print_summary_info (&summary);
360 
361  print_result (outfp, summary.max_diff_time, summary.min_diff_time, temp_line_len_max + 1);
362 
363  gettimeofday (&end, NULL);
364  program_run_time = ut_diff_time (&begin, &end);
365 
366  fprintf (stdout, "\n%s: %f sec\n", "cubrid_replay run time", program_run_time);
367 
368 end:
369  cci_disconnect (con_h, &err_buf);
370 
371  close_file (infp, outfp, cci_errfp, skip_sqlfp);
372 
373  if (linebuf_tstr)
374  {
375  free_and_init (linebuf_tstr->data);
376  }
377  free_and_init (linebuf_tstr);
378 
379  return result;
380 }
381 
382 /*
383  * get_next_log_line() -
384  * return: address of linebuf
385  * infp(in):
386  * linebuf_tstr(in):
387  * last_offset(in):
388  * lineno(in/out):
389  */
390 static char *
391 get_next_log_line (FILE * infp, T_STRING * linebuf_tstr, const off_t last_offset, int *lineno)
392 {
393  char *linebuf;
394  off_t cur_offset;
395 
396  assert (lineno != NULL);
397 
398  cur_offset = ftell (infp);
399  if (cur_offset >= last_offset)
400  {
401  return NULL;
402  }
403 
404  if (ut_get_line (infp, linebuf_tstr, NULL, NULL) < 0)
405  {
406  fprintf (stderr, "memory allocation failed\n");
407  return NULL;
408  }
409  if (t_string_len (linebuf_tstr) <= 0)
410  {
411  return NULL;
412  }
413  linebuf = t_string_str (linebuf_tstr);
414 
415  if (linebuf[strlen (linebuf) - 1] == '\n')
416  {
417  linebuf[strlen (linebuf) - 1] = '\0';
418  }
419 
420  (*lineno)++;
421 
422  return linebuf;
423 }
424 
425 /*
426  * get_query_stmt_from_plan() -
427  * return: sql statment from query plan or NULL
428  * req(in):
429  */
430 static char *
432 {
433  char *plan = NULL;
434  char *sql_stmt = NULL, *p;
435  char *result_sql = NULL;
436  int rewrite_sql_len;
437  const char *query_header_str = "Query stmt:";
438 
439  if (cci_get_query_plan (req, &plan) < 0)
440  {
441  return NULL;
442  }
443 
444  p = plan;
445 
446  while (1)
447  {
448  /* we find the last Query stmt: */
449 
450  p = strstr (p, query_header_str);
451  if (p == NULL)
452  {
453  break;
454  }
455  sql_stmt = p;
456  p += strlen (query_header_str);
457  }
458 
459  if (sql_stmt == NULL)
460  {
461  goto error;
462  }
463 
464  sql_stmt += strlen (query_header_str);
465 
466  trim (sql_stmt);
467  if (*sql_stmt == '\0')
468  {
469  goto error;
470  }
471 
472  rewrite_sql_len = (int) strlen (sql_stmt);
473 
474  result_sql = (char *) malloc (rewrite_sql_len);
475  if (result_sql)
476  {
477  p = strstr (sql_stmt, "class ");
478  if (p == NULL)
479  {
480  snprintf (result_sql, rewrite_sql_len, "%s", sql_stmt);
481  cci_query_info_free (plan);
482  return result_sql;
483  }
484  p += 6;
485 
486  p = strchr (p, ' ');
487  if (p == NULL)
488  {
489  /* in this case, we found invalid pattern. just return NULL */
490  goto error;
491  }
492  if (*(p - 1) == ',')
493  {
494  p--;
495  }
496 
497  snprintf (result_sql, rewrite_sql_len, "select 1 %s", p);
498  }
499  else
500  {
501  fprintf (stderr, "memory allocation failed\n");
502  }
503 
504  cci_query_info_free (plan);
505 
506  return result_sql;
507 
508 error:
509  free_and_init (result_sql);
510 
511  if (plan)
512  {
513  cci_query_info_free (plan);
514  }
515 
516  return NULL;
517 }
518 
519 /*
520  * log_prepare() -
521  * return: request handle id or ER_FAILED
522  * cci_errfp(in): cci error file pointer
523  * pass_sql(in): pass sql file pointer
524  * con(in): connection handle id
525  * sql_log(in):
526  * sql_info(out):
527  * summary(out):
528  */
529 static int
530 log_prepare (FILE * cci_errfp, FILE * pass_sql, int con, char *sql_log, T_SQL_INFO * sql_info, T_SUMMARY_INFO * summary)
531 {
532  int req, exec_h_id;
533  int prepare_flag, execute_flag;
534  int result;
535  char *endp;
536  char *rewrite_query;
537  T_CCI_ERROR err_buf;
538  T_CCI_CUBRID_STMT cmd_type = CUBRID_STMT_NONE;
539 
540  sql_log = ut_get_execute_type (sql_log, &prepare_flag, &execute_flag);
541  if (sql_log == NULL)
542  {
543  return ER_FAILED;
544  }
545 
546  if (strncmp (sql_log, "srv_h_id ", 9) != 0)
547  {
548  return ER_FAILED;
549  }
550 
551  result = str_to_int32 (&exec_h_id, &endp, (sql_log + 9), 10);
552  if (result != 0)
553  {
554  return ER_FAILED;
555  }
556 
557  summary->num_total_query++;
558 
559  sql_log = endp + 1;
560 
561  req = cci_prepare (con, sql_log, prepare_flag, &err_buf);
562  if (req < 0)
563  {
564  summary->num_err_query++;
565  fprintf (cci_errfp, "cci prepare error [sql:%s]\n", sql_log);
566  return ER_FAILED;
567  }
568 
569  (void) cci_get_result_info (req, &cmd_type, NULL);
570 
571  if (rewrite_query_flag == 1 && (cmd_type == CUBRID_STMT_UPDATE || cmd_type == CUBRID_STMT_DELETE))
572  {
573  rewrite_query = get_query_stmt_from_plan (req);
574  if (rewrite_query == NULL)
575  {
576  summary->num_skip_query++;
577  fprintf (pass_sql, "skip sql [%s]\n", sql_log);
578  cci_close_req_handle (req);
579  return ER_FAILED;
580  }
581 
582  cci_close_req_handle (req);
583 
584  req = cci_prepare (con, rewrite_query, prepare_flag, &err_buf);
585  if (req < 0)
586  {
587  summary->num_err_query++;
588  fprintf (cci_errfp, "cci prepare error [sql:%s]\n", rewrite_query);
589  free_and_init (rewrite_query);
590  return ER_FAILED;
591  }
592 
593  sql_info->rewrite_sql = rewrite_query;
594 
595  (void) cci_get_result_info (req, &cmd_type, NULL);
596  }
597 
598  if (cmd_type != CUBRID_STMT_SELECT)
599  {
600  /* skip this sql stmt */
601  cci_close_req_handle (req);
602  return ER_FAILED;
603  }
604 
605  sql_info->sql = strdup (sql_log);
606  if (sql_info->sql == NULL)
607  {
608  fprintf (stderr, "memory allocation failed\n");
609  return ER_FAILED;
610  }
611 
612  return req;
613 }
614 
615 /*
616  * get_cci_type() - get bind cci type from sql log
617  * return: CCI_U_TYPE
618  * p(in):
619  */
620 static int
622 {
623  int type;
624 
625  if (strcmp (p, "NULL") == 0)
626  {
627  type = CCI_U_TYPE_NULL;
628  }
629  else if (strcmp (p, "CHAR") == 0)
630  {
631  type = CCI_U_TYPE_CHAR;
632  }
633  else if (strcmp (p, "VARCHAR") == 0)
634  {
635  type = CCI_U_TYPE_STRING;
636  }
637  else if (strcmp (p, "NCHAR") == 0)
638  {
639  type = CCI_U_TYPE_NCHAR;
640  }
641  else if (strcmp (p, "VARNCHAR") == 0)
642  {
643  type = CCI_U_TYPE_VARNCHAR;
644  }
645  else if (strcmp (p, "BIT") == 0)
646  {
647  type = CCI_U_TYPE_BIT;
648  }
649  else if (strcmp (p, "VARBIT") == 0)
650  {
651  type = CCI_U_TYPE_VARBIT;
652  }
653  else if (strcmp (p, "NUMERIC") == 0)
654  {
655  type = CCI_U_TYPE_NUMERIC;
656  }
657  else if (strcmp (p, "UBIGINT") == 0)
658  {
659  type = CCI_U_TYPE_UBIGINT;
660  }
661  else if (strcmp (p, "BIGINT") == 0)
662  {
663  type = CCI_U_TYPE_BIGINT;
664  }
665  else if (strcmp (p, "UINT") == 0)
666  {
667  type = CCI_U_TYPE_UINT;
668  }
669  else if (strcmp (p, "INT") == 0)
670  {
671  type = CCI_U_TYPE_INT;
672  }
673  else if (strcmp (p, "USHORT") == 0)
674  {
675  type = CCI_U_TYPE_USHORT;
676  }
677  else if (strcmp (p, "SHORT") == 0)
678  {
679  type = CCI_U_TYPE_SHORT;
680  }
681  else if (strcmp (p, "MONETARY") == 0)
682  {
683  type = CCI_U_TYPE_MONETARY;
684  }
685  else if (strcmp (p, "FLOAT") == 0)
686  {
687  type = CCI_U_TYPE_FLOAT;
688  }
689  else if (strcmp (p, "DOUBLE") == 0)
690  {
691  type = CCI_U_TYPE_DOUBLE;
692  }
693  else if (strcmp (p, "DATE") == 0)
694  {
695  type = CCI_U_TYPE_DATE;
696  }
697  else if (strcmp (p, "TIME") == 0)
698  {
699  type = CCI_U_TYPE_TIME;
700  }
701  else if (strcmp (p, "TIMESTAMP") == 0)
702  {
703  type = CCI_U_TYPE_TIMESTAMP;
704  }
705  else if (strcmp (p, "DATETIME") == 0)
706  {
707  type = CCI_U_TYPE_DATETIME;
708  }
709  else if (strcmp (p, "OBJECT") == 0)
710  {
711  type = CCI_U_TYPE_OBJECT;
712  }
713  else if (strcmp (p, "BLOB") == 0)
714  {
715  type = CCI_U_TYPE_NULL;
716  }
717  else if (strcmp (p, "CLOB") == 0)
718  {
719  type = CCI_U_TYPE_NULL;
720  }
721  else if (strcmp (p, "ENUM") == 0)
722  {
723  type = CCI_U_TYPE_ENUM;
724  }
725  else if (strcmp (p, "JSON") == 0)
726  {
727  type = CCI_U_TYPE_JSON;
728  }
729  else
730  {
731  type = -1;
732  }
733 
734  return type;
735 }
736 
737 /*
738  * log_bind_value() -
739  * return: offset of bind string buffer or ER_FAILED
740  * req(in):
741  * linebuf(in):
742  * sql_log(in):
743  * output_result(out):
744  * remain_bind_buf(in):
745  */
746 static int
747 log_bind_value (int req, T_STRING * linebuf, char *sql_log, char *output_result, int remain_bind_buf)
748 {
749  char *p, *q, *r;
750  char *value_p;
751  char *endp;
752  int type, res;
753  int bind_idx;
754  int bind_len = 0;
755  int result = 0;
756  int offset = 0;
757 
758  assert (req > 0);
759 
760  sql_log += 5;
761 
762  result = str_to_int32 (&bind_idx, &endp, sql_log, 10);
763  if (result < 0)
764  {
765  fprintf (stderr, "invalid bind index\n");
766  return ER_FAILED;
767  }
768 
769  p = strchr (sql_log, ':');
770  if (p == NULL)
771  {
772  return ER_FAILED;
773  }
774  p += 2;
775  q = strchr (p, ' ');
776  if (q == NULL)
777  {
778  if (strcmp (p, "NULL") == 0)
779  {
780  value_p = (char *) "";
781  }
782  else
783  {
784  return ER_FAILED;
785  }
786  }
787  else
788  {
789  bind_len = t_string_bind_len (linebuf);
790  if (bind_len > 0)
791  {
792  r = strchr (q, ')');
793  if (r == NULL)
794  {
795  return ER_FAILED;
796  }
797  *q = '\0';
798  *r = '\0';
799  value_p = r + 1;
800  }
801  else
802  {
803  *q = '\0';
804  value_p = q + 1;
805  }
806  }
807 
808  type = get_cci_type (p);
809  if (type == CCI_U_TYPE_NULL)
810  {
811  value_p = (char *) "";
812  }
813  else if (type == -1)
814  {
815  fprintf (stderr, "unknown cci type\n");
816  return ER_FAILED;
817  }
818 
819  if ((type == CCI_U_TYPE_VARBIT) || (type == CCI_U_TYPE_BIT))
820  {
821  T_CCI_BIT vptr;
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);
826  }
827  else
828  {
829  cci_bind_param (req, bind_idx, CCI_A_TYPE_STR, value_p, (T_CCI_U_TYPE) type, 0);
830  }
831 
832  if (remain_bind_buf <= 0)
833  {
834  return NO_ERROR;
835  }
836 
837  if (bind_len > 0)
838  {
839  offset = snprintf (output_result, remain_bind_buf, "%d: '%s',END", bind_idx, value_p);
840  }
841  else
842  {
843  offset = snprintf (output_result, remain_bind_buf, "%d: %s,END", bind_idx, value_p);
844  }
845 
846  return offset;
847 }
848 
849 /*
850  * log_execute() -
851  * return: NO_ERROR or ER_FAILED
852  * con_h(in):
853  * req(in):
854  * sql_log(in):
855  * execute_time(out):
856  */
857 static int
858 log_execute (int con_h, int req, char *sql_log, double *execute_time)
859 {
860  char *msg_p;
861  int prepare_flag;
862  int execute_flag;
863  int res;
864  struct timeval begin, end;
865  T_CCI_ERROR cci_error;
866  CCI_AUTOCOMMIT_MODE mode;
867 
868  assert (req > 0);
869 
870  *execute_time = 0;
871 
872  mode = cci_get_autocommit (con_h);
873  if (mode == CCI_AUTOCOMMIT_TRUE)
874  {
875  res = cci_set_autocommit (con_h, CCI_AUTOCOMMIT_FALSE);
876  if (res < 0)
877  {
878  fprintf (stderr, "cannot set autocommit mode\n");
879  return ER_FAILED;
880  }
881  }
882 
883  msg_p = ut_get_execute_type (sql_log, &prepare_flag, &execute_flag);
884  if (msg_p == NULL)
885  {
886  return ER_FAILED;
887  }
888 
889  gettimeofday (&begin, NULL);
890 
891  res = cci_execute (req, (char) execute_flag, 0, &cci_error);
892  if (res < 0)
893  {
894  if (break_time > 0)
895  {
897  }
898  return res;
899  }
900 
901  gettimeofday (&end, NULL);
902  *execute_time = ut_diff_time (&begin, &end);
903 
904  res = cci_end_tran (con_h, CCI_TRAN_ROLLBACK, &cci_error);
905 
906  if (break_time > 0)
907  {
909  }
910 
911  return res;
912 }
913 
914 /*
915  * get_sql_time_info() -
916  * return: void
917  * sql_info(in):
918  * info(in/out):
919  */
920 static void
921 get_sql_time_info (char *sql_log, T_SQL_INFO * info)
922 {
923  assert (info != NULL);
924 
925  sscanf (sql_log, "%lf", &info->sql_log_time);
926 
927  info->diff_time = info->exec_time - info->sql_log_time;
928 
929  return;
930 }
931 
932 /*
933  * update_diff_time_statistics() -
934  * return: void
935  * diff_time(in):
936  */
937 static void
939 {
940  /*
941  * we save count of query witch have specific diff time
942  * to use when order with diff time
943  */
944  int diff_in_msec;
945 
946  diff_in_msec = (int) (diff_time * 1000);
947 
948  if (diff_in_msec >= STAT_MAX_DIFF_TIME)
949  {
951  }
952  else if (diff_in_msec >= 0)
953  {
954  num_slower_queries[diff_in_msec]++;
955  }
956  else if (diff_in_msec <= (-STAT_MAX_DIFF_TIME))
957  {
959  }
960  else
961  {
962  assert (diff_in_msec < 0);
963  num_faster_queries[(-diff_in_msec)]++;
964  }
965 
966  return;
967 }
968 
969 /*
970  * print_temp_result() - save temp result until all sql are executed
971  * return: line length
972  * sql_log(in):
973  * info(in):
974  */
975 static int
976 print_temp_result (char *sql_log, T_SQL_INFO * info)
977 {
978  size_t bind_len;
979  int line_len = 0;
980  char *rewrite_sql = info->rewrite_sql;
981  char *bind_str = info->bind_str;
982 
983  line_len +=
984  fprintf (br_tmpfp, "%d %d %d %s", (int) (info->diff_time * 1000), (int) (info->exec_time * 1000),
985  (int) (info->sql_log_time * 1000), info->sql);
986 
987  if (rewrite_sql != NULL)
988  {
989  line_len += fprintf (br_tmpfp, "REWRITE:%s", rewrite_sql);
990  }
991  if (bind_str != NULL)
992  {
993  bind_len = strlen (bind_str);
994  if (bind_len > 0)
995  {
996  line_len += fprintf (br_tmpfp, "BIND:%s", bind_str);
997  }
998  }
999 
1000  line_len += fprintf (br_tmpfp, "\n");
1001 
1002  return line_len;
1003 }
1004 
1005 /*
1006  * update_summary_info() -
1007  * return: void
1008  * summary(out):
1009  * sql_info(out):
1010  */
1011 static void
1013 {
1014  summary->sum_diff_time += sql_info->diff_time;
1015 
1016  if (sql_info->diff_time >= print_result_diff_time_lower)
1017  {
1018  summary->num_diff_time_query++;
1019  }
1020 
1021  summary->max_diff_time = MAX (summary->max_diff_time, sql_info->diff_time);
1022  /* min_diff_time is used for knowing lower bound of diff time when order result */
1023  summary->min_diff_time = MIN (summary->min_diff_time, sql_info->diff_time);
1024 
1025  return;
1026 }
1027 
1028 /*
1029  * print_summary_info () -
1030  * return: void
1031  * summary(in):
1032  */
1033 static void
1035 {
1036  double avg_diff_time = 0;
1037  char msg_buf[64];
1038 
1039  if (summary->num_exec_query != 0)
1040  {
1041  avg_diff_time = summary->sum_diff_time / summary->num_exec_query;
1042  }
1043 
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);
1048  snprintf (msg_buf, sizeof (msg_buf), "Slow queries (time diff > %.3f secs)", print_result_diff_time_lower);
1049  fprintf (stdout, "* %-40s : %d\n", msg_buf, summary->num_diff_time_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);
1052 
1053  return;
1054 }
1055 
1056 /*
1057  * make_sql_info() - make output result from temp file
1058  * return: memory address of result or NULL
1059  * sql_info(in):
1060  * start_p(in):
1061  * diff_time(in):
1062  * buf_size(in):
1063  */
1064 static char *
1065 make_sql_info (char *sql_info, char *start_p, int diff_time, int buf_size)
1066 {
1067  char *endp, *p;
1068  char *sql = NULL, *rewrite_sql = NULL;
1069  char *bind_str = NULL;
1070  int res, offset = 0;
1071  int sql_log_time, exec_time;
1072 
1073  res = str_to_int32 (&exec_time, &endp, start_p, 10);
1074 
1075  p = endp + 1;
1076  res = str_to_int32 (&sql_log_time, &endp, p, 10);
1077 
1078  sql = endp + 1;
1079  p = strstr (sql, "REWRITE:");
1080  if (p)
1081  {
1082  *p = '\0';
1083  p += 8;
1084  rewrite_sql = p;
1085  endp = p;
1086  }
1087 
1088  p = strstr (endp, "BIND:");
1089  if (p)
1090  {
1091  *p = '\0';
1092  p += 5;
1093  bind_str = p;
1094  }
1095 
1096  offset =
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);
1099 
1100  if (rewrite_sql && (buf_size - offset) > 0)
1101  {
1102  offset += snprintf (sql_info + offset, (buf_size - offset), "REWRITE SQL: %s\n", rewrite_sql);
1103  }
1104 
1105  if (bind_str == NULL)
1106  {
1107  return sql_info;
1108  }
1109 
1110  while ((buf_size - offset) > 0)
1111  {
1112  p = strstr (bind_str, ",END");
1113  if (p)
1114  {
1115  *p = '\0';
1116  offset += snprintf (sql_info + offset, (buf_size - offset), "BIND %s\n", bind_str);
1117  p += 4;
1118  bind_str = p;
1119  }
1120  else
1121  {
1122  break;
1123  }
1124  }
1125 
1126  return sql_info;
1127 }
1128 
1129 /*
1130  * result_sort_func() - compare sql with diff time
1131  * return: difference of diff time of two sql
1132  * arg1(in):
1133  * arg2(in):
1134  */
1135 static int
1136 result_sort_func (const void *arg1, const void *arg2)
1137 {
1138  int diff_time1;
1139  int diff_time2;
1140 
1141  diff_time1 = ((T_SQL_RESULT *) arg1)->diff_time;
1142  diff_time2 = ((T_SQL_RESULT *) arg2)->diff_time;
1143 
1144  return (diff_time2 - diff_time1);
1145 }
1146 
1147 /*
1148  * get_temp_file_lien() -
1149  * return: READ_RESULT (SUCCESS / CONTINUE / STOP)
1150  * read_buf(in):
1151  * read_buf_size(in):
1152  * diff_time(out):
1153  * endp(out):
1154  */
1155 static READ_RESULT
1156 get_temp_file_line (char *read_buf, unsigned int read_buf_size, int *diff_time, char **endp)
1157 {
1158  char *p;
1159  int res;
1160 
1161  p = fgets (read_buf, read_buf_size, br_tmpfp);
1162  if (p)
1163  {
1164  res = str_to_int32 (diff_time, endp, read_buf, 10);
1165  if (res != 0)
1166  {
1167  return READ_CONTINUE;
1168  }
1169 
1170  p = strchr (read_buf, '\n');
1171  if (p)
1172  {
1173  *(p) = '\0';
1174 
1175  return READ_SUCCESS;
1176  }
1177  else
1178  {
1179  /* continue reading temp file. buf this read_buf isn't written in output file */
1180  return READ_CONTINUE;
1181  }
1182  }
1183  /* end reading temp file */
1184  return READ_STOP;
1185 }
1186 
1187 /*
1188  * print_result_without_sort() -
1189  * return: NO_ERROR or ER_FAILED
1190  * outfp(in):
1191  * print_diff_time_lower(in): min diff time which will be print
1192  * read_buf_max(in): size of read buffer
1193  */
1194 static int
1195 print_result_without_sort (FILE * outfp, int print_diff_time_lower, int read_buf_max)
1196 {
1197  int diff_time;
1198  int res = 0;
1199  char *endp;
1200  char *read_buf;
1201  FILE *next_tmp_fp;
1202  T_SQL_RESULT result;
1203 
1204  next_tmp_fp = tmpfile ();
1205  if (next_tmp_fp == NULL)
1206  {
1207  fprintf (stderr, "cannot open temp file\n");
1208  return ER_FAILED;
1209  }
1210 
1211  read_buf = (char *) malloc (read_buf_max);
1212  if (read_buf == NULL)
1213  {
1214  fprintf (stderr, "memory allocation failed\n");
1215  fclose (next_tmp_fp);
1216  return ER_FAILED;
1217  }
1218 
1219  fseek (br_tmpfp, (off_t) 0, SEEK_SET);
1220  while (1)
1221  {
1222  res = get_temp_file_line (read_buf, read_buf_max, &diff_time, &endp);
1223  if (res == READ_STOP)
1224  {
1225  break;
1226  }
1227  else if (res == READ_CONTINUE)
1228  {
1229  continue;
1230  }
1231 
1232  if (diff_time < print_diff_time_lower)
1233  {
1234  fprintf (next_tmp_fp, "%s\n", read_buf);
1235  continue;
1236  }
1237 
1238  result.sql_info = (char *) malloc (read_buf_max + SQL_INFO_TITLE_LEN);
1239  if (result.sql_info == NULL)
1240  {
1241  fprintf (stderr, "memory allocation failed\n");
1242  fclose (next_tmp_fp);
1243  free_and_init (read_buf);
1244  return ER_FAILED;
1245  }
1246 
1247  make_sql_info (result.sql_info, endp + 1, diff_time, read_buf_max + SQL_INFO_TITLE_LEN);
1248 
1249  fprintf (outfp, "%s\n", result.sql_info);
1250  free_and_init (result.sql_info);
1251  }
1252 
1253  fclose (br_tmpfp);
1254 
1255  fflush (next_tmp_fp);
1256 
1257  /* save next temp file pointer in global variable */
1258  br_tmpfp = next_tmp_fp;
1259 
1260  free_and_init (read_buf);
1261  return NO_ERROR;
1262 }
1263 
1264 /*
1265  * print_result_with_sort() -
1266  * return: NO_ERROR or ER_FAILED
1267  * outfp(in):
1268  * print_diff_time_lower(in):
1269  * num_query(in):
1270  * read_buf_max(in): size of read buffer
1271  */
1272 static int
1273 print_result_with_sort (FILE * outfp, int print_diff_time_lower, int num_query, int read_buf_max)
1274 {
1275  int diff_time;
1276  int i = 0;
1277  int res = 0;
1278  char *endp;
1279  char *read_buf = NULL;
1280  FILE *next_tmp_fp;
1281  T_SQL_RESULT *result;
1282 
1283  if (num_query <= 0)
1284  {
1285  return NO_ERROR;
1286  }
1287 
1288  next_tmp_fp = tmpfile ();
1289  if (next_tmp_fp == NULL)
1290  {
1291  fprintf (stderr, "cannot open temp file\n");
1292  return ER_FAILED;
1293  }
1294 
1295  result = (T_SQL_RESULT *) malloc (sizeof (T_SQL_RESULT) * num_query);
1296  if (result == NULL)
1297  {
1298  fprintf (stderr, "memory allocation failed\n");
1299  fclose (next_tmp_fp);
1300  return ER_FAILED;
1301  }
1302  memset (result, '\0', sizeof (T_SQL_RESULT) * num_query);
1303 
1304  read_buf = (char *) malloc (read_buf_max);
1305  if (read_buf == NULL)
1306  {
1307  fprintf (stderr, "memory allocation failed\n");
1308  goto error;
1309  }
1310 
1311  fseek (br_tmpfp, (off_t) 0, SEEK_SET);
1312  while (1)
1313  {
1314  res = get_temp_file_line (read_buf, read_buf_max, &diff_time, &endp);
1315  if (res == READ_STOP)
1316  {
1317  break;
1318  }
1319  else if (res == READ_CONTINUE)
1320  {
1321  continue;
1322  }
1323 
1324  if (diff_time >= print_diff_time_lower)
1325  {
1326  result[i].sql_info = (char *) malloc (read_buf_max + SQL_INFO_TITLE_LEN);
1327  if (result[i].sql_info == NULL)
1328  {
1329  fprintf (stderr, "memory allocation failed\n");
1330  goto error;
1331  }
1332 
1333  result[i].diff_time = diff_time;
1334  make_sql_info (result[i].sql_info, endp + 1, diff_time, read_buf_max + SQL_INFO_TITLE_LEN);
1335  i++;
1336  }
1337  else
1338  {
1339  /*
1340  * if sql's diff time is shorter than diff_time_lower,
1341  * write in next temp file. it will be read next time.
1342  */
1343  fprintf (next_tmp_fp, "%s\n", read_buf);
1344  }
1345  }
1346 
1347  num_query = i;
1348  /* sort result order by diff time */
1349  qsort (result, num_query, sizeof (T_SQL_RESULT), result_sort_func);
1350 
1351  for (i = 0; i < num_query; i++)
1352  {
1353  fprintf (outfp, "%s\n", result[i].sql_info);
1354  free_and_init (result[i].sql_info);
1355  }
1356 
1357  free_and_init (read_buf);
1358 
1359  free_and_init (result);
1360 
1361  fclose (br_tmpfp);
1362 
1363  fflush (outfp);
1364  fflush (next_tmp_fp);
1365 
1366  /* save next temp file pointer in global variable */
1367  br_tmpfp = next_tmp_fp;
1368 
1369  return NO_ERROR;
1370 
1371 error:
1372  free_and_init (read_buf);
1373 
1374  free_and_init (result);
1375 
1376  num_query = i;
1377  for (i = 0; i < num_query; i++)
1378  {
1379  free_and_init (result[i].sql_info);
1380  }
1381  fclose (next_tmp_fp);
1382 
1383  return ER_FAILED;
1384 }
1385 
1386 /*
1387  * print_result() -
1388  * outfp(in):
1389  * max_diff_time(in):
1390  * min_diff_time(in):
1391  * temp_line_len_max(in): line max of temp file result.
1392  */
1393 static void
1394 print_result (FILE * outfp, double max_diff_time, double min_diff_time, int temp_line_len_max)
1395 {
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;
1399 
1400  max_diff_in_msec = MIN (max_diff_in_msec, STAT_MAX_DIFF_TIME - 1);
1401  min_diff_in_msec = MAX (min_diff_in_msec, -(STAT_MAX_DIFF_TIME - 1));
1402 
1403  for (i = max_diff_in_msec; i >= 0; i--)
1404  {
1405  num_sort += num_slower_queries[i];
1406  if (num_sort > SORT_BUF_MAX)
1407  {
1408  if (print_result_with_sort (outfp, i + 1, num_sort - num_slower_queries[i], temp_line_len_max) < 0)
1409  {
1410  return;
1411  }
1412  /*
1413  * we don't sort last diff time query to avoid ordering size excess SORT_BUF_SIZE
1414  * in genaral, many sql have same diff time. so, this help decrease needless sorting
1415  */
1416  if (print_result_without_sort (outfp, i, temp_line_len_max) < 0)
1417  {
1418  return;
1419  }
1420 
1421  num_sort = 0;
1422  }
1423  }
1424 
1425  for (i = -1; i >= min_diff_in_msec; i--)
1426  {
1427  num_sort += num_faster_queries[(-i)];
1428  if (num_sort > SORT_BUF_MAX)
1429  {
1430  if (print_result_with_sort (outfp, i + 1, num_sort - num_faster_queries[(-i)], temp_line_len_max) < 0)
1431  {
1432  return;
1433  }
1434 
1435  if (print_result_without_sort (outfp, i, temp_line_len_max) < 0)
1436  {
1437  return;
1438  }
1439 
1440  num_sort = 0;
1441  }
1442  }
1443 
1444  if (num_sort > 0)
1445  {
1446  print_result_with_sort (outfp, min_diff_in_msec, num_sort, temp_line_len_max);
1447  }
1448 
1449  return;
1450 }
1451 
1452 /*
1453  * get_args() -
1454  * return: option indicator or ER_FAILED
1455  * argc(in):
1456  * argv(in):
1457  */
1458 static int
1459 get_args (int argc, char *argv[])
1460 {
1461  int c;
1462  int num_file_arg;
1463  double break_time_in_sec = DEFAULT_BREAK_TIME;
1465 
1466  while (1)
1467  {
1468  c = getopt (argc, argv, "rd:u:p:I:P:F:T:h:D:");
1469  if (c == EOF)
1470  {
1471  break;
1472  }
1473  switch (c)
1474  {
1475  case 'I':
1476  host = optarg;
1477  break;
1478  case 'P':
1479  if (parse_int (&broker_port, optarg, 10) < 0)
1480  {
1481  goto usage;
1482  }
1483  break;
1484  case 'd':
1485  dbname = optarg;
1486  break;
1487  case 'u':
1488  dbuser = optarg;
1489  break;
1490  case 'p':
1491  dbpasswd = strdup (optarg);
1492 #if defined (LINUX)
1493  memset (optarg, '*', strlen (optarg));
1494 #endif
1495  break;
1496  case 'r':
1497  rewrite_query_flag = 1;
1498  break;
1499  case 'h':
1500  break_time_in_sec = atof (optarg);
1501  break;
1502  case 'D':
1504  break;
1505  case 'F':
1507  {
1508  goto date_format_err;
1509  }
1510  check_date_flag = 1;
1511  break;
1512  case 'T':
1514  {
1515  goto date_format_err;
1516  }
1517  check_date_flag = 1;
1518  break;
1519  default:
1520  goto usage;
1521  }
1522  }
1523 
1524  break_time = (int) (break_time_in_sec * 1000);
1525 
1526  num_file_arg = argc - optind;
1527  if (num_file_arg != 2)
1528  {
1529  goto usage;
1530  }
1531 
1532  if (host == NULL || broker_port == INVALID_PORT_NUM || dbname == NULL)
1533  {
1534  goto usage;
1535  }
1536 
1537  return optind;
1538 
1539 usage:
1540  fprintf (stderr,
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],
1548 
1549  return ER_FAILED;
1550 date_format_err:
1551  fprintf (stderr, "invalid date. valid date format is yy-mm-dd hh:mm:ss.\n");
1552  return ER_FAILED;
1553 }
1554 
1555 /*
1556  * open_file() -
1557  * return: NO_ERROR or ER_FAILED
1558  * infilename(in):
1559  * outfilename(in):
1560  * infp(out):
1561  * outfp(out):
1562  * cci_errfp(out):
1563  * skip_sqlfp(out):
1564  */
1565 static int
1566 open_file (char *infilename, char *outfilename, FILE ** infp, FILE ** outfp, FILE ** cci_errfp, FILE ** skip_sqlfp)
1567 {
1568  *infp = fopen (infilename, "r");
1569  if (*infp == NULL)
1570  {
1571  fprintf (stderr, "cannot open input file '%s'\n", infilename);
1572  return ER_FAILED;
1573  }
1574 
1575  *outfp = fopen (outfilename, "w");
1576  if (*outfp == NULL)
1577  {
1578  fprintf (stderr, "cannot open output file '%s'\n", outfilename);
1579  goto error;
1580  }
1581 
1582  br_tmpfp = tmpfile ();
1583  if (br_tmpfp == NULL)
1584  {
1585  fprintf (stderr, "cannot open temp file\n");
1586  goto error;
1587  }
1588 
1589  *cci_errfp = fopen (CCI_ERR_FILE_NAME, "w");
1590  if (*cci_errfp == NULL)
1591  {
1592  fprintf (stderr, "cannot open output file '%s'\n", CCI_ERR_FILE_NAME);
1593  goto error;
1594  }
1595 
1596  *skip_sqlfp = fopen (PASS_SQL_FILE_NAME, "w");
1597  if (*skip_sqlfp == NULL)
1598  {
1599  fprintf (stderr, "cannot open output file '%s'\n", PASS_SQL_FILE_NAME);
1600  goto error;
1601  }
1602 
1603  return NO_ERROR;
1604 
1605 error:
1606  close_file (*infp, *outfp, *cci_errfp, *skip_sqlfp);
1607  return ER_FAILED;
1608 }
1609 
1610 /*
1611  * close_file() -
1612  * return: void
1613  * infp(in):
1614  * outfp(in):
1615  * cci_errfp(in):
1616  * skip_sqlfp(in):
1617  */
1618 static void
1619 close_file (FILE * infp, FILE * outfp, FILE * cci_errfp, FILE * skip_sqlfp)
1620 {
1621  if (infp != NULL)
1622  {
1623  fclose (infp);
1624  }
1625 
1626  if (outfp != NULL)
1627  {
1628  fclose (outfp);
1629  }
1630 
1631  if (br_tmpfp != NULL)
1632  {
1633  fclose (br_tmpfp);
1634  }
1635 
1636  if (cci_errfp != NULL)
1637  {
1638  fclose (cci_errfp);
1639  }
1640 
1641  if (skip_sqlfp != NULL)
1642  {
1643  fclose (skip_sqlfp);
1644  }
1645 
1646  return;
1647 }
1648 
1649 int
1650 main (int argc, char *argv[])
1651 {
1652  int start_arg;
1653  char *infilename = NULL;
1654  char *outfilename = NULL;
1655  int res;
1656 
1657  start_arg = get_args (argc, argv);
1658  if (start_arg < 0)
1659  {
1660  return ER_FAILED;
1661  }
1662 
1663  assert (start_arg < argc);
1664 
1665  infilename = argv[start_arg];
1666 
1667  outfilename = argv[start_arg + 1];
1668 
1669  res = log_replay (infilename, outfilename);
1670 
1671  if (dbpasswd != NULL)
1672  {
1673  free (dbpasswd);
1674  }
1675 
1676  return res;
1677 }
#define SLEEP_MILISEC(sec, msec)
Definition: util_func.h:40
DllImport int optind
#define DATE_STR_LEN
char * trim(char *str)
Definition: porting.c:2260
static int open_file(char *infilename, char *outfilename, FILE **infp, FILE **outfp, FILE **cci_errfp, FILE **skip_sqlfp)
#define NO_ERROR
Definition: error_code.h:46
DllImport char * optarg
static int print_temp_result(char *sql_log, T_SQL_INFO *info)
static char * dbuser
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 *)
static int break_time
int argc
Definition: dynamic_load.c:951
#define BIND_STR_BUF_SIZE
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
#define ER_FAILED
Definition: error_code.h:47
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)
temp_read_result
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)
char * data
#define SORT_BUF_MAX
static void get_sql_time_info(char *sql_log, T_SQL_INFO *info)
static char to_date[128]
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 * rewrite_sql
char * t_string_str(T_STRING *t_str)
#define assert(x)
#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)
#define NULL
Definition: freelistheap.h:34
int str_to_int32(int *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2346
#define GET_CUR_DATE_STR(BUF, LINEBUF)
static char * dbname
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)
static FILE * br_tmpfp
static char * infilename
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)
Definition: gencat.c:331
static char * dbpasswd
static void print_summary_info(T_SUMMARY_INFO *summary)
static int broker_port
static unsigned int num_slower_queries[STAT_MAX_DIFF_TIME]
enum temp_read_result READ_RESULT
const char ** argv
Definition: dynamic_load.c:952
#define INVALID_PORT_NUM
#define strlen(s1)
Definition: intl_support.c:43
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)
int i
Definition: dynamic_load.c:954
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)
Definition: porting.c:901
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)
double sql_log_time
void usage(void)
static void close_file(FILE *infp, FILE *outfp, FILE *cci_errfp, FILE *skip_sqlfp)
static char * host
#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)
const char ** p
Definition: dynamic_load.c:945