> ## Documentation Index
> Fetch the complete documentation index at: https://xata.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Xata

This guide explains how to use **pgstream** with **Xata databases**, covering **snapshots** and **replication**.

👉 Throughout this guide:

* **`pgstreamsource`** refers to the user provided in the **pgstream source URL**.
* **`pgstreamtarget`** refers to the user provided in the **pgstream target URL**.

## Snapshots

### From Xata Database (Snapshots)

#### Quick Checklist

* [ ] Create a source user (**`pgstreamsource`**) with access to required schemas/tables.
* [ ] For roles without passwords → no special config needed.
* [ ] For roles with passwords → **must use the `xata` superuser**.
* [ ] Update YAML config with correct snapshot settings.

#### Steps

1. **User privileges**
   Ensure the **`pgstreamsource`** user (from the pgstream source URL) can access the database schema and tables you need.

2. **Roles handling**

   * **No roles** → no changes required.
   * **Roles without passwords** → no changes required.
   * **Roles with passwords** → **must use the `xata` user** as `pgstreamsource`.

     ⚠️ Only the `xata` user has access to the `pg_authid` table required for snapshotting roles with passwords.

     Without this, you'll see:

     ```
     pg_dumpall: error: query failed: ERROR:  permission denied for table pg_authid
     ```

3. **Config when not snapshotting roles**
   If roles are disabled or not manually managed, add the following to avoid failures:

   ```yaml theme={null}
   snapshot:
     schema:
       pgdump_pgrestore:
         roles_snapshot_mode: "disabled"
         no_owner: true
         no_privileges: true
   ```

   Example full configuration:

   ```yaml theme={null}
   source:
     postgres:
       url: "postgresql://pgstreamsource:password@<xata-host>:5432/db?sslmode=require"
       mode: snapshot
       snapshot:
         mode: full # schema + data
         tables: ["public.*"] # all tables in the public schema
         schema:
           mode: pgdump_pgrestore
           pgdump_pgrestore:
             roles_snapshot_mode: "disabled"
             no_owner: true
             no_privileges: true
   ```

ℹ️ Xata-managed roles (`xata`, `xata_superuser`, `cnpg_pooler_pgbouncer`) will not be snapshotted.

### To Xata Database (Snapshots)

#### Quick Checklist

* [ ] Create a target user (**`pgstreamtarget`**) for the pgstream target URL.
* [ ] Grant privileges for schema/database ownership.
* [ ] Grant optional privileges depending on features (create DB, create roles).
* [ ] **Use `disable_triggers: false`** (required for all non-`xata` users).

#### Steps

The **`pgstreamtarget`** user (from the pgstream target URL) must have the following privileges:

* **Schema ownership**

  ```sql theme={null}
  ALTER DATABASE db OWNER TO pgstreamtarget;
  ALTER SCHEMA public OWNER TO pgstreamtarget;
  ```

* **Database creation** (if `create_target_db` is enabled)

  ```sql theme={null}
  ALTER ROLE pgstreamtarget CREATEDB;
  ```

* **Role creation** (if `roles_snapshot_mode` is `enabled`/`no_passwords`)

  ```sql theme={null}
  ALTER ROLE pgstreamtarget CREATEROLE;
  ```

  ⚠️ `pgstreamtarget` must already hold any privileges it assigns (e.g., `REPLICATION`).

* **Disable triggers** (required for Xata)

  ⚠️ **Only the `xata` user can set `session_replication_role`** on Xata databases. For all other users, you **must** disable trigger management in pgstream:

  ```yaml theme={null}
  target:
    postgres:
      disable_triggers: false # Required for non-xata users
  ```

  ❌ If using a non-`xata` user with `disable_triggers: true`, pgstream will fail with:

  ```
  permission denied to set parameter "session_replication_role"
  ```

## Replication

### From Xata Database (Replication)

#### Quick Checklist

* [ ] Ensure logical replication is enabled on your Xata database.
* [ ] **Use the `xata` user for initialization** (only user with event trigger privileges).
* [ ] Optionally use a different **`pgstreamsource`** user for streaming.

#### Steps

1. **Enable logical replication**
   Make sure logical replication is enabled in your database. The `wal_level` must be set to `logical`. You can check the current setting by running the following:

   ```sql theme={null}
   SHOW wal_level;

   ```

   ⚠️ Changing wal\_level requires a full database restart.

2. **Replication phases**

   * **Initialization** → requires elevated privileges to create schemas, event triggers, and replication slots.
   * **Streaming** → can use a dedicated `pgstreamsource` user.

#### Initialization

Initialization does the following:

* Creates `pgstream` schema
* Creates replication slot (if missing)
* Creates event triggers/functions for schema changes

⚠️ **Only the `xata` user has sufficient privileges to create event triggers.** Use the `xata` user for initialization:

```yaml theme={null}
source:
  postgres:
    url: "postgresql://xata:password@<xata-host>:5432/db?sslmode=require"
    mode: replication
```

#### Streaming

After initialization, you can:

* Keep using `xata`, or
* Transfer ownership to a dedicated **`pgstreamsource`** role.

```sql theme={null}
-- Allow ownership transfer
GRANT pgstreamsource TO current_user;

-- Transfer ownership
ALTER DATABASE db OWNER TO pgstreamsource;
ALTER SCHEMA pgstream OWNER TO pgstreamsource;
ALTER SCHEMA <schema> OWNER TO pgstreamsource;
ALTER TABLE pgstream.schema_log OWNER TO pgstreamsource;
ALTER TABLE pgstream.table_ids OWNER TO pgstreamsource;
ALTER SEQUENCE pgstream.xid_serial OWNER TO pgstreamsource;

-- Replication privileges
ALTER ROLE pgstreamsource REPLICATION;
```

### To Xata Database (Replication)

#### Quick Checklist

* [ ] Ensure **`pgstreamtarget`** has schema/database ownership.
* [ ] If combined with snapshot → follow [Snapshot target requirements](#to-xata-database-snapshots).

#### Steps

Privileges required:

```sql theme={null}
ALTER DATABASE db OWNER TO pgstreamtarget;
ALTER SCHEMA <schema> OWNER TO pgstreamtarget;
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="permission denied for table pg_authid">
    **Cause**: Roles with passwords require pg\_authid access.\
    **Fix**: Use `xata` user as source, or disable role passwords (`roles_snapshot_mode: no_passwords`).
  </Accordion>

  <Accordion title="permission denied to set parameter &#x22;session_replication_role&#x22;">
    **Cause**: Only the `xata` user can set this parameter.\
    **Fix**: Set `disable_triggers: false` in target config, or use the `xata` user as target.
  </Accordion>

  <Accordion title="permission denied for schema public when transferring ownership">
    **Cause**: Target role lacks CREATE privilege on schema.\
    **Fix**: Grant CREATE on schema to the role: `GRANT CREATE ON SCHEMA public TO role_name;`
  </Accordion>

  <Accordion title="Role creation fails">
    **Cause**: `pgstreamtarget` lacks privileges it tries to assign.\
    **Fix**: Grant required privileges to `pgstreamtarget` first, or use a user with more privileges.
  </Accordion>
</AccordionGroup>
