Data Cleaning: Difference between revisions

From VoIPmonitor.org
(Add spooldir relocation guide and cleandatabase_size_force details)
(Fix incorrect association of _2 parameters with tar_move - they are for spooldir_2 used with capture rules (TP-38))
 
(50 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]]
 
This guide explains how VoIPmonitor manages data retention for PCAP files and database records.


== Overview ==
== Overview ==


VoIPmonitor generates two primary types of data that require periodic cleaning:
VoIPmonitor generates two types of data requiring periodic cleanup:
* '''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:
{| class="wikitable"
|-
! 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>
|}


<kroki lang="plantuml">
{{Note|These are '''independent systems''' - filesystem cleanup does not affect database records and vice versa.}}
@startuml
skinparam shadowing false
skinparam defaultFontName Arial
skinparam rectangle {
  BorderColor #4A90E2
  BackgroundColor #FFFFFF
}


rectangle "VoIPmonitor Sensor" as sensor
=== Quick Reference ===


package "Filesystem Storage" {
{| class="wikitable"
  folder "/var/spool/voipmonitor" as spool {
|-
    file "SIP PCAPs" as sip
! Purpose !! Parameter !! Example
    file "RTP PCAPs" as rtp
|-
    file "GRAPH files" as graph
| Limit total PCAP size || <code>maxpoolsize</code> || <code>maxpoolsize = 512000</code> (500 GB)
    file "AUDIO files" as audio
|-
  }
| Limit RTP specifically || <code>maxpoolrtpsize</code> || <code>maxpoolrtpsize = 102400</code> (100 GB)
}
|-
| Limit PCAP age || <code>maxpooldays</code> || <code>maxpooldays = 30</code>
|-
| CDR retention (days) || <code>cleandatabase</code> || <code>cleandatabase = 30</code>
|-
| 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)
|}


database "MySQL Database" {
== Filesystem Cleaning (PCAP Files) ==
  collections "cdr" as cdr
  collections "cdr_next" as cdrnext
  collections "register_state" as reg
  collections "sip_msg" as sipmsg
}


sensor --> spool : writes
=== How Cleanspool Works ===
sensor --> cdr : writes


rectangle "Filesystem Cleaner\n(maxpoolsize/maxpooldays)" as fscleaner #E8F5E9
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.
rectangle "Database Cleaner\n(cleandatabase)" as dbcleaner #E3F2FD


fscleaner --> spool : deletes old files
<kroki lang="plantuml">
dbcleaner --> cdr : drops partitions
@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


note bottom of fscleaner : Runs every 5 minutes\nDeletes oldest data first
S -> FS: Write PCAP
note bottom of dbcleaner : Daily partition drop\nInstant operation
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
@enduml
</kroki>
</kroki>


== Filesystem Cleaning (PCAP Spool Directory) ==
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.


The sensor stores captured call data in a structured directory tree on the local 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).}}


=== Reducing Data Collection at Source ===
=== Retention Configuration ===


Before configuring cleanup policies, consider reducing the amount of data captured. This is often the most effective long-term solution for storage management.
Limits can be set by '''size''' (MB) or '''age''' (days). When both are configured, the first limit reached triggers cleanup.


==== Save Only RTP Headers (Major Space Saver) ====
==== Global Limits ====


RTP packets typically contain the full audio payload, which consumes the majority of disk space. If you only need call quality statistics (MOS, jitter, packet loss) and not actual audio playback, switch to saving RTP headers only.
{| class="wikitable"
|-
! Parameter !! Default !! Description
|-
| <code>maxpoolsize</code> || 102400 (100 GB) || Maximum total size for all PCAP data
|-
| <code>maxpooldays</code> || (unset) || Maximum age in days for all PCAP data
|}


Edit <code>/etc/voipmonitor.conf</code>:
==== Per-Type Limits ====
 
<syntaxhighlight lang="ini">
# Change from full RTP to headers only
savertp = header
</syntaxhighlight>


{| class="wikitable"
{| class="wikitable"
|-
|-
! Setting !! Storage Impact !! Use Case
! Data Type !! Size Parameter !! Days Parameter
|-
|-
| <code>savertp = yes</code> || High (~10x more) || Requires ability to play back audio from PCAPs
| SIP signaling || <code>maxpoolsipsize</code> || <code>maxpoolsipdays</code>
|-
|-
| <code>savertp = header</code> || Low || Only CDR statistics needed, no audio playback required
| RTP audio || <code>maxpoolrtpsize</code> || <code>maxpoolrtpdays</code>
|-
| Quality graphs || <code>maxpoolgraphsize</code> || <code>maxpoolgraphdays</code>
|-
| Converted audio (WAV/OGG) || <code>maxpoolaudiosize</code> || <code>maxpoolaudiodays</code>
|}
|}


With <code>savertp = header</code>, VoIPmonitor still captures all necessary metadata for MOS scoring, jitter analysis, packet loss statistics, and quality graphs, but does not store the actual audio payload. This can reduce storage consumption by up to 90%.
==== Recommended Configuration ====
 
Limit RTP (largest files) while keeping SIP longer for troubleshooting:
 
<syntaxhighlight lang="ini">
# /etc/voipmonitor.conf
maxpoolrtpsize = 102400  # 100 GB limit for RTP
maxpoolsize = 512000      # 500 GB overall limit
</syntaxhighlight>
 
==== Secondary Storage Limits (spooldir_2) ====


'''Important:''' After changing from <code>savertp = yes</code> to <code>savertp = header</code>, existing PCAP files will remain playable. New calls will only contain RTP headers.
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 more configuration options, see [[Sniffer_configuration#Saving_Options|Sniffer Configuration - Saving Options]].
<code>maxpoolsize_2</code>, <code>maxpooldays_2</code>, <code>maxpoolrtpsize_2</code>, etc.


=== Spool Directory Location ===
{{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.}}
 
=== Emergency Cleanup ===
 
{{Warning|1=Emergency cleanup activates when disk is nearly full and '''ignores all <code>maxpool*</code> settings'''.}}


By default, all data is stored in <code>/var/spool/voipmonitor</code>. This location can be changed by setting the <code>spooldir</code> option in <code>voipmonitor.conf</code>.
{| class="wikitable"
|-
! Parameter !! Default !! Triggers When
|-
| <code>autocleanspoolminpercent</code> || 1 || Disk usage reaches 99%
|-
| <code>autocleanmingb</code> || 5 || Free space below 5 GB
|}


==== Relocating the Spool Directory to a Different Partition ====
When triggered, oldest data is deleted aggressively until thresholds are cleared. The <code>cleanspool_enable_fromto</code> time window is ignored.


If your default partition is running out of space, you can move the spool directory to a larger partition or dedicated disk. This is particularly useful when MySQL Error 28 ("No space left on device") occurs despite retention settings being in place.
=== Control Parameters ===


{| class="wikitable"
{| class="wikitable"
|-
|-
! Situation !! Recommended Action
! Parameter !! Default !! Description
|-
|-
| <code>/var/lib/mysql</code> full but other partitions available || Move spool to larger partition and update <code>spooldir</code> in <code>voipmonitor.conf</code>
| <code>cleanspool</code> || yes || Enable/disable spool cleaning
|-
|-
| Multiple disks available || Use dedicated partition for PCAP storage
| <code>cleanspool_enable_fromto</code> || 0-24 || Restrict cleaning to hours (e.g., <code>1-5</code> for 1-5 AM)
|-
|-
| GUI on same server || Sync GUI <code>SNIFFER_DATA_PATH</code> to match new <code>spooldir</code>
| <code>maxpool_clean_obsolete</code> || no || Delete files not in index (use with caution)
|-
| <code>all_unlink_log</code> || no || Log all file deletions
|}
|}


===== Procedure to Relocate Spooldir =====
=== Reducing Data at Source ===


;Step 1: Identify Available Space
==== Save RTP Headers Only ====
Check all partitions to find a suitable location:
<syntaxhighlight lang="bash">
df -h
</syntaxhighlight>


;Step 2: Create New Spool Directory
If you only need quality metrics (MOS, jitter, packet loss) without audio playback:
Create the directory on the destination partition:
<syntaxhighlight lang="bash">
# Example: Use /mnt/pcaps partition
mkdir -p /mnt/pcaps/voipmonitor
 
# Set correct ownership for both sniffer and GUI access
chown voipmonitor:voipmonitor /mnt/pcaps/voipmonitor
chmod 755 /mnt/pcaps/voipmonitor
</syntaxhighlight>


;Step 3: Update VoIPmonitor Configuration
Edit <code>/etc/voipmonitor.conf</code> to point to the new location:
<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
[general]
savertp = header
spooldir = /mnt/pcaps/voipmonitor
</syntaxhighlight>
</syntaxhighlight>


;Step 4: Update GUI Configuration (Critical)
This reduces storage by up to '''90%''' while preserving all quality statistics.


If the GUI runs on the same server, you MUST update the path the GUI uses to access the spool. This is defined in the GUI configuration file:


* Debian/Ubuntu: <code>/var/www/html/voipmonitor/config/configuration.php</code>
* RHEL/CentOS: <code>/var/www/voipmonitor/config/configuration.php</code>


Edit the GUI configuration file:
==== Disable RTP Entirely ====
<syntaxhighlight lang="php">
// Find and update this line to match your new spooldir
define('SNIFFER_DATA_PATH', '/mnt/pcaps/voipmonitor');
</syntaxhighlight>


'''Important:''' The <code>SNIFFER_DATA_PATH</code> in the GUI config MUST match the <code>spooldir</code> setting in <code>voipmonitor.conf</code>. If these are mismatched, the GUI will be unable to locate and display call recordings.
If SIP signaling retention is the priority and you do not need RTP data at all:


;Step 5: Restart Services
<syntaxhighlight lang="ini">
Apply all changes by restarting the services:
savertp = no
<syntaxhighlight lang="bash">
</syntaxhighlight>
# Restart the VoIPmonitor sensor
systemctl restart voipmonitor


# If using Apache/Nginx, reload web server
This disables RTP packet storage entirely, reducing PCAP size by approximately '''20x'''. Use this when:
systemctl reload apache2    # Debian/Ubuntu
* Storage limits are insufficient for even header-only RTP
# or
* SIP troubleshooting is the primary need (no audio analysis required)
systemctl reload nginx      # RHEL/CentOS
* You need to retain SIP signaling for much longer periods
</syntaxhighlight>


;Step 6: Verify Configuration
{{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.}}
<syntaxhighlight lang="bash">
==== Selective Recording ====
# Check if new spool directory is being used
ls -ld /mnt/pcaps/voipmonitor


# Verify GUI can access the path
To record full audio only for specific calls:
grep SNIFFER_DATA_PATH /path/to/gui/config/configuration.php
# Set <code>savertp = header</code> globally
# Create capture rules with <code>recordRTP=ON</code> for exceptions


# Check sensor logs for any spool-related errors
See [[Capture_rules]] for details.
tail -f /var/log/voipmonitor.log
</syntaxhighlight>


===== Optional: Move Existing Data =====
== Database Cleaning (CDR Records) ==


If you want to migrate existing PCAP files to the new location:
=== Partitioning Method ===
<syntaxhighlight lang="bash">
# Stop the sensor to prevent writes during migration
systemctl stop voipmonitor


# Move existing data (this may take a long time)
VoIPmonitor uses daily partitioning. Dropping old partitions is instant (milliseconds) regardless of row count.
mv /var/spool/voipmonitor/* /mnt/pcaps/voipmonitor/


# Restart the sensor
<syntaxhighlight lang="ini">
systemctl start voipmonitor
# Keep CDR records for 30 days
cleandatabase = 30
</syntaxhighlight>
</syntaxhighlight>


=== Retention Configuration ===
=== Database Cleaning Parameters ===
 
The cleaning process runs automatically every 5 minutes and removes the oldest data based on the rules you define in <code>voipmonitor.conf</code>. 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.


{| class="wikitable"
{| class="wikitable"
|-
|-
! Parameter !! Default Value !! Description
! Parameter !! Default !! Description
|-
|-
| <code>maxpoolsize</code> || 102400 (100 GB) || The total maximum disk space for '''all''' captured data (SIP, RTP, GRAPH, AUDIO).
| <code>cleandatabase</code> || 0 (disabled) || Global retention for CDR, register_state, register_failed, sip_msg
|-
|-
| <code>maxpooldays</code> || (unset) || The maximum number of days to keep '''all''' captured data.
| <code>cleandatabase_cdr</code> || 0 || CDR table (includes <code>message</code> table)
|-
|-
| <code>maxpoolsipsize</code> || (unset) || A specific size limit for SIP PCAP files only.
| <code>cleandatabase_rtp_stat</code> || 2 || RTP statistics table
|-
|-
| <code>maxpoolsipdays</code> || (unset) || A specific age limit for SIP PCAP files only.
| <code>cleandatabase_register_state</code> || 0 || Registration state
|-
|-
| <code>maxpoolrtpsize</code> || (unset) || A specific size limit for RTP PCAP files only.
| <code>cleandatabase_register_failed</code> || 0 || Failed registrations
|-
|-
| <code>maxpoolrtpdays</code> || (unset) || A specific age limit for RTP PCAP files only.
| <code>cleandatabase_register_time_info</code> || 0 || Registration timing ('''NOT''' covered by global)
|-
|-
| <code>maxpoolgraphsize</code> || (unset) || A specific size limit for GRAPH files only.
| <code>cleandatabase_sip_msg</code> || 0 || SIP messages (OPTIONS/SUBSCRIBE/NOTIFY)
|-
|-
| <code>maxpoolgraphdays</code> || (unset) || A specific age limit for GRAPH files only.
| <code>cleandatabase_ss7</code> || 0 || SS7 records
|-
|-
| <code>maxpoolaudiosize</code> || (unset) || A specific size limit for converted audio files (WAV/OGG) only.
| <code>partition_operations_enable_fromto</code> || 1-5 || Time window for partition operations (24h format)
|-
| <code>maxpoolaudiodays</code> || (unset) || An age limit for converted audio files (WAV/OGG) only.
|}
|}


=== Understanding Directory Size Differences (SIP vs RTP Retention) ===
{{Warning|1=<code>register_time_info</code> is NOT covered by global <code>cleandatabase</code>. Set <code>cleandatabase_register_time_info</code> explicitly.}}


If you configure different retention periods for SIP and RTP data (for example, <code>maxpoolsipdays = 90</code> and <code>maxpoolrtpdays = 30</code>), you will notice a significant size difference between directories within different time windows.
=== Size-Based Cleaning ===


{| class="wikitable"
To limit database by size instead of time:
|-
! Age of Directory !! Contents !! Size
|-
| 0-30 days || Both SIP and RTP PCAP files || Large
|-
| 30-90 days || SIP PCAP files only (RTP deleted) || Smaller
|-
| 90+ days || None (both SIP and RTP deleted) || Empty or absent
|}


This behavior is '''expected and by design''':
<syntaxhighlight lang="ini">
cleandatabase_size = 512000        # 500 GB limit in MB
cleandatabase_size_force = true    # Required to enable
</syntaxhighlight>


* Directories within the <code>maxpoolrtpdays</code> retention window contain both SIP and RTP data, making them significantly larger (often 5-10x larger).
=== Multi-Sensor Environments ===
* Directories older than <code>maxpoolrtpdays</code> but within <code>maxpoolsipdays</code> contain only SIP data, so they are much smaller.
* The automatic cleanup process removes RTP files after <code>maxpoolrtpdays</code> and SIP files after <code>maxpoolsipdays</code>.


This is not an error or configuration issue. It is the expected result of having different retention periods for different data types.
When multiple sensors share a database, only '''ONE''' sensor should manage partitions:


==== Diagnosis: Compare Directory Sizes ====
<syntaxhighlight lang="ini">
 
# On all sensors EXCEPT one:
To verify this behavior, check your spool directory:
disable_partition_operations = yes
 
<syntaxhighlight lang="bash">
cd /var/spool/voipmonitor


# Show directories sorted by size
# On the designated sensor:
du -h --max-depth=1 ./ | sort -rh | head -20
partition_operations_enable_fromto = 4-6
 
# Example output:
# 80G    ./2025-01          # Current month (has SIP+RTP)
# 15G    ./2024-12          # Previous month (SIP only, RTP deleted)
# 120G  .
</syntaxhighlight>
</syntaxhighlight>


Compare with your configuration:
=== Limits ===


<syntaxhighlight lang="bash">
* '''MySQL/MariaDB partition limit:''' ~8000 partitions per table (~22 years with daily partitioning)
grep -E "maxpoolsip|maxpoolrtp" /etc/voipmonitor.conf
* '''Aurora DB partition limit:''' ~800 partitions per table - much lower than standard MySQL
* '''CDR record limit:''' No practical limit - uses BIGINT


# Example configuration:
=== Aurora DB / Limited Partition Environments ===
# maxpoolsipdays = 90    # SIP kept for 90 days
# maxpoolrtpdays = 30    # RTP kept for 30 days
</syntaxhighlight>


If the size difference matches your retention configuration, this is expected behavior and no action is needed.
For databases with low partition limits (like Amazon Aurora), you can pre-create partitions before starting the sniffer and prevent runtime partition creation:


=== Troubleshooting: Disk Full / Files Disappearing ===
<syntaxhighlight lang="ini">
 
# Pre-create partitions up to a specific date before starting
If you see errors when attempting to extract older calls from the GUI, or if call files are disappearing too quickly, your spool directory may have reached its size limit.
create_new_partitions_until = 2026-01-31


==== Diagnosis: Check Disk Usage ====
# Disable only partition creation (dropping still works for cleanup)
disable_partition_operations_create = yes


# Identify the sensor/probe responsible for the missing data.
# Or disable only partition dropping (creation still works)
# SSH into the sensor/probe and navigate to the spooldir.
# disable_partition_operations_drop = yes
# Check the disk usage:
<syntaxhighlight lang="bash">
cd /var/spool/voipmonitor
du -h --max-depth=1 ./


# Example output:
# Number of partitions to create ahead (default 2)
# 150G    ./2025-01
create_new_partitions = 2
# 120G    ./2024-12
# 90G    ./2024-11
# 360G    .
</syntaxhighlight>
</syntaxhighlight>


# Compare with the configured limit:
{{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>.}}
<syntaxhighlight lang="bash">
grep maxpoolsize /etc/voipmonitor.conf
# Example output: maxpoolsize = 102400  (100 GB in MB)
</syntaxhighlight>


==== Resolution: Increase Spooldir Size ====
== Advanced Topics ==


If the actual usage exceeds the configured limit, increase <code>maxpoolsize</code>:
=== Spool Directory Location ===


<syntaxhighlight lang="ini">
Default: <code>/var/spool/voipmonitor</code>
# Edit /etc/voipmonitor.conf
[general]
maxpoolsize = 716800  # 700 GB in MB
maxpooldays = 90      # Optional: Keep data for last 90 days
</syntaxhighlight>


Apply changes:
Structure: <code>YYYY-MM-DD/HH/MM/{SIP|RTP|GRAPH|AUDIO}/files...</code>
<syntaxhighlight lang="bash">
systemctl restart voipmonitor
</syntaxhighlight>


=== Maintenance: Re-indexing the Spool Directory ===
==== Relocating the Spool ====


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.
<syntaxhighlight lang="bash">
# 1. Create new directory
mkdir -p /mnt/storage/voipmonitor
chown voipmonitor:voipmonitor /mnt/storage/voipmonitor


To trigger a manual re-index via the manager API:
# 2. Update sniffer config
# /etc/voipmonitor.conf:
# spooldir = /mnt/storage/voipmonitor


<syntaxhighlight lang="bash">
# 3. Update GUI config (config/configuration.php):
# Open a manager API session
# define('SNIFFER_DATA_PATH', '/mnt/storage/voipmonitor');
echo 'manager_file start /tmp/vmsck' | nc 127.0.0.1 5029


# Send the re-index command
# 4. Restart
echo reindexfiles | nc -U /tmp/vmsck
systemctl restart voipmonitor
</syntaxhighlight>
</syntaxhighlight>


Note: This command requires <code>netcat</code> with support for UNIX sockets (<code>-U</code>). For alternative methods, see the [[Encryption_in_manager_api_customer|Manager API documentation]].
=== Tiered Storage (tar_move) ===
 
== Database Cleaning (CDR Retention) ==
 
Managing the size of the <code>cdr</code> table and other large tables is critical for GUI performance.


=== Partitioning Method (Recommended) ===
Extend retention using secondary storage:
 
Since version 7, VoIPmonitor utilizes '''database partitioning''', which splits large tables into smaller, daily segments. This is the recommended method for managing database retention.
 
{| class="wikitable" style="width:100%;"
|-
! Aspect !! Description
|-
| '''How it works''' || Set <code>cleandatabase = 30</code> in <code>voipmonitor.conf</code> to keep the last 30 days of data.
|-
| '''Why it's better''' || Dropping old partitions is instantaneous (milliseconds), regardless of row count. Zero database load.
|-
| '''Requirement''' || Partitioning is enabled by default on new installations.
|}
 
