TimescaleDB 2.0(Hasura 포함)


우리의 #GraphQLJanuary는 블로그 글, 생방송 흐름, 불협화음 퀴즈, 근무 시간 등을 계속 발표합니다.곧 있을 행사 일정에 대해서는 커뮤니티에 가입하거나 전화https://hasura.io/graphql/graphql-january/로 등록하십시오.
이 게시물에서 하수라 엔지니어 Toan은 그가 TimescaleDB 2.0과 함께 하수라를 사용한 경험을 공유하고 무엇이 효과적인지 탐색했다.다른 사람이 해결 방법을 탐색하여 목표를 실현하는 경험에서 배우는 것은 항상 계발적이다.
TimescaleDB는 SQL이 시간 서열 데이터에 대해 신축성을 가지도록 하는 소스 데이터베이스이다.TimescaleDB의 가장 가치 있는 기능은 hypertable입니다. 이것은 시간과 공간을 뛰어넘는 자동 섹션 (섹션 키) 을 제공하는 고급 테이블입니다.
TimescaleDB 2.0은 주요 버전 업그레이드로 버전 1에 비해 많은 개선이 있었다.그것은 수평 다중 노드의 확장을 통해 쓰기 성능의 제한을 해결할 수 있는 새로운 흥미로운 특성과 기능을 도입했다.
PostgreSQL 확장이기 때문에 주로 Hasura와 함께 사용됩니다.그러나 몇 가지 제한이 있다.본고는 이미 알고 있는 문제와 해결 방법을 공유할 것이다.
예시 코드가 Github 에 업로드되었습니다.

마이그레이션 및 파괴적 변경


부터 시작하다.x ~ 2.0


