Prevent unintended sharing of parsing info
When a single GWBUF was split into two with gwbuf_split, the new GWBUF would point to the start of the shared data and the old one to the end. Data-wise, this is fine but as the parsing info for queries is stored in the shared buffer it causes problems when multiple packets get read in one network payload. The end result would be that only the first query in the lot would get parsed and the rest would get the same classification as the first one. To properly fix this without the need to deep clone the buffer would require a reorganization of the buffer mechanism in MaxScale. This commit alone doesn't fix the queued query routing problems in readwritesplit. The commit from 2.2 which fixes the ordering problems with queued queries is also required for a fully functional queued query mechanism.
This commit is contained in:
parent
4dda31ffe3
commit
dd99cadfd2
@ -220,18 +220,19 @@ GWBUF* gwbuf_clone(GWBUF* buf)
|
||||
return rval;
|
||||
}
|
||||
|
||||
GWBUF* gwbuf_deep_clone(const GWBUF* buf)
|
||||
static GWBUF* gwbuf_deep_clone_portion(const GWBUF* buf, size_t length)
|
||||
{
|
||||
mxb_assert(buf->owner == RoutingWorker::get_current_id());
|
||||
GWBUF* rval = NULL;
|
||||
|
||||
if (buf)
|
||||
{
|
||||
size_t buflen = gwbuf_length(buf);
|
||||
rval = gwbuf_alloc(buflen);
|
||||
rval = gwbuf_alloc(length);
|
||||
|
||||
if (rval && gwbuf_copy_data(buf, 0, buflen, GWBUF_DATA(rval)) == buflen)
|
||||
if (rval && gwbuf_copy_data(buf, 0, length, GWBUF_DATA(rval)) == length)
|
||||
{
|
||||
// The copying of the type is done to retain the type characteristic of the buffer without
|
||||
// having a link the orginal data or parsing info.
|
||||
rval->gwbuf_type = buf->gwbuf_type;
|
||||
}
|
||||
else
|
||||
@ -244,7 +245,12 @@ GWBUF* gwbuf_deep_clone(const GWBUF* buf)
|
||||
return rval;
|
||||
}
|
||||
|
||||
static GWBUF* gwbuf_clone_portion(GWBUF* buf,
|
||||
GWBUF* gwbuf_deep_clone(const GWBUF* buf)
|
||||
{
|
||||
return gwbuf_deep_clone_portion(buf, gwbuf_length(buf));
|
||||
}
|
||||
|
||||
static GWBUF *gwbuf_clone_portion(GWBUF* buf,
|
||||
size_t start_offset,
|
||||
size_t length)
|
||||
{
|
||||
@ -311,7 +317,7 @@ GWBUF* gwbuf_split(GWBUF** buf, size_t length)
|
||||
if (length > 0)
|
||||
{
|
||||
mxb_assert(GWBUF_LENGTH(buffer) > length);
|
||||
GWBUF* partial = gwbuf_clone_portion(buffer, 0, length);
|
||||
GWBUF* partial = gwbuf_deep_clone_portion(buffer, length);
|
||||
|
||||
/** If the head points to the original head of the buffer chain
|
||||
* and we are splitting a contiguous buffer, we only need to return
|
||||
|
Loading…
x
Reference in New Issue
Block a user