Merge lp:~vlad-lesin/percona-playback/tcpdump-parsing into lp:percona-playback
- tcpdump-parsing
- Merge into trunk
Proposed by
Vlad Lesin
Status: | Merged |
---|---|
Merged at revision: | 121 |
Proposed branch: | lp:~vlad-lesin/percona-playback/tcpdump-parsing |
Merge into: | lp:percona-playback |
Diff against target: |
2069 lines (+1710/-68) (has conflicts) 26 files modified
.bzrignore (+11/-0) Makefile.am (+36/-2) configure.ac (+5/-0) m4/pandora_have_libdrizzle-1.0.m4 (+74/-0) m4/pandora_have_libdrizzle.m4 (+0/-61) m4/pandora_have_libmysqlclient.m4 (+103/-0) percona_playback/dispatcher.cc (+14/-0) percona_playback/percona_playback.cc (+21/-0) percona_playback/query_result.h (+7/-0) percona_playback/tcpdump/connection_state.cc (+325/-0) percona_playback/tcpdump/connection_state.h (+186/-0) percona_playback/tcpdump/pcap_packets_parser.cc (+134/-0) percona_playback/tcpdump/pcap_packets_parser.h (+64/-0) percona_playback/tcpdump/plugin.ac (+1/-1) percona_playback/tcpdump/plugin.ini (+3/-1) percona_playback/tcpdump/sniff_headers.h (+59/-0) percona_playback/tcpdump/tcpdump.cc (+122/-3) percona_playback/tcpdump/tcpdump.h (+17/-0) percona_playback/tcpdump/tcpdump_mysql_parser_stats.h (+33/-0) percona_playback/tcpdump/tcpdump_query_entries.cc (+129/-0) percona_playback/tcpdump/tcpdump_query_entries.h (+73/-0) percona_playback/test/tcpdump_accuracy.cc (+69/-0) percona_playback/test/tcpdump_fragmented_packet.cc (+56/-0) percona_playback/test/tcpdump_multiple_connections.cc (+56/-0) percona_playback/test/tcpdump_stress_test.cc (+56/-0) percona_playback/test/tcpdump_without_handshake.cc (+56/-0) Text conflict in Makefile.am Text conflict in configure.ac Conflict adding file m4/pandora_have_libmysqlclient.m4. Moved existing file to m4/pandora_have_libmysqlclient.m4.moved. Text conflict in percona_playback/percona_playback.cc Text conflict in percona_playback/tcpdump/tcpdump.h |
To merge this branch: | bzr merge lp:~vlad-lesin/percona-playback/tcpdump-parsing |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith | Pending | ||
Review via email: mp+111163@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 98. By Vlad Lesin
-
Add pandora_
have_libmysqlcl ient.m4 pandora_ have_libpcap. m4 to the project because it shouldn't depend on pandora-build being installed. - 99. By Vlad Lesin
-
Free drizzle result in ConnectionState destructor.
- 100. By Vlad Lesin
-
Fix for memory leak in tcpdump plugin.
- 101. By Vlad Lesin
-
Don't use all caps in labels.
- 102. By Vlad Lesin
-
One more memory leak fix. See https:/
/bugs.launchpad .net/drizzle/ +bug/1015576. - 103. By Vlad Lesin
-
License header is added to dispatcher source.
- 104. By Vlad Lesin
-
Merge with 91..94 revisions of trunk(use autoreconf, add gettext support, add po to Makefile subdirs)
- 105. By Vlad Lesin
-
Rename pandora_
have_libdrizzle .m4 to pandora_ have_libdrizzle -1.0.m4 as it finds libdrizzle-1.0 library - 106. By Vlad Lesin
-
Use standard libdrizzle-1.0 instead of modified
- 107. By Vlad Lesin
-
Avoid compilation errors in 'set drizzle result options' code
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2011-12-30 01:47:04 +0000 |
3 | +++ .bzrignore 2012-07-02 18:23:18 +0000 |
4 | @@ -40,3 +40,14 @@ |
5 | percona_playback/test/crashme-slow |
6 | percona_playback/test/sqlbench-transactions-slow |
7 | percona_playback/test/sysbench-slow |
8 | +m4/libtool.m4 |
9 | +m4/ltoptions.m4 |
10 | +m4/ltversion.m4 |
11 | +m4/lt~obsolete.m4 |
12 | +percona_playback/test/preserve_query_time |
13 | +percona_playback/test/tcpdump_accuracy |
14 | +percona_playback/test/tcpdump_fragmented_packet |
15 | +percona_playback/test/tcpdump_multiple_connections |
16 | +percona_playback/test/tcpdump_stress_test |
17 | +percona_playback/test/tcpdump_without_handshake |
18 | +tags |
19 | |
20 | === modified file 'Makefile.am' |
21 | --- Makefile.am 2012-06-22 05:12:15 +0000 |
22 | +++ Makefile.am 2012-07-02 18:23:18 +0000 |
23 | @@ -39,6 +39,11 @@ |
24 | percona_playback/test/sqlbench-transactions-slow.log \ |
25 | percona_playback/test/sysbench-slow.log \ |
26 | percona_playback/test/preserve_query_time.log \ |
27 | + percona_playback/test/tcpdump_without_handshake.dump \ |
28 | + percona_playback/test/tcpdump_fragmented_packet.dump \ |
29 | + percona_playback/test/tcpdump_multiple_connections.dump \ |
30 | + percona_playback/test/tcpdump_stress_test.dump \ |
31 | + percona_playback/test/tcpdump_accuracy.dump \ |
32 | test_run.sh |
33 | |
34 | include config/pandora-plugin.am |
35 | @@ -71,9 +76,15 @@ |
36 | $(AM_CXXFLAGS) \ |
37 | -DBUILDING_PERCONA_PLAYBACK |
38 | |
39 | +<<<<<<< TREE |
40 | libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(TBB_LIBS) |
41 | libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(TBB_LIBS) $(pandora_plugin_libs) |
42 | libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs) |
43 | +======= |
44 | +libpercona_playback_la_LIBADD = $(LIBDL_LIBS) $(BOOST_LIBS) $(LTLIBTBB) |
45 | +libpercona_playback_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPERCONA_PLAYBACK_VERSION) $(BOOST_LIBS) $(LTLIBTBB) $(pandora_plugin_libs) |
46 | +libpercona_playback_la_DEPENDENCIES = ${noinst_LTLIBRARIES} $(pandora_plugin_libs) |
47 | +>>>>>>> MERGE-SOURCE |
48 | |
49 | check_PROGRAMS += \ |
50 | percona_playback/test/basic \ |
51 | @@ -82,6 +93,11 @@ |
52 | percona_playback/test/sqlbench-transactions-slow \ |
53 | percona_playback/test/sysbench-slow \ |
54 | percona_playback/test/preserve_query_time \ |
55 | + percona_playback/test/tcpdump_without_handshake \ |
56 | + percona_playback/test/tcpdump_fragmented_packet \ |
57 | + percona_playback/test/tcpdump_multiple_connections \ |
58 | + percona_playback/test/tcpdump_stress_test \ |
59 | + percona_playback/test/tcpdump_accuracy \ |
60 | percona_playback/test/help |
61 | |
62 | percona_playback_test_basic_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
63 | @@ -90,6 +106,11 @@ |
64 | percona_playback_test_sqlbench_transactions_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
65 | percona_playback_test_sysbench_slow_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
66 | percona_playback_test_preserve_query_time_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
67 | +percona_playback_test_tcpdump_without_handshake_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
68 | +percona_playback_test_tcpdump_fragmented_packet_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
69 | +percona_playback_test_tcpdump_multiple_connections_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
70 | +percona_playback_test_tcpdump_stress_test_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
71 | +percona_playback_test_tcpdump_accuracy_CXXFLAGS= $(AM_CXXFLAGS) -DSRCDIR=\"${srcdir}\" |
72 | |
73 | percona_playback_test_help_SOURCES= percona_playback/test/help.cc |
74 | percona_playback_test_help_LDADD= $(LDADD) $(MYSQL_LIBS) |
75 | @@ -112,7 +133,20 @@ |
76 | percona_playback_test_preserve_query_time_SOURCES= percona_playback/test/preserve_query_time.cc |
77 | percona_playback_test_preserve_query_time_LDADD= $(LDADD) $(MYSQL_LIBS) |
78 | |
79 | - |
80 | +percona_playback_test_tcpdump_without_handshake_SOURCES= percona_playback/test/tcpdump_without_handshake.cc |
81 | +percona_playback_test_tcpdump_without_handshake_LDADD= $(LDADD) $(MYSQL_LIBS) |
82 | + |
83 | +percona_playback_test_tcpdump_fragmented_packet_SOURCES= percona_playback/test/tcpdump_fragmented_packet.cc |
84 | +percona_playback_test_tcpdump_fragmented_packet_LDADD= $(LDADD) $(MYSQL_LIBS) |
85 | + |
86 | +percona_playback_test_tcpdump_multiple_connections_SOURCES= percona_playback/test/tcpdump_multiple_connections.cc |
87 | +percona_playback_test_tcpdump_multiple_connections_LDADD= $(LDADD) $(MYSQL_LIBS) |
88 | + |
89 | +percona_playback_test_tcpdump_stress_test_SOURCES= percona_playback/test/tcpdump_stress_test.cc |
90 | +percona_playback_test_tcpdump_stress_test_LDADD= $(LDADD) $(MYSQL_LIBS) |
91 | + |
92 | +percona_playback_test_tcpdump_accuracy_SOURCES= percona_playback/test/tcpdump_accuracy.cc |
93 | +percona_playback_test_tcpdump_accuracy_LDADD= $(LDADD) $(MYSQL_LIBS) |
94 | |
95 | # |
96 | # Simple percona_playback application |
97 | @@ -120,7 +154,7 @@ |
98 | |
99 | bin_PROGRAMS += bin/percona_playback |
100 | bin_percona_playback_SOURCES = bin/percona_playback.cc |
101 | -bin_percona_playback_LDADD= $(BOOST_LIBS) $(LDADD) $(TBB_LIBS) $(MYSQL_LIBS) $(pandora_plugin_libs) $(PANDORA_DYNAMIC_LDADDS) |
102 | +bin_percona_playback_LDADD= $(BOOST_LIBS) $(LDADD) $(LTLIBTBB) $(MYSQL_LIBS) $(pandora_plugin_libs) $(PANDORA_DYNAMIC_LDADDS) |
103 | |
104 | include docs/include.am |
105 | |
106 | |
107 | === modified file 'configure.ac' |
108 | --- configure.ac 2012-06-24 04:28:41 +0000 |
109 | +++ configure.ac 2012-07-02 18:23:18 +0000 |
110 | @@ -58,8 +58,13 @@ |
111 | |
112 | AC_DEFINE_UNQUOTED([PERCONA_PLAYBACK_MODULE_EXT], ["$acl_cv_shlibext"], |
113 | [Extension to use for modules.]) |
114 | +<<<<<<< TREE |
115 | AM_CXXFLAGS="${AM_CXXFLAGS} ${NO_EFF_CXX} ${NO_OLD_STYLE_CAST} ${NO_VISIBILITY}" |
116 | AC_CONFIG_FILES(Makefile dnl po/Makefile.in |
117 | +======= |
118 | +AM_CXXFLAGS="${NO_EFF_CXX}" |
119 | +AC_CONFIG_FILES(Makefile dnl po/Makefile.in |
120 | +>>>>>>> MERGE-SOURCE |
121 | percona_playback/version.h dnl |
122 | docs/header.html) |
123 | |
124 | |
125 | === added file 'm4/pandora_have_libdrizzle-1.0.m4' |
126 | --- m4/pandora_have_libdrizzle-1.0.m4 1970-01-01 00:00:00 +0000 |
127 | +++ m4/pandora_have_libdrizzle-1.0.m4 2012-07-02 18:23:18 +0000 |
128 | @@ -0,0 +1,74 @@ |
129 | +dnl Copyright (C) 2009 Sun Microsystems, Inc. |
130 | +dnl This file is free software; Sun Microsystems, Inc. |
131 | +dnl gives unlimited permission to copy and/or distribute it, |
132 | +dnl with or without modifications, as long as this notice is preserved. |
133 | + |
134 | +AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE_1_0],[ |
135 | + AC_REQUIRE([AC_LIB_PREFIX]) |
136 | + |
137 | + dnl -------------------------------------------------------------------- |
138 | + dnl Check for libdrizzle |
139 | + dnl -------------------------------------------------------------------- |
140 | + |
141 | + AC_ARG_ENABLE([libdrizzle], |
142 | + [AS_HELP_STRING([--disable-libdrizzle], |
143 | + [Build with libdrizzle support @<:@default=on@:>@])], |
144 | + [ac_enable_libdrizzle="$enableval"], |
145 | + [ac_enable_libdrizzle="yes"]) |
146 | + |
147 | + AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[ |
148 | + AC_LIB_HAVE_LINKFLAGS(drizzle,,[ |
149 | + #include <libdrizzle/drizzle_client.h> |
150 | + ],[ |
151 | + drizzle_st drizzle; |
152 | + drizzle_version(); |
153 | + ]) |
154 | + ],[ |
155 | + ac_cv_libdrizzle="no" |
156 | + ]) |
157 | + |
158 | + AS_IF([test "${ac_cv_libdrizzle}" = "no" -a "${ac_enable_libdrizzle}" = "yes"],[ |
159 | + PKG_CHECK_MODULES([LIBDRIZZLE], [libdrizzle-1.0], [ |
160 | + ac_cv_libdrizzle=yes |
161 | + LTLIBDRIZZLE=${LIBDRIZZLE_LIBS} |
162 | + LIBDRIZZLE=${LIBDRIZZLE_LIBS} |
163 | + CPPFLAGS=${LIBDRIZZLE_CFLAGS} ${CPPFLAGS} |
164 | + HAVE_LIBDRIZZLE="yes" |
165 | + AC_SUBST(HAVE_LIBDRIZZLE) |
166 | + AC_SUBST(LIBDRIZZLE) |
167 | + AC_SUBST(LTLIBDRIZZLE) |
168 | + ],[]) |
169 | + ]) |
170 | + |
171 | + AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"]) |
172 | +]) |
173 | + |
174 | +AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE_1_0],[ |
175 | + AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE_1_0]) |
176 | +]) |
177 | + |
178 | +AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE_1_0],[ |
179 | + AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE_1_0]) |
180 | + AS_IF([test "x${ac_cv_libdrizzle}" = "xno"],[ |
181 | + AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}]) |
182 | + ],[ |
183 | + dnl We need at least 0.8 on Solaris non-sparc |
184 | + AS_IF([test "$target_cpu" != "sparc" -a "x${TARGET_SOLARIS}" = "xtrue"],[ |
185 | + PANDORA_LIBDRIZZLE_RECENT |
186 | + ]) |
187 | + ]) |
188 | +]) |
189 | + |
190 | +AC_DEFUN([PANDORA_LIBDRIZZLE_RECENT],[ |
191 | + AC_CACHE_CHECK([if libdrizzle is recent enough], |
192 | + [pandora_cv_libdrizzle_recent], |
193 | + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ |
194 | +#include <libdrizzle/drizzle.h> |
195 | +drizzle_con_options_t foo= DRIZZLE_CON_EXPERIMENTAL; |
196 | + ]])], |
197 | + [pandora_cv_libdrizzle_recent=yes], |
198 | + [pandora_cv_libdrizzle_recent=no])]) |
199 | + AS_IF([test "$pandora_cv_libdrizzle_recent" = "no"],[ |
200 | + AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.8]) |
201 | + ]) |
202 | +]) |
203 | |
204 | === removed file 'm4/pandora_have_libdrizzle.m4' |
205 | --- m4/pandora_have_libdrizzle.m4 2012-04-03 05:13:48 +0000 |
206 | +++ m4/pandora_have_libdrizzle.m4 1970-01-01 00:00:00 +0000 |
207 | @@ -1,61 +0,0 @@ |
208 | -dnl Copyright (C) 2009 Sun Microsystems, Inc. |
209 | -dnl This file is free software; Sun Microsystems, Inc. |
210 | -dnl gives unlimited permission to copy and/or distribute it, |
211 | -dnl with or without modifications, as long as this notice is preserved. |
212 | - |
213 | -AC_DEFUN([_PANDORA_SEARCH_LIBDRIZZLE],[ |
214 | - AC_REQUIRE([AC_LIB_PREFIX]) |
215 | - |
216 | - dnl -------------------------------------------------------------------- |
217 | - dnl Check for libdrizzle |
218 | - dnl -------------------------------------------------------------------- |
219 | - |
220 | - AC_ARG_ENABLE([libdrizzle], |
221 | - [AS_HELP_STRING([--disable-libdrizzle], |
222 | - [Build with libdrizzle support @<:@default=on@:>@])], |
223 | - [ac_enable_libdrizzle="$enableval"], |
224 | - [ac_enable_libdrizzle="yes"]) |
225 | - |
226 | - AS_IF([test "x$ac_enable_libdrizzle" = "xyes"],[ |
227 | - AC_LIB_HAVE_LINKFLAGS(drizzle,,[ |
228 | - #include <libdrizzle/drizzle_client.h> |
229 | - ],[ |
230 | - drizzle_st drizzle; |
231 | - drizzle_version(); |
232 | - ]) |
233 | - ],[ |
234 | - ac_cv_libdrizzle="no" |
235 | - ]) |
236 | - |
237 | - AM_CONDITIONAL(HAVE_LIBDRIZZLE, [test "x${ac_cv_libdrizzle}" = "xyes"]) |
238 | -]) |
239 | - |
240 | -AC_DEFUN([PANDORA_HAVE_LIBDRIZZLE],[ |
241 | - AC_REQUIRE([_PANDORA_SEARCH_LIBDRIZZLE]) |
242 | -]) |
243 | - |
244 | -AC_DEFUN([PANDORA_REQUIRE_LIBDRIZZLE],[ |
245 | - AC_REQUIRE([PANDORA_HAVE_LIBDRIZZLE]) |
246 | - AS_IF([test "x${ac_cv_libdrizzle}" = "xno"],[ |
247 | - AC_MSG_ERROR([libdrizzle is required for ${PACKAGE}]) |
248 | - ],[ |
249 | - dnl We need at least 0.8 on Solaris non-sparc |
250 | - AS_IF([test "$target_cpu" != "sparc" -a "x${TARGET_SOLARIS}" = "xtrue"],[ |
251 | - PANDORA_LIBDRIZZLE_RECENT |
252 | - ]) |
253 | - ]) |
254 | -]) |
255 | - |
256 | -AC_DEFUN([PANDORA_LIBDRIZZLE_RECENT],[ |
257 | - AC_CACHE_CHECK([if libdrizzle is recent enough], |
258 | - [pandora_cv_libdrizzle_recent], |
259 | - [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ |
260 | -#include <libdrizzle/drizzle.h> |
261 | -drizzle_con_options_t foo= DRIZZLE_CON_EXPERIMENTAL; |
262 | - ]])], |
263 | - [pandora_cv_libdrizzle_recent=yes], |
264 | - [pandora_cv_libdrizzle_recent=no])]) |
265 | - AS_IF([test "$pandora_cv_libdrizzle_recent" = "no"],[ |
266 | - AC_MSG_ERROR([Your version of libdrizzle is too old. ${PACKAGE} requires at least version 0.8]) |
267 | - ]) |
268 | -]) |
269 | |
270 | === added file 'm4/pandora_have_libmysqlclient.m4' |
271 | --- m4/pandora_have_libmysqlclient.m4 1970-01-01 00:00:00 +0000 |
272 | +++ m4/pandora_have_libmysqlclient.m4 2012-07-02 18:23:18 +0000 |
273 | @@ -0,0 +1,103 @@ |
274 | +dnl -*- mode: m4; c-basic-offset: 2; indent-tabs-mode: nil; -*- |
275 | +dnl vim:expandtab:shiftwidth=2:tabstop=2:smarttab: |
276 | +dnl |
277 | +dnl Copyright (C) 2010 Monty Taylor |
278 | +dnl This file is free software; Sun Microsystems |
279 | +dnl gives unlimited permission to copy and/or distribute it, |
280 | +dnl with or without modifications, as long as this notice is preserved. |
281 | +dnl |
282 | + |
283 | +AC_DEFUN([PANDORA_WITH_MYSQL],[ |
284 | + AC_ARG_WITH([mysql], |
285 | + [AS_HELP_STRING([--with-mysql=PATH], |
286 | + [path to mysql_config binary or mysql prefix dir])], |
287 | + [with_mysql=$withval], |
288 | + [with_mysql=":"]) |
289 | + |
290 | + dnl There are three possibilities: |
291 | + dnl 1) nothing is given: we will search for mysql_config in PATH |
292 | + dnl 2) the location of mysql_config is given: we'll use that to determine |
293 | + dnl 3) a directory argument is given: that will be mysql_base |
294 | + |
295 | + |
296 | + dnl option 1: nothing, we need to insert something into MYSQL_CONFIG |
297 | + AS_IF([test "x$with_mysql" = "x:"],[ |
298 | + AC_CHECK_PROGS(MYSQL_CONFIG,[mysql_config]) |
299 | + ],[ |
300 | + MYSQL_CONFIG="${with_mysql}" |
301 | + ]) |
302 | + |
303 | + AC_CACHE_CHECK([for MySQL Base Location],[pandora_cv_mysql_base],[ |
304 | + |
305 | + dnl option 2: something in MYSQL_CONFIG now, use that to get a base dir |
306 | + AS_IF([test -f "${MYSQL_CONFIG}" -a -x "${MYSQL_CONFIG}"],[ |
307 | + pandora_cv_mysql_base=$(dirname $(${MYSQL_CONFIG} --include | sed 's/-I//')) |
308 | + MYSQL_INCLUDES=$(${MYSQL_CONFIG} --include) |
309 | + MYSQL_INCLUDES="$MYSQL_INCLUDES $(echo $MYSQL_INCLUDES|sed -e 's/-I/-isystem /')" |
310 | + MYSQL_LIBS=$(${MYSQL_CONFIG} --libs_r) |
311 | + ],[ |
312 | + dnl option 1: a directory |
313 | + AS_IF([test -d $with_mysql], |
314 | + [ |
315 | + pandora_cv_mysql_base=$with_mysql |
316 | + IBASE="-I${with_mysql}" |
317 | + MYSQL_CONFIG="${with_mysql}/bin/mysql_config" |
318 | + MYSQL_INCLUDES="$IBASE/include/mysql -isystem $IBASE/include/mysql" |
319 | + MYSQL_LIBS="-L${with_mysql}/lib -L${with_mysql}/lib/mysql -lmysqlclient_r" |
320 | + ], |
321 | + [ |
322 | + pandora_cv_mysql_base="" |
323 | + ]) |
324 | + ]) |
325 | + ]) |
326 | + AC_SUBST(MYSQL_CONFIG) |
327 | + AC_SUBST(MYSQL_INCLUDES) |
328 | + AC_SUBST(MYSQL_LIBS) |
329 | +]) |
330 | + |
331 | +AC_DEFUN([_PANDORA_SEARCH_LIBMYSQLCLIENT],[ |
332 | + AC_REQUIRE([AC_LIB_PREFIX]) |
333 | + |
334 | + AC_ARG_ENABLE([libmysqlclient], |
335 | + [AS_HELP_STRING([--disable-libmysqlclient], |
336 | + [Build with libmysqlclient support @<:@default=on@:>@])], |
337 | + [ac_enable_libmysqlclient="$enableval"], |
338 | + [ac_enable_libmysqlclient="yes"]) |
339 | + |
340 | + AS_IF([test "x$ac_enable_libmysqlclient" = "xyes"],[ |
341 | + AC_LIB_HAVE_LINKFLAGS(mysqlclient_r,,[ |
342 | +#include <mysql/mysql.h> |
343 | + ],[ |
344 | +MYSQL mysql; |
345 | + ])],[ |
346 | + ac_cv_libmysqlclient_r="no" |
347 | + ]) |
348 | + |
349 | + AM_CONDITIONAL(HAVE_LIBMYSQLCLIENT, [test "x${ac_cv_libmysqlclient_r}" = "xyes"]) |
350 | + |
351 | + AS_IF([test "x$MYSQL_CONFIG" = "xISDIR"],[ |
352 | + IBASE="-I${with_mysql}" |
353 | + MYSQL_CONFIG="${with_mysql}/scripts/mysql_config" |
354 | + ADDIFLAGS="$IBASE/include -isystem $IBASE/include" |
355 | + ADDLDFLAGS="-L${with_mysql}/libmysql_r/.libs/ -L${with_mysql}/mysys/.libs -L${with_mysql}/mysys -L${with_mysql}/strings/.libs -L${with_mysql}/strings " |
356 | + ],[ |
357 | + MYSQL_INCLUDES=$(${MYSQL_CONFIG} --include) |
358 | + MYSQL_INCLUDES="$MYSQL_INCLUDES $(echo $MYSQL_INCLUDES|sed -e 's/-I/-isystem /')" |
359 | + MYSQL_LIBS=$(${MYSQL_CONFIG} --libs_r) |
360 | + ]) |
361 | + |
362 | + AC_SUBST(MYSQL_CONFIG) |
363 | + AC_SUBST(MYSQL_INCLUDES) |
364 | + AC_SUBST(MYSQL_LIBS) |
365 | +]) |
366 | + |
367 | +AC_DEFUN([PANDORA_HAVE_LIBMYSQLCLIENT],[ |
368 | + AC_REQUIRE([_PANDORA_SEARCH_LIBMYSQLCLIENT]) |
369 | +]) |
370 | + |
371 | +AC_DEFUN([PANDORA_REQUIRE_LIBMYSQLCLIENT],[ |
372 | + AC_REQUIRE([PANDORA_HAVE_LIBMYSQLCLIENT]) |
373 | + AS_IF([test "x${ac_cv_libmysqlclient_r}" = "xno"], |
374 | + PANDORA_MSG_ERROR([libmysqlclient_r is required for ${PACKAGE}])) |
375 | +]) |
376 | + |
377 | |
378 | === renamed file 'm4/pandora_have_libmysqlclient.m4' => 'm4/pandora_have_libmysqlclient.m4.moved' |
379 | === modified file 'percona_playback/dispatcher.cc' |
380 | --- percona_playback/dispatcher.cc 2012-06-22 06:20:44 +0000 |
381 | +++ percona_playback/dispatcher.cc 2012-07-02 18:23:18 +0000 |
382 | @@ -1,3 +1,17 @@ |
383 | +/* BEGIN LICENSE |
384 | + * Copyright (C) 2011-2012 Percona Inc. |
385 | + * This program is free software: you can redistribute it and/or modify it |
386 | + * under the terms of the GNU General Public License version 2, as published |
387 | + * by the Free Software Foundation. |
388 | + * |
389 | + * This program is distributed in the hope that it will be useful, but |
390 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
391 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
392 | + * PURPOSE. See the GNU General Public License for more details. |
393 | + * |
394 | + * You should have received a copy of the GNU General Public License along |
395 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
396 | + * END LICENSE */ |
397 | #include "percona_playback/dispatcher.h" |
398 | #include "percona_playback/db_thread.h" |
399 | #include "percona_playback/plugin.h" |
400 | |
401 | === modified file 'percona_playback/percona_playback.cc' |
402 | --- percona_playback/percona_playback.cc 2012-06-24 04:28:41 +0000 |
403 | +++ percona_playback/percona_playback.cc 2012-07-02 18:23:18 +0000 |
404 | @@ -90,18 +90,30 @@ |
405 | std::cerr << std::endl; |
406 | std::cerr << options_description << std::endl; |
407 | std::cerr << std::endl; |
408 | +<<<<<<< TREE |
409 | std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl; |
410 | std::cerr << _("Loaded plugins: "); |
411 | BOOST_FOREACH(const std::string &plugin_name, PluginRegistry::singleton().loaded_plugin_names) |
412 | +======= |
413 | + std::cerr << _("Bugs: ") << PACKAGE_BUGREPORT << std::endl; |
414 | + std::cerr << _("Loaded plugins: "); |
415 | + BOOST_FOREACH(const std::string &plugin_name, percona_playback::PluginRegistry::singleton().loaded_plugin_names) |
416 | +>>>>>>> MERGE-SOURCE |
417 | { |
418 | std::cerr << plugin_name << " "; |
419 | } |
420 | |
421 | std::cerr << std::endl; |
422 | |
423 | +<<<<<<< TREE |
424 | std::cerr << std::endl << _("Loaded DB Plugins: "); |
425 | for(PluginRegistry::DBClientPluginMap::iterator it= PluginRegistry::singleton().dbclient_plugins.begin(); |
426 | it != PluginRegistry::singleton().dbclient_plugins.end(); |
427 | +======= |
428 | + std::cerr << std::endl << _("Loaded DB Plugins: "); |
429 | + for(percona_playback::PluginRegistry::DBClientPluginMap::iterator it= percona_playback::PluginRegistry::singleton().dbclient_plugins.begin(); |
430 | + it != percona_playback::PluginRegistry::singleton().dbclient_plugins.end(); |
431 | +>>>>>>> MERGE-SOURCE |
432 | it++) |
433 | { |
434 | std::cerr << it->first << " "; |
435 | @@ -110,12 +122,21 @@ |
436 | std::cerr << std::endl; |
437 | |
438 | assert(g_dbclient_plugin); |
439 | +<<<<<<< TREE |
440 | std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl; |
441 | |
442 | std::cerr << std::endl << _("Loaded Input Plugins: "); |
443 | |
444 | BOOST_FOREACH(const PluginRegistry::InputPluginPair &pp, |
445 | PluginRegistry::singleton().input_plugins) |
446 | +======= |
447 | + std::cerr << _("Selected DB Plugin: ") << g_dbclient_plugin->name << std::endl; |
448 | + |
449 | + std::cerr << std::endl << _("Loaded Input Plugins: "); |
450 | + |
451 | + BOOST_FOREACH(const percona_playback::PluginRegistry::InputPluginPair &pp, |
452 | + percona_playback::PluginRegistry::singleton().input_plugins) |
453 | +>>>>>>> MERGE-SOURCE |
454 | { |
455 | std::cerr << pp.first << " "; |
456 | } |
457 | |
458 | === modified file 'percona_playback/query_result.h' |
459 | --- percona_playback/query_result.h 2012-06-18 23:59:46 +0000 |
460 | +++ percona_playback/query_result.h 2012-07-02 18:23:18 +0000 |
461 | @@ -40,6 +40,13 @@ |
462 | { |
463 | } |
464 | |
465 | + void clear() |
466 | + { |
467 | + _rows_sent= _rows_examined= 0; |
468 | + _error= _warning_count= 0; |
469 | + _duration= boost::posix_time::time_duration(); |
470 | + } |
471 | + |
472 | void setRowsSent(const uint64_t &rows) { |
473 | _rows_sent= rows; |
474 | } |
475 | |
476 | === added file 'percona_playback/tcpdump/connection_state.cc' |
477 | --- percona_playback/tcpdump/connection_state.cc 1970-01-01 00:00:00 +0000 |
478 | +++ percona_playback/tcpdump/connection_state.cc 2012-07-02 18:23:18 +0000 |
479 | @@ -0,0 +1,325 @@ |
480 | +/* BEGIN LICENSE |
481 | + * Copyright (C) 2011-2012 Percona Inc. |
482 | + * This program is free software: you can redistribute it and/or modify it |
483 | + * under the terms of the GNU General Public License version 2, as published |
484 | + * by the Free Software Foundation. |
485 | + * |
486 | + * This program is distributed in the hope that it will be useful, but |
487 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
488 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
489 | + * PURPOSE. See the GNU General Public License for more details. |
490 | + * |
491 | + * You should have received a copy of the GNU General Public License along |
492 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
493 | + * END LICENSE */ |
494 | +#include <pcap.h> |
495 | +#include <iostream> |
496 | +#include <libdrizzle/drizzle_server.h> |
497 | +#include <libdrizzle/row_client.h> |
498 | +#include <stdio.h> |
499 | +#include <stdint.h> |
500 | +#include <assert.h> |
501 | + |
502 | +#include "connection_state.h" |
503 | +#include "tcpdump_query_entries.h" |
504 | +#include "percona_playback/plugin.h" |
505 | + |
506 | +extern percona_playback::DBClientPlugin *g_dbclient_plugin; |
507 | + |
508 | +void |
509 | +ConnectionState::ProcessMysqlPkts(const u_char *pkts, |
510 | + u_int pkts_len, |
511 | + const timeval &ts, |
512 | + const AddrPort &addr_port, |
513 | + OUT TcpdumpMysqlParserStats &stats) |
514 | +{ |
515 | + |
516 | + u_int used_len= 0; |
517 | + struct MysqlPkt *m; |
518 | + |
519 | + assert(pkts); |
520 | + |
521 | + // If last pkt was fragmented, merge with current pkts |
522 | + if (fragmented) |
523 | + { |
524 | + fragmented= false; |
525 | + size_t old_frag_buff_size= frag_buff.size(); |
526 | + frag_buff.insert(frag_buff.end(), pkts, pkts + pkts_len); |
527 | + pkts= &frag_buff[0]; |
528 | + pkts_len+= old_frag_buff_size; |
529 | + } |
530 | + |
531 | + for(;;) |
532 | + { |
533 | + m= (struct MysqlPkt *)pkts; // Packet header |
534 | + |
535 | + // Check if pkts > len of pkts actually received (last pkt is fragmented) |
536 | + used_len+= m->full_length(); |
537 | + |
538 | + if (used_len > pkts_len) { |
539 | + fragmented= true; |
540 | + |
541 | + size_t frag_len= m->full_length() - (used_len - pkts_len); |
542 | + |
543 | + UCharBuffer new_frag_buff(pkts, pkts + frag_len); |
544 | + frag_buff.swap(new_frag_buff); |
545 | + |
546 | + break; |
547 | + } |
548 | + |
549 | + if (m->data_length()) |
550 | + { |
551 | + UCharBuffer buff(pkts, pkts + m->full_length()); |
552 | + std::string query; |
553 | + PktResult retval= ParseMysqlPkt(buff, query); |
554 | + switch(retval) |
555 | + { |
556 | + case PKT_QUERY: |
557 | + if (!query.empty()) |
558 | + DispatchQuery(ts, query, addr_port); |
559 | + ++stats.nr_of_parsed_queries; |
560 | + ++stats.nr_of_parsed_packets; |
561 | + break; |
562 | + |
563 | + case PKT_RESULT: |
564 | + DispatchResult(ts, addr_port); |
565 | + ++stats.nr_of_parsed_packets; |
566 | + break; |
567 | + |
568 | + case PKT_ERROR: |
569 | + ++stats.nr_of_parsing_errors; |
570 | + break; |
571 | + |
572 | + default: |
573 | + ++stats.nr_of_parsed_packets; |
574 | + } |
575 | + } |
576 | + |
577 | + pkts += m->full_length(); // Next pkt header |
578 | + |
579 | + if (used_len == pkts_len) |
580 | + break; |
581 | + |
582 | + } |
583 | + |
584 | + if (!fragmented) |
585 | + frag_buff.clear(); |
586 | + |
587 | +} |
588 | + |
589 | +void |
590 | +ConnectionState::ProcessFinishConnection() |
591 | +{ |
592 | + db_thread->queries.push(QueryEntryPtr(new FinishEntry())); |
593 | +} |
594 | + |
595 | +PktResult |
596 | +ConnectionState::ParseMysqlPkt(IN UCharBuffer &buff, |
597 | + OUT std::string &query) |
598 | +{ |
599 | + if (current_origin == CLIENT) |
600 | + return ClientPacket(buff, query); |
601 | + |
602 | + if (current_origin == SERVER && was_query) |
603 | + return ServerPacket(buff); |
604 | + |
605 | + return PKT_UNKNOWN; |
606 | +} |
607 | + |
608 | +PktResult |
609 | +ConnectionState::ServerPacket(IN UCharBuffer &buff) |
610 | +{ |
611 | + PktResult retval= PKT_OK; |
612 | + |
613 | + drizzle_return_t ret; |
614 | + |
615 | + drizzle_con->buffer_ptr= &buff[0]; |
616 | + drizzle_con->buffer_size= buff.size(); |
617 | + |
618 | + /* |
619 | + Check if we should continue parsing result set or |
620 | + we can start a new loop of result parsing. |
621 | + */ |
622 | + if (!drizzle_con->result) |
623 | + { |
624 | + /* |
625 | + If there are not any parsed results then it can be "Ok", |
626 | + "Error" or "Results set header" packets. |
627 | + */ |
628 | + last_query_result.clear(); |
629 | + |
630 | + drizzle_result_st *res= drizzle_result_read(drizzle_con.get(), |
631 | + NULL, |
632 | + &ret); |
633 | + /* Check if the packet is "Error" packet */ |
634 | + if (ret == DRIZZLE_RETURN_ERROR_CODE) |
635 | + { |
636 | + last_query_result.setError(drizzle_result_error_code(res)); |
637 | + retval= PKT_RESULT; |
638 | + /* |
639 | + The text representation of error can be got with |
640 | + drizzle_result_error(res) |
641 | + */ |
642 | + goto free_and_return; |
643 | + } |
644 | + else if(ret == DRIZZLE_RETURN_OK) |
645 | + { |
646 | + /* Check if the packet is "Ok" packet */ |
647 | + if (!drizzle_result_column_count(res)) |
648 | + { |
649 | + last_query_result.setRowsSent(drizzle_result_row_count(res)); |
650 | + last_query_result.setRowsExamined(drizzle_result_affected_rows(res)); |
651 | + last_query_result.setWarningCount(drizzle_result_warning_count(res)); |
652 | + retval= PKT_RESULT; |
653 | + goto free_and_return; |
654 | + } |
655 | + /* Else this is "Result set header" packet */ |
656 | + } |
657 | + else |
658 | + { |
659 | + std::cerr << "Unknown packet type from server" << std::endl; |
660 | + retval= PKT_ERROR; |
661 | + goto free_and_return; |
662 | + } |
663 | + } |
664 | + /* Parse result set */ |
665 | + else |
666 | + { |
667 | + /* "Field" packets */ |
668 | + if (eof_count == 0) |
669 | + { |
670 | + drizzle_column_st *column= drizzle_column_read(drizzle_con->result, |
671 | + NULL, |
672 | + &ret); |
673 | + if (ret == DRIZZLE_RETURN_OK) |
674 | + { |
675 | + /* "EOF" packet */ |
676 | + if (column == NULL) |
677 | + ++eof_count; |
678 | + retval= PKT_OK; |
679 | + } |
680 | + else |
681 | + { |
682 | + std::cerr << "Parse column error" << std::endl; |
683 | + retval= PKT_ERROR; |
684 | + goto free_and_return; |
685 | + } |
686 | + } |
687 | + /* "Row" packets */ |
688 | + else if (eof_count == 1) |
689 | + { |
690 | + uint8_t old_packet_number= drizzle_con->packet_number; |
691 | + uint64_t row= drizzle_row_read(drizzle_con->result, &ret); |
692 | + if (ret != DRIZZLE_RETURN_OK) |
693 | + { |
694 | + std::cerr << "Error in parsing row" << std::endl; |
695 | + retval= PKT_ERROR; |
696 | + goto free_and_return; |
697 | + } |
698 | + else |
699 | + ++sent_rows_count; |
700 | + /* "EOF" packet */ |
701 | + if (!row) |
702 | + { |
703 | + eof_count= 0; |
704 | + |
705 | + drizzle_con->buffer_ptr= &buff[0]; |
706 | + drizzle_con->buffer_size= buff.size(); |
707 | + |
708 | + drizzle_result_free_all(drizzle_con.get()); |
709 | + drizzle_con->packet_number= old_packet_number; |
710 | + drizzle_result_st *res= drizzle_result_read(drizzle_con.get(), |
711 | + NULL, |
712 | + &ret); |
713 | + /* |
714 | + Setting DRIZZLE_RESULT_ALLOCATED in result options |
715 | + helps to avoid memory leak. |
716 | + See https://bugs.launchpad.net/drizzle/+bug/1015576 |
717 | + */ |
718 | + res->options= |
719 | + (drizzle_result_options_t) |
720 | + ((uint64_t)(res->options) | (uint64_t)DRIZZLE_RESULT_ALLOCATED); |
721 | + last_query_result.setWarningCount(drizzle_result_warning_count(res)); |
722 | + /* Don't count the last EOF packet */ |
723 | + last_query_result.setRowsSent(sent_rows_count - 1); |
724 | + |
725 | + sent_rows_count= 0; |
726 | + retval= PKT_RESULT; |
727 | + goto free_and_return; |
728 | + } |
729 | + else |
730 | + retval= PKT_OK; |
731 | + } |
732 | + } |
733 | + |
734 | + return retval; |
735 | + |
736 | +free_and_return: |
737 | + drizzle_result_free_all(drizzle_con.get()); |
738 | + drizzle_con->result= NULL; |
739 | + was_query= false; |
740 | + return retval; |
741 | +} |
742 | + |
743 | +PktResult |
744 | +ConnectionState::ClientPacket(IN UCharBuffer &buff, |
745 | + OUT std::string &query) |
746 | +{ |
747 | + drizzle_command_t command; |
748 | + drizzle_return_t ret; |
749 | + size_t total; |
750 | + uint8_t *data; |
751 | + PktResult result= PKT_UNKNOWN; |
752 | + |
753 | + drizzle_con->buffer_ptr= &buff[0]; |
754 | + drizzle_con->buffer_size= buff.size(); |
755 | + data= (uint8_t *)drizzle_con_command_buffer(drizzle_con.get(), |
756 | + &command, |
757 | + &total, |
758 | + &ret); |
759 | + if (ret == DRIZZLE_RETURN_OK) |
760 | + { |
761 | + switch(command) |
762 | + { |
763 | + case DRIZZLE_COMMAND_QUERY: |
764 | + query.assign((const char *)data); |
765 | + was_query= true; |
766 | + result= PKT_QUERY; |
767 | + break; |
768 | + |
769 | + case DRIZZLE_COMMAND_INIT_DB: |
770 | + query.assign("use "); |
771 | + query+= (const char *)data; |
772 | + was_query= true; |
773 | + result= PKT_QUERY; |
774 | + break; |
775 | + |
776 | + default:; |
777 | + } |
778 | + } |
779 | + |
780 | + free(data); |
781 | + return result; |
782 | +} |
783 | + |
784 | +void |
785 | +ConnectionState::DispatchQuery(const timeval &ts, |
786 | + const std::string &query, |
787 | + const AddrPort &addr_port) |
788 | +{ |
789 | + boost::shared_ptr<TcpdumpQueryEntry> |
790 | + query_entry(new TcpdumpQueryEntry(ts, |
791 | + query, |
792 | + addr_port)); |
793 | + db_thread->queries.push(query_entry); |
794 | +} |
795 | + |
796 | +void |
797 | +ConnectionState::DispatchResult(const timeval &ts, |
798 | + const AddrPort &addr_port) |
799 | +{ |
800 | + boost::shared_ptr<TcpdumpResultEntry> |
801 | + result_entry(new TcpdumpResultEntry(addr_port, ts, last_query_result)); |
802 | + db_thread->queries.push(result_entry); |
803 | +} |
804 | + |
805 | |
806 | === added file 'percona_playback/tcpdump/connection_state.h' |
807 | --- percona_playback/tcpdump/connection_state.h 1970-01-01 00:00:00 +0000 |
808 | +++ percona_playback/tcpdump/connection_state.h 2012-07-02 18:23:18 +0000 |
809 | @@ -0,0 +1,186 @@ |
810 | +/* BEGIN LICENSE |
811 | + * Copyright (C) 2011 Percona Inc. |
812 | + * This program is free software: you can redistribute it and/or modify it |
813 | + * under the terms of the GNU General Public License version 2, as published |
814 | + * by the Free Software Foundation. |
815 | + * |
816 | + * This program is distributed in the hope that it will be useful, but |
817 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
818 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
819 | + * PURPOSE. See the GNU General Public License for more details. |
820 | + * |
821 | + * You should have received a copy of the GNU General Public License along |
822 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
823 | + * END LICENSE */ |
824 | + |
825 | +#ifndef PERCONA_PLAYBACK_CONNECTION_STATE_H |
826 | +#define PERCONA_PLAYBACK_CONNECTION_STATE_H |
827 | + |
828 | +#include <stdlib.h> |
829 | +#include <sys/time.h> |
830 | +#include <vector> |
831 | +#include <string> |
832 | +#include <string.h> |
833 | +#include <boost/shared_ptr.hpp> |
834 | +#include <libdrizzle/drizzle_client.h> |
835 | + |
836 | +#include "percona_playback/query_result.h" |
837 | +#include "percona_playback/db_thread.h" |
838 | +#include "tcpdump_mysql_parser_stats.h" |
839 | + |
840 | +enum PktResult |
841 | +{ |
842 | + PKT_QUERY, |
843 | + PKT_RESULT, |
844 | + PKT_OK, |
845 | + PKT_UNKNOWN, |
846 | + PKT_ERROR |
847 | +}; |
848 | + |
849 | +#define IN |
850 | +#define OUT |
851 | + |
852 | +#pragma pack(push, 1) |
853 | +// Every logical MySQL packet starts w/ this 4 byte header |
854 | +struct MysqlPkt { |
855 | + uint16_t length_low; |
856 | + uint8_t length_high; |
857 | + uint8_t id; |
858 | + uint8_t data[0]; |
859 | + |
860 | + size_t data_length() const |
861 | + { |
862 | + return (size_t)length_low | ((size_t)length_high << 16); |
863 | + } |
864 | + |
865 | + size_t full_length() const |
866 | + { |
867 | + return data_length() + header_size(); |
868 | + } |
869 | + |
870 | + static size_t header_size() |
871 | + { |
872 | + return offsetof(MysqlPkt, data); |
873 | + } |
874 | +}; |
875 | +#pragma pack(pop) |
876 | + |
877 | +struct AddrPort |
878 | +{ |
879 | + AddrPort() : address(0), port(0) {} |
880 | + AddrPort(uint32_t address, uint16_t port) : address(address), port(port) {} |
881 | + uint32_t address; |
882 | + uint16_t port; |
883 | + uint64_t ThreadId() const |
884 | + { |
885 | + return (uint64_t)address | ((uint64_t)port << 32); |
886 | + } |
887 | +}; |
888 | + |
889 | +struct LastExecutedQueryInfo |
890 | +{ |
891 | + std::string query; |
892 | + QueryResult result; |
893 | + timeval begin_pcap_timestamp; |
894 | + timeval end_pcap_timestamp; |
895 | + timeval end_timestamp; |
896 | + |
897 | + LastExecutedQueryInfo() |
898 | + { |
899 | + memset(&begin_pcap_timestamp, 0, sizeof(begin_pcap_timestamp)); |
900 | + memset(&end_pcap_timestamp, 0, sizeof(end_pcap_timestamp)); |
901 | + memset(&end_timestamp, 0, sizeof(end_timestamp)); |
902 | + } |
903 | +}; |
904 | + |
905 | + |
906 | +class ConnectionState : public DBThreadState |
907 | + |
908 | +{ |
909 | + |
910 | +public: |
911 | + |
912 | + enum Origin |
913 | + { |
914 | + UNDEF, |
915 | + CLIENT, |
916 | + SERVER |
917 | + }; |
918 | + |
919 | + ConnectionState() : |
920 | + current_origin(UNDEF), |
921 | + fragmented(false), |
922 | + handshake_from_client(false), |
923 | + was_query(false), |
924 | + eof_count(0), |
925 | + sent_rows_count(0), |
926 | + drizzle(drizzle_create(NULL), drizzle_free), |
927 | + drizzle_con( |
928 | + drizzle_con_add_tcp(drizzle.get(), |
929 | + NULL, |
930 | + "localhost", |
931 | + 3306, |
932 | + "user", |
933 | + "password", |
934 | + "db", |
935 | + (drizzle_con_options_t) |
936 | + DRIZZLE_CON_MYSQL), |
937 | + drizzle_con_free), |
938 | + db_thread(NULL) |
939 | + { |
940 | + drizzle_con->result= NULL; |
941 | + } |
942 | + |
943 | + ~ConnectionState() |
944 | + { |
945 | + drizzle_result_free_all(drizzle_con.get()); |
946 | + } |
947 | + |
948 | + void ProcessMysqlPkts(const u_char *pkts, |
949 | + u_int total_len, |
950 | + const timeval &ts, |
951 | + const AddrPort &addr_port, |
952 | + OUT TcpdumpMysqlParserStats &stats); |
953 | + |
954 | + void ProcessFinishConnection(); |
955 | + |
956 | + void SetCurrentOrigin(Origin o) { current_origin = o; } |
957 | + |
958 | + void SetDBThread(DBThread *t) { db_thread= t; } |
959 | + |
960 | + LastExecutedQueryInfo last_executed_query_info; |
961 | + |
962 | +private: |
963 | + |
964 | + typedef std::vector<unsigned char> UCharBuffer; |
965 | + |
966 | + PktResult ParseMysqlPkt(IN UCharBuffer &buff, OUT std::string &query); |
967 | + |
968 | + PktResult ServerPacket(IN UCharBuffer &buff); |
969 | + PktResult ClientPacket(IN UCharBuffer &buff, OUT std::string &query); |
970 | + |
971 | + void DispatchQuery(const timeval &ts, |
972 | + const std::string &query, |
973 | + const AddrPort &addr_port); |
974 | + |
975 | + void DispatchResult(const timeval &ts, |
976 | + const AddrPort &addr_port); |
977 | + |
978 | + Origin current_origin; |
979 | + bool fragmented; |
980 | + UCharBuffer frag_buff; |
981 | + bool handshake_from_client; |
982 | + bool was_query; |
983 | + size_t eof_count; |
984 | + size_t sent_rows_count; |
985 | + |
986 | + boost::shared_ptr<drizzle_st> drizzle; |
987 | + boost::shared_ptr<drizzle_con_st> drizzle_con; |
988 | + |
989 | + QueryResult last_query_result; |
990 | + |
991 | + DBThread *db_thread; |
992 | + |
993 | +}; |
994 | + |
995 | +#endif // PERCONA_PLAYBACK_CONNECTION_STATE_H |
996 | |
997 | === added file 'percona_playback/tcpdump/pcap_packets_parser.cc' |
998 | --- percona_playback/tcpdump/pcap_packets_parser.cc 1970-01-01 00:00:00 +0000 |
999 | +++ percona_playback/tcpdump/pcap_packets_parser.cc 2012-07-02 18:23:18 +0000 |
1000 | @@ -0,0 +1,134 @@ |
1001 | +/* BEGIN LICENSE |
1002 | + * Copyright (C) 2011-2012 Percona Inc. |
1003 | + * This program is free software: you can redistribute it and/or modify it |
1004 | + * under the terms of the GNU General Public License version 2, as published |
1005 | + * by the Free Software Foundation. |
1006 | + * |
1007 | + * This program is distributed in the hope that it will be useful, but |
1008 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1009 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1010 | + * PURPOSE. See the GNU General Public License for more details. |
1011 | + * |
1012 | + * You should have received a copy of the GNU General Public License along |
1013 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1014 | + * END LICENSE */ |
1015 | +#include "pcap_packets_parser.h" |
1016 | +#include "sniff_headers.h" |
1017 | +#include "tcpdump.h" |
1018 | + |
1019 | +#include "percona_playback/db_thread.h" |
1020 | +#include "percona_playback/plugin.h" |
1021 | +#include "percona_playback/dispatcher.h" |
1022 | + |
1023 | +#include <netinet/in.h> |
1024 | +#include <arpa/inet.h> |
1025 | +#include <iostream> |
1026 | +#include <boost/foreach.hpp> |
1027 | +#include <assert.h> |
1028 | + |
1029 | +#define SNAP_LEN 16500 // pcap's max capture size |
1030 | + |
1031 | +extern percona_playback::DBClientPlugin *g_dbclient_plugin; |
1032 | + |
1033 | +void |
1034 | +PcapPacketsParser::ParsePkt(const struct pcap_pkthdr *header, |
1035 | + const u_char *packet) |
1036 | +{ |
1037 | + ConnectionState::Origin origin= ConnectionState::UNDEF; |
1038 | + const struct sniff_ethernet *ethernet; |
1039 | + const struct sniff_ip *ip; |
1040 | + const struct sniff_tcp *tcp; |
1041 | + const uint8_t *mysql; |
1042 | + size_t size_ip; |
1043 | + size_t size_tcp; |
1044 | + size_t size_mysql; |
1045 | + |
1046 | + assert(header); |
1047 | + assert(packet); |
1048 | + |
1049 | + if(header->len > SNAP_LEN) { |
1050 | + std::cerr << "Captured packet too large: " |
1051 | + << header->len |
1052 | + << " bytes, Max capture packet size: " |
1053 | + << SNAP_LEN << " bytes" << std::endl; |
1054 | + return; |
1055 | + } |
1056 | + |
1057 | + ethernet= (struct sniff_ethernet*)(packet); |
1058 | + ip= (struct sniff_ip*)(packet + SIZE_ETHERNET); |
1059 | + size_ip= IP_HL(ip) * 4; |
1060 | + tcp= (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); |
1061 | + size_tcp= TH_OFF(tcp) * 4; |
1062 | + mysql= (packet + SIZE_ETHERNET + size_ip + size_tcp); |
1063 | + size_mysql= ntohs(ip->ip_len) - size_ip - size_tcp; |
1064 | + |
1065 | + |
1066 | + AddrPort addr_port; |
1067 | + |
1068 | + if (ntohs(tcp->th_sport) == g_tcpdump_port) |
1069 | + { |
1070 | + addr_port.address= ip->ip_dst.s_addr; |
1071 | + addr_port.port= tcp->th_dport; |
1072 | + origin= ConnectionState::SERVER; |
1073 | + } |
1074 | + else |
1075 | + { |
1076 | + addr_port.address= ip->ip_src.s_addr; |
1077 | + addr_port.port= tcp->th_sport; |
1078 | + origin= ConnectionState::CLIENT; |
1079 | + } |
1080 | + |
1081 | + /* The connection was closed. */ |
1082 | + if (size_mysql == 0 && |
1083 | + ((tcp->th_flags & TH_FIN) || (tcp->th_flags & TH_RST))) |
1084 | + { |
1085 | + g_dispatcher.finish(addr_port.ThreadId()); |
1086 | + return; |
1087 | + } |
1088 | + |
1089 | + /* The mysql packet is too small. It may be due to tcp service packets. */ |
1090 | + if (size_mysql < MysqlPkt::header_size()) |
1091 | + return; |
1092 | + |
1093 | + if (!was_first_packet) |
1094 | + { |
1095 | + gettimeofday(&first_packet_timestamp, 0); |
1096 | + first_packet_pcap_timestamp= header->ts; |
1097 | + was_first_packet= true; |
1098 | + } |
1099 | + |
1100 | + /* If there is no DBThread with such id create it */ |
1101 | + boost::shared_ptr<DBThreadState> |
1102 | + state= g_dispatcher.get_thread_state(addr_port.ThreadId(), |
1103 | + boost::bind(&PcapPacketsParser::CreateConnectionState, |
1104 | + this, |
1105 | + _1)); |
1106 | + |
1107 | + assert(state.get()); |
1108 | + |
1109 | + ((ConnectionState *)state.get())->SetCurrentOrigin(origin); |
1110 | + ((ConnectionState *)state.get())->ProcessMysqlPkts(mysql, |
1111 | + size_mysql, |
1112 | + header->ts, |
1113 | + addr_port, |
1114 | + stats); |
1115 | +} |
1116 | + |
1117 | +void |
1118 | +PcapPacketsParser::WaitForUnfinishedTasks() |
1119 | +{ |
1120 | + g_dispatcher.finish_all_and_wait(); |
1121 | +} |
1122 | + |
1123 | +void |
1124 | +PcapPacketsParser::CreateConnectionState(DBThread *db_thread) |
1125 | +{ |
1126 | + assert(db_thread); |
1127 | + boost::shared_ptr<ConnectionState> state(new ConnectionState()); |
1128 | + state->last_executed_query_info.end_pcap_timestamp= |
1129 | + first_packet_pcap_timestamp; |
1130 | + state->last_executed_query_info.end_timestamp= |
1131 | + first_packet_timestamp; |
1132 | + db_thread->set_state(state); |
1133 | + state->SetDBThread(db_thread); |
1134 | +} |
1135 | |
1136 | === added file 'percona_playback/tcpdump/pcap_packets_parser.h' |
1137 | --- percona_playback/tcpdump/pcap_packets_parser.h 1970-01-01 00:00:00 +0000 |
1138 | +++ percona_playback/tcpdump/pcap_packets_parser.h 2012-07-02 18:23:18 +0000 |
1139 | @@ -0,0 +1,64 @@ |
1140 | +/* BEGIN LICENSE |
1141 | + * Copyright (C) 2011 Percona Inc. |
1142 | + * This program is free software: you can redistribute it and/or modify it |
1143 | + * under the terms of the GNU General Public License version 2, as published |
1144 | + * by the Free Software Foundation. |
1145 | + * |
1146 | + * This program is distributed in the hope that it will be useful, but |
1147 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1148 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1149 | + * PURPOSE. See the GNU General Public License for more details. |
1150 | + * |
1151 | + * You should have received a copy of the GNU General Public License along |
1152 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1153 | + * END LICENSE */ |
1154 | + |
1155 | +#ifndef PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H |
1156 | +#define PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H |
1157 | + |
1158 | +#include "connection_state.h" |
1159 | +#include "tcpdump_mysql_parser_stats.h" |
1160 | + |
1161 | +#include <pcap.h> |
1162 | +#include <tbb/concurrent_queue.h> |
1163 | +#include <boost/thread.hpp> |
1164 | +#include <boost/bind.hpp> |
1165 | + |
1166 | +class DBThread; |
1167 | + |
1168 | +class PcapPacketsParser |
1169 | +{ |
1170 | + TcpdumpMysqlParserStats stats; |
1171 | + timeval first_packet_timestamp; |
1172 | + timeval first_packet_pcap_timestamp; |
1173 | + bool was_first_packet; |
1174 | + |
1175 | +public: |
1176 | + |
1177 | + PcapPacketsParser() : was_first_packet(false) |
1178 | + { |
1179 | + first_packet_timestamp.tv_sec= first_packet_timestamp.tv_usec= 0; |
1180 | + first_packet_pcap_timestamp.tv_sec= first_packet_pcap_timestamp.tv_usec= 0; |
1181 | + } |
1182 | + |
1183 | + static void Process(u_char *arg, |
1184 | + const struct pcap_pkthdr *header, |
1185 | + const u_char *packet) |
1186 | + { |
1187 | + ((PcapPacketsParser *)arg)->ParsePkt(header, packet); |
1188 | + } |
1189 | + |
1190 | + const TcpdumpMysqlParserStats &GetStats() const { return stats; } |
1191 | + |
1192 | + void WaitForUnfinishedTasks(); |
1193 | + |
1194 | + void CreateConnectionState(DBThread *db_thread); |
1195 | + |
1196 | +private: |
1197 | + |
1198 | + void ParsePkt(const struct pcap_pkthdr *header, |
1199 | + const u_char *packet); |
1200 | + |
1201 | +}; |
1202 | + |
1203 | +#endif //PERCONA_PLAYBACK_PCAP_PACKETS_PARSER_H |
1204 | |
1205 | === modified file 'percona_playback/tcpdump/plugin.ac' |
1206 | --- percona_playback/tcpdump/plugin.ac 2012-06-19 01:09:31 +0000 |
1207 | +++ percona_playback/tcpdump/plugin.ac 2012-07-02 18:23:18 +0000 |
1208 | @@ -1,2 +1,2 @@ |
1209 | PANDORA_HAVE_LIBPCAP |
1210 | -PANDORA_HAVE_LIBDRIZZLE |
1211 | +PANDORA_HAVE_LIBDRIZZLE_1_0 |
1212 | |
1213 | === modified file 'percona_playback/tcpdump/plugin.ini' |
1214 | --- percona_playback/tcpdump/plugin.ini 2012-06-19 01:09:31 +0000 |
1215 | +++ percona_playback/tcpdump/plugin.ini 2012-07-02 18:23:18 +0000 |
1216 | @@ -6,4 +6,6 @@ |
1217 | headers=tcpdump.h |
1218 | load_by_default=yes |
1219 | ldflags=${PCAP_LIBS} ${LTLIBDRIZZLE} ${LDFLAGS} |
1220 | -cppflags=${PCAP_INCLUDES} ${CPPFLAGS} |
1221 | +cppflags=${PCAP_INCLUDES} ${CPPFLAGS} |
1222 | +headers=tcpdump.h sniff_headers.h connection_state.h pcap_packets_parser.h tcpdump_query_entries.h tcpdump_mysql_parser_stats.h |
1223 | +sources=tcpdump.cc connection_state.cc pcap_packets_parser.cc tcpdump_query_entries.cc |
1224 | |
1225 | === added file 'percona_playback/tcpdump/sniff_headers.h' |
1226 | --- percona_playback/tcpdump/sniff_headers.h 1970-01-01 00:00:00 +0000 |
1227 | +++ percona_playback/tcpdump/sniff_headers.h 2012-07-02 18:23:18 +0000 |
1228 | @@ -0,0 +1,59 @@ |
1229 | +/* ethernet headers are always exactly 14 bytes [1] */ |
1230 | +#define SIZE_ETHERNET 14 |
1231 | + |
1232 | +/* Ethernet addresses are 6 bytes */ |
1233 | +#define ETHER_ADDR_LEN 6 |
1234 | + |
1235 | +//#pragma pack(push, 1) |
1236 | +/* Ethernet header */ |
1237 | +struct sniff_ethernet { |
1238 | + u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */ |
1239 | + u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */ |
1240 | + u_short ether_type; /* IP? ARP? RARP? etc */ |
1241 | +}; |
1242 | + |
1243 | +/* IP header */ |
1244 | +struct sniff_ip { |
1245 | + u_char ip_vhl; /* version << 4 | header length >> 2 */ |
1246 | + u_char ip_tos; /* type of service */ |
1247 | + u_short ip_len; /* total length */ |
1248 | + u_short ip_id; /* identification */ |
1249 | + u_short ip_off; /* fragment offset field */ |
1250 | + #define IP_RF 0x8000 /* reserved fragment flag */ |
1251 | + #define IP_DF 0x4000 /* dont fragment flag */ |
1252 | + #define IP_MF 0x2000 /* more fragments flag */ |
1253 | + #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ |
1254 | + u_char ip_ttl; /* time to live */ |
1255 | + u_char ip_p; /* protocol */ |
1256 | + u_short ip_sum; /* checksum */ |
1257 | + struct in_addr ip_src,ip_dst; /* source and dest address */ |
1258 | +}; |
1259 | +#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f) |
1260 | +#define IP_V(ip) (((ip)->ip_vhl) >> 4) |
1261 | + |
1262 | +/* TCP header */ |
1263 | +typedef u_int tcp_seq; |
1264 | + |
1265 | +struct sniff_tcp { |
1266 | + u_short th_sport; /* source port */ |
1267 | + u_short th_dport; /* destination port */ |
1268 | + tcp_seq th_seq; /* sequence number */ |
1269 | + tcp_seq th_ack; /* acknowledgement number */ |
1270 | + u_char th_offx2; /* data offset, rsvd */ |
1271 | +#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4) |
1272 | + u_char th_flags; |
1273 | + #define TH_FIN 0x01 |
1274 | + #define TH_SYN 0x02 |
1275 | + #define TH_RST 0x04 |
1276 | + #define TH_PUSH 0x08 |
1277 | + #define TH_ACK 0x10 |
1278 | + #define TH_URG 0x20 |
1279 | + #define TH_ECE 0x40 |
1280 | + #define TH_CWR 0x80 |
1281 | + #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR) |
1282 | + u_short th_win; /* window */ |
1283 | + u_short th_sum; /* checksum */ |
1284 | + u_short th_urp; /* urgent pointer */ |
1285 | +}; |
1286 | + |
1287 | +//#pragma pack(pop) |
1288 | |
1289 | === modified file 'percona_playback/tcpdump/tcpdump.cc' |
1290 | --- percona_playback/tcpdump/tcpdump.cc 2012-06-19 01:09:31 +0000 |
1291 | +++ percona_playback/tcpdump/tcpdump.cc 2012-07-02 18:23:18 +0000 |
1292 | @@ -14,15 +14,54 @@ |
1293 | * END LICENSE */ |
1294 | |
1295 | #include "tcpdump.h" |
1296 | +#include "pcap_packets_parser.h" |
1297 | + |
1298 | +#include "percona_playback/percona_playback.h" |
1299 | + |
1300 | #include <stdio.h> |
1301 | +#include <pcap.h> |
1302 | + |
1303 | +#define FILTER_EXP_SIZE 11 // max filter expression size |
1304 | + |
1305 | +std::string g_tcpdump_file_name; |
1306 | +uint16_t g_tcpdump_port; |
1307 | +TcpdumpPluginMode g_tcpdump_mode; |
1308 | + |
1309 | +std::istream& operator>>(std::istream& in, TcpdumpPluginMode& unit) |
1310 | +{ |
1311 | + std::string token; |
1312 | + in >> token; |
1313 | + if (token == "fast") |
1314 | + unit = TCPDUMP_MODE_FAST; |
1315 | + else if (token == "accurate") |
1316 | + unit = TCPDUMP_MODE_ACCURATE; |
1317 | + else |
1318 | + throw |
1319 | + boost::program_options::validation_error( |
1320 | + "Allowed input-type values are (fast|accurate)" |
1321 | + ); |
1322 | + return in; |
1323 | +} |
1324 | |
1325 | boost::program_options::options_description* |
1326 | TcpDumpParserPlugin::getProgramOptions() |
1327 | { |
1328 | options.add_options() |
1329 | ("tcpdump-file", |
1330 | - boost::program_options::value<std::string>(&file_name), |
1331 | - "Tcpdump file name"); |
1332 | + boost::program_options::value<std::string>(&g_tcpdump_file_name), |
1333 | + "Tcpdump file name") |
1334 | + ("tcpdump-port", |
1335 | + boost::program_options::value<uint16_t>(&g_tcpdump_port) |
1336 | + ->default_value(3306), |
1337 | + "Tcpdump port") |
1338 | + ("tcpdump-mode", |
1339 | + boost::program_options::value<TcpdumpPluginMode>(&g_tcpdump_mode) |
1340 | + ->multitoken()->default_value(TCPDUMP_MODE_FAST, "fast"), |
1341 | + "The mode of tcpdump plugin (fast|accurate), in 'fast' mode " |
1342 | + "the plugin executes queries as fast as it can whereas in " |
1343 | + "'accurate' mode the plugin preserves queries execution time " |
1344 | + "and pauses between queries") |
1345 | + ; |
1346 | |
1347 | return &options; |
1348 | } |
1349 | @@ -32,7 +71,9 @@ |
1350 | boost::program_options::variables_map &vm) |
1351 | { |
1352 | if (!active && |
1353 | - (vm.count("tcpdump-file"))) |
1354 | + (vm.count("tcpdump-file") || |
1355 | + !vm["tcpdump-port"].defaulted() || |
1356 | + !vm["tcpdump-mode"].defaulted())) |
1357 | { |
1358 | fprintf(stderr, |
1359 | gettext("tcpdump plugin is not selected, " |
1360 | @@ -40,9 +81,87 @@ |
1361 | "command line options\n")); |
1362 | return -1; |
1363 | } |
1364 | + |
1365 | + if (!active) |
1366 | + return 0; |
1367 | + |
1368 | + if (!vm.count("tcpdump-file")) |
1369 | + { |
1370 | + fprintf(stderr, |
1371 | + gettext("tcpdump-file argument is requred\n")); |
1372 | + return -1; |
1373 | + } |
1374 | + |
1375 | return 0; |
1376 | } |
1377 | |
1378 | +void |
1379 | +TcpDumpParserPlugin::run(percona_playback_run_result &r) |
1380 | +{ |
1381 | + char errbuf[PCAP_ERRBUF_SIZE]; |
1382 | + pcap_t *handle; |
1383 | + struct bpf_program fp; |
1384 | + char filter_exp[11]; |
1385 | + PcapPacketsParser packets_parser; |
1386 | + |
1387 | + |
1388 | + if (g_tcpdump_file_name.empty()) |
1389 | + { |
1390 | + r.err= -1; |
1391 | + return; |
1392 | + } |
1393 | + |
1394 | + handle = pcap_open_offline(g_tcpdump_file_name.c_str(), errbuf); |
1395 | + |
1396 | + if (handle == NULL) |
1397 | + { |
1398 | + std::cerr << "Couldn't open file " << g_tcpdump_file_name << ": " |
1399 | + << errbuf << std::endl; |
1400 | + r.err= -1; |
1401 | + return; |
1402 | + } |
1403 | + |
1404 | + snprintf(filter_exp, FILTER_EXP_SIZE, "port %u", (unsigned)g_tcpdump_port); |
1405 | + |
1406 | + if(pcap_compile(handle, &fp, filter_exp, 0, 0) == -1) |
1407 | + { |
1408 | + std::cerr << "Couldn't parse filter " << filter_exp << ": " |
1409 | + << pcap_geterr(handle) << std::endl; |
1410 | + r.err= -1; |
1411 | + return; |
1412 | + } |
1413 | + |
1414 | + if (pcap_setfilter(handle, &fp) == -1) |
1415 | + { |
1416 | + std::cerr << "Couldn't install filter " << filter_exp << ": " |
1417 | + << pcap_geterr(handle) << std::endl; |
1418 | + r.err= -1; |
1419 | + return; |
1420 | + } |
1421 | + |
1422 | + if (pcap_loop(handle, |
1423 | + -1, |
1424 | + PcapPacketsParser::Process, |
1425 | + (u_char *)&packets_parser) < 0) |
1426 | + { |
1427 | + std::cerr << "pcap_loop error " |
1428 | + << pcap_geterr(handle) << std::endl; |
1429 | + r.err= -1; |
1430 | + return; |
1431 | + } |
1432 | + |
1433 | + /* Wait for unfinished DBThreads */ |
1434 | + packets_parser.WaitForUnfinishedTasks(); |
1435 | + |
1436 | + const TcpdumpMysqlParserStats &stats= packets_parser.GetStats(); |
1437 | + |
1438 | + r.n_log_entries= stats.nr_of_parsed_packets; |
1439 | + r.n_queries= stats.nr_of_parsed_queries; |
1440 | + r.err= stats.nr_of_parsing_errors; |
1441 | + |
1442 | + return; |
1443 | +} |
1444 | + |
1445 | static void init_plugin(percona_playback::PluginRegistry &r) |
1446 | { |
1447 | r.add("tcpdump", new TcpDumpParserPlugin("tcpdump")); |
1448 | |
1449 | === modified file 'percona_playback/tcpdump/tcpdump.h' |
1450 | --- percona_playback/tcpdump/tcpdump.h 2012-06-24 04:28:41 +0000 |
1451 | +++ percona_playback/tcpdump/tcpdump.h 2012-07-02 18:23:18 +0000 |
1452 | @@ -19,9 +19,17 @@ |
1453 | #include <percona_playback/plugin.h> |
1454 | |
1455 | #include <boost/program_options.hpp> |
1456 | +#include <string> |
1457 | + |
1458 | +enum TcpdumpPluginMode |
1459 | +{ |
1460 | + TCPDUMP_MODE_FAST, |
1461 | + TCPDUMP_MODE_ACCURATE |
1462 | +}; |
1463 | |
1464 | class TcpDumpParserPlugin : public percona_playback::InputPlugin |
1465 | { |
1466 | + boost::program_options::options_description options; |
1467 | |
1468 | public: |
1469 | TcpDumpParserPlugin(const std::string &_name) : |
1470 | @@ -33,11 +41,20 @@ |
1471 | |
1472 | virtual int processOptions(boost::program_options::variables_map &vm); |
1473 | |
1474 | +<<<<<<< TREE |
1475 | virtual void run(percona_playback_run_result &) {} |
1476 | |
1477 | |
1478 | std::string file_name; |
1479 | boost::program_options::options_description options; |
1480 | +======= |
1481 | + virtual void run(percona_playback_run_result &result); |
1482 | +>>>>>>> MERGE-SOURCE |
1483 | }; |
1484 | |
1485 | +extern std::string g_tcpdump_file_name; |
1486 | +extern uint16_t g_tcpdump_port; |
1487 | +extern TcpdumpPluginMode g_tcpdump_mode; |
1488 | + |
1489 | + |
1490 | #endif /* PERCONA_PLAYBACK_TCPDUMP_PARSER_H */ |
1491 | |
1492 | === added file 'percona_playback/tcpdump/tcpdump_mysql_parser_stats.h' |
1493 | --- percona_playback/tcpdump/tcpdump_mysql_parser_stats.h 1970-01-01 00:00:00 +0000 |
1494 | +++ percona_playback/tcpdump/tcpdump_mysql_parser_stats.h 2012-07-02 18:23:18 +0000 |
1495 | @@ -0,0 +1,33 @@ |
1496 | +/* BEGIN LICENSE |
1497 | + * Copyright (C) 2011 Percona Inc. |
1498 | + * This program is free software: you can redistribute it and/or modify it |
1499 | + * under the terms of the GNU General Public License version 2, as published |
1500 | + * by the Free Software Foundation. |
1501 | + * |
1502 | + * This program is distributed in the hope that it will be useful, but |
1503 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1504 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1505 | + * PURPOSE. See the GNU General Public License for more details. |
1506 | + * |
1507 | + * You should have received a copy of the GNU General Public License along |
1508 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1509 | + * END LICENSE */ |
1510 | + |
1511 | +#ifndef PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H |
1512 | +#define PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H |
1513 | + |
1514 | +struct TcpdumpMysqlParserStats |
1515 | +{ |
1516 | + size_t nr_of_parsed_packets; |
1517 | + size_t nr_of_parsed_queries; |
1518 | + size_t nr_of_parsing_errors; |
1519 | + |
1520 | + TcpdumpMysqlParserStats() : |
1521 | + nr_of_parsed_packets(0), |
1522 | + nr_of_parsed_queries(0), |
1523 | + nr_of_parsing_errors(0) |
1524 | + {} |
1525 | + |
1526 | +}; |
1527 | + |
1528 | +#endif //PERCONA_PLAYBACK_TCPDUMP_MYSQL_PARSER_STATS_H |
1529 | |
1530 | === added file 'percona_playback/tcpdump/tcpdump_query_entries.cc' |
1531 | --- percona_playback/tcpdump/tcpdump_query_entries.cc 1970-01-01 00:00:00 +0000 |
1532 | +++ percona_playback/tcpdump/tcpdump_query_entries.cc 2012-07-02 18:23:18 +0000 |
1533 | @@ -0,0 +1,129 @@ |
1534 | +/* BEGIN LICENSE |
1535 | + * Copyright (C) 2011-2012 Percona Inc. |
1536 | + * This program is free software: you can redistribute it and/or modify it |
1537 | + * under the terms of the GNU General Public License version 2, as published |
1538 | + * by the Free Software Foundation. |
1539 | + * |
1540 | + * This program is distributed in the hope that it will be useful, but |
1541 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1542 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1543 | + * PURPOSE. See the GNU General Public License for more details. |
1544 | + * |
1545 | + * You should have received a copy of the GNU General Public License along |
1546 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1547 | + * END LICENSE */ |
1548 | +#include "tcpdump_query_entries.h" |
1549 | +#include "tcpdump.h" |
1550 | +#include "percona_playback/db_thread.h" |
1551 | +#include "percona_playback/plugin.h" |
1552 | + |
1553 | +#include <boost/date_time/posix_time/posix_time.hpp> |
1554 | +#include <boost/foreach.hpp> |
1555 | +#include <boost/shared_ptr.hpp> |
1556 | +#include <string.h> |
1557 | +#include <iostream> |
1558 | +#include <assert.h> |
1559 | + |
1560 | +void |
1561 | +TcpdumpQueryEntry::execute(DBThread *t) |
1562 | +{ |
1563 | + QueryResult expected_result; |
1564 | + boost::posix_time::ptime start_time; |
1565 | + boost::posix_time::ptime end_time; |
1566 | + boost::shared_ptr<DBThreadState> thr_state; |
1567 | + |
1568 | + assert(t); |
1569 | + |
1570 | + thr_state= t->get_state(); |
1571 | + |
1572 | + assert(thr_state.get()); |
1573 | + |
1574 | + ConnectionState &state= (ConnectionState &)*thr_state; |
1575 | + |
1576 | + LastExecutedQueryInfo &last_query_info= state.last_executed_query_info; |
1577 | + |
1578 | + if (g_tcpdump_mode == TCPDUMP_MODE_ACCURATE && |
1579 | + last_query_info.end_timestamp.tv_sec != 0 && |
1580 | + last_query_info.end_timestamp.tv_usec != 0 && |
1581 | + last_query_info.end_pcap_timestamp.tv_sec != 0 && |
1582 | + last_query_info.end_pcap_timestamp.tv_usec != 0) |
1583 | + { |
1584 | + timeval current_timestamp; |
1585 | + timeval pause_time; |
1586 | + timeval pcap_pause_time; |
1587 | + |
1588 | + gettimeofday(¤t_timestamp, NULL); |
1589 | + timersub(¤t_timestamp, &last_query_info.end_timestamp, &pause_time); |
1590 | + |
1591 | + timersub(&pcap_timestamp, |
1592 | + &last_query_info.end_pcap_timestamp, |
1593 | + &pcap_pause_time); |
1594 | + |
1595 | + if (timercmp(&pause_time, &pcap_pause_time, <)) |
1596 | + { |
1597 | + timeval time_to_sleep; |
1598 | + timersub(&pcap_pause_time, |
1599 | + &pause_time, |
1600 | + &time_to_sleep); |
1601 | + usleep(time_to_sleep.tv_sec*1000000 + time_to_sleep.tv_usec); |
1602 | + } |
1603 | + } |
1604 | + |
1605 | + last_query_info.result.clear(); |
1606 | + |
1607 | + start_time= boost::posix_time::microsec_clock::universal_time(); |
1608 | + t->execute_query(query, &last_query_info.result, expected_result); |
1609 | + end_time= boost::posix_time::microsec_clock::universal_time(); |
1610 | + |
1611 | + boost::posix_time::time_period duration(start_time, end_time); |
1612 | + last_query_info.result.setDuration(duration.length()); |
1613 | + last_query_info.begin_pcap_timestamp= pcap_timestamp; |
1614 | + last_query_info.query= query; |
1615 | +} |
1616 | + |
1617 | +void |
1618 | +TcpdumpResultEntry::execute(DBThread *t) |
1619 | +{ |
1620 | + timeval query_execution_time; |
1621 | + boost::shared_ptr<DBThreadState> thr_state; |
1622 | + |
1623 | + assert(t); |
1624 | + |
1625 | + thr_state= t->get_state(); |
1626 | + |
1627 | + assert(thr_state.get()); |
1628 | + |
1629 | + |
1630 | + ConnectionState &state= (ConnectionState &)*thr_state; |
1631 | + LastExecutedQueryInfo &last_query_info= state.last_executed_query_info; |
1632 | + |
1633 | + timersub(&pcap_timestamp, |
1634 | + &last_query_info.begin_pcap_timestamp, |
1635 | + &query_execution_time); |
1636 | + |
1637 | + expected_result.setDuration( |
1638 | + boost::posix_time::microseconds( |
1639 | + query_execution_time.tv_usec + |
1640 | + query_execution_time.tv_sec*1000000)); |
1641 | + |
1642 | + if (g_tcpdump_mode == TCPDUMP_MODE_ACCURATE && |
1643 | + (expected_result.getDuration() > last_query_info.result.getDuration())) |
1644 | + { |
1645 | + boost::posix_time::time_duration us_sleep_time= |
1646 | + expected_result.getDuration() - last_query_info.result.getDuration(); |
1647 | + |
1648 | + usleep(us_sleep_time.total_microseconds()); |
1649 | + } |
1650 | + |
1651 | + gettimeofday(&last_query_info.end_timestamp, NULL); |
1652 | + last_query_info.end_pcap_timestamp= pcap_timestamp; |
1653 | + |
1654 | + BOOST_FOREACH(const percona_playback::PluginRegistry::ReportPluginPair pp, |
1655 | + percona_playback::PluginRegistry::singleton().report_plugins) |
1656 | + { |
1657 | + pp.second->query_execution(getThreadId(), |
1658 | + last_query_info.query, |
1659 | + expected_result, |
1660 | + last_query_info.result); |
1661 | + } |
1662 | +} |
1663 | |
1664 | === added file 'percona_playback/tcpdump/tcpdump_query_entries.h' |
1665 | --- percona_playback/tcpdump/tcpdump_query_entries.h 1970-01-01 00:00:00 +0000 |
1666 | +++ percona_playback/tcpdump/tcpdump_query_entries.h 2012-07-02 18:23:18 +0000 |
1667 | @@ -0,0 +1,73 @@ |
1668 | +/* BEGIN LICENSE |
1669 | + * Copyright (C) 2011 Percona Inc. |
1670 | + * This program is free software: you can redistribute it and/or modify it |
1671 | + * under the terms of the GNU General Public License version 2, as published |
1672 | + * by the Free Software Foundation. |
1673 | + * |
1674 | + * This program is distributed in the hope that it will be useful, but |
1675 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1676 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1677 | + * PURPOSE. See the GNU General Public License for more details. |
1678 | + * |
1679 | + * You should have received a copy of the GNU General Public License along |
1680 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1681 | + * END LICENSE */ |
1682 | + |
1683 | +#ifndef PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H |
1684 | +#define PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H |
1685 | + |
1686 | +#include "percona_playback/query_entry.h" |
1687 | +#include "percona_playback/query_result.h" |
1688 | +#include "connection_state.h" |
1689 | + |
1690 | +#include <sys/time.h> |
1691 | + |
1692 | +class TcpdumpQueryEntry : public QueryEntry |
1693 | +{ |
1694 | + timeval pcap_timestamp; |
1695 | + std::string query; |
1696 | + |
1697 | +public: |
1698 | + |
1699 | + TcpdumpQueryEntry() |
1700 | + { |
1701 | + pcap_timestamp.tv_sec= pcap_timestamp.tv_usec= 0; |
1702 | + } |
1703 | + |
1704 | + TcpdumpQueryEntry(const timeval &pcap_timestamp, |
1705 | + const std::string &query, |
1706 | + const AddrPort &addr_port) : |
1707 | + QueryEntry(addr_port.ThreadId(), false), |
1708 | + pcap_timestamp(pcap_timestamp), |
1709 | + query(query) |
1710 | + {} |
1711 | + |
1712 | + bool is_quit() { return false; } |
1713 | + |
1714 | + void execute(DBThread *t); |
1715 | +}; |
1716 | + |
1717 | +class TcpdumpResultEntry : public QueryEntry |
1718 | +{ |
1719 | + |
1720 | + timeval pcap_timestamp; |
1721 | + QueryResult expected_result; |
1722 | + |
1723 | +public: |
1724 | + TcpdumpResultEntry() {} |
1725 | + TcpdumpResultEntry(const AddrPort &addr_port, |
1726 | + const timeval &pcap_timestamp, |
1727 | + const QueryResult &expected_result) : |
1728 | + QueryEntry(addr_port.ThreadId(), false), |
1729 | + pcap_timestamp(pcap_timestamp), |
1730 | + expected_result(expected_result) |
1731 | + {} |
1732 | + |
1733 | + bool is_quit() { return false; } |
1734 | + |
1735 | + void execute(DBThread *t); |
1736 | + |
1737 | +}; |
1738 | + |
1739 | +#endif// PERCONA_PLAYBACK_TCPDUMP_QUERY_ENTRIES_H |
1740 | + |
1741 | |
1742 | === added file 'percona_playback/test/tcpdump_accuracy.cc' |
1743 | --- percona_playback/test/tcpdump_accuracy.cc 1970-01-01 00:00:00 +0000 |
1744 | +++ percona_playback/test/tcpdump_accuracy.cc 2012-07-02 18:23:18 +0000 |
1745 | @@ -0,0 +1,69 @@ |
1746 | +/* BEGIN LICENSE |
1747 | + * Copyright (C) 2011-2012 Percona Inc. |
1748 | + * This program is free software: you can redistribute it and/or modify it |
1749 | + * under the terms of the GNU General Public License version 3, as published |
1750 | + * by the Free Software Foundation. |
1751 | + * |
1752 | + * This program is distributed in the hope that it will be useful, but |
1753 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1754 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1755 | + * PURPOSE. See the GNU General Public License for more details. |
1756 | + * |
1757 | + * You should have received a copy of the GNU General Public License along |
1758 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1759 | + * END LICENSE */ |
1760 | + |
1761 | +#include "config.h" |
1762 | +#include <iostream> |
1763 | +#include <assert.h> |
1764 | +#include <boost/date_time/posix_time/posix_time.hpp> |
1765 | + |
1766 | +#include "percona_playback/percona_playback.h" |
1767 | +#include "percona_playback/plugin.h" |
1768 | + |
1769 | +const size_t pp_argc= 5; |
1770 | + |
1771 | +int main(int, char **argv) |
1772 | +{ |
1773 | + percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); |
1774 | + assert(the_percona_playback); |
1775 | + |
1776 | + char *pp_argv[pp_argc]; |
1777 | + char pp_argv_0[]= "--db-plugin=null"; |
1778 | + char pp_argv_1[]= "--input-plugin=tcpdump"; |
1779 | + char pp_argv_2[]= "--tcpdump-file=" |
1780 | + SRCDIR |
1781 | + "/percona_playback/test" |
1782 | + "/tcpdump_accuracy.dump"; |
1783 | + char pp_argv_3[]= "--tcpdump-mode=accurate"; |
1784 | + |
1785 | + pp_argv[0]= argv[0]; |
1786 | + pp_argv[1]= pp_argv_0; |
1787 | + pp_argv[2]= pp_argv_1; |
1788 | + pp_argv[3]= pp_argv_2; |
1789 | + pp_argv[4]= pp_argv_3; |
1790 | + |
1791 | + assert(0 == percona_playback_argv(the_percona_playback, |
1792 | + pp_argc, |
1793 | + pp_argv)); |
1794 | + |
1795 | + boost::posix_time::ptime start_time; |
1796 | + start_time= boost::posix_time::microsec_clock::universal_time(); |
1797 | + |
1798 | + struct percona_playback_run_result *r= |
1799 | + percona_playback_run(the_percona_playback); |
1800 | + |
1801 | + boost::posix_time::ptime end_time; |
1802 | + end_time= boost::posix_time::microsec_clock::universal_time(); |
1803 | + |
1804 | + boost::posix_time::time_period duration(start_time, end_time); |
1805 | + |
1806 | + assert(duration.length().total_microseconds() > 4000000); |
1807 | + |
1808 | + assert(r->err == 0); |
1809 | + assert(r->n_queries == 60); |
1810 | + assert(r->n_log_entries == 480); |
1811 | + |
1812 | + percona_playback_destroy(&the_percona_playback); |
1813 | + return r->err; |
1814 | +} |
1815 | |
1816 | === added file 'percona_playback/test/tcpdump_accuracy.dump' |
1817 | Binary files percona_playback/test/tcpdump_accuracy.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_accuracy.dump 2012-07-02 18:23:18 +0000 differ |
1818 | === added file 'percona_playback/test/tcpdump_fragmented_packet.cc' |
1819 | --- percona_playback/test/tcpdump_fragmented_packet.cc 1970-01-01 00:00:00 +0000 |
1820 | +++ percona_playback/test/tcpdump_fragmented_packet.cc 2012-07-02 18:23:18 +0000 |
1821 | @@ -0,0 +1,56 @@ |
1822 | +/* BEGIN LICENSE |
1823 | + * Copyright (C) 2011-2012 Percona Inc. |
1824 | + * This program is free software: you can redistribute it and/or modify it |
1825 | + * under the terms of the GNU General Public License version 3, as published |
1826 | + * by the Free Software Foundation. |
1827 | + * |
1828 | + * This program is distributed in the hope that it will be useful, but |
1829 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1830 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1831 | + * PURPOSE. See the GNU General Public License for more details. |
1832 | + * |
1833 | + * You should have received a copy of the GNU General Public License along |
1834 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1835 | + * END LICENSE */ |
1836 | + |
1837 | +#include "config.h" |
1838 | +#include <iostream> |
1839 | +#include <assert.h> |
1840 | +#include "percona_playback/percona_playback.h" |
1841 | +#include "percona_playback/plugin.h" |
1842 | + |
1843 | +const size_t pp_argc= 4; |
1844 | + |
1845 | +int main(int, char **argv) |
1846 | +{ |
1847 | + percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); |
1848 | + assert(the_percona_playback); |
1849 | + |
1850 | + char *pp_argv[pp_argc]; |
1851 | + char pp_argv_0[]= "--db-plugin=null"; |
1852 | + char pp_argv_1[]= "--input-plugin=tcpdump"; |
1853 | + char pp_argv_2[]= "--tcpdump-file=" |
1854 | + SRCDIR |
1855 | + "/percona_playback/test" |
1856 | + "/tcpdump_fragmented_packet.dump"; |
1857 | + |
1858 | + |
1859 | + pp_argv[0]= argv[0]; |
1860 | + pp_argv[1]= pp_argv_0; |
1861 | + pp_argv[2]= pp_argv_1; |
1862 | + pp_argv[3]= pp_argv_2; |
1863 | + |
1864 | + assert(0 == percona_playback_argv(the_percona_playback, |
1865 | + pp_argc, |
1866 | + pp_argv)); |
1867 | + |
1868 | + struct percona_playback_run_result *r= |
1869 | + percona_playback_run(the_percona_playback); |
1870 | + |
1871 | + assert(r->err == 0); |
1872 | + assert(r->n_queries == 1); |
1873 | + assert(r->n_log_entries == 6); |
1874 | + |
1875 | + percona_playback_destroy(&the_percona_playback); |
1876 | + return r->err; |
1877 | +} |
1878 | |
1879 | === added file 'percona_playback/test/tcpdump_fragmented_packet.dump' |
1880 | Binary files percona_playback/test/tcpdump_fragmented_packet.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_fragmented_packet.dump 2012-07-02 18:23:18 +0000 differ |
1881 | === added file 'percona_playback/test/tcpdump_multiple_connections.cc' |
1882 | --- percona_playback/test/tcpdump_multiple_connections.cc 1970-01-01 00:00:00 +0000 |
1883 | +++ percona_playback/test/tcpdump_multiple_connections.cc 2012-07-02 18:23:18 +0000 |
1884 | @@ -0,0 +1,56 @@ |
1885 | +/* BEGIN LICENSE |
1886 | + * Copyright (C) 2011-2012 Percona Inc. |
1887 | + * This program is free software: you can redistribute it and/or modify it |
1888 | + * under the terms of the GNU General Public License version 3, as published |
1889 | + * by the Free Software Foundation. |
1890 | + * |
1891 | + * This program is distributed in the hope that it will be useful, but |
1892 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1893 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1894 | + * PURPOSE. See the GNU General Public License for more details. |
1895 | + * |
1896 | + * You should have received a copy of the GNU General Public License along |
1897 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1898 | + * END LICENSE */ |
1899 | + |
1900 | +#include "config.h" |
1901 | +#include <iostream> |
1902 | +#include <assert.h> |
1903 | +#include "percona_playback/percona_playback.h" |
1904 | +#include "percona_playback/plugin.h" |
1905 | + |
1906 | +const size_t pp_argc= 4; |
1907 | + |
1908 | +int main(int, char **argv) |
1909 | +{ |
1910 | + percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); |
1911 | + assert(the_percona_playback); |
1912 | + |
1913 | + char *pp_argv[pp_argc]; |
1914 | + char pp_argv_0[]= "--db-plugin=null"; |
1915 | + char pp_argv_1[]= "--input-plugin=tcpdump"; |
1916 | + char pp_argv_2[]= "--tcpdump-file=" |
1917 | + SRCDIR |
1918 | + "/percona_playback/test" |
1919 | + "/tcpdump_multiple_connections.dump"; |
1920 | + |
1921 | + |
1922 | + pp_argv[0]= argv[0]; |
1923 | + pp_argv[1]= pp_argv_0; |
1924 | + pp_argv[2]= pp_argv_1; |
1925 | + pp_argv[3]= pp_argv_2; |
1926 | + |
1927 | + assert(0 == percona_playback_argv(the_percona_playback, |
1928 | + pp_argc, |
1929 | + pp_argv)); |
1930 | + |
1931 | + struct percona_playback_run_result *r= |
1932 | + percona_playback_run(the_percona_playback); |
1933 | + |
1934 | + assert(r->err == 0); |
1935 | + assert(r->n_queries == 2000); |
1936 | + assert(r->n_log_entries == 16000); |
1937 | + |
1938 | + percona_playback_destroy(&the_percona_playback); |
1939 | + return r->err; |
1940 | +} |
1941 | |
1942 | === added file 'percona_playback/test/tcpdump_multiple_connections.dump' |
1943 | Binary files percona_playback/test/tcpdump_multiple_connections.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_multiple_connections.dump 2012-07-02 18:23:18 +0000 differ |
1944 | === added file 'percona_playback/test/tcpdump_stress_test.cc' |
1945 | --- percona_playback/test/tcpdump_stress_test.cc 1970-01-01 00:00:00 +0000 |
1946 | +++ percona_playback/test/tcpdump_stress_test.cc 2012-07-02 18:23:18 +0000 |
1947 | @@ -0,0 +1,56 @@ |
1948 | +/* BEGIN LICENSE |
1949 | + * Copyright (C) 2011-2012 Percona Inc. |
1950 | + * This program is free software: you can redistribute it and/or modify it |
1951 | + * under the terms of the GNU General Public License version 3, as published |
1952 | + * by the Free Software Foundation. |
1953 | + * |
1954 | + * This program is distributed in the hope that it will be useful, but |
1955 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
1956 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
1957 | + * PURPOSE. See the GNU General Public License for more details. |
1958 | + * |
1959 | + * You should have received a copy of the GNU General Public License along |
1960 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
1961 | + * END LICENSE */ |
1962 | + |
1963 | +#include "config.h" |
1964 | +#include <iostream> |
1965 | +#include <assert.h> |
1966 | +#include "percona_playback/percona_playback.h" |
1967 | +#include "percona_playback/plugin.h" |
1968 | + |
1969 | +const size_t pp_argc= 4; |
1970 | + |
1971 | +int main(int, char **argv) |
1972 | +{ |
1973 | + percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); |
1974 | + assert(the_percona_playback); |
1975 | + |
1976 | + char *pp_argv[pp_argc]; |
1977 | + char pp_argv_0[]= "--db-plugin=null"; |
1978 | + char pp_argv_1[]= "--input-plugin=tcpdump"; |
1979 | + char pp_argv_2[]= "--tcpdump-file=" |
1980 | + SRCDIR |
1981 | + "/percona_playback/test" |
1982 | + "/tcpdump_stress_test.dump"; |
1983 | + |
1984 | + |
1985 | + pp_argv[0]= argv[0]; |
1986 | + pp_argv[1]= pp_argv_0; |
1987 | + pp_argv[2]= pp_argv_1; |
1988 | + pp_argv[3]= pp_argv_2; |
1989 | + |
1990 | + assert(0 == percona_playback_argv(the_percona_playback, |
1991 | + pp_argc, |
1992 | + pp_argv)); |
1993 | + |
1994 | + struct percona_playback_run_result *r= |
1995 | + percona_playback_run(the_percona_playback); |
1996 | + |
1997 | + assert(r->err == 0); |
1998 | + assert(r->n_queries == 9088); |
1999 | + assert(r->n_log_entries == 62306); |
2000 | + |
2001 | + percona_playback_destroy(&the_percona_playback); |
2002 | + return r->err; |
2003 | +} |
2004 | |
2005 | === added file 'percona_playback/test/tcpdump_stress_test.dump' |
2006 | Binary files percona_playback/test/tcpdump_stress_test.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_stress_test.dump 2012-07-02 18:23:18 +0000 differ |
2007 | === added file 'percona_playback/test/tcpdump_without_handshake.cc' |
2008 | --- percona_playback/test/tcpdump_without_handshake.cc 1970-01-01 00:00:00 +0000 |
2009 | +++ percona_playback/test/tcpdump_without_handshake.cc 2012-07-02 18:23:18 +0000 |
2010 | @@ -0,0 +1,56 @@ |
2011 | +/* BEGIN LICENSE |
2012 | + * Copyright (C) 2011-2012 Percona Inc. |
2013 | + * This program is free software: you can redistribute it and/or modify it |
2014 | + * under the terms of the GNU General Public License version 3, as published |
2015 | + * by the Free Software Foundation. |
2016 | + * |
2017 | + * This program is distributed in the hope that it will be useful, but |
2018 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
2019 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2020 | + * PURPOSE. See the GNU General Public License for more details. |
2021 | + * |
2022 | + * You should have received a copy of the GNU General Public License along |
2023 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
2024 | + * END LICENSE */ |
2025 | + |
2026 | +#include "config.h" |
2027 | +#include <iostream> |
2028 | +#include <assert.h> |
2029 | +#include "percona_playback/percona_playback.h" |
2030 | +#include "percona_playback/plugin.h" |
2031 | + |
2032 | +const size_t pp_argc= 4; |
2033 | + |
2034 | +int main(int, char **argv) |
2035 | +{ |
2036 | + percona_playback_st *the_percona_playback= percona_playback_create("test_Percona Playback"); |
2037 | + assert(the_percona_playback); |
2038 | + |
2039 | + char *pp_argv[pp_argc]; |
2040 | + char pp_argv_0[]= "--db-plugin=null"; |
2041 | + char pp_argv_1[]= "--input-plugin=tcpdump"; |
2042 | + char pp_argv_2[]= "--tcpdump-file=" |
2043 | + SRCDIR |
2044 | + "/percona_playback/test" |
2045 | + "/tcpdump_without_handshake.dump"; |
2046 | + |
2047 | + |
2048 | + pp_argv[0]= argv[0]; |
2049 | + pp_argv[1]= pp_argv_0; |
2050 | + pp_argv[2]= pp_argv_1; |
2051 | + pp_argv[3]= pp_argv_2; |
2052 | + |
2053 | + assert(0 == percona_playback_argv(the_percona_playback, |
2054 | + pp_argc, |
2055 | + pp_argv)); |
2056 | + |
2057 | + struct percona_playback_run_result *r= |
2058 | + percona_playback_run(the_percona_playback); |
2059 | + |
2060 | + assert(r->err == 0); |
2061 | + assert(r->n_queries == 7); |
2062 | + assert(r->n_log_entries == 44); |
2063 | + |
2064 | + percona_playback_destroy(&the_percona_playback); |
2065 | + return r->err; |
2066 | +} |
2067 | |
2068 | === added file 'percona_playback/test/tcpdump_without_handshake.dump' |
2069 | Binary files percona_playback/test/tcpdump_without_handshake.dump 1970-01-01 00:00:00 +0000 and percona_playback/test/tcpdump_without_handshake.dump 2012-07-02 18:23:18 +0000 differ |