programing

Postgre 실행 중메모리에만 있는 SQL

lastmoon 2023. 7. 1. 09:18
반응형

Postgre 실행 중메모리에만 있는 SQL

나는 작은 Postgre를 운영하고 싶습니다.내가 쓰는 각 단위 테스트에 대해 메모리에서만 실행되는 SQL 데이터베이스.예를 들어:

@Before
void setUp() {
    String port = runPostgresOnRandomPort();
    connectTo("postgres://localhost:"+port+"/in_memory_db");
    // ...
}

이상적으로는 유닛 테스트에서 사용할 버전 컨트롤에 단일 포스트그래스 실행 파일을 체크인할 것입니다.

같은 거.HSQL하지만 사후에.내가 어떻게 그럴 수 있을까?

제가 그런 Postgres 버전을 구할 수 있을까요?디스크를 사용하지 않도록 지시하려면 어떻게 해야 합니까?

(메모리 내 Postgre 사용에서 답변 이동)SQL 및 일반화):

Pg를 인프로세스, 인메모리로 실행할 수 없습니다.

테스트를 위해 인메모리 Postgres 데이터베이스를 실행하는 방법을 알 수 없습니다.가능합니까?

아니요, 불가능합니다.됩니다.SQL은 C에서 구현되며 플랫폼 코드로 컴파일됩니다.H2나 더비와 달리 당신은 그냥 로드할 수 없습니다.jar그리고 그것을 일회용 메모리 DB로 발사합니다.

스토리지는 파일 시스템 기반이며, 메모리 내 데이터스토어만 사용할 수 있는 스토리지 추상화 기능이 내장되어 있지 않습니다.그러나 RAM 디스크, tempfs 또는 기타 사용 후 삭제 파일 시스템 저장소를 가리키도록 할 수 있습니다.

C로 작성되어 플랫폼 코드로 컴파일되는 SQLite와 달리 Postgre는SQL도 진행 중에 로드할 수 없습니다.멀티스레딩 아키텍처가 아닌 멀티프로세싱 아키텍처이기 때문에 여러 프로세스(연결당 하나)가 필요합니다.다중 처리 요구 사항은 포스트마스터를 독립 실행형 프로세스로 시작해야 한다는 것을 의미합니다.

일회용 용기 사용

제가 처음 이 글을 쓴 이후로 용기의 사용은 널리 퍼졌고, 잘 이해되었고, 쉽게 이해되었습니다.

테스트 용도로 Docker 컨테이너에 일회용 Postgres 인스턴스를 구성한 다음 마지막에 해체하는 것은 쉬운 일이 아닙니다.다음과 같은 해킹으로 속도를 높일 수 있습니다.LD_PRELOADlibeatmydata 성가신 "충돌 시 내 데이터를 끔찍하게 손상시키지 않음" 기능을 비활성화합니다;).

원하는 테스트 제품군과 언어 또는 툴체인에 대해 이를 자동화할 수 있는 포장지가 많이 있습니다.

또는 연결을 사전 구성합니다.

(간단한 컨테이너화 전에 작성, 더 이상 권장되지 않음)

이름/ 이름할 것으로 하기 위해 를 사용하는 것이 좋습니다.CREATE DATABASE 데이터베이스에 일용데베이스터이, 음다그회.DROP DATABASE 파일, 속성,변수 정보를 .속성 파일, 빌드 대상 속성, 환경 변수 등에서 데이터베이스 연결 세부 정보를 가져옵니다.

기존 Postgre를 사용해도 안전합니다.SQL 인스턴스에는 이미 관심 있는 데이터베이스가 있습니다. 장치 테스트에 제공하는 사용자가 슈퍼 사용자가 아닌 사용자만 있는 경우CREATEDB◦◦ 의 경우 할 수 최악의 경우 다른 데이터베이스에 성능 문제가 발생할 수 있습니다.저는 완전히 격리된 Postgre를 실행하는 것을 선호합니다.이러한 이유로 테스트를 위해 SQL을 설치합니다.

대신: 일회용 Postgre 시작테스트용 SQL 인스턴스

또는 테스트 하니스에서 및 이진 파일을 찾고, 데이터베이스를 만들고, 수정하고, 임의 포트에서 시작하고, 사용자를 만들고, DB를 만들고, 테스트를 실행할 수 있습니다.당신은 Postgre를 묶을 수도 있습니다.테스트를 실행하기 전에 여러 아키텍처에 대한 SQL 이진 파일을 병에 넣고 현재 아키텍처에 대한 이진 파일을 임시 디렉토리에 압축을 풉니다.

개인적으로 이 문제는 피해야 할 큰 문제라고 생각합니다. 테스트 DB를 구성하는 것이 훨씬 쉽습니다.하지만, 그것은 의 등장과 함께 조금 더 쉬워졌습니다.include_dir에서 합니다.postgresql.conf이제 한 줄만 추가하고 나머지 모두에 대해 생성된 구성 파일을 작성할 수 있습니다.