==== Quick Start: Global Retention ====
 
For most deployments, configure one parameter in <code>voipmonitor.conf</code>:


<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
# Keep all records for 30 days
spooldir = /var/spool/voipmonitor
cleandatabase = 30
tar_move = yes
tar_move_destination_path = /mnt/archive/voipmonitor
</syntaxhighlight>
</syntaxhighlight>


The <code>cleandatabase</code> parameter acts as a global default for all <code>cleandatabase_*</code> options and applies to:
Files in secondary storage remain accessible via GUI.
* <code>cdr</code> - Call Detail Records
* <code>message</code> - SIP MESSAGE texts
* <code>sip_msg</code> - SIP OPTIONS/SUBSCRIBE/NOTIFY messages
* <code>register_state</code> - SIP registration states
* <code>register_failed</code> - Failed registration attempts


==== Retention Parameters ====
==== S3 Cloud Storage ====


{| class="wikitable"
Use <code>rclone</code> instead of <code>s3fs</code> to avoid GUI unresponsiveness:
|-
! Parameter !! Default !! Description
|-
| <code>cleandatabase</code> || 0 (disabled) || Master retention setting in days.
|-
| <code>cleandatabase_cdr</code> || 0 || Specific retention for <code>cdr</code> and <code>message</code> tables.
|-
| <code>cleandatabase_rtp_stat</code> || 2 || Retention for detailed RTP statistics.
|-
| <code>cleandatabase_sip_msg</code> || 0 || Retention for OPTIONS/SUBSCRIBE/NOTIFY.
|-
| <code>cleandatabase_size</code> || (unset) || Alternative: size-based limit in MB (requires version 2024.05.1+).
|-
| <code>partition_operations_enable_fromto</code> || 1-5 || Time window for partition operations (e.g., 1-5 AM).
|}


