mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-31 12:00:42 +00:00
Add read/write throughput performance tests (#1883)
Part of #1467 This PR adds several performance tests that compare the [PG statistics](https://www.postgresql.org/docs/current/monitoring-stats.html) obtained when running PG benchmarks against Neon and vanilla PG to measure the read/write throughput of the DB.
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import pytest
|
||||
from contextlib import contextmanager
|
||||
from abc import ABC, abstractmethod
|
||||
from fixtures.pg_stats import PgStatTable
|
||||
|
||||
from fixtures.neon_fixtures import PgBin, PgProtocol, VanillaPostgres, RemotePostgres, NeonEnv
|
||||
from fixtures.benchmark_fixture import MetricReport, NeonBenchmarker
|
||||
|
||||
# Type-related stuff
|
||||
from typing import Iterator
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class PgCompare(ABC):
|
||||
@@ -51,6 +52,31 @@ class PgCompare(ABC):
|
||||
def record_duration(self, out_name):
|
||||
pass
|
||||
|
||||
@contextmanager
|
||||
def record_pg_stats(self, pg_stats: List[PgStatTable]):
|
||||
init_data = self._retrieve_pg_stats(pg_stats)
|
||||
|
||||
yield
|
||||
|
||||
data = self._retrieve_pg_stats(pg_stats)
|
||||
|
||||
for k in set(init_data) & set(data):
|
||||
self.zenbenchmark.record(k, data[k] - init_data[k], '', MetricReport.HIGHER_IS_BETTER)
|
||||
|
||||
def _retrieve_pg_stats(self, pg_stats: List[PgStatTable]) -> Dict[str, int]:
|
||||
results: Dict[str, int] = {}
|
||||
|
||||
with self.pg.connect().cursor() as cur:
|
||||
for pg_stat in pg_stats:
|
||||
cur.execute(pg_stat.query)
|
||||
row = cur.fetchone()
|
||||
assert len(row) == len(pg_stat.columns)
|
||||
|
||||
for col, val in zip(pg_stat.columns, row):
|
||||
results[f"{pg_stat.table}.{col}"] = int(val)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
class NeonCompare(PgCompare):
|
||||
"""PgCompare interface for the neon stack."""
|
||||
|
||||
52
test_runner/fixtures/pg_stats.py
Normal file
52
test_runner/fixtures/pg_stats.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from typing import List
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class PgStatTable:
|
||||
table: str
|
||||
columns: List[str]
|
||||
additional_query: str
|
||||
|
||||
def __init__(self, table: str, columns: List[str], filter_query: str = ""):
|
||||
self.table = table
|
||||
self.columns = columns
|
||||
self.additional_query = filter_query
|
||||
|
||||
@property
|
||||
def query(self) -> str:
|
||||
return f"SELECT {','.join(self.columns)} FROM {self.table} {self.additional_query}"
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def pg_stats_rw() -> List[PgStatTable]:
|
||||
return [
|
||||
PgStatTable("pg_stat_database",
|
||||
["tup_returned", "tup_fetched", "tup_inserted", "tup_updated", "tup_deleted"],
|
||||
"WHERE datname='postgres'"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def pg_stats_ro() -> List[PgStatTable]:
|
||||
return [
|
||||
PgStatTable("pg_stat_database", ["tup_returned", "tup_fetched"],
|
||||
"WHERE datname='postgres'"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def pg_stats_wo() -> List[PgStatTable]:
|
||||
return [
|
||||
PgStatTable("pg_stat_database", ["tup_inserted", "tup_updated", "tup_deleted"],
|
||||
"WHERE datname='postgres'"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def pg_stats_wal() -> List[PgStatTable]:
|
||||
return [
|
||||
PgStatTable("pg_stat_wal",
|
||||
["wal_records", "wal_fpi", "wal_bytes", "wal_buffers_full", "wal_write"],
|
||||
"")
|
||||
]
|
||||
Reference in New Issue
Block a user