26Z07b

Young-Kyoo Kim·2026년 8월 7일

prefix 값이 나오지 않고 비어있는 이유는 StarRocks의 regexp_extract 함수 동작 방식 및 문자열 에스케이핑 처리 때문입니다.

regexp_extract(object_key, '^(.*)/[^/]+$', 1) 식에서 마지막 파일명 앞까지 추출하는 정규식이 정상적으로 매칭되지 않았거나, MinIO의 URL Encoding(예: / 대신 %2F 등으로 인코딩되어 들어오는 경우)으로 인해 슬래시(/) 구분자를 찾지 못했기 때문입니다.

StarRocks는 정규식 대신 내장 경로 처리 함수(parse_url_path)나 문자열 정규화 함수(url_decode) + reverse/`substr` 조합을 사용하면 훨씬 직관적이고 완벽하게 Prefix를 추출할 수 있습니다.


1. Prefix 추출 로직 보완 (Routine Load 수정)

경로가 folder/sub/file.txt 일 때 folder/sub 또는 folder/sub/ 형태의 prefix를 안전하게 추출하도록 Routine Load의 prefix 컬럼 정의 부분을 수정합니다.

STOP ROUTINE LOAD FOR minio_metadata.minio_event_load;

CREATE ROUTINE LOAD minio_metadata.minio_event_load ON object_current_state
COLUMNS (
    event_time_str,
    event_name,
    bucket,
    raw_object_key,
    size_bytes,
    etag,
    -- 1. URL Encoding 처리되어 들어오는 경우 디코딩 (예: %2F -> /)
    object_key = url_decode(raw_object_key),
    event_time = str_to_date(substr(event_time_str, 1, 19), '%Y-%m-%dT%H:%i:%s'),
    
    -- 2. 슬래시(/)가 포함되어 있다면 마지막 슬래시 이전까지를 prefix로 추출
    prefix = if(
        locate('/', url_decode(raw_object_key)) > 0, 
        substr(url_decode(raw_object_key), 1, length(url_decode(raw_object_key)) - length(reverse(substr(reverse(url_decode(raw_object_key)), 1, locate('/', reverse(url_decode(raw_object_key))))))),
        ''
    ),
    
    __deleted = if(event_name LIKE 's3:ObjectRemoved%', 1, 0),
    object_id = md5(concat(bucket, ':', url_decode(raw_object_key)))
)
PROPERTIES (
    "format" = "json",
    "json_root" = "$.Records",
    "jsonpaths" = "[\"$.eventTime\", \"$.eventName\", \"$.s3.bucket.name\", \"$.s3.object.key\", \"$.s3.object.size\", \"$.s3.object.eTag\"]",
    "merge_condition" = "event_time"
)
FROM KAFKA (
    "kafka_broker_list" = "192.168.x.x:9092", -- 실제 Kafka Broker IP로 수정
    "kafka_topic" = "minio-bucket-events",
    "property.group.id" = "starrocks_minio_events",
    "property.kafka_default_offsets" = "OFFSET_BEGINNING"
);

단순화 팁: 만약 정규식을 선호하신다면 regexp_extract(url_decode(raw_object_key), '^(.*)/', 1) 구문으로 작성하셔도 슬래시 전까지의 Prefix가 추출됩니다.


2. 기존 데이터의 Prefix 일괄 업데이트

이미 테이블에 들어와서 Prefix가 비어 있는 기존 데이터들은 아래 UPDATE 쿼리로 한 번에 복구할 수 있습니다.

UPDATE object_current_state
SET 
    object_key = url_decode(object_key),
    prefix = if(
        locate('/', url_decode(object_key)) > 0,
        regexp_extract(url_decode(object_key), '^(.*)/', 1),
        ''
    )
WHERE prefix = '' AND object_key LIKE '%/%';

3. 검증 Query

업데이트 후 데이터베이스에서 직접 조회하여 prefix 컬럼에 값(a/b, images/2026 등)이 제대로 채워졌는지 확인합니다.

-- 1. 테이블 원본 데이터 prefix 확인
SELECT bucket, object_key, prefix, size_bytes FROM object_current_state LIMIT 10;

-- 2. View 집계 확인
SELECT * FROM v_prefix_summary;

0개의 댓글