===== Size-Based Database Cleaning =====
<syntaxhighlight lang="bash">
 
rclone mount bucket-name /mnt/s3-archive \
In addition to time-based retention, VoIPmonitor supports size-based database cleanup using <code>cleandatabase_size</code>. This is useful when you want to limit the database size regardless of data age.
  --allow-other --dir-cache-time 30s --vfs-cache-mode off
 
<syntaxhighlight lang="ini">
# Limit database to 50 GB
cleandatabase_size = 51200
 
# Force immediate cleanup if size exceeded (required for size-based)
cleandatabase_size_force = true
</syntaxhighlight>
</syntaxhighlight>


{| class="wikitable"
=== Custom Autocleaning (GUI) ===
|-
! Parameter !! Description
|-
| <code>cleandatabase_size</code> || Maximum database size in MB. When exceeded, the oldest partitions are dropped until the size is below this limit.
|-
| <code>cleandatabase_size_force</code> || Must be set to <code>true</code> to enable size-based cleanup. Without this, <code>cleandatabase_size</code> will not trigger cleanup.
|}
 
'''Behavior:'''
* The size check is performed daily during partition operations
* When the size exceeds <code>cleandatabase_size</code> + 5% buffer, the oldest partitions are dropped
* This ensures the database stays within the specified size limit
* Works independently of <code>cleandatabase</code> (time-based retention)


