# Collector

Find the heading that matches what you see.  A collector can report healthy while one feature is
still missing, so check here even when everything else looks fine.

If the Query Performance page is empty, see
[The Query Performance page is empty](/docs/troubleshooting/empty-pages/#the-query-performance-page-is-empty)
in Empty pages.

## No data has arrived yet

### Cause

A first run takes time.  The PostgreSQL receiver collects on a 10 second interval by default, but
a first run also has to discover databases, capture schema and take a first statistics sample.

### Fix

Give it a few minutes before assuming a fault.  If nothing has appeared after that, work through
the three causes under [The collector cannot connect](#the-collector-cannot-connect), in order.

## The collector cannot connect

### Cause

Check the collector's own logs first.  They identify the failed stage, and each of the three causes looks
different:

| Cause | What to check |
|---|---|
| Network | The collector connects outbound over 443 to DBGorilla, and separately to your database on its own port.  A database unreachable from the container is common in Docker and Kubernetes, where `localhost` means the container rather than the host. |
| Credentials | The login in your collector config must exist and be allowed to connect to every database you listed. |
| TLS | See [A certificate was rejected](#a-certificate-was-rejected). |

## A certificate was rejected

### Fix

[Choosing `ssl_mode`](/docs/reference/collector-configuration/#choosing-ssl_mode)
covers the trade-off.

## Query text is cut off

### Cause

The database truncated the text before DBGorilla saw it, so the fix is a server setting.  A query
plan needs the whole statement, so fix this before asking for
[plans and experiments](#dbgorilla-cannot-show-a-query-plan-or-test-a-recommendation).

### Fix

#### MySQL

Two settings cap stored statement text: `max_digest_length` and
`performance_schema_max_digest_length`.  Both default to 1024 bytes, and the
smaller one wins, so raise both to the same value.  Both take effect at the next
server restart.

A third setting, `performance_schema_max_sql_text_length`, caps the text of a
statement while it runs, which DBGorilla shows for active sessions.  It also
defaults to 1024 bytes and takes effect at restart, so raise it in the same
change.

Raising them costs memory.  MySQL reserves `max_digest_length` bytes per session
and `performance_schema_max_digest_length` bytes per stored statement, so raise
them to what your longest statement needs rather than to the maximum.  Both are
described in the MySQL manual under
[Performance Schema Statement Digests](https://dev.mysql.com/doc/refman/8.4/en/performance-schema-statement-digests.html).

| Where MySQL runs | How to raise them |
|---|---|
| Self-managed | Set both under `[mysqld]` in `my.cnf` and restart the server. |
| AWS RDS for MySQL, Aurora MySQL | Set the digest-length parameters your engine's DB parameter group offers.  They go in a custom parameter group, since the default group is read-only.  Reboot the instance. |
| Google Cloud SQL for MySQL | Set both as database flags.  The instance restarts. |

```ini
[mysqld]
max_digest_length = 8192
performance_schema_max_digest_length = 8192
performance_schema_max_sql_text_length = 8192
```

#### PostgreSQL

The Query Performance page keeps the whole statement.  The text shown for a running session is
capped by `track_activity_query_size`, which is 1024 bytes by default.  It can only be set at
server start, so raise it in `postgresql.conf`, or in the parameter group or database flag on a
managed service, and restart.

### Check the fix worked

On MySQL, check what the server is using after the restart:

```sql
SHOW GLOBAL VARIABLES WHERE Variable_name IN
  ('max_digest_length', 'performance_schema_max_digest_length',
   'performance_schema_max_sql_text_length');
```

## DBGorilla cannot show a query plan or test a recommendation

Chat or the advisor says it cannot run `EXPLAIN`, or an experiment reports that the component does
not allow that command.  Metrics, schema and query statistics keep arriving normally.

### Cause

Both features run through the collector's `[commands]` section, which does not allow them.

### Fix

Allow `explain` and `collect_statistics` and restart the collector:

```toml
[commands]
enabled = true
allowed = ["explain", "collect_statistics"]
```

A `[[component]]` with its own
`commands` list ignores the global switch, so check there too.
[Database commands](/docs/reference/collector-commands/#database-commands)
has the full reference.

On MySQL, `collect_statistics` also needs two grants that the monitoring
grants do not cover:

```sql
GRANT SELECT ON mysql.innodb_table_stats TO 'dbg_monitor'@'%';
GRANT SELECT ON mysql.innodb_index_stats TO 'dbg_monitor'@'%';
```

The tables are described in
[InnoDB Persistent Statistics Tables](https://dev.mysql.com/doc/refman/8.4/en/innodb-persistent-stats.html#innodb-persistent-stats-tables).

A plan also needs the whole statement, so fix
[cut-off query text](#query-text-is-cut-off) first.

## Schema capture fails with `permission denied for table`

Metrics arrive normally while `permission denied for table ...` appears in the logs as a warning
that retries forever.

### Cause

A permissions gap.  `pg_monitor` alone is not enough.  Schema capture runs `pg_dump`, which must
`SELECT` every table it reads, and the `USAGE` and `SELECT` grants apply only to
the database and schema where you ran them.

Tables created *after* the grant are another source of failures:
`ALTER DEFAULT PRIVILEGES` without `FOR ROLE` covers only tables created by the
role that ran it.  An application creating its own tables is not covered.

### Fix

[Database grants](/docs/connect/prepare-postgresql/#database-grants)
has the full statement set and the query that lists which roles own tables.

## Still stuck

Email [support@dbgorilla.com](mailto:support@dbgorilla.com).

Send the collector's logs and your collector configuration **with the database
password removed**.