새 버전을 업그레이드하려면 the official guide here
다음 표에서는 TimescaleDB 1.7과 2.0 사이의 구문 비교를 보여 줍니다.
1.7
2
코멘트
블록 압축 정책 추가
압축 정책 추가
압축 정책 추가
삭제 압축 블록 정책
압축 정책 삭제
압축 정책 삭제
추가 삭제 블록 정책
보존 정책 추가
보존 정책 추가
블록 정책 삭제
보존 정책 제거
보존 정책 제거
뷰 생성...있음(timescaledb.continuous)
물화 뷰 생성...(시간 눈금db. 연속);연속 집합 정책 추가(...)를 선택합니다.
물적 보기 만들기(연속 집합)
드롭다운 뷰 캐스케이드
적물화 보기
물적 보기 삭제(연속 집합)
timescaledb 정보에서 * 을 선택합니다.슈퍼 테이블, 여기서 테이블 name="
테이블 크기 초과("")에서 선택*
하이퍼테이블 크기 가져오기
^
하이퍼테이블 인덱스 크기 선택("")
하이퍼테이블 인덱스 크기 가져오기
^
하이퍼테이블 상세 크기 선택("")
하이퍼테이블 인덱스의 상세 크기 가져오기
timescaledb 정보에서 * 을 선택합니다.블록 통계를 압축합니다. 여기서 하이퍼테이블 이름은 ""입니다.
하이퍼테이블 압축 통계 데이터("")에서 선택*
압축 데이터 가져오기
많은 함수와 SQL 구문의 이름이 바뀝니다.timescaledb_information 보기 구조가 매우 다르다.hypertable, timescaledb_information.hypertables를 사용하여 모든 timescaledb_information.compressed_hypertable_stats 사이즈를 열거할 수 없지만 hypertable_size, hypertable_compression_stats 기능을 사용하여 테이블을 선택할 수 있습니다.
버전 2.0에는 다음과 같은 두 가지 새로운 흥미로운 기능이 있습니다.
  • 계획 작업.현재, Postgres에서cronjob을 실행하면, 예를 들어 물적 보기를 자동으로 새로 고침하는 등 많은 작업을 수행할 수 있습니다.
  • 다중 노드.그것은 우리가 여러 데이터 노드로 읽기/쓰기를 확장하는 데 도움을 준다.
  • 예정된 일 때문에Continuous Aggregate Materialized View는 큰 재구성과 획기적인 변경이 있으므로 다음 섹션에서 더 자세히 살펴보겠습니다.

    물화 보기(연속 집합)


    연속 중합체화 보기는 자동 리셋과 구역을 가진 물화 보기이다.마이그레이션의 측면에서 볼 때 고급 SQL 정의는 내부 문으로 변환됩니다.
    입력:
    CREATE MATERIALIZED VIEW conditions_summary_minutely
        WITH (timescaledb.continuous) AS
        SELECT time_bucket(INTERVAL '1 minute', time) AS bucket,
            AVG(temperature),
            MAX(temperature),
            MIN(temperature)
        FROM conditions
        GROUP BY bucket;
    
    
    출력:
    CREATE OR REPLACE VIEW "public"."conditions_summary_minutely" AS
    SELECT
      _materialized_hypertable_5.bucket,
      _timescaledb_internal.finalize_agg(
        'avg(double precision)' :: text,
        NULL :: name,
        NULL :: name,
        '{{pg_catalog,float8}}' :: name [],
        _materialized_hypertable_5.agg_2_2,
        NULL :: double precision
      ) AS avg,
      _timescaledb_internal.finalize_agg(
        'max(double precision)' :: text,
        NULL :: name,
        NULL :: name,
        '{{pg_catalog,float8}}' :: name [],
        _materialized_hypertable_5.agg_3_3,
        NULL :: double precision
      ) AS max,
      _timescaledb_internal.finalize_agg(
        'min(double precision)' :: text,
        NULL :: name,
        NULL :: name,
        '{{pg_catalog,float8}}' :: name [],
        _materialized_hypertable_5.agg_4_4,
        NULL :: double precision
      ) AS min
    FROM
      _timescaledb_internal._materialized_hypertable_5
    WHERE
      (
        _materialized_hypertable_5.bucket < COALESCE(
          _timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(5)),
          '-infinity' :: timestamp with time zone
        )
      )
    GROUP BY
      _materialized_hypertable_5.bucket
    UNION ALL
    SELECT
      time_bucket('00:01:00' :: interval, conditions."time") AS bucket,
      avg(conditions.temperature) AS avg,
      max(conditions.temperature) AS max,
      min(conditions.temperature) AS min
    FROM
      conditions
    WHERE
      (
        conditions."time" >= COALESCE(
          _timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(5)),
          '-infinity' :: timestamp with time zone
        )
      )
    GROUP BY
      (
        time_bucket('00:01:00' :: interval, conditions."time")
      );
    
    
    원본 스크립트를 잃어버리면 콘솔에서 정의를 다시 쓰는 것은 우울하다.또한 현재 정의를 바꾸는 것을 지원하지 않기 때문에 삭제하고 보기를 만들어야 합니다.TimescaleDB 2.0에서 시작하여 연속적인 집합을 위한 새로운 API와 프레임워크는 정책을 핵심 기능과 분리#2118합니다.연속 뷰 작성 구문이 변경되었습니다.
    -- old syntax
    CREATE VIEW conditions_summary_minutely
    WITH (timescaledb.continuous,
        timescaledb.refresh_lag = '1h',
        timescaledb.refresh_interval = '1h')
    AS
        SELECT time_bucket(INTERVAL '1 minute', time) AS bucket,
            AVG(temperature),
            MAX(temperature),
            MIN(temperature)
        FROM conditions
        GROUP BY bucket;
    
    -- new syntax
    CREATE MATERIALIZED VIEW conditions_summary_minutely
        WITH (timescaledb.continuous) AS
        SELECT time_bucket(INTERVAL '1 minute', time) AS bucket,
               AVG(temperature),
               MAX(temperature),
               MIN(temperature)
        FROM conditions
        GROUP BY bucket;
    
    -- the continuous aggregate policy is a separated job
    SELECT add_continuous_aggregate_policy('conditions_summary_minutely',
        start_offset => INTERVAL '2 h',
        end_offset => INTERVAL '1 h',
        schedule_interval => INTERVAL '1 h');
    
    
    새로운continuous 보기는continuous aggregate 정책을 하나의 CREATE OR REPLACE 문장의 인자가 아닌 다른 함수 add_continuous_aggregate_policy 로 분리합니다.또 다른 문제를 일으켰습니다.CREATE VIEW

    파타레로:...트랜잭션 블록 내에서 실행할 수 없음


    일부 기능은 CREATE MATERIALIZED VIEW ... WITH DATA cannot run inside a transaction block 모드에서 실행되어야 합니다.모든 문장은 제출 후 자동으로 제출된다.AUTOCOMMIT 자동 커밋이 기본적으로 열립니다.psql SQL 문을 하나씩 실행하는 것을 알아차렸습니까?자, 이 작업에서 이 오류가 발생합니다.
  • 관리 명령: 데이터베이스, 테이블 공간 생성/삭제...
  • 동시 인덱스 생성
  • 현재 이 오류도 새로운 연속 물화시도에 나타난다.psql를 사용하여 뷰를 생성하는 경우에는 문제가 되지 않습니다.그러나 트랜잭션 애플리케이션을 사용하여 파일을 마이그레이션하기 때문에 Hasura migration CLI를 사용할 수 없게 되었습니다.
    데이터베이스 드라이버를 사용하여 마이그레이션을 실행하는 것은 불가능한 일이 아닙니다.
  • 트랜잭션 없이 SQL 문을 실행합니다.
  • 요청마다 문장이 하나씩 있습니다.
  • 불행하게도 GraphQL 엔진의 원본 코드는 엔진의 핵심 기능과 관련되기 때문에 변경하기 어렵다.그래서 나는 아이디어를 하나 생각해냈다.native Go의 lib/pq 옵션을 사용하여 CLI를 사용자 정의하는 것이 더 쉽습니다.
    이것은 해커 공격이기 때문에 주요 상류에서는 공식적인 것이 아니다.사용자 정의 CLIhere를 다운로드하거나 the single node example에서 시험적으로 사용할 수 있습니다.psql몇 가지 경고가 있습니다.
  • 마이그레이션 파일은 한 트랜잭션에서 대량 SQL 애플리케이션이 아닌 한 번에 하나씩 적용됩니다.따라서 마이그레이션을 취소할 수 없습니다.예를 들어, 마이그레이션을 3번 적용hasura migrate apply --disable-transaction --database-url "<url>"했습니다.마이그레이션에 오류가 있는 경우A, B, CC, A가 그대로 적용됩니다.
  • B와 같은 특수 문장을 사용하면 up.sql 중 SQL 문장은 하나만 있을 수 있다.
  • GraphQL


    TimescaleDB는 Postgres의 확장이기 때문에GraphQL 엔진과 호환됩니다.그러나 TimescaleDB는 Hasura의 제한 사항에 영향을 미칩니다.
  • Hypertable에는 주 키가 필요하지 않습니다.따라서 CREATE MATERIALIZED VIEW 조회, 돌연변이, 구독이 비활성화되었습니다.
  • hypertable에서는 Upsert가 지원되지 않습니다.
  • Hypertable은 외부 키를 지원하지 않습니다.
  • 비록 우리는 시계 간에 수동 관계를 만들 수 있지만 조회 성능을 고려해야 한다.
  • 콘솔 및 Hasura CLI


    Hasura 콘솔에서는 TimescaleDB SQL API를 지원하지 않습니다.우리는 <hypertable_name>_by_pk를 사용하거나 수동으로 이전을 만들어야 한다.이론적으로Raw SQL는 표의 고위층이므로 우리는 컨트롤러에서 그것을 만들 수 있다.그러나 hypertable 시간 스탬프나 숫자열을 섹션 키로 사용합니다.그것은 이 열을 메인 키로 포함해야 한다.따라서, 우리는 메인 키를 무시하거나 복합 키를 사용해야 한다. 실제로 우리는 그것을 무시하기로 선택했다.문제는 Hasura 콘솔에서 메인 키 생성 테이블#6235을 강제로 만들었다는 것이다.수동 이전 창설은 불가피합니다.
    그러나 콘솔 UI에서는 연속 집계 뷰를 삭제할 수 없습니다.막후에서 SQL 실행을 요청hypertable합니다.정확한 견해는DROP VIEW이다.
    물적 보기 오류 삭제 TimescaleDB와 Hasura
    hypertable에서 선택할 수 있는 메인 키 때문에 자세한 정보를 볼 수 없고, 데이터 테이블의 줄을 업데이트하고 삭제할 수 없습니다.
    TimescaleDB 및 Hasura 콘솔
    따라서 대부분의 TimescaleDB 함수는 원래 SQL에서 실행되어야 합니다.콘솔은 이곳에서 별로 도움이 되지 않는다.

    업그레이드해야 하나요?


    그래, 이동의 변화를 파괴하는 것을 두려워하지 않는다면.새로운 연속 물화시도도 또 다른 문제다.
    TimescaleDB 2.0은 또한 다중 노드 확장 솔루션을 사용하여 업그레이드할 가치가 있습니다.우리는 곧 다가올 시리즈의 다음 부분에서 탐색을 진행할 것이다.

    좋은 웹페이지 즐겨찾기