Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiple postgres database & metadata storage separation #5797

Closed

Conversation

rakeshkky
Copy link
Member

@rakeshkky rakeshkky commented Sep 17, 2020

TODO

  • Avoid hdb_catalog.hdb_catalog.check_violation

  • Cron/Scheduled triggers

  • Console support - metadata storage data APIs

  • Backwards compatibilty of DATABASE_URL

  • v1/query API backwards compatibility

    • Make existing tests work
  • pg_dump API to accept source

  • Heterogeneous execution (i.e, merge master)

  • Action queries/mutations execution in appropriate source (when there are relationships defined)

  • Tests for multiple sources**

  • Add/modify column issue:
    The server gets stuck with requests like the following one:

     {
          "type": "run_sql",
          "source": "default",
          "args": {
                 "sql": "alter table \"public\".\"test\" add column \"test_col\" text null;",
                 "cascade": false,
                 "read_only": false
          }
      }
    
  • pg_invoke_event_trigger results in the following error:

    {
     "internal": {
         "statement": "\n           SELECT hdb_catalog.insert_event_log($1, $2, $3, $4, $5)\n                ",
         "prepared": true,
         "error": {
             "exec_status": "FatalError",
             "hint": null,
             "message": "invalid input syntax for type json",
             "status_code": "22P02",
             "description": "The input string ended unexpectedly."
         },
         "arguments": [
             "(Oid 25,Just (\"public\",Binary))",
             "(Oid 25,Just (\"test\",Binary))",
             "(Oid 25,Just (\"lala\",Binary))",
             "(Oid 25,Just (\"MANUAL\",Binary))",
             "(Oid 114,Just (\"{\\\"row\\\":{\\\"id\\\":2}}\",Binary))"
         ]
     },
     "path": "$",
     "error": "database query error",
     "code": "unexpected"
    }
    
  • can't set comments for computed fields. Request:

        {
             "type": "pg_add_computed_field",
             "args": {
                 "table": {
                     "schema": "public",
                     "name": "users"
                 },
                 "name": "test",
                 "definition": {
                     "function": {
                         "schema": "public",
                         "name": "author_full_name"
                     },
                     "table_argument": "author_row"
                 },
                 "comment": "some comment",
                 "source": "my db 1"
             }
         }
    

** - can be done in parallel

Description

Metadata:-

  • This PR overhauls the way in which the metadata is persisted in Postgres database. Now, the metadata is stored as a single json blob in hdb_catalog.hdb_metadata table in a single row. This reduces the Hasura footprint in the hdb_catalog schema.
  • Metadata can be stored in a separate database, use --metadata-database-url or HASURA_GRAPHQL_METADATA_DATABASE_URL option. By default it is stored in the database specified via --database-url. One can start the server with only metadata database specified and configure the postgres database as sources (see below).

Multiple Databases

  • Introduction of new notion in metadata - Source, a user Postgres database where all tables/views and functions can reside in. We can configure multiple sources via Metadata API or console UI.
  • This change will pave the way for supporting sources of multiple backends other than Postgres. (MySQL, MSSQL etc.)

Changelog

  • CHANGELOG.md is updated with user-facing content relevant to this PR. If no changelog is required, then add the no-changelog-required label.

Affected components

  • Server
  • Tests

Limitations, known bugs & workarounds

Actions:-

  1. Action query subscriptions
  2. Action with relationships to postgres tables

Metadata

The metadata version is bumped to 3. The only difference from version 2 is that now the tables and functions will be present inside new sources field for each time. The other top level fields remain as it is.
Example:-
version 2:

version: 2
tables:
- table:
    schema: public
    name: test
functions:
- function:
    schema: public
    name: search_test

version 3:

version: 3
sources:
- name: default
  tables:
  - table:
      schema: public
      name: test
  functions:
  - function:
      schema: public
      name: test
- name: chinook
  tables:
  - table:
      schema: public
      name: actors
  configuration:
    database_url: postgres://postgres@127.0.0.1:5432/chinook
    connection_pool_settings:
      retries: 1
      idle_timeout: 180
      max_connections: 50

