본문 바로가기
CDBMS/Clickhouse

[Clickhouse] Ver. 22.8 Release note 요약

by 연습장이 2024. 4. 29.
728x90
반응형

목적

  • upgrade에 따른 데이터 정합성, 성능 간 이슈 등을 사전에 체크하여 장애 발생을 방지
  • 지속적으로 dbms 생명주기를 관리하여 신기술에 대한 인지 및 도입 방안 마련

 

읽기 전에

  • 아래 내용은 Release note 내용 중 필요하다고 판단되는 부분 위주로 정리함
  • 버전의 A.B 에서 A는 년(ex_ 20의 경우 2020년)을 의미하며 B는 월(ex_ 6의 경우 6월)을 의미함. 즉, 버전에서 Release date를 유추할 수 있음
  • 중복된 내용의 경우 가장 낮은 버전(이전 버전)에서 최초 기입하며 이후 중복 기입하지 않음

 

Upgrade Notes

  • Ver. 22.8
    • -

 

Backward Incompatible Change

  • Ver. 22.8
    • Date32, DateTime64의 년도 도메인이 1925 to 2283 > 1900 to 2299 로 확장됨. 따라서 이전에 1899-01-01을 입력하면 1925-01-01이 되었으나 이제 1900-01-01로 저장됨
    • 딕셔너리 소스 중 clickhouse 등에 대하여 config.xml 파일 내 remote_url_allow_hosts 태그를 인지하도록 동작함. http, postgresql, mysql 등은 이미 동작함

 

New Feature

  • Ver. 22.8
    • MergeTree 테이블에 대한 DELETE FROM 구문이 추가됨
    • interactive mode에서 "SET param_abc = 'def'"와 같은 파라미터 설정이 가능함
    • 로그 출력시 JSON 타입으로도 동작이 가능함
    • Ordinary에서 Atomic으로 데이터베이스 엔진의 자동 변환이 구현됨. flags 폴더 내 비어있는 convert_ordinary_to_atomic 파일을 생성하면 다음 서버 시작 시 변환됨
    • SELECT ... INTO OUTFILE '...' AND STDOUT 이 지원됨

 

Bug Fix

  • Ver. 22.8
    • 다른 data/time 타입을 사용하여 ORDER BY WITH FILL이 포함된 SELECT 문에서 행이 걸리는 버그가 수정됨
    • RENAME TABLE 후 로그에 잘못된 테이블명이 기입되는 버그가 수정됨
    • materialized view가 사용된 DROP과 INSERT 사이에 경쟁 상태에 대한 예외가 발생하는 버그가 수정됨
    • fetch 시 매우 큰 메모리 사용을 하는 버그가 수정됨

 

Improvement

  • Ver. 22.8
    • system.backups 시스템 테이블이 다시 동작함. 사용자가 연산의 ID를 지정할 수 있음. num_files, uncompressed_size, compressed_size, start_time, end_time 컬럼이 추가됨
    • MergeTree 엔진에 대한 pk 분석이 개선됨
    • CREATE TEMPORARY TABLE ... ( COLUMN...) AS ... 구문이 지원됨
    • 재시작 시 로그 로테이션에 대한 잘못된 행동이 수정됨
    • input rows와 같은 추가적인 정보가 system.processors_profile_log에 포함됨

 

Performance Improvement

  • Ver. 22.8
    • 집계 결과의 병합에서 메모리 사용이 개선됨
    • 쿼리에 의해 생성된 동시 스레드의 전체 수를 제한하는 로직이 추가됨. concurrent_threads_soft_limit 파라미터를 통해 제어 가능함

 

Experimental Feature

  • Ver. 22.8
    • -

 

Build/Testing/Packaging Improvement

  • Ver. 22.8
    • 읽기 및 쓰기 모드에서 클릭하우스 버전을 테스트할 수 있는 새로운 tool인 ClickFiddle이 추가됨

 

