Skip to content

Commit 5007bbb

Browse files
authored
fix: avoid useless io in large-payload queries (#500)
* fix: avoid useless io in large-payload queries * fix: only limit request body size * fix: body is not exclusive to the POST method * docs: update the description of retry_number
1 parent fb0436c commit 5007bbb

File tree

3 files changed

+17
-15
lines changed

3 files changed

+17
-15
lines changed

config/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ kill_query_user: <kill_query_user_config> | optional
347347
heartbeat: <heartbeat_config> | optional
348348

349349
# RetryNumber - user configuration for query retry when one host cannot respond.
350+
# By default there are no query retries.
351+
# Note: Retrying may impact performance if there are many large-payload requests (such as inserts),
352+
# because it requires copying the request body for reuse.
350353
retry_number: 0
351354

352355
```
@@ -381,11 +384,11 @@ max_execution_time: <duration> | optional | default = 120s
381384
# By default there are no per-minute limits
382385
requests_per_minute: <int> | optional | default = 0
383386

384-
# The burst of request packet size token bucket for user
387+
# The burst of request packet body size token bucket for user
385388
# By default there are no request packet size limits
386389
request_packet_size_tokens_burst: <byte_size> | optional | default = 0
387390

388-
# The request packet size tokens produced rate per second for user
391+
# The request packet body size tokens produced rate per second for user
389392
# By default there are no request packet size limits
390393
request_packet_size_tokens_rate: <byte_size> | optional | default = 0
391394

proxy.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -205,21 +205,22 @@ func executeWithRetry(
205205
startTime := time.Now()
206206
var since float64
207207

208+
var body []byte
209+
var err error
208210
// Use readAndRestoreRequestBody to read the entire request body into a byte slice,
209211
// and to restore req.Body so that it can be reused later in the code.
210-
body, err := readAndRestoreRequestBody(req)
211-
if err != nil {
212-
since := time.Since(startTime).Seconds()
213-
return since, err
212+
if maxRetry > 0 {
213+
body, err = readAndRestoreRequestBody(req)
214+
if err != nil {
215+
since := time.Since(startTime).Seconds()
216+
return since, err
217+
}
214218
}
215219

216220
numRetry := 0
217221
for {
218222
rp(rw, req)
219223

220-
// Restore req.Body after it's consumed by 'rp' for potential reuse.
221-
req.Body = io.NopCloser(bytes.NewBuffer(body))
222-
223224
err := ctx.Err()
224225
if err != nil {
225226
since = time.Since(startTime).Seconds()
@@ -269,6 +270,8 @@ func executeWithRetry(
269270
since = time.Since(startTime).Seconds()
270271
break
271272
}
273+
// Restore req.Body after it's consumed by 'rp' for potential reuse.
274+
req.Body = io.NopCloser(bytes.NewBuffer(body))
272275
numRetry++
273276
}
274277
return since, nil
@@ -915,11 +918,5 @@ func (rp *reverseProxy) getScope(req *http.Request) (*scope, int, error) {
915918
}
916919

917920
s := newScope(req, u, c, cu, sessionId, sessionTimeout)
918-
919-
q, err := getFullQuery(req)
920-
if err != nil {
921-
return nil, http.StatusBadRequest, fmt.Errorf("%s: cannot read query: %w", s, err)
922-
}
923-
s.requestPacketSize = len(q)
924921
return s, 0, nil
925922
}

scope.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ func newScope(req *http.Request, u *user, c *cluster, cu *clusterUser, sessionId
8686
"replica": h.ReplicaName(),
8787
"cluster_node": h.Host(),
8888
},
89+
90+
requestPacketSize: max(0, int(req.ContentLength)),
8991
}
9092
return s
9193
}

0 commit comments

Comments
 (0)