mirror of
https://github.com/neondatabase/neon.git
synced 2026-07-13 09:00:37 +00:00
Compare commits
120 Commits
exponentia
...
alubenniko
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7ffa85b71 | ||
|
|
e530b6e6ba | ||
|
|
df92c40306 | ||
|
|
494c60f9d3 | ||
|
|
0e2110523d | ||
|
|
feb6eaa7a5 | ||
|
|
72c99f8260 | ||
|
|
6b90ea836f | ||
|
|
f08e6ab370 | ||
|
|
bf008b8f99 | ||
|
|
9353b8ee07 | ||
|
|
46348cf8c1 | ||
|
|
d753fd9c80 | ||
|
|
234d3287ed | ||
|
|
24431cfbdf | ||
|
|
0ec1d6f73f | ||
|
|
cdd6a978b9 | ||
|
|
b2a8d96262 | ||
|
|
caaa399293 | ||
|
|
81e1001ae5 | ||
|
|
76016391ee | ||
|
|
f4493a65db | ||
|
|
9b6e46969e | ||
|
|
8b04fc469d | ||
|
|
f8b9ec0dd0 | ||
|
|
b45560db75 | ||
|
|
c4d98915ff | ||
|
|
9ac06ea3d9 | ||
|
|
841b39f7c5 | ||
|
|
fe8fee0b88 | ||
|
|
dbde226f38 | ||
|
|
01c37c6c6c | ||
|
|
e989bf1887 | ||
|
|
84ca400dcf | ||
|
|
c7157d1c01 | ||
|
|
b74d463b15 | ||
|
|
e127e97797 | ||
|
|
b04995f10f | ||
|
|
287e05f49d | ||
|
|
650fb7b2d7 | ||
|
|
c29f78acc4 | ||
|
|
b7fd9e5123 | ||
|
|
b4d9632b19 | ||
|
|
3b6449fb7b | ||
|
|
130066898e | ||
|
|
6f2d7b4662 | ||
|
|
8a00cc817c | ||
|
|
7469656b72 | ||
|
|
9d8ba21f65 | ||
|
|
e54f8bc5ff | ||
|
|
ac72832589 | ||
|
|
2098184d67 | ||
|
|
c7f2a26cb9 | ||
|
|
ebdd187398 | ||
|
|
6c679f722c | ||
|
|
d0cf670b76 | ||
|
|
6d66a2ebe7 | ||
|
|
a8d1cbe376 | ||
|
|
222f483ce8 | ||
|
|
6f6d5f1ea3 | ||
|
|
7cd76ee351 | ||
|
|
0510676a3f | ||
|
|
c7d9eda56a | ||
|
|
6140e3b6b1 | ||
|
|
74eec88125 | ||
|
|
195c7a359d | ||
|
|
8bb0e97880 | ||
|
|
243db8ab4a | ||
|
|
815d7d6ab1 | ||
|
|
226464e6b5 | ||
|
|
e4dc7fe4a5 | ||
|
|
7a324f84e4 | ||
|
|
b54a919d51 | ||
|
|
afd25c896c | ||
|
|
99f9ab2c07 | ||
|
|
e8676ffff7 | ||
|
|
9e61284d10 | ||
|
|
288388f14e | ||
|
|
bfb7bf92f2 | ||
|
|
f8c9966aff | ||
|
|
2e1725c570 | ||
|
|
9414976c4c | ||
|
|
777c01938d | ||
|
|
302a2203a1 | ||
|
|
bc1697ab28 | ||
|
|
61f3ac3fbf | ||
|
|
f7f0be8727 | ||
|
|
c34323eb80 | ||
|
|
4104b1cbd4 | ||
|
|
d143822f64 | ||
|
|
6ff6843dbb | ||
|
|
c14d53b923 | ||
|
|
c7dde2e784 | ||
|
|
173aef925c | ||
|
|
b2af44f027 | ||
|
|
a07fda3a86 | ||
|
|
6b5d33de7d | ||
|
|
16450111c9 | ||
|
|
e8775dda76 | ||
|
|
8959cb1219 | ||
|
|
ecf20bb6fa | ||
|
|
5a4a2ae4cd | ||
|
|
d4f656daa2 | ||
|
|
e2921e352c | ||
|
|
8fb8ec57ea | ||
|
|
0c6b34b5a0 | ||
|
|
b3d90a7d7d | ||
|
|
9b0e277514 | ||
|
|
362f411735 | ||
|
|
fc89b662a3 | ||
|
|
b1c5330241 | ||
|
|
8e90dba6b4 | ||
|
|
5315a78bbe | ||
|
|
95ef3e8d21 | ||
|
|
236e8551fa | ||
|
|
e42dbae4a7 | ||
|
|
1dba8846f8 | ||
|
|
224564e2e0 | ||
|
|
82ba1155f9 | ||
|
|
418ccba23b |
104
.github/workflows/cloud-regress.yml
vendored
Normal file
104
.github/workflows/cloud-regress.yml
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
name: Cloud Regression Test
|
||||
on:
|
||||
push:
|
||||
branches: [amasterov/regress-arm]
|
||||
schedule:
|
||||
# * is a special character in YAML so you have to quote this string
|
||||
# ┌───────────── minute (0 - 59)
|
||||
# │ ┌───────────── hour (0 - 23)
|
||||
# │ │ ┌───────────── day of the month (1 - 31)
|
||||
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
||||
- cron: '0 3 * * *' # run once a day, timezone is utc
|
||||
workflow_dispatch: # adds ability to run this manually
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -euxo pipefail {0}
|
||||
|
||||
concurrency:
|
||||
# Allow only one workflow
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
regress:
|
||||
env:
|
||||
POSTGRES_DISTRIB_DIR: /tmp/neon/pg_install
|
||||
DEFAULT_PG_VERSION: 16
|
||||
TEST_OUTPUT: /tmp/test_output
|
||||
BUILD_TYPE: remote
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_DEV }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_KEY_DEV }}
|
||||
|
||||
runs-on: us-east-2
|
||||
container:
|
||||
image: neondatabase/build-tools:pinned
|
||||
options: --init
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Patch the test
|
||||
run: |
|
||||
cd "vendor/postgres-v${DEFAULT_PG_VERSION}"
|
||||
patch -p1 < "../../patches/cloud_regress_pg${DEFAULT_PG_VERSION}.patch"
|
||||
|
||||
- name: Generate a random password
|
||||
id: pwgen
|
||||
run: |
|
||||
set +x
|
||||
DBPASS=$(dd if=/dev/random bs=48 count=1 2>/dev/null | base64)
|
||||
echo "::add-mask::${DBPASS//\//}"
|
||||
echo DBPASS="${DBPASS//\//}" >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Change tests according to the generated password
|
||||
env:
|
||||
DBPASS: ${{ steps.pwgen.outputs.DBPASS }}
|
||||
run: |
|
||||
cd vendor/postgres-v"${DEFAULT_PG_VERSION}"/src/test/regress
|
||||
for fname in sql/*.sql expected/*.out; do
|
||||
sed -i.bak s/NEON_PASSWORD_PLACEHOLDER/"'${DBPASS}'"/ "${fname}"
|
||||
done
|
||||
for ph in $(grep NEON_MD5_PLACEHOLDER expected/password.out | awk '{print $3;}' | sort | uniq); do
|
||||
USER=$(echo "${ph}" | cut -c 22-)
|
||||
MD5=md5$(echo -n "${DBPASS}${USER}" | md5sum | awk '{print $1;}')
|
||||
sed -i.bak "s/${ph}/${MD5}/" expected/password.out
|
||||
done
|
||||
|
||||
- name: Download Neon artifact
|
||||
uses: ./.github/actions/download
|
||||
with:
|
||||
name: neon-${{ runner.os }}-${{ runner.arch }}-release-artifact
|
||||
path: /tmp/neon/
|
||||
prefix: latest
|
||||
|
||||
- name: Run the regression tests
|
||||
uses: ./.github/actions/run-python-test-set
|
||||
with:
|
||||
build_type: ${{ env.BUILD_TYPE }}
|
||||
test_selection: cloud_regress
|
||||
pg_version: ${{ env.DEFAULT_PG_VERSION }}
|
||||
extra_params: -m remote_cluster
|
||||
env:
|
||||
BENCHMARK_CONNSTR: ${{ secrets.PG_REGRESS_CONNSTR }}
|
||||
|
||||
- name: Create Allure report
|
||||
id: create-allure-report
|
||||
if: ${{ !cancelled() }}
|
||||
uses: ./.github/actions/allure-report-generate
|
||||
|
||||
- name: Post to a Slack channel
|
||||
if: ${{ github.event.schedule && failure() }}
|
||||
uses: slackapi/slack-github-action@v1
|
||||
with:
|
||||
channel-id: "C033QLM5P7D" # on-call-staging-stream
|
||||
slack-message: |
|
||||
Periodic pg_regress on staging: ${{ job.status }}
|
||||
<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|GitHub Run>
|
||||
<${{ steps.create-allure-report.outputs.report-url }}|Allure report>
|
||||
env:
|
||||
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
||||
|
||||
3949
patches/cloud_regress_pg16.patch
Normal file
3949
patches/cloud_regress_pg16.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ SHLIB_LINK_INTERNAL = $(libpq)
|
||||
SHLIB_LINK = -lcurl
|
||||
|
||||
EXTENSION = neon
|
||||
DATA = neon--1.0.sql neon--1.0--1.1.sql neon--1.1--1.2.sql neon--1.2--1.3.sql neon--1.3--1.2.sql neon--1.2--1.1.sql neon--1.1--1.0.sql neon--1.3--1.4.sql neon--1.4--1.3.sql neon--1.4--1.5.sql neon--1.5--1.4.sql
|
||||
DATA = neon--1.0.sql neon--1.0--1.1.sql neon--1.1--1.2.sql neon--1.2--1.3.sql neon--1.3--1.2.sql neon--1.2--1.1.sql neon--1.1--1.0.sql neon--1.3--1.4.sql neon--1.4--1.3.sql
|
||||
PGFILEDESC = "neon - cloud storage for PostgreSQL"
|
||||
|
||||
EXTRA_CLEAN = \
|
||||
|
||||
@@ -1263,7 +1263,7 @@ approximate_working_set_size_seconds(PG_FUNCTION_ARGS)
|
||||
int32 dc;
|
||||
time_t duration = PG_ARGISNULL(0) ? (time_t)-1 : PG_GETARG_INT32(0);
|
||||
LWLockAcquire(lfc_lock, LW_SHARED);
|
||||
dc = (int32) estimateSHLL(&lfc_ctl->wss_estimation, duration, 1.0);
|
||||
dc = (int32) estimateSHLL(&lfc_ctl->wss_estimation, duration);
|
||||
LWLockRelease(lfc_lock);
|
||||
PG_RETURN_INT32(dc);
|
||||
}
|
||||
@@ -1280,7 +1280,7 @@ approximate_working_set_size(PG_FUNCTION_ARGS)
|
||||
int32 dc;
|
||||
bool reset = PG_GETARG_BOOL(0);
|
||||
LWLockAcquire(lfc_lock, reset ? LW_EXCLUSIVE : LW_SHARED);
|
||||
dc = (int32) estimateSHLL(&lfc_ctl->wss_estimation, (time_t)-1, 1.0);
|
||||
dc = (int32) estimateSHLL(&lfc_ctl->wss_estimation, (time_t)-1);
|
||||
if (reset)
|
||||
memset(lfc_ctl->wss_estimation.regs, 0, sizeof lfc_ctl->wss_estimation.regs);
|
||||
LWLockRelease(lfc_lock);
|
||||
@@ -1288,21 +1288,3 @@ approximate_working_set_size(PG_FUNCTION_ARGS)
|
||||
}
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(approximate_optimal_cache_size);
|
||||
|
||||
Datum
|
||||
approximate_optimal_cache_size(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (lfc_size_limit != 0)
|
||||
{
|
||||
int32 dc;
|
||||
time_t duration = PG_ARGISNULL(0) ? (time_t)-1 : PG_GETARG_INT32(0);
|
||||
double min_hit_ratio = PG_ARGISNULL(1) ? 1.0 : PG_GETARG_FLOAT8(1);
|
||||
LWLockAcquire(lfc_lock, LW_SHARED);
|
||||
dc = (int32) estimateSHLL(&lfc_ctl->wss_estimation, duration, min_hit_ratio);
|
||||
LWLockRelease(lfc_lock);
|
||||
PG_RETURN_INT32(dc);
|
||||
}
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 2014-2023, PostgreSQL Global Development Group
|
||||
*
|
||||
* Implements https://hal.science/hal-00465313/document
|
||||
*
|
||||
*
|
||||
* Based on Hideaki Ohno's C++ implementation. This is probably not ideally
|
||||
* suited to estimating the cardinality of very large sets; in particular, we
|
||||
* have not attempted to further optimize the implementation as described in
|
||||
@@ -126,78 +126,22 @@ addSHLL(HyperLogLogState *cState, uint32 hash)
|
||||
/* Compute the rank of the remaining 32 - "k" (registerWidth) bits */
|
||||
count = rho(hash << HLL_BIT_WIDTH, HLL_C_BITS);
|
||||
|
||||
if (cState->regs[index][count].ts)
|
||||
{
|
||||
/* update histgoram */
|
||||
int64_t delta = (now - cState->regs[index][count].ts)/USECS_PER_SEC;
|
||||
uint32_t new_histogram[HIST_SIZE] = {0};
|
||||
for (int i = 0; i < HIST_SIZE; i++) {
|
||||
/* Use middle point of interval */
|
||||
uint32 interval_log2 = pg_ceil_log2_32((delta + (HIST_MIN_INTERVAL*((1<<i) + ((1<<i)/2))/2)) / HIST_MIN_INTERVAL);
|
||||
uint32 cell = Min(interval_log2, HIST_SIZE-1);
|
||||
new_histogram[cell] += cState->regs[index][count].histogram[i];
|
||||
}
|
||||
memcpy(cState->regs[index][count].histogram, new_histogram, sizeof new_histogram);
|
||||
}
|
||||
cState->regs[index][count].ts = now;
|
||||
cState->regs[index][count].histogram[0] += 1; // most recent access always goes to first histogram backet
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
getAccessCount(const HyperLogLogRegister* reg, time_t duration)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
// Simplest solution is to take in account all points fro overlapped interval
|
||||
// for (size_t i = 0; i < HIST_SIZE && HIST_MIN_INTERVAL*((1 << i)/2) <= duration; i++) {
|
||||
for (size_t i = 0; i < HIST_SIZE; i++) {
|
||||
uint32_t high_boundary = HIST_MIN_INTERVAL*(1 << i);
|
||||
uint32_t low_boundary = HIST_MIN_INTERVAL*((1 << i)/2);
|
||||
if (high_boundary >= duration) {
|
||||
// Assume uniform distribution of points within interval and use proportional number of points
|
||||
Assert(duration >= low_boundary);
|
||||
count += reg->histogram[i] * (duration - low_boundary) / (high_boundary - low_boundary);
|
||||
break; // it's last interval within specified time range
|
||||
} else {
|
||||
count += reg->histogram[i];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
cState->regs[index][count] = now;
|
||||
}
|
||||
|
||||
static uint8
|
||||
getMaximum(const HyperLogLogRegister* reg, TimestampTz since, time_t duration, double min_hit_ratio)
|
||||
getMaximum(const TimestampTz* reg, TimestampTz since)
|
||||
{
|
||||
uint8 max = 0;
|
||||
size_t i, j;
|
||||
if (min_hit_ratio == 1.0)
|
||||
|
||||
for (size_t i = 0; i < HLL_C_BITS + 1; i++)
|
||||
{
|
||||
for (i = 0; i < HLL_C_BITS + 1; i++)
|
||||
if (reg[i] >= since)
|
||||
{
|
||||
if (reg[i].ts >= since)
|
||||
{
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t total_count = 0;
|
||||
for (i = 0; i < HLL_C_BITS + 1; i++)
|
||||
{
|
||||
total_count += getAccessCount(®[i], duration);
|
||||
}
|
||||
if (total_count != 0)
|
||||
{
|
||||
for (i = 0; i < HLL_C_BITS + 1; i++)
|
||||
{
|
||||
// Take in account only bits with access frequncy exceeding maximal miss rate (1 - hit rate)
|
||||
if (reg[i].ts >= since && 1.0 - (double)getAccessCount(®[i], duration) / total_count <= min_hit_ratio)
|
||||
{
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
max = i;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
@@ -206,7 +150,7 @@ getMaximum(const HyperLogLogRegister* reg, TimestampTz since, time_t duration, d
|
||||
* Estimates cardinality, based on elements added so far
|
||||
*/
|
||||
double
|
||||
estimateSHLL(HyperLogLogState *cState, time_t duration, double min_hit_ratio)
|
||||
estimateSHLL(HyperLogLogState *cState, time_t duration)
|
||||
{
|
||||
double result;
|
||||
double sum = 0.0;
|
||||
@@ -217,7 +161,7 @@ estimateSHLL(HyperLogLogState *cState, time_t duration, double min_hit_ratio)
|
||||
|
||||
for (i = 0; i < HLL_N_REGISTERS; i++)
|
||||
{
|
||||
R[i] = getMaximum(cState->regs[i], since, duration, min_hit_ratio);
|
||||
R[i] = getMaximum(cState->regs[i], since);
|
||||
sum += 1.0 / pow(2.0, R[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,14 +53,6 @@
|
||||
#define HLL_C_BITS (32 - HLL_BIT_WIDTH)
|
||||
#define HLL_N_REGISTERS (1 << HLL_BIT_WIDTH)
|
||||
|
||||
/*
|
||||
* Number of histogram cells. We use exponential histogram with first interval
|
||||
* equals to one minutes. Autoscaler request LFC statistic with intervals 1,2,...,60 minutes
|
||||
* so 2^8=64 seems to be enough for our needs.
|
||||
*/
|
||||
#define HIST_SIZE 8
|
||||
#define HIST_MIN_INTERVAL 60 /* seconds */
|
||||
|
||||
/*
|
||||
* HyperLogLog is an approximate technique for computing the number of distinct
|
||||
* entries in a set. Importantly, it does this by using a fixed amount of
|
||||
@@ -77,21 +69,18 @@
|
||||
* modified timestamp >= the query timestamp. This value is the number of bits
|
||||
* for this register in the normal HLL calculation.
|
||||
*
|
||||
* The memory usage is 2^B * (C + 1) * sizeof(HyperLogLogRegister), or 920kiB.
|
||||
* The memory usage is 2^B * (C + 1) * sizeof(TimetampTz), or 184kiB.
|
||||
* Usage could be halved if we decide to reduce the required time dimension
|
||||
* precision; as 32 bits in second precision should be enough for statistics.
|
||||
* However, that is not yet implemented.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
TimestampTz ts; /* last access timestamp */
|
||||
uint32_t histogram[HIST_SIZE]; /* access counter exponential histogram */
|
||||
} HyperLogLogRegister;
|
||||
|
||||
typedef struct HyperLogLogState
|
||||
{
|
||||
HyperLogLogRegister regs[HLL_N_REGISTERS][HLL_C_BITS + 1];
|
||||
TimestampTz regs[HLL_N_REGISTERS][HLL_C_BITS + 1];
|
||||
} HyperLogLogState;
|
||||
|
||||
extern void initSHLL(HyperLogLogState *cState);
|
||||
extern void addSHLL(HyperLogLogState *cState, uint32 hash);
|
||||
extern double estimateSHLL(HyperLogLogState *cState, time_t dutration, double min_hit_ratio);
|
||||
extern double estimateSHLL(HyperLogLogState *cState, time_t dutration);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
\echo Use "ALTER EXTENSION neon UPDATE TO '1.5'" to load this file. \quit
|
||||
|
||||
-- returns minimal LFC cache size (in 8kb pages) provided specified hit rate
|
||||
CREATE FUNCTION approximate_optimal_cache_size(duration_sec integer default null, min_hit_ration float8 default null)
|
||||
RETURNS integer
|
||||
AS 'MODULE_PATHNAME', 'approximate_optimal_cache_size'
|
||||
LANGUAGE C PARALLEL SAFE;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION approximate_optimal_cache_size(integer,float8) TO pg_monitor;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
DROP FUNCTION IF EXISTS approximate_optimal_cache_size(integer,float8) CASCADE;
|
||||
108
test_runner/cloud_regress/test_cloud_regress.py
Normal file
108
test_runner/cloud_regress/test_cloud_regress.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""
|
||||
Run the regression tests on the cloud instance of Neon
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import psycopg2
|
||||
import pytest
|
||||
from fixtures.log_helper import log
|
||||
from fixtures.neon_fixtures import RemotePostgres
|
||||
from fixtures.pg_version import PgVersion
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup(remote_pg: RemotePostgres):
|
||||
"""
|
||||
Setup and teardown of the tests
|
||||
"""
|
||||
with psycopg2.connect(remote_pg.connstr()) as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur = conn.cursor()
|
||||
log.info("Creating the extension")
|
||||
cur.execute("CREATE EXTENSION IF NOT EXISTS regress_so")
|
||||
conn.commit()
|
||||
log.info("Looking for subscriptions in the regress database")
|
||||
cur.execute(
|
||||
"SELECT subname FROM pg_catalog.pg_subscription WHERE "
|
||||
"subdbid = (SELECT oid FROM pg_catalog.pg_database WHERE datname='regression');"
|
||||
)
|
||||
if cur.rowcount > 0:
|
||||
with psycopg2.connect(
|
||||
dbname="regression",
|
||||
host=remote_pg.default_options["host"],
|
||||
user=remote_pg.default_options["user"],
|
||||
password=remote_pg.default_options["password"],
|
||||
) as regress_conn:
|
||||
with regress_conn.cursor() as regress_cur:
|
||||
for sub in cur:
|
||||
regress_cur.execute(f"ALTER SUBSCRIPTION {sub[0]} DISABLE")
|
||||
regress_cur.execute(
|
||||
f"ALTER SUBSCRIPTION {sub[0]} SET (slot_name = NONE)"
|
||||
)
|
||||
regress_cur.execute(f"DROP SUBSCRIPTION {sub[0]}")
|
||||
regress_conn.commit()
|
||||
|
||||
# This is also a workaround for the full path problem
|
||||
# If we specify the full path in the command, the library won't be downloaded
|
||||
# So we specify the name only for the first time
|
||||
log.info("Creating a C function to check availability of regress.so")
|
||||
cur.execute(
|
||||
"CREATE FUNCTION get_columns_length(oid[]) "
|
||||
"RETURNS int AS 'regress.so' LANGUAGE C STRICT STABLE PARALLEL SAFE;"
|
||||
)
|
||||
conn.rollback()
|
||||
yield
|
||||
log.info("Looking for extra roles...")
|
||||
with psycopg2.connect(remote_pg.connstr()) as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT rolname FROM pg_catalog.pg_roles WHERE oid > 16384 AND rolname <> 'neondb_owner'"
|
||||
)
|
||||
roles: list[Any] = []
|
||||
for role in cur:
|
||||
log.info("Role found: %s", role[0])
|
||||
roles.append(role[0])
|
||||
for role in roles:
|
||||
cur.execute(f"DROP ROLE {role}")
|
||||
conn.commit()
|
||||
|
||||
|
||||
@pytest.mark.timeout(7200)
|
||||
@pytest.mark.remote_cluster
|
||||
def test_cloud_regress(
|
||||
setup,
|
||||
remote_pg: RemotePostgres,
|
||||
pg_version: PgVersion,
|
||||
pg_distrib_dir: Path,
|
||||
base_dir: Path,
|
||||
test_output_dir: Path,
|
||||
):
|
||||
"""
|
||||
Run the regression tests
|
||||
"""
|
||||
regress_bin = (
|
||||
pg_distrib_dir / f"{pg_version.v_prefixed}/lib/postgresql/pgxs/src/test/regress/pg_regress"
|
||||
)
|
||||
test_path = base_dir / f"vendor/postgres-{pg_version.v_prefixed}/src/test/regress"
|
||||
|
||||
env_vars = {
|
||||
"PGHOST": remote_pg.default_options["host"],
|
||||
"PGPORT": str(
|
||||
remote_pg.default_options["port"] if "port" in remote_pg.default_options else 5432
|
||||
),
|
||||
"PGUSER": remote_pg.default_options["user"],
|
||||
"PGPASSWORD": remote_pg.default_options["password"],
|
||||
"PGDATABASE": remote_pg.default_options["dbname"],
|
||||
}
|
||||
regress_cmd = [
|
||||
str(regress_bin),
|
||||
f"--inputdir={test_path}",
|
||||
f"--bindir={pg_distrib_dir}/{pg_version.v_prefixed}/bin",
|
||||
"--dlpath=/usr/local/lib",
|
||||
"--max-concurrent-tests=20",
|
||||
f"--schedule={test_path}/parallel_schedule",
|
||||
"--max-connections=5",
|
||||
]
|
||||
remote_pg.pg_bin.run(regress_cmd, env=env_vars, cwd=test_output_dir)
|
||||
@@ -236,7 +236,7 @@ def get_scale_for_db(size_mb: int) -> int:
|
||||
|
||||
|
||||
ATTACHMENT_NAME_REGEX: re.Pattern = re.compile( # type: ignore[type-arg]
|
||||
r"regression\.diffs|.+\.(?:log|stderr|stdout|filediff|metrics|html|walredo)"
|
||||
r"regression\.(diffs|out)|.+\.(?:log|stderr|stdout|filediff|metrics|html|walredo)"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -114,46 +114,3 @@ def test_sliding_working_set_approximation(neon_simple_env: NeonEnv):
|
||||
|
||||
assert estimation_1k >= 20 and estimation_1k <= 40
|
||||
assert estimation_10k >= 200 and estimation_10k <= 400
|
||||
|
||||
|
||||
def test_optimal_cache_size_approximation(neon_simple_env: NeonEnv):
|
||||
env = neon_simple_env
|
||||
|
||||
endpoint = env.endpoints.create_start(
|
||||
branch_name="main",
|
||||
config_lines=[
|
||||
"autovacuum = off",
|
||||
"shared_buffers=1MB",
|
||||
"neon.max_file_cache_size=256MB",
|
||||
"neon.file_cache_size_limit=245MB",
|
||||
],
|
||||
)
|
||||
conn = endpoint.connect()
|
||||
cur = conn.cursor()
|
||||
cur.execute("create extension neon version '1.5'")
|
||||
cur.execute(
|
||||
"create table t_huge(pk integer primary key, count integer default 0, payload text default repeat('?', 128))"
|
||||
)
|
||||
cur.execute(
|
||||
"create table t_small(pk integer primary key, count integer default 0, payload text default repeat('?', 128))"
|
||||
)
|
||||
cur.execute(
|
||||
"insert into t_huge(pk) values (generate_series(1,1000000))"
|
||||
) # table size is 21277 pages
|
||||
cur.execute(
|
||||
"insert into t_small(pk) values (generate_series(1,100000))"
|
||||
) # table size is 2128 pages
|
||||
time.sleep(2)
|
||||
before = time.monotonic()
|
||||
for _ in range(100):
|
||||
cur.execute("select sum(count) from t_small")
|
||||
cur.execute("select sum(count) from t_huge")
|
||||
after = time.monotonic()
|
||||
cur.execute(f"select approximate_working_set_size_seconds({int(after - before + 1)})")
|
||||
ws_estimation = cur.fetchall()[0][0]
|
||||
log.info(f"Working set size estimaton {ws_estimation}")
|
||||
cur.execute(f"select approximate_optimal_cache_size({int(after - before + 1)}, 0.99)")
|
||||
optimal_cache_size = cur.fetchall()[0][0]
|
||||
log.info(f"Optimal cache size for 99% hit rate {optimal_cache_size}")
|
||||
assert ws_estimation >= 20000 and ws_estimation <= 30000
|
||||
assert optimal_cache_size >= 2000 and optimal_cache_size <= 3000
|
||||
|
||||
2
vendor/postgres-v14
vendored
2
vendor/postgres-v14
vendored
Submodule vendor/postgres-v14 updated: 8f4cad62e3...f9c51c1243
2
vendor/postgres-v15
vendored
2
vendor/postgres-v15
vendored
Submodule vendor/postgres-v15 updated: 3718b4cfc8...1dbd6f3164
2
vendor/postgres-v16
vendored
2
vendor/postgres-v16
vendored
Submodule vendor/postgres-v16 updated: 52504a3e80...d009084a74
2
vendor/postgres-v17
vendored
2
vendor/postgres-v17
vendored
Submodule vendor/postgres-v17 updated: aa22728787...dadd6fe208
8
vendor/revisions.json
vendored
8
vendor/revisions.json
vendored
@@ -1,18 +1,18 @@
|
||||
{
|
||||
"v17": [
|
||||
"17rc1",
|
||||
"9156d63ce253bed9d1f76355ceec610e444eaffa"
|
||||
"dadd6fe208bb906cc0a48980f2ab4e13c47ba3ad"
|
||||
],
|
||||
"v16": [
|
||||
"16.4",
|
||||
"0baa7346dfd42d61912eeca554c9bb0a190f0a1e"
|
||||
"d009084a745cb4d5e6de222c778b2a562c8b2767"
|
||||
],
|
||||
"v15": [
|
||||
"15.8",
|
||||
"6f6d77fb5960602fcd3fd130aca9f99ecb1619c9"
|
||||
"1dbd6f316416c8360bbd4f3d6db956cf70937cf0"
|
||||
],
|
||||
"v14": [
|
||||
"14.13",
|
||||
"a317b9b5b96978b49e78986697f3dd80d06f99a7"
|
||||
"f9c51c12438b20049b6905eb4e43d321defd6ff2"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user