Postgre를 통한 더 빠른 테스트SQL

Postgre의 성능을 안전하게 개선하는 방법에 대한 자세한 내용은 다음을 참조하십시오.테스트용 SQL은 앞서 이 항목에 대해 작성한 자세한 답변을 참조하십시오.최적화 Postgre신속한 테스트를 위한 SQL

H2's PostgreSQL 방언은 진정한 대체어가 아닙니다.

일부 사람들은 대신 Postgre의 H2 데이터베이스를 사용합니다.테스트를 실행할 SQL 방언 모드입니다.그것은 테스트 및 Postgre를 위해 SQLite를 사용하는 레일즈 사람들만큼 나쁘다고 생각합니다.운영 배포를 위한 SQL.

H2는 일부 Postgre를 지원합니다.SQL 확장 및 Postgre 에뮬레이트SQL 방언하지만, 그것은 단지 - 에뮬레이션입니다.H2가 쿼리를 허용하지만 Postgre는 허용하는 영역을 찾을 수 있습니다.SQL은 동작이 다른등을 지원하지 않습니다.또한 포스그리가 있는 곳도 많이 찾을 수 있을 겁니다.SQL은 H2가 작성 시 창 기능과 같이 할 수 없는 작업을 지원합니다.

이 접근 방식의 한계를 이해하고 데이터베이스 액세스가 간단하다면 H2도 괜찮을 수 있습니다.하지만 그런 경우에는 데이터베이스의 흥미로운 기능을 사용하지 않기 때문에 데이터베이스를 추상화하는 ORM에 더 적합할 것입니다. 그런 경우에는 데이터베이스 호환성에 대해 더 이상 신경 쓸 필요가 없습니다.

테이블스페이스는 정답이 아닙니다!

테이블스페이스를 사용하여 "메모리 내" 데이터베이스를 작성하지 마십시오.성능에 큰 도움이 되지 않기 때문에 불필요할 뿐만 아니라, 동일한 Postgre에서 관심을 가질 수 있는 다른 사용자에 대한 액세스를 방해할 수 있는 훌륭한 방법입니다.SQL 설치.이제 9.4 설명서에는 다음 경고가 포함되어 있습니다.

경고

Postgre 메인 외부에 위치하고 있음에도 불구하고SQL 데이터 디렉토리, 테이블스페이스는 데이터베이스 클러스터의 필수적인 부분이며 데이터 파일의 자율적인 모음으로 처리할 수 없습니다.기본 데이터 디렉터리에 포함된 메타데이터에 종속되므로 다른 데이터베이스 클러스터에 연결하거나 개별적으로 백업할 수 없습니다.마찬가지로 테이블스페이스가 손실되면(파일 삭제, 디스크 오류 등) 데이터베이스 클러스터를 읽을 수 없거나 시작할 수 없습니다.Ramdisk와 같은 임시 파일 시스템에 테이블스페이스를 배치하면 전체 클러스터의 신뢰성이 저하될 위험이 있습니다.

너무 많은 사람들이 이런 짓을 하고 문제에 부딪히는 것을 알아차렸기 때문입니다.

당신이 , 은 할 수 있습니다.)mkdirPostgrePostgre를 위한 . SQL을 합니다.DROP누락된 데이터베이스, 테이블 등그냥 하지 않는 것이 좋습니다.)

또는 ramfs/tempfs에서 를 생성하여 모든 개체를 생성할 수 있습니다.
저는 최근에 리눅스에서 정확히 그렇게 하는 것에 관한 기사를 가리켰습니다.원래 링크가 비활성화되었습니다.하지만 보관되었습니다(Arsinclair 제공).

경고

이로 인해 전체 데이터베이스 클러스터의 무결성이 위험해질 수 있습니다.
설명서의 추가된 경고를 읽습니다.
따라서 이것은 소모성 데이터에 대한 옵션일 뿐입니다.

유닛 테스트의 경우 잘 작동할 것입니다.동일한 컴퓨터에서 다른 데이터베이스를 실행하는 경우 안전을 위해 별도의 데이터베이스 클러스터(자체 포트가 있음)를 사용해야 합니다.

이것은 Postgres에서는 불가능합니다.HSQLDB나 MySQL과 같은 프로세스 내/메모리 내 엔진은 제공하지 않습니다.

독립형 환경을 만들고 싶다면 Postgres 바이너리를 SVN에 넣을 수 있습니다(단, 하나의 실행 파일 이상의 기능).

이 작업을 수행하려면 먼저 initdb를 실행하여 테스트 데이터베이스를 설정해야 합니다.이 작업은 배치 파일에서 수행하거나 Runtime.exe()를 사용하여 수행할 수 있습니다.그러나 initdb는 빠른 것이 아닙니다.각 테스트에 대해 해당 테스트를 실행하지 않을 것입니다.하지만 당신은 당신의 테스트 스위트 전에 이것을 실행하는 것을 피할 수 있습니다.

