pg /c database 通过。似乎是pg使用 open/write 写入了某个文件,通过 fopen/fscanf 绕过了hook路径导致的。出现了新的段错误。
This commit is contained in:
@@ -15,10 +15,14 @@ dynamic_shared_memory_type = sysv
|
||||
|
||||
# 4. 重启 PostgreSQL
|
||||
|
||||
## 清理旧空间
|
||||
sudo systemctl stop postgresql
|
||||
pkill -9 -u postgres postgres || true
|
||||
rm -rf /home/lian/pg/pgdata
|
||||
rm -rf /zvfs/pg_ts_bench
|
||||
rm -rf /tmp/pg.log
|
||||
|
||||
## 初始化
|
||||
sudo chown -R postgres:postgres /home/lian/pg
|
||||
sudo -u postgres mkdir -p /home/lian/pg/pgdata
|
||||
sudo chown -R postgres:postgres /home/lian/pg/pgdata
|
||||
@@ -26,36 +30,42 @@ sudo chown -R postgres:postgres /home/lian/pg/pgdata
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/initdb -D /home/lian/pg/pgdata
|
||||
|
||||
## 修改配置文件
|
||||
cp ./postgresql.conf /home/lian/pg/pgdata/
|
||||
sudo chown -R postgres:postgres /home/lian/pg/pgdata/postgresql.conf
|
||||
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/pg_ctl -D /home/lian/pg/pgdata -l /tmp/pg.log start
|
||||
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/psql
|
||||
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/pg_ctl -D /home/lian/pg/pgdata -l /tmp/pg.log restart
|
||||
|
||||
# 创建测试环境
|
||||
## 创建测试环境
|
||||
sudo -u postgres mkdir -p /zvfs/pg_ts_bench
|
||||
sudo chown -R postgres:postgres /zvfs/pg_ts_bench
|
||||
sudo chmod 700 /zvfs/pg_ts_bench
|
||||
|
||||
CREATE TABLESPACE zvfs_ts LOCATION '/zvfs/pg_ts_bench';
|
||||
DROP DATABASE IF EXISTS benchdb;
|
||||
CREATE DATABASE benchdb TABLESPACE zvfs_ts;
|
||||
|
||||
DROP TABLE IF EXISTS hook_probe;
|
||||
CREATE TABLE hook_probe(id int) TABLESPACE zvfs_ts;
|
||||
INSERT INTO hook_probe VALUES (1);
|
||||
INSERT INTO hook_probe VALUES (2);
|
||||
INSERT INTO hook_probe VALUES (3);
|
||||
INSERT INTO hook_probe VALUES (4);
|
||||
SELECT * FROM hook_probe;
|
||||
DELETE FROM hook_probe WHERE id = 1;
|
||||
UPDATE hook_probe SET id = 11 WHERE id = 2;
|
||||
SELECT * FROM hook_probe;
|
||||
|
||||
## 启动服务
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/pg_ctl -D /home/lian/pg/pgdata -l /tmp/pg.log start
|
||||
|
||||
sudo -u postgres env \
|
||||
LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
ZVFS_DEBUG_OPEN=1 \
|
||||
ZVFS_DEBUG_OPEN_MATCH=PG_VERSION \
|
||||
ZVFS_DEBUG_RW=1 \
|
||||
/usr/lib/postgresql/12/bin/pg_ctl -D /home/lian/pg/pgdata -l /tmp/pg.log start
|
||||
|
||||
## 打开命令行工具
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/psql
|
||||
|
||||
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
ZVFS_DEBUG_OPEN=1 \
|
||||
ZVFS_DEBUG_OPEN_MATCH=PG_VERSION \
|
||||
ZVFS_DEBUG_RW=1 \
|
||||
/usr/lib/postgresql/12/bin/psql
|
||||
|
||||
## 重启服务
|
||||
sudo -u postgres env LD_PRELOAD=/home/lian/try/zvfs/src/libzvfs.so \
|
||||
/usr/lib/postgresql/12/bin/pg_ctl -D /home/lian/pg/pgdata -l /tmp/pg.log restart
|
||||
|
||||
|
||||
# 5. 验证配置生效
|
||||
@@ -63,15 +73,76 @@ pid=$(pgrep -u postgres -xo postgres)
|
||||
echo "pid=$pid"
|
||||
sudo grep libzvfs /proc/$pid/maps
|
||||
|
||||
sudo -u postgres psql -p 5432 -c "show data_directory;"
|
||||
sudo -u postgres psql -c "SHOW shared_memory_type;"
|
||||
sudo -u postgres psql -c "SHOW dynamic_shared_memory_type;"
|
||||
show data_directory;
|
||||
SHOW shared_memory_type;
|
||||
SHOW dynamic_shared_memory_type;
|
||||
```
|
||||
|
||||
# 6. 创建测试库(如未创建)
|
||||
## 简易功能测试
|
||||
```shell
|
||||
# 1. 创建 tablespace
|
||||
DROP TABLESPACE IF EXISTS zvfs_ts;
|
||||
CREATE TABLESPACE zvfs_ts LOCATION '/zvfs/pg_ts_bench';
|
||||
|
||||
sudo -u postgres createdb benchdb
|
||||
# 2. 创建数据库
|
||||
DROP DATABASE IF EXISTS benchdb;
|
||||
CREATE DATABASE benchdb TABLESPACE zvfs_ts;
|
||||
|
||||
# 7. 运行你的 bench 脚本
|
||||
## 3. 连接数据库
|
||||
\c benchdb
|
||||
|
||||
# -- 查看数据库默认 tablespace
|
||||
SHOW default_tablespace;
|
||||
|
||||
# 4. 创建表(默认 tablespace)
|
||||
DROP TABLE IF EXISTS hook_probe;
|
||||
CREATE TABLE hook_probe(
|
||||
id int,
|
||||
val text
|
||||
);
|
||||
|
||||
INSERT INTO hook_probe VALUES (1,'a');
|
||||
INSERT INTO hook_probe VALUES (2,'b');
|
||||
INSERT INTO hook_probe VALUES (3,'c');
|
||||
INSERT INTO hook_probe VALUES (4,'d');
|
||||
|
||||
SELECT * FROM hook_probe;
|
||||
|
||||
# 5. UPDATE / DELETE 测试
|
||||
DELETE FROM hook_probe WHERE id = 1;
|
||||
UPDATE hook_probe SET id = 11 WHERE id = 2;
|
||||
SELECT * FROM hook_probe;
|
||||
|
||||
|
||||
# 6. 批量 INSERT 测试
|
||||
INSERT INTO hook_probe
|
||||
SELECT generate_series(100,10000), 'bulk';
|
||||
|
||||
SELECT count(*) FROM hook_probe;
|
||||
|
||||
# 7. 创建索引(测试 index file)
|
||||
CREATE INDEX idx_hook_probe_id ON hook_probe(id);
|
||||
|
||||
# 8. 大对象测试(TOAST)
|
||||
INSERT INTO hook_probe VALUES (99999, repeat('zvfs_test_',1000));
|
||||
|
||||
# 9. VACUUM 测试
|
||||
VACUUM hook_probe;
|
||||
|
||||
# 10. ANALYZE
|
||||
ANALYZE hook_probe;
|
||||
|
||||
# 11. 查看物理文件位置
|
||||
SELECT
|
||||
relname,
|
||||
pg_relation_filepath(oid)
|
||||
FROM pg_class
|
||||
WHERE relname='hook_probe';
|
||||
|
||||
# 12. 删表
|
||||
DROP TABLE IF EXISTS hook_probe;
|
||||
|
||||
|
||||
# 13. 压测
|
||||
bash /home/lian/try/zvfs/scripts/run_pgbench_no_mmap.sh
|
||||
```
|
||||
47
scripts/do_trace.md
Normal file
47
scripts/do_trace.md
Normal file
@@ -0,0 +1,47 @@
|
||||
```shell
|
||||
pm=$(pgrep -u postgres -xo postgres)
|
||||
sudo strace -ff -f -yy -s 256 \
|
||||
-e trace=%file,read,pread64,readv \
|
||||
-p "$pm" -o /tmp/pg.sys.trace
|
||||
|
||||
|
||||
strace: Process 233035 attached
|
||||
strace: Process 235357 attached
|
||||
^Cstrace: Process 233035 detached
|
||||
|
||||
|
||||
fatal_pid=$(grep 'FATAL: "pg_tblspc' /tmp/pg.log | tail -1 | sed -n 's/.*\[\([0-9]\+\)\].*/\1/p'); echo "fatal_pid=$fatal_pid"
|
||||
|
||||
fatal_pid=235357
|
||||
|
||||
|
||||
grep -n "PG_VERSION\|pg_tblspc/16384/PG_12_201909212/16385" /tmp/pg.sys.trace.$fatal_pid
|
||||
|
||||
18:access("pg_tblspc/16384/PG_12_201909212/16385", F_OK) = 0
|
||||
19:openat(AT_FDCWD, "pg_tblspc/16384/PG_12_201909212/16385/PG_VERSION", O_RDONLY) = 4</zvfs/pg_ts_bench/PG_12_201909212/16385/PG_VERSION>
|
||||
20:read(4</zvfs/pg_ts_bench/PG_12_201909212/16385/PG_VERSION>, "\0\0\0", 4096) = 3
|
||||
21:read(4</zvfs/pg_ts_bench/PG_12_201909212/16385/PG_VERSION>, "", 4096) = 0
|
||||
|
||||
|
||||
|
||||
fatal_pid=$(grep 'FATAL: "pg_tblspc' /tmp/pg.log | tail -1 | sed -n 's/.*\[\([0-9]\+\)\].*/\1/p'); echo "fatal_pid=$fatal_pid"
|
||||
|
||||
grep -n "\[zvfs\]\[rw-dbg\].*pid=${fatal_pid}" /tmp/pg.log | tail -n 120
|
||||
|
||||
6461:[zvfs][rw-dbg][pid=235357][tid=140193133607488][fd=4] read passthrough reason=fd_not_zvfs count=512
|
||||
6462:[zvfs][rw-dbg][pid=235357][tid=140193133607488][fd=4] read passthrough ret=512 errno=0(OK)
|
||||
```
|
||||
|
||||
|
||||
```shell
|
||||
sudo strace -ff -f -k -yy -s 256 -e trace=openat,read,pread64 -p "$pm" -o /tmp/pg.ktrace
|
||||
```
|
||||
|
||||
调用链:
|
||||
|
||||
libc(__open64) -> _IO_file_open -> fopen -> AllocateFile -> ValidatePgVersion
|
||||
|
||||
是fopen,内部调用 libc_(__open64)
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ BENCHMARKS="fillrandom,readrandom"
|
||||
|
||||
# key数
|
||||
# NUM=1000000
|
||||
NUM=500
|
||||
NUM=5000
|
||||
|
||||
# 线程数
|
||||
THREADS=2
|
||||
|
||||
@@ -1,91 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 仅执行 pgbench 的脚本(不安装 PostgreSQL,不 initdb,不启停服务,不改配置)。
|
||||
#
|
||||
# 前提条件:
|
||||
# 1) PostgreSQL 已经在运行。
|
||||
# 2) 测试库已经存在(默认 benchdb)。
|
||||
# 3) PostgreSQL 已经在外部配置为禁用 mmap 共享内存:
|
||||
# shared_memory_type = sysv
|
||||
# dynamic_shared_memory_type = sysv
|
||||
#
|
||||
# 关于 Malloc0:
|
||||
# - 当前后端是内存虚拟设备,容量有限。
|
||||
# - 默认参数故意设置得较小,避免一次灌入过多数据。
|
||||
#
|
||||
# 关于 LD_PRELOAD:
|
||||
# - USE_LD_PRELOAD_INIT=1:初始化阶段(pgbench -i)启用 LD_PRELOAD
|
||||
# - USE_LD_PRELOAD_RUN=1 :压测阶段启用 LD_PRELOAD
|
||||
# - 设为 0 即可关闭对应阶段的 LD_PRELOAD
|
||||
#
|
||||
# 用法:
|
||||
# bash codex/run_pgbench_no_mmap.sh
|
||||
#
|
||||
# 可选环境变量(含义):
|
||||
# PG_HOST=127.0.0.1
|
||||
# PostgreSQL 服务器地址。
|
||||
# PG_PORT=5432
|
||||
# PostgreSQL 服务器端口(默认改为 5432)。
|
||||
# PG_DB=benchdb
|
||||
# 压测数据库名。
|
||||
# PG_SCALE=2
|
||||
# pgbench 初始化规模因子(-s),越大初始数据越多。
|
||||
# PG_TIME=20
|
||||
# 压测持续时间(秒,pgbench -T)。
|
||||
# PG_CLIENTS=2
|
||||
# 并发客户端数(pgbench -c)。
|
||||
# PG_JOBS=2
|
||||
# 工作线程数(pgbench -j)。
|
||||
# PG_SUPERUSER=postgres
|
||||
# 执行 pgbench 的系统用户(通常是 postgres)。
|
||||
# LD_PRELOAD_PATH=/home/lian/try/zvfs/src/libzvfs.so
|
||||
# LD_PRELOAD 目标库路径(你的 zvfs hook so)。
|
||||
# PG_BIN_DIR=/usr/lib/postgresql/16/bin
|
||||
# pgbench 所在目录;不填时自动从 PATH 查找。
|
||||
# USE_LD_PRELOAD_INIT=1
|
||||
# 初始化阶段(pgbench -i)是否启用 LD_PRELOAD:1=启用,0=关闭。
|
||||
# USE_LD_PRELOAD_RUN=1
|
||||
# 压测阶段是否启用 LD_PRELOAD:1=启用,0=关闭。
|
||||
# 简化版 pgbench 测试脚本:
|
||||
# 1) 参数都在本文件顶部配置;
|
||||
# 2) 直接连接 benchdb;
|
||||
# 3) 执行 pgbench 初始化和压测。
|
||||
|
||||
PG_HOST="${PG_HOST:-127.0.0.1}"
|
||||
PG_PORT="${PG_PORT:-5432}"
|
||||
PG_DB="${PG_DB:-benchdb}"
|
||||
PG_SCALE="${PG_SCALE:-2}"
|
||||
PG_TIME="${PG_TIME:-20}"
|
||||
PG_CLIENTS="${PG_CLIENTS:-2}"
|
||||
PG_JOBS="${PG_JOBS:-2}"
|
||||
PG_SUPERUSER="${PG_SUPERUSER:-postgres}"
|
||||
LD_PRELOAD_PATH="${LD_PRELOAD_PATH:-/home/lian/try/zvfs/src/libzvfs.so}"
|
||||
PG_BIN_DIR="${PG_BIN_DIR:-$(dirname "$(command -v pgbench 2>/dev/null || true)")}"
|
||||
USE_LD_PRELOAD_INIT="${USE_LD_PRELOAD_INIT:-1}"
|
||||
USE_LD_PRELOAD_RUN="${USE_LD_PRELOAD_RUN:-1}"
|
||||
# ---------------------------
|
||||
# 固定配置(按需改这里)
|
||||
# ---------------------------
|
||||
PG_HOST="127.0.0.1"
|
||||
PG_PORT="5432"
|
||||
PG_DB="benchdb"
|
||||
PG_SCALE="10"
|
||||
PG_TIME="20"
|
||||
PG_CLIENTS="2"
|
||||
PG_SUPERUSER="postgres"
|
||||
USE_LD_PRELOAD="1"
|
||||
LD_PRELOAD_PATH="/home/lian/try/zvfs/src/libzvfs.so"
|
||||
|
||||
# 可选:优先使用这个目录;为空时自动从 PATH 里找
|
||||
PG_BIN_DIR="/usr/lib/postgresql/12/bin"
|
||||
|
||||
if [[ ! -x "${PG_BIN_DIR}/pgbench" ]]; then
|
||||
PG_BIN_DIR="$(dirname "$(command -v pgbench 2>/dev/null || true)")"
|
||||
fi
|
||||
|
||||
if [[ -z "${PG_BIN_DIR}" || ! -x "${PG_BIN_DIR}/pgbench" ]]; then
|
||||
echo "未找到 pgbench,请设置 PG_BIN_DIR 或把 pgbench 放到 PATH 中。" >&2
|
||||
echo "未找到 pgbench,请先安装 PostgreSQL 客户端或修正 PG_BIN_DIR。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
run_pgbench_cmd() {
|
||||
local use_preload="$1"
|
||||
shift
|
||||
if [[ "${use_preload}" == "1" ]]; then
|
||||
run_pg_cmd() {
|
||||
if [[ "${USE_LD_PRELOAD}" == "1" ]]; then
|
||||
sudo -u "${PG_SUPERUSER}" env LD_PRELOAD="${LD_PRELOAD_PATH}" "$@"
|
||||
else
|
||||
sudo -u "${PG_SUPERUSER}" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "当前参数:"
|
||||
echo "当前配置:"
|
||||
echo " host=${PG_HOST} port=${PG_PORT} db=${PG_DB}"
|
||||
echo " scale=${PG_SCALE} clients=${PG_CLIENTS} jobs=${PG_JOBS} time=${PG_TIME}s"
|
||||
echo " preload_init=${USE_LD_PRELOAD_INIT} preload_run=${USE_LD_PRELOAD_RUN}"
|
||||
echo " scale=${PG_SCALE} clients=${PG_CLIENTS} time=${PG_TIME}s preload=${USE_LD_PRELOAD}"
|
||||
echo
|
||||
|
||||
echo "[1/2] 初始化数据(pgbench -i)"
|
||||
run_pgbench_cmd "${USE_LD_PRELOAD_INIT}" \
|
||||
"${PG_BIN_DIR}/pgbench" -h "${PG_HOST}" -p "${PG_PORT}" -i -s "${PG_SCALE}" "${PG_DB}"
|
||||
echo "[1/2] pgbench 初始化(-i)"
|
||||
run_pg_cmd "${PG_BIN_DIR}/pgbench" \
|
||||
-h "${PG_HOST}" -p "${PG_PORT}" -i -s "${PG_SCALE}" "${PG_DB}"
|
||||
|
||||
echo "[2/2] 执行压测(pgbench -T)"
|
||||
run_pgbench_cmd "${USE_LD_PRELOAD_RUN}" \
|
||||
"${PG_BIN_DIR}/pgbench" -h "${PG_HOST}" -p "${PG_PORT}" \
|
||||
-c "${PG_CLIENTS}" -j "${PG_JOBS}" -T "${PG_TIME}" -P 5 "${PG_DB}"
|
||||
echo "[2/2] pgbench 压测(-T)"
|
||||
run_pg_cmd "${PG_BIN_DIR}/pgbench" \
|
||||
-h "${PG_HOST}" -p "${PG_PORT}" -c "${PG_CLIENTS}" -T "${PG_TIME}" "${PG_DB}"
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
pgrep -u postgres -x postgres | while read p; do
|
||||
echo "PID=$p"
|
||||
sudo grep -m1 libzvfs /proc/$p/maps || echo " (no libzvfs)"
|
||||
# pgrep -u postgres -x postgres | while read p; do
|
||||
# echo "PID=$p"
|
||||
# sudo grep -m1 libzvfs /proc/$p/maps || echo " (no libzvfs)"
|
||||
# done
|
||||
|
||||
for p in 185591 185633 185664; do
|
||||
echo "== $p"; grep libzvfs /proc/$p/maps || echo "NO_LIB";
|
||||
done
|
||||
Reference in New Issue
Block a user