Where default is the source configured via --database-url server option and chinook is newly added postgres source via metadata API.

New APIs

It is recommended to use newly added /v1/metadata to manage metadata and /v2/query to query postgres sources via JSON DSL, instead of /v1/query API.

/v1/metadata

It contains all query types in /v1/query except database DML operations like insert, select etc.
Query types for managing postgres related metadata are appended with pg_.
For example, track_table is changed to pg_track_table and similarly for all query types for managing tables, functions, relationships, remote relationships, event triggers and computed fields.
This also supports bulk query type for running multiple metadata queries in a single request.

APIs for console data requirements from metadata storage:

  1. Get the console state:

request,

{
  "type": "get_catalog_state",
  "args": {}
}

response,

{
    "id": "fc0bc750-b343-44cc-a7f4-46637b0067f7",
    "cli_state": {},
    "console_state": {}
}
  1. Set the console state:

request,

{
  "type": "set_catalog_state",
  "args": {
    "type": "console",
    "state": {"key": "value"}
  }
}

{ "message": "success" } is the response.

  1. Get invocation logs for cron/scheduled (one-off) events.

request,

{
  "type": "get_event_invocations",
  "args": {
    "type": "one_off",
    "limit": 10,
    "offset": 10
  }
}
{
  "type": "get_event_invocations",
  "args": {
    "type": "cron",
    "trigger_name": "some_trigger_name",
    "limit": 10,
    "offset": 10
  }
}

By event id,

{
  "type": "get_event_invocations",
  "args": {
    "type": "cron",
    "event_id": "some_event_id"
  }
}

response,

{
    "invocations": <list of invocation objects>,
    "count": <count of total invocations"
}

By Event Id:

  1. Get all scheduled events.

One off:-
pending

{
    "type": "get_scheduled_events",
    "args": {
        "type": "one_off",
        "limit": 10,
        "offset": 10,
        "status": ["scheduled"] 
    }
}

processed

{
    "type": "get_scheduled_events",
    "args": {
        "type": "one_off",
        "limit": 10,
        "offset": 10,
        "status": ["delivered", "error", "dead"] 
    }
}

Cron:-

{
    "type": "get_scheduled_events",
    "args": {
        "type": "cron",
        "trigger_name": "test"
    }
}

trigger_name is required if type is cron.

Response:-

{
    "events": <list of events, the object structure is different for cron and one_off>,
    "count": <total-count>
}
  1. Delete cron/scheduled (one-off) event by event id

request:-

{
  "type": "delete_scheduled_event",
  "args": {
    "type": "one_off",
    "event_id": "00a8d34c-de0d-417a-ac9f-22df310af989"
  }
}

{"message": "success"} is the response.

/v2/query

All database DML operations like insert, select, delete, update, count and run_sql from /v1/query. An optional top level field source is accepted in payload and its absence treated as default source. These queries are run in the Postgres source specified.
Example:-

---
type: select
source: chinook
args:
  table: actor
  columns:
  - id
  - name

Console issues:

  • get_invocation_logs: filter by cron trigger name, for one-off return all invocations
  • get_invocation_logs: pagination
  • get_invocation_logs: count all
// example req
    {
      "type": "get_event_invocations",
      "args": {
        "type": "one_off",
        "offset": 10,
        "limit": 10,
      }
    }

// response
{
  invocations: [...], count: 122,
}
  • get_scheduled_events: filter by status - pending/processed
  • get_scheduled_events: pagination
  • get_scheduled_events: count

