Merge lp:~miguelaraujo/mysql-proxy/load_data_infile_handling into lp:mysql-proxy/0.8

Proposed by Miguel Araújo
Status: Merged
Merged at revision: 1248
Proposed branch: lp:~miguelaraujo/mysql-proxy/load_data_infile_handling
Merge into: lp:mysql-proxy/0.8
Diff against target: 98 lines (+37/-3)
3 files modified
plugins/proxy/proxy-plugin.c (+7/-2)
src/network-mysqld.c (+25/-1)
src/network-mysqld.h (+5/-0)
To merge this branch: bzr merge lp:~miguelaraujo/mysql-proxy/load_data_infile_handling
Reviewer Review Type Date Requested Status
Jan Kneschke (community) Approve
Review via email: mp+98836@code.launchpad.net

Description of the change

redesigned handling of LOAD DATA INFILE statements:

   - instead of buffering the whole data until the last packet and then send it to the backends,
     we send immediatly each packet of data received to the backends until there is no more
     data to read;

   - added new flag on mysql connection struct (gboolean local_file_data_is_finished),
     used to indicate whether we have received all data from LOAD DATA INFILE;

  added safe-guard for the connection state-machine:

   - critical message if the state-machines reaches the end without waiting for an event;

To post a comment you must log in.
Revision history for this message
Jan Kneschke (jan-kneschke) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/proxy/proxy-plugin.c'
2--- plugins/proxy/proxy-plugin.c 2012-03-05 16:11:45 +0000
3+++ plugins/proxy/proxy-plugin.c 2012-03-22 13:01:19 +0000
4@@ -2047,9 +2047,14 @@
5 g_assert_cmpint(com_query->state, ==, PARSE_COM_QUERY_LOCAL_INFILE_DATA);
6
7 query_result = network_mysqld_proto_get_query_result(&packet, con);
8+
9+ /* set the testing flag for all data received or not */
10+ con->local_file_data_is_finished = (query_result == 1);
11+
12 if (query_result == -1) return NETWORK_SOCKET_ERROR; /* something happend, let's get out of here */
13
14 if (con->server) {
15+ /* we haven't received all data from load data infile, so let's continue reading and writing to the backend */
16 network_mysqld_queue_append_raw(send_sock, send_sock->send_queue,
17 g_queue_pop_tail(recv_sock->recv_queue->chunks));
18 } else {
19@@ -2062,8 +2067,8 @@
20 while ((s = g_queue_pop_head(recv_sock->recv_queue->chunks))) g_string_free(s, TRUE);
21 }
22
23- if (query_result == 1) { /* we have everything, send it to the backend */
24- if (con->server) {
25+ if (query_result == 1) {
26+ if (con->server) { /* we have received all data, lets move forward reading the result from the server */
27 con->state = CON_STATE_SEND_LOCAL_INFILE_DATA;
28 } else {
29 network_mysqld_con_send_ok(con->client);
30
31=== modified file 'src/network-mysqld.c'
32--- src/network-mysqld.c 2012-02-10 13:21:00 +0000
33+++ src/network-mysqld.c 2012-03-22 13:01:19 +0000
34@@ -1837,8 +1837,20 @@
35
36 if (con->state != ostate) break; /* the state has changed (e.g. CON_STATE_ERROR) */
37
38+ /**
39+ * do the plugin call to decode the result-set to track if we are finished already
40+ * or we need to keep reading the data
41+ */
42 switch ((call_ret = plugin_call(srv, con, con->state))) {
43 case NETWORK_SOCKET_SUCCESS:
44+ /**
45+ * if we still haven't read all data from LDLI, lets forward immediatly
46+ * the data to the backends so that we can read the next packets
47+ */
48+ if (!con->local_file_data_is_finished && con->server) {
49+ con->state = CON_STATE_SEND_LOCAL_INFILE_DATA;
50+ }
51+
52 break;
53 default:
54 g_critical("%s: plugin_call(%s) unexpected return value: %d",
55@@ -1849,7 +1861,8 @@
56 con->state = CON_STATE_ERROR;
57 break;
58 }
59- } while (con->state == ostate); /* read packets from the network until the plugin decodes to go to the next state */
60+ /* read packets from the network until the plugin decodes to go to the next state */
61+ } while (con->state == CON_STATE_READ_LOCAL_INFILE_DATA);
62
63 break; }
64 case CON_STATE_SEND_LOCAL_INFILE_DATA:
65@@ -1857,6 +1870,17 @@
66
67 switch (network_mysqld_write(srv, con->server)) {
68 case NETWORK_SOCKET_SUCCESS:
69+ /* if we still haven't read all data from LDLI so we need to go back and read more
70+ */
71+ if (!con->local_file_data_is_finished && con->server) {
72+ con->state = CON_STATE_READ_LOCAL_INFILE_DATA;
73+ }
74+ /* we have read all data from LDLI so we need to read the LDLI result from the server
75+ */
76+ else {
77+ con->state = CON_STATE_READ_LOCAL_INFILE_RESULT;
78+ }
79+
80 break;
81 case NETWORK_SOCKET_WAIT_FOR_EVENT:
82 timeout = con->write_timeout;
83
84=== modified file 'src/network-mysqld.h'
85--- src/network-mysqld.h 2012-02-10 13:21:00 +0000
86+++ src/network-mysqld.h 2012-03-22 13:01:19 +0000
87@@ -340,6 +340,11 @@
88 gboolean com_quit_seen;
89
90 /**
91+ * Flag indicating whether we have received all data from load data infile.
92+ */
93+ gboolean local_file_data_is_finished;
94+
95+ /**
96 * Contains the parsed packet.
97 */
98 struct network_mysqld_con_parse parse;

Subscribers

People subscribed via source and target branches