그러나 이 작업을 수행할 수는 있지만 테스트를 실행하기 전에 테스트 데이터베이스를 다시 만드는 전용 Postgres 설치를 권장합니다.

템플릿 데이터베이스를 사용하여 테스트 데이터베이스를 다시 만들 수 있습니다. 템플릿 데이터베이스를 사용하는 것이 각 테스트 실행에 대해 initdb를 실행하는 것보다 훨씬 빠릅니다.

이제 Postgre의 메모리 내 인스턴스를 실행할 수 있습니다.Embedded Postgre를 통한 Junit 테스트의 SQLOpenTable의 SQL 구성 요소: https://github.com/opentable/otj-pg-embedded

otj-pg-delay 라이브러리(https://mvnrepository.com/artifact/com.opentable.components/otj-pg-embedded) 종속성을 추가하면 자신의 Postgre 인스턴스를 시작하고 중지할 수 있습니다.@Before 및 @Afer 후크의 SQL:

EmbeddedPostgres pg = EmbeddedPostgres.start();

그들은 Junit이 당신의 Postgre를 자동으로 시작하고 중지하도록 하는 Junit 규칙도 제공합니다.SQL 데이터베이스 서버:

@Rule
public SingleInstancePostgresRule pg = EmbeddedPostgresRules.singleInstance();

테스트 컨테이너를 사용하여 Posgre를 회전시킬 수 있습니다.테스트용 SQL 도커 컨테이너: http://testcontainers.viewdocs.io/testcontainers-java/usage/database_containers/

TestContainers는 JUNit @Rule/@ClassRule을 제공합니다. 이 모드는 테스트 전에 컨테이너 내부에서 데이터베이스를 시작하고 이후에 데이터베이스를 해체합니다.

예:

public class SimplePostgreSQLTest {

    @Rule
    public PostgreSQLContainer postgres = new PostgreSQLContainer();

    @Test
    public void testSimple() throws SQLException {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setJdbcUrl(postgres.getJdbcUrl());
        hikariConfig.setUsername(postgres.getUsername());
        hikariConfig.setPassword(postgres.getPassword());

        HikariDataSource ds = new HikariDataSource(hikariConfig);
        Statement statement = ds.getConnection().createStatement();
        statement.execute("SELECT 1");
        ResultSet resultSet = statement.getResultSet();

        resultSet.next();
        int resultSetInt = resultSet.getInt(1);
        assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
    }
}

NodeJS를 사용하는 경우 pg-mem(거부자:저는 포스트그레스 DB의 가장 일반적인 특징을 에뮬레이트하는 저자입니다.

PG 동작을 복제하는 완전한 인메모리, 격리된 플랫폼에 구애받지 않는 데이터베이스가 제공됩니다(브라우저에서도 실행 가능).

여기서 당신의 유닛 테스트에 사용하는 방법을 보여주기 위해 기사를 썼습니다.

현재 Postgre의 메모리 내 버전이 있습니다.Yandex라는 러시아 검색 회사의 SQL: https://github.com/yandex-qatools/postgresql-embedded

Flapdoodle OSS의 임베디드 프로세스를 기반으로 합니다.

(github 페이지에서) 사용 예:

// starting Postgres
final EmbeddedPostgres postgres = new EmbeddedPostgres(V9_6);
// predefined data directory
// final EmbeddedPostgres postgres = new EmbeddedPostgres(V9_6, "/path/to/predefined/data/directory");
final String url = postgres.start("localhost", 5432, "dbName", "userName", "password");

// connecting to a running Postgres and feeding up the database
final Connection conn = DriverManager.getConnection(url);
conn.createStatement().execute("CREATE TABLE films (code char(5));");

저는 가끔 그것을 사용하고 있습니다.잘 작동합니다.

업데이트됨: 이 프로젝트는 더 이상 현재 유지 관리되고 있지 않습니다.

Please be adviced that the main maintainer of this project has successfuly 
migrated to the use of Test Containers project. This is the best possible 
alternative nowadays.

도커를 사용할 수 있는 경우 테스트를 위해 postgresql 데이터 디렉토리를 메모리에 마운트할 수 있습니다.

docker run --tmpfs=/data -e PGDATA=/data postgres

Postgre를 사용할 수도 있습니다.메모리 내 데이터베이스에 의존하지 않고 성능을 달성하기 위한 SQL 구성 설정(예: 질문에 자세히 설명되어 있고 여기에 수락된 답변)

만약 당신이 자바를 사용하고 있다면, 주로 유닛 테스트에 사용되는 메모리 내 "내장된" 포스트그레스 환경을 제공하는 라이브러리가 효과적으로 사용되고 있습니다.

https://github.com/opentable/otj-pg-embedded

이 검색 결과에서 답을 찾는다면 사용 사례를 해결할 수 있습니다.

환경을 완벽하게 제어할 수 있는 경우에는 거의 실행할 수 있습니다.postgreSQL…에

언급URL : https://stackoverflow.com/questions/7872693/running-postgresql-in-memory-only

반응형