Skip to content

Commit 88edaac

Browse files
authored
Merge pull request #5258 from sysown/misc251219
Documentation additions and bug fix for vacuum_stats()
2 parents efd87ae + cf8cbfd commit 88edaac

File tree

5 files changed

+824
-1
lines changed

5 files changed

+824
-1
lines changed
Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
# ProxySQL: On‑Demand Core Dump Generation (coredump_filters)
2+
3+
## Introduction
4+
5+
ProxySQL includes a debugging feature that allows on‑demand generation of core dump files when specific code locations are reached. This is useful for diagnosing rare or hard‑to‑reproduce bugs without requiring a full debug build or restarting the proxy.
6+
7+
The feature works by:
8+
9+
1. **Defining filters**: Inserting file‑name and line‑number pairs into the `coredump_filters` table.
10+
2. **Enabling filters**: Loading the filters to runtime with `LOAD COREDUMP TO RUNTIME`.
11+
3. **Triggering core dumps**: When the macro `generate_coredump()` is executed at a filtered location, a core file is written to disk (subject to rate‑limiting and platform constraints).
12+
13+
Core dump generation is **rate‑limited** and **platform‑specific** (currently Linux on x86‑32, x86‑64, ARM, and MIPS architectures).
14+
15+
---
16+
17+
## Table Definitions
18+
19+
### `coredump_filters` (persistent configuration)
20+
21+
| Column | Type | Nullable | Primary Key | Description |
22+
|----------|--------------|----------|-------------|-------------|
23+
| filename | VARCHAR | NOT NULL | Yes | Source file name (as seen by the compiler) |
24+
| line | INT | NOT NULL | Yes | Line number within that file |
25+
26+
**Primary key**: (`filename`, `line`)
27+
28+
**SQL definition**:
29+
```sql
30+
CREATE TABLE coredump_filters (
31+
filename VARCHAR NOT NULL,
32+
line INT NOT NULL,
33+
PRIMARY KEY (filename, line)
34+
);
35+
```
36+
37+
### `runtime_coredump_filters` (runtime state)
38+
39+
This table mirrors the active filters currently loaded into memory. It is updated automatically when `LOAD COREDUMP TO RUNTIME` is executed.
40+
41+
**SQL definition**:
42+
```sql
43+
CREATE TABLE runtime_coredump_filters (
44+
filename VARCHAR NOT NULL,
45+
line INT NOT NULL,
46+
PRIMARY KEY (filename, line)
47+
);
48+
```
49+
50+
---
51+
52+
## Configuration Variables
53+
54+
Two global variables control the rate‑limiting behavior:
55+
56+
| Variable | Default | Range | Description |
57+
|----------|---------|-------|-------------|
58+
| `admin‑coredump_generation_threshold` | 10 | 1–500 | Maximum number of core files that can be generated during the lifetime of the ProxySQL process. |
59+
| `admin‑coredump_generation_interval_ms` | 30000 (30 seconds) | 0–INT_MAX | Minimum time between two consecutive core dump generations. A value of `0` disables the interval check. |
60+
61+
**Notes**:
62+
- Both variables are stored in the `global_variables` table (admin database).
63+
- Changes take effect immediately when the variable is set (no need to `LOAD … TO RUNTIME`).
64+
- The threshold is a **global counter**; once reached, no further core dumps will be generated until the process restarts.
65+
- The interval is measured in **milliseconds**.
66+
67+
---
68+
69+
## Admin Commands
70+
71+
### `LOAD COREDUMP TO RUNTIME`
72+
73+
Reads the `coredump_filters` table and loads the filters into memory. After this command, any location matching a filter becomes active for core dump generation.
74+
75+
**Aliases**:
76+
- `LOAD COREDUMP FROM MEMORY`
77+
- `LOAD COREDUMP FROM MEM`
78+
- `LOAD COREDUMP TO RUN`
79+
80+
**Example**:
81+
```sql
82+
LOAD COREDUMP TO RUNTIME;
83+
```
84+
85+
**Effect**:
86+
1. Clears the previous runtime filter set.
87+
2. Reads all rows from `coredump_filters`.
88+
3. Converts each row into a string `"filename:line"` and stores it in an internal hash set.
89+
4. If at least one filter exists, the global flag `coredump_enabled` is set to `true`.
90+
91+
### `SAVE COREDUMP` (not implemented)
92+
93+
As of this writing, there is **no `SAVE COREDUMP` command**. The runtime state (`runtime_coredump_filters`) is automatically updated when filters are loaded, but there is no built‑in command to persist runtime filters back to the `coredump_filters` table.
94+
95+
If you need to copy the active filters back to the configuration table, you can do so manually:
96+
97+
```sql
98+
INSERT INTO coredump_filters SELECT * FROM runtime_coredump_filters;
99+
```
100+
101+
---
102+
103+
## Important Notes
104+
105+
- **Case‑sensitive filenames**: The `filename` column must match exactly the string returned by `__FILE__` (including relative path from the source root). The comparison is case‑sensitive.
106+
- **Runtime‑only behavior**: Filters loaded via `LOAD COREDUMP TO RUNTIME` are stored in memory only. They are lost when ProxySQL restarts. To make filters persistent, keep them in the `coredump_filters` table and reload after each restart.
107+
- **Instance‑specific**: Filters are local to the ProxySQL instance; there is no automatic synchronization across a cluster.
108+
- **Rate limiting**: The feature includes two safety limits (`admin‑coredump_generation_threshold` and `admin‑coredump_generation_interval_ms`) to prevent disk filling and performance degradation.
109+
- **Platform‑specific**: Core dump generation works only on Linux x86‑32, x86‑64, ARM, and MIPS architectures. On other platforms the macro logs a warning and does nothing.
110+
111+
---
112+
113+
## Usage Example
114+
115+
### 1. Insert a filter
116+
117+
Suppose you want to generate a core dump when the function `MySQL_Data_Stream::check_data_flow()` reaches line 485 (where `generate_coredump()` is called).
118+
119+
First, find the exact file name as used in the source code. The macro `LOCATION()` expands to `__FILE__ ":" __LINE__`. For the file `lib/mysql_data_stream.cpp` line 485:
120+
121+
```sql
122+
INSERT INTO coredump_filters (filename, line) VALUES ('lib/mysql_data_stream.cpp', 485);
123+
```
124+
125+
### 2. (Optional) Adjust rate‑limiting variables
126+
127+
Increase the threshold and shorten the interval if you expect to trigger the dump multiple times quickly:
128+
129+
```sql
130+
SET admin-coredump_generation_threshold = 50;
131+
SET admin-coredump_generation_interval_ms = 1000; -- 1 second
132+
```
133+
134+
These changes take effect immediately.
135+
136+
### 3. Load filters to runtime
137+
138+
```sql
139+
LOAD COREDUMP TO RUNTIME;
140+
```
141+
142+
### 4. Trigger the condition
143+
144+
Cause the code path to reach the filtered location. In this example, you would need to create a MySQL data‑stream condition where data exists at both ends of the stream (a fatal error). When that happens, ProxySQL will log:
145+
146+
```
147+
[INFO] Coredump filter location 'lib/mysql_data_stream.cpp:485' was hit.
148+
[INFO] Generating coredump file 'core.<pid>.<counter>'...
149+
[INFO] Coredump file 'core.<pid>.<counter>' was generated ...
150+
```
151+
152+
### 5. Inspect the core file
153+
154+
The core file is written in the current working directory of the ProxySQL process, with the name pattern `core.<pid>.<counter>` (e.g., `core.12345.0`). It is compressed using the **coredumper** library.
155+
156+
Analyze it with `gdb`:
157+
158+
```bash
159+
gdb /usr/bin/proxysql core.12345.0
160+
```
161+
162+
---
163+
164+
## Rate Limiting and Safety Features
165+
166+
To prevent disk filling and performance impact, core dump generation is protected by two mechanisms:
167+
168+
1. **Threshold limit**: The total number of core dumps generated during the process lifetime cannot exceed `admin‑coredump_generation_threshold` (default 10). Once the threshold is reached, `generate_coredump()` will still log the hit but will not write a new core file.
169+
170+
2. **Interval limit**: After a core dump is written, at least `admin‑coredump_generation_interval_ms` milliseconds must pass before another core dump can be generated (unless the interval is set to 0). This prevents burst generation when a hot code path is repeatedly executed.
171+
172+
Both counters are reset when `LOAD COREDUMP TO RUNTIME` is executed (or when `proxy_coredump_reset_stats()` is called internally).
173+
174+
---
175+
176+
## Platform Support
177+
178+
Core dump generation is **only available** on the following platforms:
179+
180+
- **Operating system**: Linux
181+
- **Architectures**: x86‑32 (`__i386__`), x86‑64 (`__x86_64__`), ARM (`__ARM_ARCH_3__`), MIPS (`__mips__`)
182+
183+
On other platforms (e.g., FreeBSD, macOS, Windows) the `generate_coredump()` macro will log a warning and do nothing.
184+
185+
The feature relies on the **coredumper** library (https://github.com/elastic/coredumper), which is bundled as a dependency.
186+
187+
---
188+
189+
## Internal Implementation Details
190+
191+
### Macros and Functions
192+
193+
- `generate_coredump()`: The macro used in the source code to conditionally generate a core dump. It checks `coredump_enabled` and looks up the current `__FILE__:__LINE__` in the filter set.
194+
- `proxy_coredump_load_filters()`: Loads a set of `"filename:line"` strings into the internal hash table.
195+
- `proxy_coredump_generate()`: Performs the actual core dump writing, subject to rate‑limiting checks.
196+
- `proxy_coredump_reset_stats()`: Resets the generation counter and last‑creation timestamp.
197+
198+
### Database‑to‑Runtime Flow
199+
200+
1. `LOAD COREDUMP TO RUNTIME` calls `ProxySQL_Admin::load_coredump_to_runtime()`.
201+
2. Which calls `flush_coredump_filters_database_to_runtime()`.
202+
3. Reads `coredump_filters` table, builds the string set, and passes it to `proxy_coredump_load_filters()`.
203+
4. The runtime state is mirrored to `runtime_coredump_filters` via `dump_coredump_filter_values_table()`.
204+
205+
### Where `generate_coredump()` is Used
206+
207+
Currently, the macro is placed in a few strategic “fatal error” locations:
208+
209+
- `MySQL_Data_Stream::check_data_flow()` – when data exists at both ends of a MySQL data stream.
210+
- `PgSQL_Data_Stream::check_data_flow()` – analogous condition for PostgreSQL.
211+
212+
Developers can add more `generate_coredump()` calls in other debug‑sensitive code sections.
213+
214+
---
215+
216+
## Troubleshooting
217+
218+
### No core file is generated even though the filter was hit
219+
220+
1. **Check platform support**: Verify ProxySQL is running on a supported Linux architecture.
221+
2. **Check rate‑limiting counters**: The global threshold may have been reached. Execute `LOAD COREDUMP TO RUNTIME` to reset the counters (or restart ProxySQL).
222+
3. **Check directory permissions**: The process must have write permission in the current working directory.
223+
4. **Check disk space**: Ensure there is sufficient free disk space.
224+
225+
### Error “Coredump generation is not supported on this platform.”
226+
227+
The platform is not among the supported architectures. Use a different machine or consider using a debugger instead.
228+
229+
### Filters are not being activated after `LOAD COREDUMP TO RUNTIME`
230+
231+
- Verify that the `filename` matches exactly the string that `__FILE__` expands to (relative path from the source root).
232+
- Ensure the line number is correct (check the source code for the exact line where `generate_coredump()` appears).
233+
- Inspect the `runtime_coredump_filters` table to confirm the filters were loaded.
234+
235+
### High frequency of core dumps is affecting performance
236+
237+
Increase `admin‑coredump_generation_interval_ms` to space out the generation, or reduce `admin‑coredump_generation_threshold` to limit the total number.
238+
239+
---
240+
241+
## Best Practices
242+
243+
1. **Use for debugging only**: Enable coredump filters only during debugging sessions. Remove filters afterward to avoid unnecessary overhead.
244+
2. **Limit the threshold**: Keep `admin‑coredump_generation_threshold` low (e.g., 1‑5) unless you are investigating a recurring issue.
245+
3. **Set a reasonable interval**: A minimum interval of several seconds (e.g., 30000 ms) prevents storm generation.
246+
4. **Document filter locations**: Keep a record of why each filter was inserted and under what condition it triggers.
247+
5. **Monitor disk usage**: Core files can be large; ensure the working directory has enough space and consider a dedicated partition.
248+
249+
---
250+
251+
## Related Features
252+
253+
- **Debug filters**: ProxySQL also supports `debug_filters` for enabling debug logs at specific file‑line locations.
254+
- **Core dump on crash**: For crash‑induced core dumps, use system‑level configuration (e.g., `ulimit -c unlimited`, `sysctl kernel.core_pattern`).
255+
256+
---
257+
258+
## Summary
259+
260+
The `coredump_filters` feature provides a targeted, rate‑limited way to obtain core dumps from specific code locations without restarting ProxySQL or building a debug binary. It is a valuable tool for diagnosing elusive bugs in production‑like environments.
261+
262+
Remember that core dump generation is **platform‑dependent** and **rate‑limited**; always verify support and adjust the configuration variables according to your debugging needs.

0 commit comments

Comments
 (0)