개요
설명
chdb_hook 모듈은 PostgreSQL COPY 명령에 후크를 걸어, chDB를 사용해 로컬 파일, AWS S3 버킷, Google Cloud Storage 등에서 [chDB가 지원하는 데이터 포맷][formats] 중 하나로 데이터를TO 또는 FROM 복사할 수 있도록 합니다. 또한 CREATE TABLE에도 후크를 걸어, 동일한 대상들로부터 테이블의 컬럼을 도출하고 행을 로드할 수 있게 합니다.
로딩
수퍼유저(super user) 권한으로 다음 방법 중 하나를 사용해 chdb_hook을 로드하십시오. 사용 사례에 가장 적합한 방법을 선택하십시오:-
LOAD 명령으로 명시적으로 로드하며, 해당 세션이 유지되는 동안에만 적용됩니다:
ClickHouse Cloud SQL 콘솔은 아직
LOAD 'chdb_hook'명령을 지원하지 않지만, psql이나 다른 데이터베이스 연결을 통해 실행할 수 있습니다. 그렇지 않은 경우 지원 담당자에게 문의하여 Postgres 서비스 구성에 추가하면, 이후 SQL 콘솔에서도 사용할 수 있습니다. -
모든 세션에 적용하려면
postgresql.conf에서 [session_preload_libraries] 설정을 사용하십시오:또는 ALTER SYSTEM으로 설정합니다:이 설정은 ALTER DATABASE를 사용해 데이터베이스 단위로도 지정할 수 있습니다:또는 ALTER ROLE을 사용해 특정 사용자 및 그룹에 지정할 수 있습니다: -
[shared_preload_libraries] 설정으로 서버 시작 시 로드하면, 모든 세션과
데이터베이스에서 항상 사용할 수 있습니다:
COPY 오버로딩
loading 시 chdb_hook은 Postgres COPY 명령에 후크를 걸어, 로컬 파일, AWS S3 버킷, Google Cloud Storage 등에서 [chDB가 제공하는 데이터 포맷][formats] 중 하나로 데이터를TO 또는 FROM 방향으로 복사합니다. 예를 들어 S3에 있는 CSV 파일에서 테이블을 로드하려면, 먼저 테이블을 CREATE한 다음 s3:// URL과 함께 COPY를 호출하십시오:
권한
chdb_hookCOPY는 자신이 대체하는 COPY와 동일한 권한을 필요로 합니다.
즉, COPY TO에는 릴레이션 또는 복사되는 모든 컬럼에 대한 SELECT 권한이,
COPY FROM에는 INSERT 권한이 필요합니다. file:// URL은 server의 파일을
읽거나 쓰기 때문에 pg_read_server_files 또는 pg_write_server_files 멤버십도 필요합니다.
또한 COPY FROM은 읽기-쓰기 transaction에서만 사용할 수 있습니다.
URL 스킴
chdb_hook은 다음 스킴 중 하나를 사용하는 URLCOPY 대상에 대해서만 실행됩니다:
URL 포맷
URL 포맷은 대상(target)에 따라 다릅니다.File
Postgres 서버의 절대 경로여야 합니다. 상대 경로를 지정하면 오류가 발생합니다. Postgres 사용자는 용도에 따라pg_read_server_files 또는 pg_write_server_files 역할(Role)의 멤버여야 합니다. 또한 Postgres 시스템 사용자에게 해당 파일에 대한 읽기 또는 쓰기 액세스 권한이 있어야 합니다. COPY TO에서 경로가 존재하지 않으면 chdb_hook이 누락된 상위 디렉터리를 생성하며, 이때 필요한 파일 시스템 권한을 갖추고 있어야 합니다. 예시:
HTTP
퍼블릭 클라우드 스토리지를 포함한 일반적인 HTTP URL을 모두 지원합니다.COPY TO에서는
chdb_hook이 해당 URL로 데이터를 POST하려고 시도합니다. 예시:
S3
S3 URL은 S3 URI 형식일 수 있습니다GCS
GCS URL은 퍼블릭 URL 형식을 따릅니다:Azure Blob Storage
계정 이름을 하위 도메인으로 지정한blob.windows.net URL을 사용하십시오:
Azure ABFS
ABFS URL은 반드시 다음 포맷을 사용해야 합니다:HDFS URL
HDFS URL은 일반적인 HTTP 스타일 URL 형식을 사용할 수 있으며, 포트는 선택 사항입니다:경로 와일드카드
COPY FROM 명령어의 URL 경로에는 글롭 패턴을 사용할 수 있습니다. 파일은 접미사나 접두사만이 아니라 전체 경로 패턴과 일치해야 합니다. 단 한 가지 예외가 있는데, 경로가 기존 디렉터리를 가리키고 글롭 패턴을 사용하지 않는 경우에는 해당 디렉터리의 모든 파일을 선택하도록 경로 뒤에 *가 암시적으로 추가됩니다.
지원되는 와일드카드는 다음과 같습니다.
*:/를 제외한 임의 개수의 문자와 일치하며, 빈 문자열도 포함합니다.?: 임의의 단일 문자와 일치합니다.{groucho,harpo,chico}: “groucho”, “harpo”, “chico” 문자열 중 하나로 대체합니다. 이 문자열에는/가 포함될 수 있습니다.{N..M}:>= N이고<= M인 임의의 숫자와 일치합니다.**: 디렉터리 내의 모든 파일을 재귀적으로 일치시킵니다.
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_1.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_2.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/some_prefix/some_file_3.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another_prefix/some_file_1.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another_prefix/some_file_2.csv
- https://clickhouse-public-datasets.s3.amazonaws.com/my-test-bucket-768/another_prefix/some_file_3.csv
{some,another}_prefix로, 파일은 some_file_{1..3}.csv'로 일치시킵니다. 다음과 같이 작성하십시오:
옵션
chdb_hook의COPY 명령은 다음 옵션을 지원합니다:
format:
읽거나 쓸 포맷입니다. chDB에서 제공하는 포맷 중 하나여야 하며,
여기에는 TSV, CSV, Parquet, Iceberg, JSON 등이 포함됩니다. 생략하거나
auto로 설정하면 chDB가 URL 끝의 파일 이름 확장자를 보고 포맷을 결정합니다.
structure
행의 chDB 데이터 구조입니다. 컬럼명 목록과 ClickHouse 데이터 타입, 수정자로
구성됩니다. 생략하면 chdb_hook이 Postgres 데이터 타입을 대체로 적합한
ClickHouse 타입으로 매핑합니다. 자세한 내용은 Postgres to
chDB를 참조하십시오. auto로 설정하면 chDB가 타입을 추론합니다.
예시:
access_key와 access_secret
요청을 인증하는 데 사용되는 AWS 계정 사용자의 장기 자격 증명입니다.
- S3: AWS [액세스 키 ID 및 액세스 시크릿]으로, 보통
AWS_ACCESS_KEY_ID및AWS_SECRET_ACCESS_KEY환경 변수로 정의됩니다 - GCS: GCP [HMAC 키 및 시크릿]
- Azure: Azure 스토리지 계정 이름 및 [액세스 키]
session_token
access_key 및 access_secret과 함께 사용하는 AWS 세션 토큰으로, 보통 환경 변수 AWS_SESSION_TOKEN으로 정의됩니다. S3 URL에만 사용됩니다.
compression
파일 압축 포맷입니다. 파일 이름으로 압축 방식을 추론할 수 없을 때 사용합니다.
지원되는 값:
auto(기본값)nonegzip또는gzbrotli또는brxz또는LZMAzstd또는zstlz4bz2snappy
timeout
요청 타임아웃(밀리초 단위)입니다. HTTP, S3, GCS, Azure URL에 적용됩니다.
기본값은 30000(30초)입니다.
디버깅
오류가 발생하면 chdb_hook의COPY 명령은 실행을 시도했던 chDB 쿼리를 오류 Context에 포함합니다:
{name:Type} 형식의 placeholder를 사용합니다.
다만 문제를 디버깅하기 위해 해당 매개변수의 내용을 확인해야 한다면, Postgres의 [log_min_messages] GUC를 일시적으로 DEBUG1 이상으로 설정하십시오. 그러면 chdb_hook이 쿼리와 매개변수를 Postgres 로그로 전송하며(클라이언트로는 절대 전송하지 않습니다), 다음과 같이 표시됩니다:
CREATE TABLE 오버로딩
chdb_hook은 CREATE TABLE에도 후크를 연결하므로, 테이블이 URL에서 컬럼을 도출하고 행을 로드할 수 있습니다. URL에서 도출된 구조로 테이블을 생성하려면structure_from 옵션에 URL을 전달하고 컬럼 목록은 비워 두십시오:
copy_from을 사용하십시오:
copy_from은 statement가 자체 컬럼을 전혀 지정하지 않은 경우에만 컬럼을 추론합니다.
컬럼 목록, INHERITS 절, OF 유형, 파티션은 각각 컬럼을 정의하므로,
이 경우 copy_from은 다음 항목만 복사합니다:
COPY와 동일한 URL scheme과
옵션을 지원하며, 자격 증명, 포맷, 압축, timeout,
심지어 명시적인 구조 지정까지 모두 적용됩니다. Postgres는 남아 있는
스토리지 매개변수를 그대로 유지합니다:
structure_from과 copy_from은 모두 IF NOT EXISTS와 함께 사용할 수 없습니다. 기존 릴레이션을 로드하려면
COPY를 사용하십시오.
제한 사항
Postgres와 chDB 간 데이터 타입 동작의 차이 및 몇 가지 알려진 문제로 인해 chdb_hook에는 다음과 같은 제한 사항이 있습니다:- 복사를 수행하는 역할에 적용되는 row-level security 정책이 있는 릴레이션은
COPY할 수 없습니다. Postgres는COPY TO를 쿼리로 다시 작성하는 방식으로 이러한 정책을 적용하는데, chdb_hook은 이를 지원하지 않습니다. - ClickHouse에는 NULL 배열이 없으므로,
COPY TO는NULL을 빈 배열([])로 저장합니다. - ClickHouse는
lseg,path,polygon에 해당하는 값을 배열로 표현합니다. 따라서 이러한 타입의 NULL 값도COPY TO시 빈 배열([])로 출력됩니다. - 지정된 structure에서 해당 컬럼을 Nullable로 정의하지 않으면 NULL 값은 기본값으로 출력됩니다. 이러한 변환을 방지하려면 structure에 널 허용 컬럼을 항상 명시적으로 정의하십시오.
- 마지막 점이 첫 번째 점과 같은 열린
path는 닫힌 경로로 출력됩니다. - Protobuf의 반복 필드에는 null이 없으므로 배열의 NULL 값은 생략됩니다.
- chDB JSON type은 JSON 객체만 지원합니다. 모든 값이 JSON 객체인 경우에만
json및jsonb의 기본String매핑을JSON으로 재정의하십시오. (ClickHouse/ClickHouse#68428) - chDB JSON type은
null을 무시하므로, NULL 값을 가진 객체 키는 출력 시 생략됩니다. 객체 값이null이 아니거나 그 값의 손실을 허용할 수 있는 경우에만json및jsonb의 기본String매핑을JSON으로 재정의하십시오. (ClickHouse/ClickHouse#68428) - JSON, JSONCompact, JSONColumnsWithMetadata 포맷은 항상 UTF-8을 검사하므로, bytea 값을 대체 문자로 치환하여 출력합니다.
COPY FROM은 빈 문자열이나 0을 포함하는 ProtobufNullable필드를NULL로 읽습니다. (chdb-io/chdb-core#152)- Parquet으로의
COPY TO는 Nullable Tuple 자체의 null map에서NULL을 누락시킵니다. (ClickHouse/ClickHouse#112427) - Parquet, Arrow, ArrowStream, ORC, Avro, Protobuf, ProtobufList, MsgPack,
BSONEachRow 포맷에는 Postgres
time또는 chDBTime64에 해당하는 타입이 없습니다. 값을 보존하려면 명시적인 structure에서time컬럼을String으로 구성하십시오. - Protobuf 출력은 timestamp 값을 초 단위로 절삭합니다.
- Protobuf 출력은 1970-01-01 이전 날짜를 지원하지 않습니다. 값을 보존하려면
명시적인 structure에서
time컬럼을String으로 구성하십시오. (ClickHouse/ClickHouse#111860) - CSVWithNames 및 CSVWithNamesAndTypes 포맷은 현재
NULLbox 또는 circle 값을 가져올 수 없습니다. (ClickHouse/ClickHouse#115523)
데이터 타입
COPY는 릴레이션의 Postgres 타입을 chDB 타입으로 매핑하고, CREATE TABLE은 URL의 chDB 타입을 Postgres 타입으로 매핑합니다.Postgres to chDB
명시적인 structure 옵션이 없으면 chdb_hook은 Postgres 타입을 적절한 chDB 타입으로 매핑합니다. 이 매핑이 사용 사례에 맞지 않으면 structure를 지정하여 자동 생성된 타입을 필요한 타입으로 재정의하십시오.
배열 타입은 매핑된 원소 타입의
Array로 매핑됩니다. ClickHouse는 널 허용 여부를 컬럼 단위로 제한하지만 Postgres는 배열 단위로 제한하므로, 원소는 항상 Nullable입니다.
Map 또는 Tuple로 매핑되는 Postgres 타입은 없지만, structure에서 이를 지정할 수 있습니다. Map은 key value 쌍의 배열로 변환할 수 있고, Tuple은 배열로 변환됩니다. 서로 다른 타입을 함께 담아야 하는 경우에는 text[]를 사용하십시오.
타임스탬프 변환
일반 텍스트 형식(TSV, CSV 등)에서COPY 후크는 현재 datestyle 설정과 관계없이
DateTime 및 DateTime64 값을 ISO-8601 형식인 YYYY-MM-DDThh:mm:ssZ로 출력합니다.
이를 통해 값을 가져오는 소스가 다른 시간대를 사용하더라도 timestamptz 값이
일관되게 유지됩니다. structure 출력에서 Datetime64(3, 'America/Los_Angeles')와 같은 다른 유형을 사용해도 출력 오프셋에는 영향이 없으며,
정밀도만 달라집니다.
Timestamp TZ 예시:
또한
COPY 후크는 timestamp 값을 세션 시간대에서 UTC로 변환하므로, 값이 항상 UTC를
기준으로 출력됩니다. 이 값을 새로운 시스템에 로드하면 해당 시스템의 로컬 시간대로
변환됩니다. 따라서 시간대가 다르면 표시되는 값도 달라지지만, 시간대 차이를 감안하면
동일한 시점을 가리킵니다.
timezone 설정이 timestamp 2026-08-28T12:00:00에 미치는 영향의 예시:
chDB에서 Postgres로
chdb_hook은DESCRIBE가 반환하는 ClickHouse 타입을 다음 Postgres 타입으로 매핑합니다:
이 표에 없는 chDB 타입은 모두 오류를 발생시키며,
Nested, Variant, Dynamic이 여기에 해당합니다. 이러한 타입을 텍스트로 읽으려면 해당 타입을 String으로 매핑하는 structure를 사용하십시오.
Postgres는 이러한 타입 중 일부에서 chDB보다 좁은 범위만 지원합니다. 따라서 24시간을 초과하는 Time 또는 Time64 값, 그리고 Postgres의 날짜 범위를 벗어난 Date32 값을 복사하면 오류가 발생합니다.
텍스트 인코딩
chDB는String, FixedString, Enum, JSON을 바이트로 읽으며, 인코딩은 보장하지 않습니다. 이러한 컬럼을 text 또는 그 외 비바이너리 타입으로 복사하면 데이터베이스 인코딩을 기준으로 바이트를 검증하고, 표현할 수 없는 데이터에 대해서는 오류를 발생시킵니다:
text에 저장할 수 없습니다.
chDB가 기록한 바이트를 그대로 유지하려면 bytea로 복사하십시오. CREATE TABLE은 이러한 타입에 대해 text를 도출하므로, 다음과 같이 이름을 지정하십시오:
FixedString(N)은 길이가 짧은 값을 NUL 바이트로 채웁니다. text로 복사하면
뒤쪽의 NUL이 삭제되지만, bytea는 N 바이트 전체를 유지합니다.
설정
chdb_hook.max_memory
max_memory_usage 설정을 지정하는 데 사용됩니다. 슈퍼유저 권한이 필요합니다. 메가바이트 단위의
정수 값을 지정하거나 다음 메모리 단위 중 하나를 사용하십시오:
B(바이트)kB(킬로바이트)MB(메가바이트)GB(기가바이트)TB(테라바이트)
0이며, 이 경우 메모리를 제한하지 않습니다.
chdb_hook.max_threads
max_threads 설정을 지정하는 데 사용됩니다. 슈퍼유저 권한이 필요합니다. 기본값은 0이며, 이 경우 chDB가 값을 자동으로 결정합니다.
대규모 COPY를 실행하기 전에 chdb_hook.max_threads를 설정하여 chDB가 CPU 사용량을 독점해 PostgreSQL의 성능이 저하되는 것을 방지할 것을 강력히 권장합니다.
chdb_hook.max_parsing_threads
max_parsing_threads
설정을 지정하는 데 사용됩니다. 슈퍼유저 권한이 필요합니다. 기본값은 0이며, 이 경우 chDB가
값을 직접 결정합니다.
대량의 데이터를 COPY하기 전에 chdb_hook.max_parsing_threads를 설정하여
chDB가 PostgreSQL을 희생시키면서 CPU 사용량을 최대치까지 점유하지 않도록 하는 것을 권장합니다.
버전 관리 정책
chdb_hook는 공개 릴리스에 Semantic Versioning을 따릅니다.- 메이저 버전은 API 변경 시 증가합니다
- 마이너 버전은 하위 호환되는 SQL 변경 시 증가합니다
- 패치 버전은 바이너리 전용 변경 시 증가합니다
pg_get_loaded_modules() 함수를 통해 PostgreSQL에서 버전을 확인할 수 있습니다.