Contents that needs to be tested

  • Ver. 22.8
    • Date32, DateTime64의 년도 도메인이 1925 to 2283 > 1900 to 2299 로 확장됨. 따라서 이전에 1899-01-01을 입력하면 1925-01-01이 되었으나 이제 1900-01-01로 저장됨
      • 22.6 test
        june :) select version(), '1899-01-01'::date32, '1899-01-01'::datetime64, '2300-01-01'::date32, '2300-01-01'::datetime64;
         
        SELECT
            version(),
            CAST('1899-01-01', 'date32'),
            CAST('1899-01-01', 'datetime64'),
            CAST('2300-01-01', 'date32'),
            CAST('2300-01-01', 'datetime64')
         
        Query id: acda340a-2756-4f97-ae08-427ebbfd111c
         
        ┌─version()───┬─CAST('1899-01-01', 'date32')─┬─CAST('1899-01-01', 'datetime64')─┬─CAST('2300-01-01', 'date32')─┬─CAST('2300-01-01', 'datetime64')─┐
        │ 22.6.1.1985 │                   1925-01-01 │          1925-01-01 00:00:00.000 │                   2283-11-11 │          2283-11-11 00:00:00.000 │
        └─────────────┴──────────────────────────────┴──────────────────────────────────┴──────────────────────────────┴──────────────────────────────────┘
         
        1 row in set. Elapsed: 0.001 sec.​
      • 22.8 test
        june :) select version(), '1899-01-01'::date32, '1899-01-01'::datetime64, '2300-01-01'::date32, '2300-01-01'::datetime64;
         
        SELECT
            version(),
            CAST('1899-01-01', 'date32'),
            CAST('1899-01-01', 'datetime64'),
            CAST('2300-01-01', 'date32'),
            CAST('2300-01-01', 'datetime64')
         
        Query id: b962cf2d-2d4f-4221-a3c8-112597e08cd3
         
        ┌─version()───┬─CAST('1899-01-01', 'date32')─┬─CAST('1899-01-01', 'datetime64')─┬─CAST('2300-01-01', 'date32')─┬─CAST('2300-01-01', 'datetime64')─┐
        │ 22.8.1.2097 │                   1900-01-01 │          1900-01-01 00:00:00.000 │                   2299-12-31 │          1970-05-01 21:41:13.200 │
        └─────────────┴──────────────────────────────┴──────────────────────────────────┴──────────────────────────────┴──────────────────────────────────┘
         
        1 row in set. Elapsed: 0.001 sec.​
      • '2300-01-01'::datetime64로 형변환 시, 예상했던 2299-12-31가 아닌 1970-05-01 21:41:13.200가 나옴. 그 외에는 예상했던 값대로 나왔으며 로직상 null에 대한 default값이 최소값인지, 최대값인지 확인 필요
    • 딕셔너리 소스 중 clickhouse 등에 대하여 config.xml 파일 내 remote_url_allow_hosts 태그를 인지하도록 동작함. http, postgresql, mysql 등은 이미 동작함
      1. 확인해야할 사항 : 이전 히스토리에서 upgrade 시 remote_url_allow_hosts에 누락된 도메인이 있었음. 유현님 피드백으로 clickhouse는 설정파일과 관계 없이 서버만 선반영했던 경우가 있어, 거짓 긍정이 있을 수 있다고 함 
        • 테스트 스크립트
          -- 테스트 시나리오 개요
          # 22.7 환경에서
          > xx3번 노드에 postgresql, mariaDB 설치
           
          > 184번 노드에서 config.xml에 remote_url_allow_hosts 태그내 xx3번 도메인 유무에 따라 remote 함수로 정상 동작하는지
           
          -- 도출되어야할 결론
          # 22.7 환경에서 clickhouse 서버가 config.xml의 remote_url_allow_hosts 내용을 무시하는지, 올바르게 인지하는지?
           
          # 22.8 환경에서 clickhouse 서버가 remote 함수를 이용한 타 노드의 mariaDB, postgresql에 정상적으로 접근하는지?
           
          -- 테스트 시나리오
          1. postgresql <> clickhouse 통신
          # 01번 노드에서
          > postgresql 설치
           
          > postgreql 접속
          psql
           
          > 테스트용 계정 생성
          create user june_test0001 with password '마스킹';
           
          > 테스트에 필요한 권한 부여
          grant create, temporary to june_test0001;
           
          > 테스트 계정 접속 및 테스트용 테이블 생성, 더미 데이터 삽입
          psql --user june_test0001 --password -d postgres
           
          create table june_test0001 ( num int, dummy varchar(10));
           
          insert into june_test0001 select i, concat('테스트',i) from generate_series(1,1000000) as i;
           
          # 02번 노드에서
          > 테스트용 계정 생성 및 권한 부여
          create user june_test002 identified by '마스킹';
           
          grant create table on *.* to june_test002;
           
          grant create temporary table, postgres on *.* to june_test002;
           
          grant select on *.* to june_test002;
           
          > 테스트용 계정으로 접속 및 원격 테스트 테이블 생성, 조회
          clickhouse-client --user=june_test002 --password=마스킹
           
          create table june_test.june_test_remote_pg (num int, dummy varchar(10)) as postgresql('192.168.xxx.xx3:5432','postgres','june_test0001','june_test0001','마스킹')
           
          select * from june_test.june_test_remote_pg limit 1;
           
          2. mariaDB <> clickhouse 통신
          # 01번 노드에서
          > mariaDB 설치
           
          > mariaDB 접속
          mysql
           
          > 테스트용 계정 생성
          create user june_test0002@'%' identified by '마스킹'; -- 이게 있어야 clickhouse에서 원격 접근 가능
           
          create user june_test0002@'localhost' identified by '마스킹';
           
          > 테스트에 필요한 권한 부여
          grant all privileges on *.* to 'june_test0002'@'localhost' identified by '마스킹';
           
          flush privileges;
           
          > 테스트 계정 접속 및 테스트용 테이블 생성, 더미 데이터 삽입
          mysql -u june_test0002 -p test
           
          create table test.june_test0002(num2 int, dummy2 varchar(20));
           
          insert into test.june_test0002 select 1, 'test1';
          insert into test.june_test0002 select 2, 'test2';
          insert into test.june_test0002 select 3, 'test3';
           
          # 02번 노드에서
          > 마스터 계정으로 pg 테스트 계정에 필요한 권한 부여
          grant create temporary table, mysql on *.* to june_test002;
           
          > pg 테스트 계정으로 접속 및 원격 테스트 테이블 생성, 조회
          clickhouse-client --user=june_test002 --password=마스킹
           
          create table june_test.june_test_remote_ma (num2 int, dummy2 varchar(20)) as mysql('192.168.xxx.xx3:3306','test','june_test0002','june_test0002','마스킹')
           
          select * from june_test.june_test_remote_ma;​
        • 결론
          • 22.7 버전에서 아래와 같이 케이스를 나누어 진행한 결과 > remote 함수 관련하여 현 업무 요건에서는 clickhouse DBMS 서버가 항상 config.xml를 인식하고 있으므로 영향도 없을 것으로 판단됨
            1. 이미 config.xml에 원격 도메인이 설정된 상태에서 pg <> clickhouse , mariaDB <> clickhouse 간 통신이 되었을 때 config.xml에 해당 도메인을 빼면 정상 작동하는가? > 에러 반환됨. 즉 config.xml을 인식함
            2. pg <> clickhouse, mariaDB <> clickhouse 간 원격 테이블이 없고 config.xml에도 해당 도메인이 없는 상태에서, pg, mariaDB 원격 테이블 생성 시 생성 되는가(거짓 긍정)? 에러 반환됨. 즉 config.xml을 인식함
      2. 확인해야할 사항 : 딕셔너리만 해당되는지, remote함수 자체가 role로 관리가 되어야 하는지? 예를 들어 1번 노드에서 2번 노드의 mergetree 테이블을 remote 함수를 사용하여 조회할 경우 권한 제어는 어떻게 이루어지는지?
        • 테스트 스크립트
          -- 테스트 환경
          # config.xml 파일에 아래와 같이 june01 ~ june03 노드만 열리고 그 외엔 기입 사항 없음
          <host_regexp>192.168.xxx.12[3-5]</host_regexp>
           
          -- 테스트 시나리오
          별도의 role 제어 없이 01번의 테스트 계정으로 02번의 테스트 테이블에 조회 가능한지?
          그 반대도 가능한지?
           
          -- june01 host
          # default 계정
          > 테스트용 계정 생성
          create user june_test001 identified by 'xxx1';
           
          > 테스트용 계정에 권한 부여
          grant all on *.* to june_test001;
           
          # 테스트 계정
          > 테스트용 테이블 생성
          create table june_test.remote_test001 ( dummy varchar(100)) engine = MergeTree() order by dummy;
           
          > 테스트용 테이블에 적재 및 정상 조회 확인
          insert into june_test.remote_test001 select 'june01';
          select * from june_test.remote_test001;
           
          -- june02 host
          # default 계정
          > 테스트용 계정 생성
          create user june_test002 identified by 'xxx1';
           
          > 테스트용 계정에 권한 부여
          grant all on *.* to june_test002;
           
          # 테스트 계정
          > 테스트용 테이블 생성
          create table june_test.remote_test002 ( dummy varchar(100)) engine = MergeTree() order by dummy;
           
          > 테스트용 테이블에 적재 및 정상 조회 확인
          insert into june_test.remote_test002 select 'june02';
          select * from june_test.remote_test002;
           
          -- june01 host
          > june01 노드의 default 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.124','june_test.remote_test002','default',''); -- 정상 조회
           
          > june01 노드의 테스트용 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.124','june_test.remote_test002','june_test002','xxx1'); -- 정상 조회
           
          # default 계정
          > 테스트용 테이블의 모든 권한 회수
          revoke all on *.* from june_test001;
           
          # 테스트용 계정
          > june01 노드의 default 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.124','june_test.remote_test002','default',''); -- 조회 불가
           
          > june01 노드의 테스트용 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.124','june_test.remote_test002','june_test002','xxx1'); -- 조회 불가
           
          -- june02 host
          > june02 노드의 default 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','default',''); -- 정상 조회
           
          > june02 노드의 테스트용 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','june_test001','xxx1'); -- 정상 조회
           
          # default 계정
          > 테스트용 테이블의 모든 권한 회수
          revoke all on *.* from june_test002;
           
          # 테스트용 계정
          > june02 노드의 default 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','default',''); -- 조회 불가
           
          > june02 노드의 테스트용 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','june_test001','xxx1'); -- 조회 불가
           
          -- role 테스트
          # default 계정
          > remote 함수에 필요한 권한을 가진 role 생성
          create role remote_gr;
           
          # role 테스트용 계정으로 remote 테이블 함수 사용
          > june02 노드의 default 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','default',''); -- 조회 불가
           
          > june02 노드의 테스트용 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','june_test001','xxx1'); -- 조회 불가
           
          # default 계정
          > remote 함수에 필요한 권한을 가진 role 부여
          grant remote_gr to june_test003;
           
          # role 테스트용 계정으로 remote 테이블 함수 사용
          > june02 노드의 default 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','default',''); -- 정상 조회
           
          > june02 노드의 테스트용 계정으로 테스트용 테이블을 remote 테이블 함수로 정상 조회 확인
          select * from remote('192.168.xxx.123','june_test.remote_test001','june_test001','xxx1'); -- 정상 조회
           
          -- 참고 사항
          # default 계정으로 테스트용 계정 생성시 users.xml에 <access_management>1</access_management>의 주석 처리 해제하여 활성화
          # users.xml에 access_management 활성화 시 동적 적용됨
          # config.xml에 remote_url_allow_hosts 태그 변경시 동적 적용됨​
        • 결론
          • remote함수를 사용하는 로컬 계정은 GRANT CREATE TEMPORARY TABLE, REMOTE ON *.*의 권한이 부여되어야 함
          • remote함수를 사용하는 로컬 계정의 위 권한이 있을 경우 타겟 계정(default, 테스트용 계정) 모두 접근 가능함
          • role로 pg처럼 사용자에게 권한 부여하여 remote함수 권한 제어 가능함

 

참고

728x90
반응형