코드 :
# 테이블스페이스 실제 디렉터리 생성(root)
mkdir -p /pg_ts/koh
# 테이블스페이스 디렉터리 소유자를 postgres로 변경
chown postgres:postgres /pg_ts/koh
# 테이블스페이스 디렉터리 접근 권한을 소유자만 가능(700)하도록 설정
chmod 700 /pg_ts/koh
# 테이블스페이스 디렉터리 생성/권한 상태 확인
ls -ld /pg_ts/koh
drwx------. 2 postgres postgres 6 4월 28 18:04 /pg_ts/koh
# postgres OS 계정으로 전환(환경 변수/홈 디렉터리 포함)
su - postgres
# testdb 데이터베이스로 psql 접속
psql -d testdb
CREATE TABLESPACE koh
LOCATION '/pg_ts/koh';
SELECT spcname
FROM pg_tablespace
WHERE spcname = 'koh';
CREATE TABLE public.koh_table
(
id integer,
name varchar(30),
memo text,
ins_dt timestamp default now()
)
TABLESPACE koh;
INSERT INTO public.koh_table(id, name, memo)
SELECT level,
'user_' || level,
'tablespace recovery test row ' || level
FROM generate_series(1, 10000) AS level;
SELECT count(*)
FROM public.koh_table;
CHECKPOINT;
SELECT pg_relation_filepath('public.koh_table');
\q
REL_PATH=$(psql -At -d testdb -c "SELECT pg_relation_filepath('public.koh_table');")
echo $REL_PATH
FILE_PATH="/var/lib/pgsql/15/data/${REL_PATH}"
echo $FILE_PATH
REAL_FILE=$(readlink -f "$FILE_PATH")
echo $REAL_FILE
ls -lh "$REAL_FILE"
# 테이블 물리 파일을 권한/시간 정보를 보존(-p)하여 백업 파일로 복사
cp -p "$REAL_FILE" /backup/tbs_file/koh_table.bak
ls -lh /backup/tbs_file/koh_table.bak
ls -lh "$REAL_FILE" /backup/tbs_file/koh_table.bak
# WAL 세그먼트를 강제로 전환하여 아카이브 동작을 유도
psql -c "SELECT pg_switch_wal();"
ls -lht /archive/pg15/ | head -5
exit
# 파일 손상 작업을 안전하게 하기 위해 PostgreSQL 서비스 정지(root)
systemctl stop postgresql-15
# PostgreSQL 서비스가 정상 기동 상태인지 확인
systemctl status postgresql-15
# postgres OS 계정으로 전환(환경 변수/홈 디렉터리 포함)
su - postgres
REAL_FILE="/var/lib/pgsql/15/data/pg_tblspc/65553/PG_15_202209061/32779/65554"
ls -lh "$REAL_FILE"
# 테이블 파일 첫 페이지(8KB)만 랜덤 데이터로 덮어써서 페이지 헤더 손상 유발(파일 크기는 유지)
dd if=/dev/urandom of="$REAL_FILE" bs=8192 count=1 conv=notrunc
exit
su -
# PostgreSQL 서비스 시작(손상 상태에서 기동되는지 확인)(root)
systemctl start postgresql-15
# postgres OS 계정으로 전환(환경 변수/홈 디렉터리 포함)
su - postgres
# testdb 데이터베이스로 psql 접속
psql -d testdb
SELECT count(*)
FROM public.koh_table;
\q
exit
# root 유저로 전환 후 PostgreSQL 서비스 정지
su -
# 파일 손상 작업을 안전하게 하기 위해 PostgreSQL 서비스 정지(root)
systemctl stop postgresql-15
# postgres OS 계정으로 전환(환경 변수/홈 디렉터리 포함)
su - postgres
REAL_FILE="/var/lib/pgsql/15/data/pg_tblspc/65553/PG_15_202209061/32779/65554"
# 손상된 원본 파일을 보관(.broken)으로 이동
mv "$REAL_FILE" "${REAL_FILE}.broken"
# 백업 파일을 원래 위치로 복사하여 물리 파일 복구
cp -p /backup/tbs_file/koh_table.bak "$REAL_FILE"
ls -lh "$REAL_FILE" "${REAL_FILE}.broken"
chown postgres:postgres "$REAL_FILE"
exit
# root 유저로 전환 후 PostgreSQL 서비스 시작
su -
# PostgreSQL 서비스 시작(손상 상태에서 기동되는지 확인)(root)
systemctl start postgresql-15
# postgres OS 계정으로 전환(환경 변수/홈 디렉터리 포함)
su - postgres
# testdb 데이터베이스로 psql 접속
psql -d testdb
SELECT count(*)
FROM public.koh_table;
SELECT *
FROM public.koh_table
ORDER BY id
LIMIT 10;
SELECT pg_is_in_recovery();
\q