'''Note:''' Size-based cleanup only affects partitioned tables. Non-partitioned tables are not affected.
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


More details: [[Sniffer_configuration#Database_Cleaning|Sniffer Configuration - Database Cleaning]].
== Troubleshooting ==


=== Legacy Method: Manual Deletion (Not Recommended) ===
=== Files Disappearing Faster Than Expected ===


For very old, non-partitioned databases, you would need custom scripts with <code>DELETE FROM cdr WHERE calldate < ...</code> queries.
;1. Check if emergency cleanup is active
<syntaxhighlight lang="bash">
df -h /var/spool/voipmonitor
# If >95% full, emergency cleanup is running
</syntaxhighlight>


'''Warning:''' Manual DELETE on large tables is extremely slow and resource-intensive. A single operation on millions of rows can take hours and impact GUI performance.
;2. Check GUI configuration override
When <code>mysqlloadconfig = yes</code> (default), GUI settings override config file. Check: Settings > Sensors > wrench icon.


== Troubleshooting Disk Space Issues ==
;3. Set appropriate limits
Set <code>maxpoolsize</code> to 90-95% of disk capacity to leave buffer for growth.


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


If automatic cleanup runs but disk space is not freed from the MySQL data directory, check the <code>innodb_file_per_table</code> setting:
Check <code>innodb_file_per_table</code>:


<syntaxhighlight lang="sql">
<syntaxhighlight lang="sql">
Line 421: Line 347:
</syntaxhighlight>
</syntaxhighlight>


{| class="wikitable"
If OFF, enable in <code>my.cnf</code>:
|-
! Value !! Behavior
|-
| '''ON''' || Each table/partition has its own <code>.ibd</code> file. Dropping partitions reclaims space immediately.
|-
| '''OFF''' || All data in shared <code>ibdata1</code> file. Dropping partitions does '''not''' reduce file size.
|}
 
==== Solutions ====


;Option 1: Enable for Future Tables
Add to <code>/etc/my.cnf</code> or <code>/etc/mysql/my.cnf</code>:
<syntaxhighlight lang="ini">
<syntaxhighlight lang="ini">
[mysqld]
[mysqld]
innodb_file_per_table = 1
innodb_file_per_table = 1
</syntaxhighlight>
</syntaxhighlight>
<syntaxhighlight lang="bash">
systemctl restart mysql
</syntaxhighlight>
Note: This only affects NEW tables/partitions. Existing data in <code>ibdata1</code> remains.


;Option 2: Reclaim Space from Existing Tables
=== MySQL Error 28: No Space Left ===
<syntaxhighlight lang="sql">
 
OPTIMIZE TABLE cdr;
Enable size-based cleaning:
</syntaxhighlight>
'''Warning:''' Requires significant free disk space to duplicate table data. May crash if disk is nearly full.


;Option 3: Export and Re-import
<syntaxhighlight lang="ini">
<syntaxhighlight lang="bash">
cleandatabase_size = 512000
mysqldump -u root -p voipmonitor > voipmonitor_backup.sql
cleandatabase_size_force = true
mysql -u root -p -e "DROP DATABASE voipmonitor; CREATE DATABASE voipmonitor;"
mysql -u root -p voipmonitor < voipmonitor_backup.sql
</syntaxhighlight>
</syntaxhighlight>


=== Monitoring Database Health ===
Other causes: Inode exhaustion (<code>df -i</code>), MySQL tmpdir full.


==== SQL Queue Metrics ====
=== Verify Database Cleaning ===


The sensor tracks queue metrics visible in GUI → Settings → Sensors → Status:
<syntaxhighlight lang="sql">
 
SELECT PARTITION_NAME, TABLE_ROWS
{| class="wikitable"
FROM information_schema.PARTITIONS
|-
WHERE TABLE_NAME = 'cdr'
! Metric !! Description !! Healthy Range
ORDER BY PARTITION_ORDINAL_POSITION DESC
|-
LIMIT 10;
| '''SQLq''' || CDRs waiting to be written to database || Near 0, sporadic spikes OK
|-
| '''SQLf''' || Failed database write attempts || Zero (not growing)
|}
 
* Consistently high/growing SQLq → database cannot keep up
* Non-zero/growing SQLf → database errors or connectivity issues
 
See [[SQL_queue_is_growing_in_a_peaktime|SQL Queue Troubleshooting]] for details.
 
==== System Monitoring ====
 
<syntaxhighlight lang="bash">
# Check system load
cat /proc/loadavg
 
# Monitor disk I/O (shows only active processes)
iotop -o
</syntaxhighlight>
</syntaxhighlight>


High I/O from <code>mysqld</code> processes may indicate slow storage or poorly tuned MySQL settings.
If partition count matches your <code>cleandatabase</code> setting, cleaning IS working.


== MySQL Performance Settings ==
For SQL queue issues and database performance, see [[Database_troubleshooting]].


For high-performance operation with partitioning:
== See Also ==
 
<syntaxhighlight lang="ini">
[mysqld]
# Use 50-70% of available RAM for caching
innodb_buffer_pool_size = 4G
 
# Flush logs to OS every second (faster, safe for VoIPmonitor)
innodb_flush_log_at_trx_commit = 2


# Enable per-table filespace for easy space reclamation
* [[Sniffer_configuration]] - Full parameter reference
innodb_file_per_table = 1
* [[Database_troubleshooting]] - SQL queue, performance issues
</syntaxhighlight>
* [[Scaling]] - Performance tuning
* [[Capture_rules]] - Selective recording


For comprehensive tuning, see [[Scaling|Scaling and Performance Guide]].


== See Also ==


* [[Sniffer_configuration|Sniffer Configuration Reference]]
== AI Summary for RAG ==
* [[Scaling|Scaling and Performance Guide]]
* [[SQL_queue_is_growing_in_a_peaktime|SQL Queue Troubleshooting]]
* [[Sniffer_troubleshooting|Sniffer Troubleshooting]]


== AI Summary for RAG ==
'''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).
'''Summary:''' VoIPmonitor has two independent data retention mechanisms: (1) Filesystem cleaning for PCAP files using <code>maxpoolsize</code>/<code>maxpooldays</code> parameters, running every 5 minutes to delete oldest data first; (2) Database cleaning using <code>cleandatabase</code> parameter with daily partitioning for instant partition drops. Key behavior: directories within <code>maxpoolrtpdays</code> window contain both SIP and RTP (large), while directories within <code>maxpoolsipdays</code> but beyond <code>maxpoolrtpdays</code> contain only SIP (smaller) - this is expected. Troubleshooting covers disk full scenarios (check with <code>du -h --max-depth=1</code>, increase <code>maxpoolsize</code>), space not reclaimed issues (<code>innodb_file_per_table</code> setting), and database health monitoring (SQLq/SQLf metrics). Additional topics: relocating spooldir to different partition, syncing GUI <code>SNIFFER_DATA_PATH</code> configuration, size-based database cleaning via <code>cleandatabase_size</code> and <code>cleandatabase_size_force</code>.


'''Keywords:''' data retention, cleaning, delete old calls, disk space, spooldir, maxpoolsize, maxpooldays, maxpoolsipdays, maxpoolrtpdays, cleandatabase, partitioning, cleandatabase_size, cleandatabase_size_force, reindexfiles, innodb_file_per_table, SQLq, SQLf, directory size difference, SIP vs RTP retention, relocate spooldir, SNIFFER_DATA_PATH, MySQL Error 28
'''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?
* 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 deleted - how to fix?
* How to limit database size?
* How do I configure database retention with cleandatabase?
* Why are files being deleted faster than expected?
* Why is disk space not reclaimed after MySQL cleanup?
* How to fix MySQL Error 28 no space left?
* What do SQLq and SQLf metrics mean?
* How to reduce storage usage (savertp header)?
* Why are recent directories much larger than old ones in my spool?
* How to configure tiered storage?
* Directory size difference with maxpoolsipdays and maxpoolrtpdays
* Why is disk space not reclaimed after cleanup?
* How do I move the spooldir to a larger partition?
* How to manage partitions in multi-sensor environment?
* What is cleandatabase_size and cleandatabase_size_force?
* How do I fix MySQL Error 28 "No space left on device"?

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?