rakeshkky and others added 30 commits August 12, 2020 19:10
-> move all essential metadata types from RQL/DDL/* to RQL/Types/*
Resolve Conflicts:
	server/graphql-engine.cabal
	server/src-lib/Hasura/GraphQL/Schema/Action.hs
	server/src-lib/Hasura/RQL/DDL/EventTrigger.hs
	server/src-lib/Hasura/RQL/DDL/Metadata.hs
	server/src-lib/Hasura/RQL/DDL/Metadata/Generator.hs
	server/src-lib/Hasura/RQL/DDL/Metadata/Types.hs
	server/src-lib/Hasura/RQL/DDL/Permission.hs
	server/src-lib/Hasura/RQL/DDL/RemoteRelationship.hs
	server/src-lib/Hasura/RQL/DDL/RemoteSchema.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Cache.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Cache/Fields.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Rename.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Table.hs
	server/src-lib/Hasura/RQL/Types/Action.hs
	server/src-lib/Hasura/RQL/Types/RemoteRelationship.hs
	server/src-lib/Hasura/Server/App.hs
Resolve Conflicts:
	server/src-lib/Hasura/App.hs
	server/src-lib/Hasura/RQL/DDL/ComputedField.hs
	server/src-lib/Hasura/RQL/DDL/Metadata.hs
	server/src-lib/Hasura/RQL/DDL/Metadata/Types.hs
	server/src-lib/Hasura/RQL/DDL/Permission.hs
	server/src-lib/Hasura/RQL/DDL/Permission/Internal.hs
	server/src-lib/Hasura/RQL/DDL/Relationship.hs
	server/src-lib/Hasura/RQL/DDL/RemoteRelationship.hs
	server/src-lib/Hasura/RQL/DDL/Schema.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Cache.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Cache/Fields.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Catalog.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Function.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Rename.hs
	server/src-lib/Hasura/RQL/DDL/Schema/Table.hs
	server/src-lib/Hasura/RQL/Types.hs
ecthiender and others added 3 commits October 16, 2020 16:05
Resolve Conflicts:
	server/src-lib/Hasura/App.hs
	server/src-lib/Hasura/Db.hs
	server/src-lib/Hasura/Eventing/EventTrigger.hs
	server/src-lib/Hasura/Eventing/ScheduledTrigger.hs
	server/src-lib/Hasura/GraphQL/Execute/Insert.hs
	server/src-lib/Hasura/GraphQL/Execute/Mutation.hs
	server/src-lib/Hasura/GraphQL/Execute/Prepare.hs
	server/src-lib/Hasura/GraphQL/Execute/Query.hs
	server/src-lib/Hasura/GraphQL/Schema.hs
	server/src-lib/Hasura/GraphQL/Transport/HTTP.hs
	server/src-lib/Hasura/GraphQL/Transport/WebSocket.hs
	server/src-lib/Hasura/RQL/DDL/EventTrigger.hs
	server/src-lib/Hasura/RQL/Types/EventTrigger.hs
	server/src-lib/Hasura/RQL/Types/SchemaCache.hs
	server/src-lib/Hasura/Server/App.hs
@tirumaraiselvan tirumaraiselvan added this to the v1.4 milestone Oct 20, 2020
@beerose beerose mentioned this pull request Nov 2, 2020
24 tasks
@rakeshkky rakeshkky mentioned this pull request Nov 12, 2020
11 tasks
hasura-bot added a commit that referenced this pull request Nov 25, 2020
An incremental PR towards #5797

* metadata storage abstraction for scheduled triggers

Co-authored-by: rakeshkky <12475069+rakeshkky@users.noreply.github.com>
Co-authored-by: Rakesh Emmadi <12475069+rakeshkky@users.noreply.github.com>
Co-authored-by: Auke Booij <auke@hasura.io>
GITHUB_PR_NUMBER: 6131
GITHUB_PR_URL: #6131

* update pro server code

Co-authored-by: rakeshkky <12475069+rakeshkky@users.noreply.github.com>
Co-authored-by: Auke Booij <auke@hasura.io>
GitOrigin-RevId: 17244a4
hasura-bot pushed a commit that referenced this pull request Dec 14, 2020
…adata operations (#184)

An incremental PR towards #5797
- Expands `MonadMetadataStorage` with operations related to async actions and setting/updating metadata

GitOrigin-RevId: 53386b7
hasura-bot pushed a commit that referenced this pull request Dec 28, 2020
…multi sources (#197)

This is an incremental PR towards #5797

Co-authored-by: Anon Ray <ecthiender@users.noreply.github.com>
GitOrigin-RevId: a6cb8c2
@tirumaraiselvan tirumaraiselvan removed this from the v1.4 milestone Mar 1, 2021
@0x777 0x777 closed this Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants