진짜 하루 종일 삽질함.
근데 덕분에 docker-compose 써보고, docker 명령어 좀 익숙해짐.
psql로 cli에서 DB다루고 쿼리 날리는 것도 해봄.
다음 코드가 문제였다.
const userExists = await this.usersService.findByUsername(
createUserDto.username,
);
회원가입 전 먼저 유저가 존재하는지 읽어오는데, 여기서 아직 스키마가 생성되지 않은 슬레이브로 접근해서 생기는 문제였다.
synchronize: true 적용이 안 됨.const masterQueryRunner = dataSource.createQueryRunner("master")
try {
const postsFromMaster = await dataSource
.createQueryBuilder(Post, "post", masterQueryRunner) // you can either pass QueryRunner as an optional argument with query builder
.setQueryRunner(masterQueryRunner) // or use setQueryRunner which sets or overrides query builder's QueryRunner
.getMany()
} finally {
await masterQueryRunner.release()
}
수동으로 생성된 QueryRunner인스턴스는 자체적으로 명시적으로 해제되어야 합니다. 쿼리 실행기를 해제하지 않으면 풀에서 연결이 체크아웃된 상태로 유지되고 다른 쿼리에서 해당 연결을 사용하지 못하게 됩니다.
이거 때문에 하루 종일 실패함..
volumes:
- slave_data:/var/lib/postgresql/data
- ./pg_hba.conf:/etc/postgresql/pg_hba.con
요지는 최초 컨테이너 실행 시 마운트 경로에는 아무 것도 없어어ㅑ 하는데,
같은 경로로 마운트를 동시에 연결해서 충돌이 생기는 거였음.
요점은 PostgreSQL 컨테이너를 처음 실행할 때 /var/lib/postgresql/data 디렉토리가 비어 있어야 하는데, 동일한 경로에 여러 파일을 마운트하면서 충돌이 발생한 것입니다.
WAL(Write-Ahead Logging)은 데이터베이스 시스템에서 데이터 무결성과 복구를 보장하기 위해 사용되는 기술
WAL의 주요 목적은 데이터베이스 트랜잭션을 로그에 기록하여 시스템 오류나 충돌 후에도 데이터 무결성을 유지하고, 복구를 가능하게 하는 것

DB 볼륨 마운트 폴더는 1개만 연결할 수 있음.
/var/lib/postgresql/data
pg_gba.conf는 etc의 위치에 있기만 하면 됨
postgresql.conf는 위치 알려줘야 함 (커맨드 명령어)
기본적으로 public 스키마 안에 테이블이 만들어 짐. psql에서 스키마는 테이블의 폴더 같은 느낌
DB > 스키마 > 테이블 이 구조
DB가 물리적 구분이라면 스키마는 논리적 구분 같은 느낌?

다중 컨테이너 Docker 애플리케이션을 정의하고 실행하는 도구
postgres 명령어는 PostgreSQL 서버 자체를 실행하고 설정 파일을 지정하는 데 사용됩니다.
psql 명령어는 PostgreSQL에 대한 대화형 터미널 클라이언트입니다.
i 옵션: 터미널 내부에서 입력할 수 있게 함. 표준 입력을 컨테이너 내부 프로세스로 전달
t 옵션: 터미널 실행
슬레이브에 listen 설정 안 돼서 계속 접속이 안 됨
hot_standby = on
listen_addresses = '*'
아니, 슬레이브를 클라이언트에서 접속 하지 않는 경우도 있어?
ㅇㅇ 있음
슬레이브 서버는 백업 또는 분석 작업에만 사용 경우
primary_conninfo = 'host=postgres_master port=5432 user=masteruser password=masterpassword sslmode=prefer sslcompression=1'
여기서 host를 localhost가 아니라 컨테이너 서비스 이름으로 해도 compose로 실행되는 컨테이너는 기본적으로 서비스 간 네트워킹이 설정됨. 그래서 서비스 이름을 호스트로 사용하여 접근할 수 있음.
Docker Compose는 같은 네트워크에 속한 서비스들이 서로의 서비스 이름을 호스트 이름으로 사용하여 통신할 수 있도록 합니다.
네, PostgreSQL 12 이상 버전에서는 슬레이브 서버를 핫 스탠바이 모드로 설정하기 위해 standby.signal 파일을 생성하는 것이 필수?? 진짜??
슬레이브에서 이 쿼리에 연결 상태가 나와야 함
SELECT * FROM pg_stat_wal_receiver;
동기
Master의 WAL 파일 자체를 전송하는 방식
응답이 없으므로 유실 가능
WAL 파일이 크기를 다 채워야만 Slave로 전송
WAL 파일의 크기를 채우는 동안 Master와 Slave는 동일하지 않은 데이터로 인해 불일치.
동기, 비동기
Master의 WAL 내용을 전송하는 방식
복제 응답이 있음
단, wal_keep_segments 한도 내에서 덮어쓰기가 일어나므로 전송이 지연되면 wal 파일 덮어쓰기로 인해 유실 가능
마스터에서는 센터 프로세스, 슬레이브에서는 리시버 프로세스가 동작
설정을 모두 열어놓았음에도 불구하고 slaveuser가 필요한 이유는 복제 및 데이터베이스 접근에 있어서 PostgreSQL이 사용자(role) 기반의 권한 관리를 수행하기 때문입니다. 권한 설정(pg_hba.conf)이 아무리 허용적이라 할지라도, 사용자 계정 자체가 데이터베이스 시스템에 존재하지 않으면 접근할 수 없습니다.