Skip to content

Commit 909ceb6

Browse files
craig[bot]msbutlerfqazi
committed
147861: storage: introduce ComputeSSTStatsDiff r=sumeerbhola a=msbutler This patch adds the new ComputeSSTStatsDiff utility which will be called in batcheval.EvalAddSSTable in a future PR to ingest an sst over non empty key space with an accurate stats update. Informs #145548 Release note: none 148222: pgwire: limit size of SSL frames sent r=fqazi a=fqazi Previously, CRDB bumped up the result buffer size (sql.defaults.results_buffer.size) from 16k to a higher value. After this change we started seeing asynchronous libpq clients start hanging because they can only consume 8 kilobytes of data at a time. As a result large SSL frames can be problematic in this configuration. To address this, this patch limits CRDB to sending the result buffer at 8 kilobytes at a time. Fixes: #147890 Release note (bug fix): Addressed a bug where libpq clients using the async API could hang with large result sets (psycopg, activerecord, ruby-pg) Co-authored-by: Michael Butler <[email protected]> Co-authored-by: Faizan Qazi <[email protected]>
3 parents 352b1d2 + eef8437 + c52adfc commit 909ceb6

File tree

9 files changed

+647
-6
lines changed

9 files changed

+647
-6
lines changed

pkg/acceptance/adapter_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func TestDockerNodeJS(t *testing.T) {
6969
export SHOULD_FAIL=%v
7070
# Get access to globally installed node modules.
7171
export NODE_PATH=$NODE_PATH:/usr/lib/node
72+
export NODE_TLS_REJECT_UNAUTHORIZED=0
7273
# Have a 10 second timeout on promises, in case the server is slow.
7374
/usr/lib/node/.bin/mocha -t 10000 .
7475
`
@@ -110,9 +111,12 @@ func TestDockerPython(t *testing.T) {
110111
ctx := context.Background()
111112
t.Run("Success", func(t *testing.T) {
112113
testDockerSuccess(ctx, t, "python", []string{"sh", "-c", "cd /mnt/data/python && python test.py 3"})
114+
testDockerSuccess(ctx, t, "python", []string{"sh", "-c", "cd /mnt/data/python && python3 test_pyscopg3.py 3"})
115+
113116
})
114117
t.Run("Fail", func(t *testing.T) {
115118
testDockerFail(ctx, t, "python", []string{"sh", "-c", "cd /mnt/data/python && python test.py 2"})
119+
testDockerFail(ctx, t, "python", []string{"sh", "-c", "cd /mnt/data/python && python3 test_pyscopg3.py 2"})
116120
})
117121
}
118122

pkg/acceptance/testdata/Dockerfile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,13 @@ RUN curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg > /etc/apt/trusted.gpg.d
6363
ruby \
6464
ruby-pg \
6565
xmlstarlet \
66-
yarn
66+
yarn \
67+
python3-dev \
68+
python3-pip \
69+
python3-setuptools \
70+
&& pip3 install --upgrade pip \
71+
&& pip3 install backports.zoneinfo \
72+
&& pip3 install psycopg
6773

6874
RUN case ${TARGETPLATFORM} in \
6975
"linux/amd64") ARCH=amd64; SHASUM=442dae58b727a79f81368127fac141d7f95501ffa05f8c48943d27c4e807deb7 ;; \

pkg/acceptance/testdata/node/base-test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ describe('arrays', () => {
7171
});
7272
});
7373

74+
// Temporarily disabled until https://github.com/brianc/node-postgres/issues/3487
75+
// gets resolved. The binary encoding in node-postgres was regressed at some
76+
// point leading to protocol violation errors.
77+
/*
7478
describe('regression tests', () => {
7579
it('allows you to switch between format modes for arrays', () => {
7680
return client.query({
@@ -88,3 +92,4 @@ describe('regression tests', () => {
8892
});
8993
});
9094
})
95+
*/
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright 2018 The Cockroach Authors.
2+
#
3+
# Use of this software is governed by the CockroachDB Software License
4+
# included in the /LICENSE file.
5+
6+
import decimal
7+
import sys
8+
import psycopg
9+
10+
conn = psycopg.connect('')
11+
cur = conn.cursor()
12+
cur.execute("SELECT 1, 2+{}".format(sys.argv[1]))
13+
v = cur.fetchall()
14+
assert v == [(1, 5)]
15+
16+
# Verify #6597 (timestamp format) is fixed.
17+
cur = conn.cursor()
18+
cur.execute("SELECT now()")
19+
v = cur.fetchall()
20+
21+
# Verify round-trip of strings containing backslashes.
22+
# https://github.com/cockroachdb/cockroachdb-python/issues/23
23+
s = ('\\\\',)
24+
cur.execute("SELECT %s::STRING", s)
25+
v = cur.fetchall()
26+
assert v == [s], (v, s)
27+
28+
# Verify decimals with exponents can be parsed.
29+
cur = conn.cursor()
30+
cur.execute("SELECT 1e1::decimal")
31+
v = cur.fetchall()
32+
d = v[0][0]
33+
assert type(d) is decimal.Decimal
34+
# Use of compare_total here guarantees that we didn't just get '10' back, we got '1e1'.
35+
assert d.compare_total(decimal.Decimal('1e1')) == 0
36+
37+
# Verify arrays with strings can be parsed.
38+
cur = conn.cursor()
39+
cur.execute("SELECT ARRAY['foo','bar','baz']")
40+
v = cur.fetchall()
41+
d = v[0][0]
42+
assert d == ["foo","bar","baz"]
43+
44+
# Verify JSON values come through properly.
45+
cur = conn.cursor()
46+
cur.execute("SELECT '{\"a\":\"b\"}'::JSONB")
47+
v = cur.fetchall()
48+
d = v[0][0]
49+
assert d == {"a": "b"}
50+
51+
52+
# Verify queries with large result sets can be run and do not
53+
# hang.
54+
query = """
55+
SELECT
56+
'000000000000000000000' AS aaaaaaaa,
57+
'000000000000000000000' AS b,
58+
'000000000000000000000' AS c,
59+
'000000000000000000000' AS d,
60+
'000000000000000000000' AS e,
61+
'000000000000000000000' AS f,
62+
'000000000000000000000' AS g,
63+
'0000000000000000000' AS h
64+
FROM generate_series(1, 238)
65+
"""
66+
67+
for i in range(30):
68+
cur.execute(query)
69+
v = cur.fetchall()
70+
assert len(v) == 238
71+

pkg/acceptance/util_docker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func testDockerSuccess(ctx context.Context, t *testing.T, name string, cmd []str
6363
const (
6464
// Iterating against a locally built version of the docker image can be done
6565
// by changing acceptanceImage to the hash of the container.
66-
acceptanceImage = "us-east1-docker.pkg.dev/crl-ci-images/cockroach/acceptance:20221005-223354"
66+
acceptanceImage = "us-east1-docker.pkg.dev/crl-ci-images/cockroach/acceptance:20250612-132728"
6767
)
6868

6969
func testDocker(

pkg/sql/pgwire/conn.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,11 +1251,26 @@ func (c *conn) Flush(pos sql.CmdPos) error {
12511251
// the underlying ring buffer memory for reuse.
12521252
c.writerState.fi.cmdStarts.Reset()
12531253

1254-
_ /* n */, err := c.writerState.buf.WriteTo(c.conn)
1255-
if err != nil {
1256-
c.setErr(err)
1257-
return err
1254+
// When flushing, writes into the socket buffer limit how many bytes
1255+
// are written into an SSL frame at a time. Stock Postgres will at most
1256+
// write 8 kilobytes of unencrypted data at a time. libpq can also only
1257+
// consume 8 kilobytes (via PQConsumeInput), so async clients will hang
1258+
// if bigger SSL frames are sent.
1259+
const maxWriteSize = 8192
1260+
bytesToWrite := c.writerState.buf.Bytes()
1261+
for i := 0; i < len(bytesToWrite); i += maxWriteSize {
1262+
targetSize := min(len(bytesToWrite)-i, maxWriteSize)
1263+
m, err := c.conn.Write(bytesToWrite[i : i+targetSize])
1264+
if err == nil && m < targetSize {
1265+
err = io.ErrShortWrite
1266+
}
1267+
if err != nil {
1268+
c.setErr(err)
1269+
c.writerState.buf.Reset()
1270+
return err
1271+
}
12581272
}
1273+
c.writerState.buf.Reset()
12591274
return nil
12601275
}
12611276

pkg/storage/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ go_test(
148148
"pebble_mvcc_scanner_test.go",
149149
"pebble_test.go",
150150
"read_as_of_iterator_test.go",
151+
"sst_stats_diff_test.go",
151152
"sst_test.go",
152153
"sst_writer_test.go",
153154
"store_properties_test.go",

0 commit comments

Comments
 (0)