docs: restructure documentation and add invalid transaction termination exception

This commit is contained in:
Maksym Buz
2026-05-11 13:13:30 +00:00
parent 6e9c76ad76
commit b695cc8442
2 changed files with 30 additions and 4 deletions

View File

@@ -87,6 +87,9 @@ If you use a visual database manager, simply open each file in your query editor
Partitioning requires a daily job to create new partitions for tomorrow and drop old partitions from last month.
> [!WARNING]
> **CRITICAL EXECUTION RULE**: You MUST execute the maintenance procedure as a standalone command exactly as shown below. **DO NOT** wrap it in a transaction block (`BEGIN; ... COMMIT;`) or batch it with other SQL commands in a single string, or it will crash with an `invalid transaction termination` error.
If you are using **AWS RDS** or a managed database with `pg_cron` enabled, run this inside `psql`:
```sql
@@ -94,7 +97,12 @@ CREATE EXTENSION IF NOT EXISTS pg_cron;
SELECT cron.schedule('zabbix_partition_maintenance', '30 5,23 * * *', 'CALL partitions.run_maintenance();');
```
*(If you are self-hosting and don't have `pg_cron`, please refer to the `README.md` for instructions on setting up standard OS `cron` or systemd timers.)*
If you are **self-hosting** and prefer standard system `cron`, simply add this to your `crontab -e`:
```bash
# Run Zabbix partition maintenance twice daily (5:30 AM and 11:30 PM)
30 5,23 * * * psql -U postgres -d zabbix -c "CALL partitions.run_maintenance();" >> /var/log/zabbix_maintenance.log 2>&1
```
---
@@ -106,7 +114,7 @@ Now that the database is fully partitioned, you can safely start Zabbix Server a
sudo systemctl start zabbix-server
```
*(Note: Your old history data remains in tables like `history_old`. It is no longer visible in the UI. If you need it, you must manually insert it into the new tables. See `README.md` for more details.)*
*(Note: Your old history data remains safely preserved in tables like `history_old`. It is no longer visible in the UI, but it is available in the database if you ever need to manually migrate it.)*
---

View File

@@ -39,8 +39,8 @@ All procedures, information, statistics and configuration are stored in the `par
## Installation
> [!IMPORTANT]
> **Please refer to the [MANUAL.md](MANUAL.md) for the complete, step-by-step, foolproof installation instructions.**
> The manual contains critical safety procedures, backup warnings, and copy-pasteable commands for a safe deployment.
> **For deployment instructions, please refer to [MANUAL.md](MANUAL.md).**
> `MANUAL.md` contains the step-by-step, foolproof installation guide intended for customer sharing. This `README.md` serves as an internal knowledge base for maintaining, troubleshooting, and understanding the architecture.
## Configuration
@@ -246,6 +246,9 @@ The enablement script guarantees practically zero downtime by automatically rena
* New data flows into the new partitioned tables immediately.
* Old data remains accessible in `table_name_old` for manual lookup or migration if required.
> [!WARNING]
> **Non-Atomic Enablement**: The `02_enable_partitioning.sql` script is executed within a `DO $$` block. However, because it calls the maintenance procedure (which issues `COMMIT` statements to manage locks), the enablement process is **not atomic**. If the script crashes halfway through (e.g., due to a missing table), it will not roll back the previously converted tables. The database will be in a partially partitioned state. Fortunately, the script is fully restartable. Simply fix the underlying issue and run the script again; it will skip already partitioned tables and resume where it left off.
### Housekeeper Interceptor
Even when Zabbix Housekeeping is disabled in the UI for History and Trends, the Zabbix Server daemon may still generate and insert tasks into the `housekeeper` table (e.g., when an item or trigger is deleted, it schedules the deletion of its historical data). Without intervention, this results in the `housekeeper` table bloating massively over time, leading to slow sequential scans and `autovacuum` overhead.
@@ -254,6 +257,21 @@ To prevent this, this extension installs a `BEFORE INSERT` trigger on the `house
* If the table is partitioned (like `history`), the trigger **silently discards the insert** (`RETURNS NULL`), preventing disk I/O and table bloat entirely.
* If the table is not partitioned (like `events` or `sessions`), the task is allowed to be recorded and is cleaned up naturally by Zabbix.
## Troubleshooting & Known Exceptions
### `invalid transaction termination`
When manually executing or scheduling the maintenance procedure (`CALL partitions.run_maintenance();`), you or the customer might encounter the following fatal error:
`ERROR: invalid transaction termination`
**Why this happens:**
Inside the `partitions` PL/pgSQL procedures, we execute `COMMIT;` statements within loops to eagerly release locks and prevent transaction bloat when dropping dozens of partitions. PostgreSQL fundamentally prohibits executing `COMMIT` from within a procedure if that procedure was called from inside an explicit transaction block or a batched command string.
**How to fix/avoid it:**
Ensure the procedure is ALWAYS executed as a top-level, standalone command.
* **Bad**: `BEGIN; CALL partitions.run_maintenance(); COMMIT;`
* **Bad**: `psql -c "UPDATE partitions.config SET keep_history = '1 day'; CALL partitions.run_maintenance();"` (psql batches these into one transaction)
* **Good**: `psql -c "CALL partitions.run_maintenance();"`
## PostgreSQL Tuning
Before or immediately after enabling partitioning, you should tune your `postgresql.conf`. The standard configuration is not optimized for partitioned tables and might cause performance degradation or out-of-memory errors.