Data Cleaning: Difference between revisions

From VoIPmonitor.org
(Clarify that cleandatabase is a global default for all cleandatabase_* parameters)
(Fix incorrect association of _2 parameters with tar_move - they are for spooldir_2 used with capture rules (TP-38))
 
(56 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''This guide explains how VoIPmonitor manages data retention for both captured packets (PCAP files) and Call Detail Records (CDRs) in the database. Proper configuration is essential for managing disk space and maintaining long-term database performance.  '''
{{DISPLAYTITLE:Data Cleaning and Retention}}
[[Category:Configuration]]
[[Category:Administration]]


== Overview of Data Cleaning ==
This guide explains how VoIPmonitor manages data retention for PCAP files and database records.
VoIPmonitor generates two primary types of data that require periodic cleaning:
*'''PCAP Files:''' Raw packet captures of SIP/RTP/GRAPH data stored on the filesystem in the spool directory. These can consume significant disk space.
*'''CDR Data:''' Call metadata stored in the MySQL database. Large tables can slow down GUI performance if not managed properly.


The system uses two separate, independent mechanisms to manage the retention of this data.
== Overview ==


== 1. Filesystem Cleaning (PCAP Spool Directory) ==
VoIPmonitor generates two types of data requiring periodic cleanup:
The sensor stores captured call data in a structured directory tree on the local filesystem.


=== Spool Directory Location ===
{| class="wikitable"
By default, all data is stored in `/var/spool/voipmonitor`. This location can be changed by setting the `spooldir` option in `voipmonitor.conf`.
|-
! Data Type !! Storage !! Cleanup Mechanism !! Key Parameters
|-
| '''PCAP Files''' || Filesystem (spool directory) || Cleanspool process (every 5 min) || <code>maxpoolsize</code>, <code>maxpooldays</code>
|-
| '''CDR Records''' || MySQL database || Partition dropping (instant) || <code>cleandatabase</code>
|}
 
{{Note|These are '''independent systems''' - filesystem cleanup does not affect database records and vice versa.}}


=== Retention Configuration ===
=== Quick Reference ===
The cleaning process runs automatically every 5 minutes and removes the oldest data based on the rules you define in `voipmonitor.conf`. You can set limits based on total size (in Megabytes) or age (in days). If both a size and day limit are set for the same data type, the first limit that is reached will trigger the cleaning.


The following options are available:
{| class="wikitable"
{| class="wikitable"
|-
|-
! Parameter !! Default Value !! Description
! Purpose !! Parameter !! Example
|-
| Limit total PCAP size || <code>maxpoolsize</code> || <code>maxpoolsize = 512000</code> (500 GB)
|-
| Limit RTP specifically || <code>maxpoolrtpsize</code> || <code>maxpoolrtpsize = 102400</code> (100 GB)
|-
| Limit PCAP age || <code>maxpooldays</code> || <code>maxpooldays = 30</code>
|-
|-
| `maxpoolsize` || `102400` (100 GB) || The total maximum disk space for '''all''' captured data (SIP, RTP, GRAPH, AUDIO).
| CDR retention (days) || <code>cleandatabase</code> || <code>cleandatabase = 30</code>
|-
|-
| `maxpooldays` || (unset) || The maximum number of days to keep '''all''' captured data.
| CDR retention (size) || <code>cleandatabase_size</code> || <code>cleandatabase_size = 512000</code> (+ <code>cleandatabase_size_force = true</code>)
|-
| Save only RTP stats || <code>savertp</code> || <code>savertp = header</code> (saves ~90% space)
|}
 
== Filesystem Cleaning (PCAP Files) ==
 
=== How Cleanspool Works ===
 
The sniffer maintains a file index '''in memory'''. Every 5 minutes, the cleanspool thread checks retention limits and deletes the oldest files when limits are exceeded.
 
<kroki lang="plantuml">
@startuml
skinparam shadowing false
skinparam defaultFontSize 11
participant "Sniffer" as S
participant "Cleanspool" as C
database "In-Memory\nIndex" as MEM
collections "Filesystem" as FS
 
S -> FS: Write PCAP
S -> MEM: Update index
... Every 5 minutes ...
C -> MEM: Find oldest files\nexceeding limits
loop Delete old files
    C -> FS: DELETE
    C -> MEM: Remove entry
end
note over MEM : Persisted to\n.cleanspool_cache
@enduml
</kroki>
 
The <code>.cleanspool_cache</code> files in hourly directories serve as '''persistent storage for fast restart''' - they allow quick index reload without scanning the entire filesystem.
 
{{Note|1='''Legacy Indexing:''' Old VoIPmonitor versions stored metadata in MySQL <code>files</code> table. This can be enabled with <code>cleanspool_use_files = yes</code> (deprecated, do not use).}}
 
=== Retention Configuration ===
 
Limits can be set by '''size''' (MB) or '''age''' (days). When both are configured, the first limit reached triggers cleanup.
 
==== Global Limits ====
 
{| class="wikitable"
|-
|-
| `maxpoolsipsize` || (unset) || A specific size limit for SIP PCAP files only.
! Parameter !! Default !! Description
|-
|-
| `maxpoolsipdays` || (unset) || A specific age limit for SIP PCAP files only.
| <code>maxpoolsize</code> || 102400 (100 GB) || Maximum total size for all PCAP data
|-
|-
| `maxpoolrtpsize` || (unset) || A specific size limit for RTP PCAP files only.
| <code>maxpooldays</code> || (unset) || Maximum age in days for all PCAP data
|}
 
==== Per-Type Limits ====
 
{| class="wikitable"
|-
|-
| `maxpoolrtpdays` || (unset) || A specific age limit for RTP PCAP files only.
! Data Type !! Size Parameter !! Days Parameter
|-
|-
| `maxpoolgraphsize` || (unset) || A specific size limit for GRAPH files only.
| SIP signaling || <code>maxpoolsipsize</code> || <code>maxpoolsipdays</code>
|-
|-
| `maxpoolgraphdays` || (unset) || A specific age limit for GRAPH files only.
| RTP audio || <code>maxpoolrtpsize</code> || <code>maxpoolrtpdays</code>
|-
|-
| `maxpoolaudiosize` || (unset) || A specific size limit for converted audio files (WAV/OGG) only.
| Quality graphs || <code>maxpoolgraphsize</code> || <code>maxpoolgraphdays</code>
|-
|-
| `maxpoolaudiodays` || (unset) || An age limit for converted audio files (WAV/OGG) only.
| Converted audio (WAV/OGG) || <code>maxpoolaudiosize</code> || <code>maxpoolaudiodays</code>
|}
|}


=== Maintenance: Re-indexing the Spool Directory ===
==== Recommended Configuration ====
VoIPmonitor maintains an index of all created PCAP files to perform cleaning efficiently without scanning the entire directory tree. If this index becomes corrupt, or if you manually move files into the spool, old data may not be deleted correctly.


In this case, you must trigger a manual re-index. This can be done via the sniffer's manager API.
Limit RTP (largest files) while keeping SIP longer for troubleshooting:
# '''Open a manager API session:'''
#<pre>echo 'manager_file start /tmp/vmsck' | nc 127.0.0.1 5029</pre>
# '''Send the re-index command:'''
#<pre>echo reindexfiles | nc -U /tmp/vmsck</pre>
''Note: This command requires `netcat` with support for UNIX sockets (`-U`). For alternative methods, see the [[Encryption_in_manager_api_customer|Manager API documentation]].''


== 2. Database Cleaning (CDR Retention) ==
<syntaxhighlight lang="ini">
Managing the size of the `cdr` table and other large tables is critical for GUI performance.
# /etc/voipmonitor.conf
maxpoolrtpsize = 102400  # 100 GB limit for RTP
maxpoolsize = 512000      # 500 GB overall limit
</syntaxhighlight>


=== The Modern Method: Partitioning (Recommended) ===
==== Secondary Storage Limits (spooldir_2) ====
Since version 7, VoIPmonitor utilizes **database partitioning**, which splits large tables into smaller, daily segments. This is the highly recommended method for managing database retention.
* '''How it works:''' You set a single parameter, `cleandatabase`, in `voipmonitor.conf`. This defines the number of days to keep CDRs. For example, `cleandatabase = 30` will keep the last 30 days of data.
* '''Why it's better:''' The sniffer automatically drops old daily partitions, which is an instantaneous operation that takes milliseconds, regardless of how many millions of rows it contains. This puts zero load on the database.
* '''Requirement:''' Partitioning is enabled by default on all new installations. If you are upgrading from a very old version, it may require starting with a fresh database.


==== Quick Start: Global Retention ====
When using <code>spooldir_2</code> for secondary storage (configured via [[Capture_rules|capture rules]] with "Store pcaps to second spooldir" enabled), use <code>_2</code> suffix parameters for cleaning:
For most deployments, you only need to configure one parameter in `/etc/voipmonitor.conf`:


<pre>
<code>maxpoolsize_2</code>, <code>maxpooldays_2</code>, <code>maxpoolrtpsize_2</code>, etc.
# Keep all records for 30 days (applies to CDR, sip_msg, register_state, etc.)
cleandatabase = 30
</pre>


The `cleandatabase` parameter acts as a ''global default'' for ALL `cleandatabase_*` options. If you only set `cleandatabase`, it will automatically apply to these tables unless you explicitly override them:
{{Note|1=<code>spooldir_2</code> is '''independent''' from <code>tar_move</code>. The <code>_2</code> suffix parameters apply only to the secondary spooldir configured via capture rules, not to <code>tar_move</code> destination storage.}}
* `cdr` - Call Detail Records
* `message` - SIP MESSAGE texts
* `sip_msg` - SIP OPTIONS/SUBSCRIBE/NOTIFY messages
* `register_state` - SIP registration states
* `register_failed` - Failed registration attempts


This is the simplest way to ensure consistent retention across all table types and prevents unexpected database growth from auxiliary SIP tables.
=== Emergency Cleanup ===


More details can be found in the [[Sniffer_configuration#cleandatabase|Sniffer Configuration guide]].
{{Warning|1=Emergency cleanup activates when disk is nearly full and '''ignores all <code>maxpool*</code> settings'''.}}
 
==== Database Retention Parameters ====


{| class="wikitable"
{| class="wikitable"
|-
|-
! Parameter !! Default Value !! Description
! Parameter !! Default !! Triggers When
|-
|-
| `cleandatabase` || `0` (disabled) || Master retention setting in days for CDRs and several other tables.
| <code>autocleanspoolminpercent</code> || 1 || Disk usage reaches 99%
|-
|-
| `cleandatabase_cdr` || `0` (disabled, uses cleandatabase) || Specific retention period for `cdr` and `message` tables.
| <code>autocleanmingb</code> || 5 || Free space below 5 GB
|}
 
When triggered, oldest data is deleted aggressively until thresholds are cleared. The <code>cleanspool_enable_fromto</code> time window is ignored.
 
=== Control Parameters ===
 
{| class="wikitable"
|-
|-
| `cleandatabase_rtp_stat` || `2` days || Retention in days for detailed RTP statistics.
! Parameter !! Default !! Description
|-
|-
| `cleandatabase_sip_msg` || `0` (disabled) || Retention for SIP OPTIONS/SUBSCRIBE/NOTIFY messages.
| <code>cleanspool</code> || yes || Enable/disable spool cleaning
|-
|-
| `cleandatabase_size` || (unset) || Alternative cleaning method that removes old data to stay below a total database size limit (in Megabytes). Requires sniffer version 2024.05.1 or newer.
| <code>cleanspool_enable_fromto</code> || 0-24 || Restrict cleaning to hours (e.g., <code>1-5</code> for 1-5 AM)
|-
|-
| `partition_operations_enable_fromto` || `1-5` || Restricts partition-dropping operations to a specific time window (e.g., 1 AM to 5 AM) to avoid impacting performance during peak hours.
| <code>maxpool_clean_obsolete</code> || no || Delete files not in index (use with caution)
|-
| <code>all_unlink_log</code> || no || Log all file deletions
|}
|}


=== The Legacy Method: Manual Deletion (Not Recommended) ===
=== Reducing Data at Source ===
If you are running a very old, non-partitioned database, you cannot use the `cleandatabase` option. You would need to create a custom script that runs a `DELETE FROM cdr WHERE calldate < ...` query.
 
* '''Warning:''' This method is extremely slow and resource-intensive on large tables. A single `DELETE` operation on millions of rows can take hours and generate significant I/O load on your database server, potentially impacting GUI performance.
==== Save RTP Headers Only ====
 
If you only need quality metrics (MOS, jitter, packet loss) without audio playback:
 
<syntaxhighlight lang="ini">
savertp = header
</syntaxhighlight>
 
This reduces storage by up to '''90%''' while preserving all quality statistics.


== 3. Troubleshooting Disk Space Issues ==


=== Disk Space Not Reclaimed After Cleanup ===


If you have configured automatic cleanup but disk space is not being freed from the MySQL data directory, the issue is likely related to the MySQL `innodb_file_per_table` setting. This setting controls whether each InnoDB table is stored in its own `.ibd` file or in the shared `ibdata1` file.
==== Disable RTP Entirely ====


'''Check the Current Setting:'''
If SIP signaling retention is the priority and you do not need RTP data at all:
<pre>
mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name        | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
</pre>


'''What This Means:'''
<syntaxhighlight lang="ini">
*'''If value is ON:''' Each table/partition is stored in its own file. When a partition is dropped, the file is deleted immediately, and disk space is reclaimed.
savertp = no
*'''If value is OFF when database was created:''' All table data is stored in the shared `ibdata1` file. Dropping partitions or rows will not reduce this file size.
</syntaxhighlight>


'''Solutions:'''
This disables RTP packet storage entirely, reducing PCAP size by approximately '''20x'''. Use this when:
* Storage limits are insufficient for even header-only RTP
* SIP troubleshooting is the primary need (no audio analysis required)
* You need to retain SIP signaling for much longer periods


''Option 1: Enable innodb_file_per_table (Preventative)''
{{Warning|Setting <code>savertp = no</code> removes all RTP data including quality statistics. Use <code>savertp = header</code> instead if you need MOS, jitter, or packet loss metrics.}}
Add to `/etc/my.cnf` or `/etc/mysql/my.cnf`:
==== Selective Recording ====
<pre>
[mysqld]
innodb_file_per_table = 1
</pre>
After changing this setting, restart MySQL:
<pre>
service mysql restart
</pre>
''Note: This only affects NEW tables/partitions. Existing data in `ibdata1` will remain.''


''Option 2: Reclaim Space from Existing Tables''
To record full audio only for specific calls:
If `innodb_file_per_table` is ON and you have partitioned tables, run:
# Set <code>savertp = header</code> globally
<pre>
# Create capture rules with <code>recordRTP=ON</code> for exceptions
OPTIMIZE TABLE cdr;
</pre>
'''Warning:''' This requires significant free disk space to duplicate the table data. If your disk is already nearly full, this command will fail or crash the database.


''Option 3: Export and Re-import (Complete Reclaim)''
See [[Capture_rules]] for details.
If `innodb_file_per_table` was OFF when the database was created and you must reclaim space:
<pre>
mysqldump -u root -p voipmonitor > voipmonitor_backup.sql
mysql -u root -p -e "DROP DATABASE voipmonitor; CREATE DATABASE voipmonitor;"
mysql -u root -p voipmonitor < voipmonitor_backup.sql
</pre>


=== Monitoring Database Health ===
== Database Cleaning (CDR Records) ==


To proactively monitor database health and detect issues before they become critical, use the following metrics and tools.
=== Partitioning Method ===


'''SQL Queue Metrics (SQLq/SQLf)'''
VoIPmonitor uses daily partitioning. Dropping old partitions is instant (milliseconds) regardless of row count.


The VoIPmonitor sensor tracks database queue metrics that indicate if the database is falling behind processing CDRs. These are visible in:
<syntaxhighlight lang="ini">
# Keep CDR records for 30 days
cleandatabase = 30
</syntaxhighlight>


* GUI: Settings → Sensors → Status (expanded status line)
=== Database Cleaning Parameters ===
* RRD files (if using collectd or similar)
* Sniffer's internal health monitoring logs


{| class="wikitable"
{| class="wikitable"
|-
|-
! Metric !! Description !! Healthy Range
! Parameter !! Default !! Description
|-
|-
| SQLq || SQL Queue count - number of CDRs waiting to be written to database || Near 0, sporadic spikes
| <code>cleandatabase</code> || 0 (disabled) || Global retention for CDR, register_state, register_failed, sip_msg
|-
|-
| SQLf || SQL Failed count - number of failed database write attempts || Zero (or very low, not growing)
| <code>cleandatabase_cdr</code> || 0 || CDR table (includes <code>message</code> table)
|-
| <code>cleandatabase_rtp_stat</code> || 2 || RTP statistics table
|-
| <code>cleandatabase_register_state</code> || 0 || Registration state
|-
| <code>cleandatabase_register_failed</code> || 0 || Failed registrations
|-
| <code>cleandatabase_register_time_info</code> || 0 || Registration timing ('''NOT''' covered by global)
|-
| <code>cleandatabase_sip_msg</code> || 0 || SIP messages (OPTIONS/SUBSCRIBE/NOTIFY)
|-
| <code>cleandatabase_ss7</code> || 0 || SS7 records
|-
| <code>partition_operations_enable_fromto</code> || 1-5 || Time window for partition operations (24h format)
|}
|}


'''Interpreting SQLq/SQLf:'''
{{Warning|1=<code>register_time_info</code> is NOT covered by global <code>cleandatabase</code>. Set <code>cleandatabase_register_time_info</code> explicitly.}}
* Occasionally high SQLq during traffic spikes is normal
* Consistently high or growing SQLq indicates the database cannot keep up
* Non-zero or growing SQLf indicates database errors or connectivity issues


For detailed troubleshooting of high SQL queue, see [[SQL_queue_is_growing_in_a_peaktime|SQL Queue Troubleshooting]].
=== Size-Based Cleaning ===


'''System Load Monitoring'''
To limit database by size instead of time:


Check overall system load average:
<syntaxhighlight lang="ini">
<pre>
cleandatabase_size = 512000        # 500 GB limit in MB
cat /proc/loadavg
cleandatabase_size_force = true    # Required to enable
</pre>
</syntaxhighlight>
The three numbers represent 1-minute, 5-minute, and 15-minute load averages. Consistently high load averages indicate CPU, I/O, or memory bottlenecks.


'''Disk I/O Monitoring'''
=== Multi-Sensor Environments ===


Use `iotop` to identify processes causing disk I/O bottlenecks:
When multiple sensors share a database, only '''ONE''' sensor should manage partitions:
<pre>
iotop -o
</pre>
The `-o` flag shows only processes with active I/O. Look for high I/O from `mysql` or `mysqld` processes, which may indicate slow storage or poorly tuned MySQL settings.


== 4. Recommended MySQL Performance Settings ==
<syntaxhighlight lang="ini">
# On all sensors EXCEPT one:
disable_partition_operations = yes


For high-performance database operations (especially with partitioning enabled), ensure your MySQL configuration includes these critical settings:
# On the designated sensor:
partition_operations_enable_fromto = 4-6
</syntaxhighlight>


<pre>
=== Limits ===
 
* '''MySQL/MariaDB partition limit:''' ~8000 partitions per table (~22 years with daily partitioning)
* '''Aurora DB partition limit:''' ~800 partitions per table - much lower than standard MySQL
* '''CDR record limit:''' No practical limit - uses BIGINT
 
=== Aurora DB / Limited Partition Environments ===
 
For databases with low partition limits (like Amazon Aurora), you can pre-create partitions before starting the sniffer and prevent runtime partition creation:
 
<syntaxhighlight lang="ini">
# Pre-create partitions up to a specific date before starting
create_new_partitions_until = 2026-01-31
 
# Disable only partition creation (dropping still works for cleanup)
disable_partition_operations_create = yes
 
# Or disable only partition dropping (creation still works)
# disable_partition_operations_drop = yes
 
# Number of partitions to create ahead (default 2)
create_new_partitions = 2
</syntaxhighlight>
 
{{Note|1=For Aurora DB with ~800 partition limit: with daily partitions, this gives ~2 years of data. Plan retention accordingly using <code>cleandatabase</code>.}}
 
== Advanced Topics ==
 
=== Spool Directory Location ===
 
Default: <code>/var/spool/voipmonitor</code>
 
Structure: <code>YYYY-MM-DD/HH/MM/{SIP|RTP|GRAPH|AUDIO}/files...</code>
 
==== Relocating the Spool ====
 
<syntaxhighlight lang="bash">
# 1. Create new directory
mkdir -p /mnt/storage/voipmonitor
chown voipmonitor:voipmonitor /mnt/storage/voipmonitor
 
# 2. Update sniffer config
# /etc/voipmonitor.conf:
# spooldir = /mnt/storage/voipmonitor
 
# 3. Update GUI config (config/configuration.php):
# define('SNIFFER_DATA_PATH', '/mnt/storage/voipmonitor');
 
# 4. Restart
systemctl restart voipmonitor
</syntaxhighlight>
 
=== Tiered Storage (tar_move) ===
 
Extend retention using secondary storage:
 
<syntaxhighlight lang="ini">
spooldir = /var/spool/voipmonitor
tar_move = yes
tar_move_destination_path = /mnt/archive/voipmonitor
</syntaxhighlight>
 
Files in secondary storage remain accessible via GUI.
 
==== S3 Cloud Storage ====
 
Use <code>rclone</code> instead of <code>s3fs</code> to avoid GUI unresponsiveness:
 
<syntaxhighlight lang="bash">
rclone mount bucket-name /mnt/s3-archive \
  --allow-other --dir-cache-time 30s --vfs-cache-mode off
</syntaxhighlight>
 
=== Custom Autocleaning (GUI) ===
 
For one-time cleanup of specific recordings (by IP, phone number, etc.):
# Navigate to Settings > Custom Autocleaning
# Create rule with filters
# Apply and remove rule after completion
 
== Troubleshooting ==
 
=== Files Disappearing Faster Than Expected ===
 
;1. Check if emergency cleanup is active
<syntaxhighlight lang="bash">
df -h /var/spool/voipmonitor
# If >95% full, emergency cleanup is running
</syntaxhighlight>
 
;2. Check GUI configuration override
When <code>mysqlloadconfig = yes</code> (default), GUI settings override config file. Check: Settings > Sensors > wrench icon.
 
;3. Set appropriate limits
Set <code>maxpoolsize</code> to 90-95% of disk capacity to leave buffer for growth.
 
=== Disk Space Not Reclaimed After Database Cleanup ===
 
Check <code>innodb_file_per_table</code>:
 
<syntaxhighlight lang="sql">
SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';
</syntaxhighlight>
 
If OFF, enable in <code>my.cnf</code>:
 
<syntaxhighlight lang="ini">
[mysqld]
[mysqld]
# Use 50-70% of available RAM for caching
innodb_file_per_table = 1
innodb_buffer_pool_size = 4G
</syntaxhighlight>


# Flush logs to OS every second (faster, safe for VoIPmonitor)
=== MySQL Error 28: No Space Left ===
innodb_flush_log_at_trx_commit = 2
 
Enable size-based cleaning:
 
<syntaxhighlight lang="ini">
cleandatabase_size = 512000
cleandatabase_size_force = true
</syntaxhighlight>
 
Other causes: Inode exhaustion (<code>df -i</code>), MySQL tmpdir full.
 
=== Verify Database Cleaning ===
 
<syntaxhighlight lang="sql">
SELECT PARTITION_NAME, TABLE_ROWS
FROM information_schema.PARTITIONS
WHERE TABLE_NAME = 'cdr'
ORDER BY PARTITION_ORDINAL_POSITION DESC
LIMIT 10;
</syntaxhighlight>
 
If partition count matches your <code>cleandatabase</code> setting, cleaning IS working.
 
For SQL queue issues and database performance, see [[Database_troubleshooting]].
 
== See Also ==
 
* [[Sniffer_configuration]] - Full parameter reference
* [[Database_troubleshooting]] - SQL queue, performance issues
* [[Scaling]] - Performance tuning
* [[Capture_rules]] - Selective recording


# Enable per-table filespace for easy space reclamation
innodb_file_per_table = 1
</pre>


For comprehensive performance tuning guidelines, see the [[Scaling|Scaling and Performance guide]].


== AI Summary for RAG ==
== AI Summary for RAG ==
'''Summary:''' This article explains the two distinct data retention mechanisms in VoIPmonitor: filesystem cleaning for PCAP files and database cleaning for CDRs. For filesystem storage in the `spooldir`, it details the various `maxpoolsize` and `maxpooldays` configuration options that control the retention of SIP, RTP, and other files based on size or age. It also describes the `reindexfiles` manager command for troubleshooting cases where old files are not being deleted. For database retention, it explains the modern partitioning approach with `cleandatabase` parameters (day-based and size-based), partitioning configuration, and scheduling via `partition_operations_enable_fromto`. It includes troubleshooting guidance for disk space not being reclaimed due to `innodb_file_per_table` settings, with solutions including OPTIMIZE TABLE and database export/import. It also provides monitoring guidance using SQLq/SQLf metrics from health charts and system monitoring tools like `iotop` and `cat /proc/loadavg`, and recommends key MySQL performance settings.
 
'''Keywords:''' data retention, cleaning, delete old calls, purge data, disk space, spooldir, maxpoolsize, maxpooldays, pcap, filesystem, database, cdr, cleandatabase, cleandatabase_size, partitioning, reindexfiles, manager api, innodb_file_per_table, SQLq, SQLf, monitoring, iotop, database health, mysql performance
'''Summary:''' VoIPmonitor has two independent data retention systems: (1) Cleanspool for PCAP files using <code>maxpoolsize</code>/<code>maxpooldays</code> parameters, running every 5 minutes with in-memory file index; (2) Database cleaning using <code>cleandatabase</code> with instant partition dropping. Key space-saving option: <code>savertp = header</code> reduces storage by 90% while keeping quality metrics. Emergency cleanup (<code>autocleanspoolminpercent=1</code>, <code>autocleanmingb=5</code>) activates when disk nearly full and ignores normal limits. GUI settings override config file when <code>mysqlloadconfig=yes</code>. Size-based database cleaning requires BOTH <code>cleandatabase_size</code> AND <code>cleandatabase_size_force=true</code>. In multi-sensor environments, only one sensor should manage partitions (<code>disable_partition_operations=yes</code> on others).
 
'''Keywords:''' data retention, maxpoolsize, maxpooldays, maxpoolrtpsize, cleandatabase, cleandatabase_size, cleandatabase_size_force, cleanspool, autocleanspoolminpercent, autocleanmingb, tar_move, tiered storage, savertp header, innodb_file_per_table, partition dropping, emergency cleanup, mysqlloadconfig, disable_partition_operations
 
'''Key Questions:'''
'''Key Questions:'''
* How do I automatically delete old PCAP files to free up disk space?
* How does VoIPmonitor cleanspool work?
* What is the difference between `maxpoolsize` and `maxpooldays`?
* How to configure PCAP file retention?
* My spool directory is full, but old files are not being deleted. How do I fix it?
* How to limit database size?
* How do I automatically delete old CDRs from the database?
* Why are files being deleted faster than expected?
* What is the `cleandatabase` option and how does it work?
* How to fix MySQL Error 28 no space left?
* Why is database partitioning important for VoIPmonitor?
* How to reduce storage usage (savertp header)?
* What is `cleandatabase_size` and how does it differ from `cleandatabase`?
* How to configure tiered storage?
* Disk space is not reclaimed after cleanup. What should i check?
* Why is disk space not reclaimed after cleanup?
* What do SQLq and SQLf metrics mean in the health status?
* How to manage partitions in multi-sensor environment?
* How do I monitor database health and performance?
* Why does MySQL not free disk space after dropping partitions?

Latest revision as of 12:10, 22 January 2026


This guide explains how VoIPmonitor manages data retention for PCAP files and database records.

Overview

VoIPmonitor generates two types of data requiring periodic cleanup:

Data Type Storage Cleanup Mechanism Key Parameters
PCAP Files Filesystem (spool directory) Cleanspool process (every 5 min) maxpoolsize, maxpooldays
CDR Records MySQL database Partition dropping (instant) cleandatabase

ℹ️ Note: These are independent systems - filesystem cleanup does not affect database records and vice versa.

Quick Reference

Purpose Parameter Example
Limit total PCAP size maxpoolsize maxpoolsize = 512000 (500 GB)
Limit RTP specifically maxpoolrtpsize maxpoolrtpsize = 102400 (100 GB)
Limit PCAP age maxpooldays maxpooldays = 30
CDR retention (days) cleandatabase cleandatabase = 30
CDR retention (size) cleandatabase_size cleandatabase_size = 512000 (+ cleandatabase_size_force = true)
Save only RTP stats savertp savertp = header (saves ~90% space)

Filesystem Cleaning (PCAP Files)

How Cleanspool Works

The sniffer maintains a file index in memory. Every 5 minutes, the cleanspool thread checks retention limits and deletes the oldest files when limits are exceeded.

The .cleanspool_cache files in hourly directories serve as persistent storage for fast restart - they allow quick index reload without scanning the entire filesystem.

ℹ️ Note: Legacy Indexing: Old VoIPmonitor versions stored metadata in MySQL files table. This can be enabled with cleanspool_use_files = yes (deprecated, do not use).

Retention Configuration

Limits can be set by size (MB) or age (days). When both are configured, the first limit reached triggers cleanup.

Global Limits

Parameter Default Description
maxpoolsize 102400 (100 GB) Maximum total size for all PCAP data
maxpooldays (unset) Maximum age in days for all PCAP data

Per-Type Limits

Data Type Size Parameter Days Parameter
SIP signaling maxpoolsipsize maxpoolsipdays
RTP audio maxpoolrtpsize maxpoolrtpdays
Quality graphs maxpoolgraphsize maxpoolgraphdays
Converted audio (WAV/OGG) maxpoolaudiosize maxpoolaudiodays

Recommended Configuration

Limit RTP (largest files) while keeping SIP longer for troubleshooting:

# /etc/voipmonitor.conf
maxpoolrtpsize = 102400   # 100 GB limit for RTP
maxpoolsize = 512000      # 500 GB overall limit

Secondary Storage Limits (spooldir_2)

When using spooldir_2 for secondary storage (configured via capture rules with "Store pcaps to second spooldir" enabled), use _2 suffix parameters for cleaning:

maxpoolsize_2, maxpooldays_2, maxpoolrtpsize_2, etc.

ℹ️ Note: spooldir_2 is independent from tar_move. The _2 suffix parameters apply only to the secondary spooldir configured via capture rules, not to tar_move destination storage.

Emergency Cleanup

⚠️ Warning: Emergency cleanup activates when disk is nearly full and ignores all maxpool* settings.

Parameter Default Triggers When
autocleanspoolminpercent 1 Disk usage reaches 99%
autocleanmingb 5 Free space below 5 GB

When triggered, oldest data is deleted aggressively until thresholds are cleared. The cleanspool_enable_fromto time window is ignored.

Control Parameters

Parameter Default Description
cleanspool yes Enable/disable spool cleaning
cleanspool_enable_fromto 0-24 Restrict cleaning to hours (e.g., 1-5 for 1-5 AM)
maxpool_clean_obsolete no Delete files not in index (use with caution)
all_unlink_log no Log all file deletions

Reducing Data at Source

Save RTP Headers Only

If you only need quality metrics (MOS, jitter, packet loss) without audio playback:

savertp = header

This reduces storage by up to 90% while preserving all quality statistics.


Disable RTP Entirely

If SIP signaling retention is the priority and you do not need RTP data at all:

savertp = no

This disables RTP packet storage entirely, reducing PCAP size by approximately 20x. Use this when:

  • Storage limits are insufficient for even header-only RTP
  • SIP troubleshooting is the primary need (no audio analysis required)
  • You need to retain SIP signaling for much longer periods

⚠️ Warning:

Selective Recording

To record full audio only for specific calls:

  1. Set savertp = header globally
  2. Create capture rules with recordRTP=ON for exceptions

See Capture_rules for details.

Database Cleaning (CDR Records)

Partitioning Method

VoIPmonitor uses daily partitioning. Dropping old partitions is instant (milliseconds) regardless of row count.

# Keep CDR records for 30 days
cleandatabase = 30

Database Cleaning Parameters

Parameter Default Description
cleandatabase 0 (disabled) Global retention for CDR, register_state, register_failed, sip_msg
cleandatabase_cdr 0 CDR table (includes message table)
cleandatabase_rtp_stat 2 RTP statistics table
cleandatabase_register_state 0 Registration state
cleandatabase_register_failed 0 Failed registrations
cleandatabase_register_time_info 0 Registration timing (NOT covered by global)
cleandatabase_sip_msg 0 SIP messages (OPTIONS/SUBSCRIBE/NOTIFY)
cleandatabase_ss7 0 SS7 records
partition_operations_enable_fromto 1-5 Time window for partition operations (24h format)

⚠️ Warning: register_time_info is NOT covered by global cleandatabase. Set cleandatabase_register_time_info explicitly.

Size-Based Cleaning

To limit database by size instead of time:

cleandatabase_size = 512000        # 500 GB limit in MB
cleandatabase_size_force = true    # Required to enable

Multi-Sensor Environments

When multiple sensors share a database, only ONE sensor should manage partitions:

# On all sensors EXCEPT one:
disable_partition_operations = yes

# On the designated sensor:
partition_operations_enable_fromto = 4-6

Limits

  • MySQL/MariaDB partition limit: ~8000 partitions per table (~22 years with daily partitioning)
  • Aurora DB partition limit: ~800 partitions per table - much lower than standard MySQL
  • CDR record limit: No practical limit - uses BIGINT

Aurora DB / Limited Partition Environments

For databases with low partition limits (like Amazon Aurora), you can pre-create partitions before starting the sniffer and prevent runtime partition creation:

# Pre-create partitions up to a specific date before starting
create_new_partitions_until = 2026-01-31

# Disable only partition creation (dropping still works for cleanup)
disable_partition_operations_create = yes

# Or disable only partition dropping (creation still works)
# disable_partition_operations_drop = yes

# Number of partitions to create ahead (default 2)
create_new_partitions = 2

ℹ️ Note: For Aurora DB with ~800 partition limit: with daily partitions, this gives ~2 years of data. Plan retention accordingly using cleandatabase.

Advanced Topics

Spool Directory Location

Default: /var/spool/voipmonitor

Structure: YYYY-MM-DD/HH/MM/{SIP|RTP|GRAPH|AUDIO}/files...

Relocating the Spool

# 1. Create new directory
mkdir -p /mnt/storage/voipmonitor
chown voipmonitor:voipmonitor /mnt/storage/voipmonitor

# 2. Update sniffer config
# /etc/voipmonitor.conf:
# spooldir = /mnt/storage/voipmonitor

# 3. Update GUI config (config/configuration.php):
# define('SNIFFER_DATA_PATH', '/mnt/storage/voipmonitor');

# 4. Restart
systemctl restart voipmonitor

Tiered Storage (tar_move)

Extend retention using secondary storage:

spooldir = /var/spool/voipmonitor
tar_move = yes
tar_move_destination_path = /mnt/archive/voipmonitor

Files in secondary storage remain accessible via GUI.

S3 Cloud Storage

Use rclone instead of s3fs to avoid GUI unresponsiveness:

rclone mount bucket-name /mnt/s3-archive \
  --allow-other --dir-cache-time 30s --vfs-cache-mode off

Custom Autocleaning (GUI)

For one-time cleanup of specific recordings (by IP, phone number, etc.):

  1. Navigate to Settings > Custom Autocleaning
  2. Create rule with filters
  3. Apply and remove rule after completion

Troubleshooting

Files Disappearing Faster Than Expected

1. Check if emergency cleanup is active
df -h /var/spool/voipmonitor
# If >95% full, emergency cleanup is running
2. Check GUI configuration override

When mysqlloadconfig = yes (default), GUI settings override config file. Check: Settings > Sensors > wrench icon.

3. Set appropriate limits

Set maxpoolsize to 90-95% of disk capacity to leave buffer for growth.

Disk Space Not Reclaimed After Database Cleanup

Check innodb_file_per_table:

SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';

If OFF, enable in my.cnf:

[mysqld]
innodb_file_per_table = 1

MySQL Error 28: No Space Left

Enable size-based cleaning:

cleandatabase_size = 512000
cleandatabase_size_force = true

Other causes: Inode exhaustion (df -i), MySQL tmpdir full.

Verify Database Cleaning

SELECT PARTITION_NAME, TABLE_ROWS
FROM information_schema.PARTITIONS
WHERE TABLE_NAME = 'cdr'
ORDER BY PARTITION_ORDINAL_POSITION DESC
LIMIT 10;

If partition count matches your cleandatabase setting, cleaning IS working.

For SQL queue issues and database performance, see Database_troubleshooting.

See Also


AI Summary for RAG

Summary: VoIPmonitor has two independent data retention systems: (1) Cleanspool for PCAP files using maxpoolsize/maxpooldays parameters, running every 5 minutes with in-memory file index; (2) Database cleaning using cleandatabase with instant partition dropping. Key space-saving option: savertp = header reduces storage by 90% while keeping quality metrics. Emergency cleanup (autocleanspoolminpercent=1, autocleanmingb=5) activates when disk nearly full and ignores normal limits. GUI settings override config file when mysqlloadconfig=yes. Size-based database cleaning requires BOTH cleandatabase_size AND cleandatabase_size_force=true. In multi-sensor environments, only one sensor should manage partitions (disable_partition_operations=yes on others).

Keywords: data retention, maxpoolsize, maxpooldays, maxpoolrtpsize, cleandatabase, cleandatabase_size, cleandatabase_size_force, cleanspool, autocleanspoolminpercent, autocleanmingb, tar_move, tiered storage, savertp header, innodb_file_per_table, partition dropping, emergency cleanup, mysqlloadconfig, disable_partition_operations

Key Questions:

  • How does VoIPmonitor cleanspool work?
  • How to configure PCAP file retention?
  • How to limit database size?
  • Why are files being deleted faster than expected?
  • How to fix MySQL Error 28 no space left?
  • How to reduce storage usage (savertp header)?
  • How to configure tiered storage?
  • Why is disk space not reclaimed after cleanup?
  • How to manage partitions in multi-sensor environment?