-
Notifications
You must be signed in to change notification settings - Fork 1k
Documentation additions and bug fix for vacuum_stats() #5258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6966b79
de214cb
efe0d4f
cf8cbfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,262 @@ | ||||||
| # ProxySQL: On‑Demand Core Dump Generation (coredump_filters) | ||||||
|
|
||||||
| ## Introduction | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| The feature works by: | ||||||
|
|
||||||
| 1. **Defining filters**: Inserting file‑name and line‑number pairs into the `coredump_filters` table. | ||||||
| 2. **Enabling filters**: Loading the filters to runtime with `LOAD COREDUMP TO RUNTIME`. | ||||||
| 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). | ||||||
|
|
||||||
| Core dump generation is **rate‑limited** and **platform‑specific** (currently Linux on x86‑32, x86‑64, ARM, and MIPS architectures). | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Table Definitions | ||||||
|
|
||||||
| ### `coredump_filters` (persistent configuration) | ||||||
|
|
||||||
| | Column | Type | Nullable | Primary Key | Description | | ||||||
| |----------|--------------|----------|-------------|-------------| | ||||||
| | filename | VARCHAR | NOT NULL | Yes | Source file name (as seen by the compiler) | | ||||||
| | line | INT | NOT NULL | Yes | Line number within that file | | ||||||
|
|
||||||
| **Primary key**: (`filename`, `line`) | ||||||
|
|
||||||
| **SQL definition**: | ||||||
| ```sql | ||||||
| CREATE TABLE coredump_filters ( | ||||||
| filename VARCHAR NOT NULL, | ||||||
| line INT NOT NULL, | ||||||
| PRIMARY KEY (filename, line) | ||||||
| ); | ||||||
| ``` | ||||||
|
|
||||||
| ### `runtime_coredump_filters` (runtime state) | ||||||
|
|
||||||
| This table mirrors the active filters currently loaded into memory. It is updated automatically when `LOAD COREDUMP TO RUNTIME` is executed. | ||||||
|
|
||||||
| **SQL definition**: | ||||||
| ```sql | ||||||
| CREATE TABLE runtime_coredump_filters ( | ||||||
| filename VARCHAR NOT NULL, | ||||||
| line INT NOT NULL, | ||||||
| PRIMARY KEY (filename, line) | ||||||
| ); | ||||||
| ``` | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Configuration Variables | ||||||
|
|
||||||
| Two global variables control the rate‑limiting behavior: | ||||||
|
|
||||||
| | Variable | Default | Range | Description | | ||||||
| |----------|---------|-------|-------------| | ||||||
| | `admin‑coredump_generation_threshold` | 10 | 1–500 | Maximum number of core files that can be generated during the lifetime of the ProxySQL process. | | ||||||
| | `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. | | ||||||
|
|
||||||
| **Notes**: | ||||||
| - Both variables are stored in the `global_variables` table (admin database). | ||||||
| - Changes take effect immediately when the variable is set (no need to `LOAD … TO RUNTIME`). | ||||||
| - The threshold is a **global counter**; once reached, no further core dumps will be generated until the process restarts. | ||||||
| - The interval is measured in **milliseconds**. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Admin Commands | ||||||
|
|
||||||
| ### `LOAD COREDUMP TO RUNTIME` | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| **Aliases**: | ||||||
| - `LOAD COREDUMP FROM MEMORY` | ||||||
| - `LOAD COREDUMP FROM MEM` | ||||||
| - `LOAD COREDUMP TO RUN` | ||||||
|
|
||||||
| **Example**: | ||||||
| ```sql | ||||||
| LOAD COREDUMP TO RUNTIME; | ||||||
| ``` | ||||||
|
|
||||||
| **Effect**: | ||||||
| 1. Clears the previous runtime filter set. | ||||||
| 2. Reads all rows from `coredump_filters`. | ||||||
| 3. Converts each row into a string `"filename:line"` and stores it in an internal hash set. | ||||||
| 4. If at least one filter exists, the global flag `coredump_enabled` is set to `true`. | ||||||
|
|
||||||
| ### `SAVE COREDUMP` (not implemented) | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| If you need to copy the active filters back to the configuration table, you can do so manually: | ||||||
|
|
||||||
| ```sql | ||||||
| INSERT INTO coredump_filters SELECT * FROM runtime_coredump_filters; | ||||||
| ``` | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Important Notes | ||||||
|
|
||||||
| - **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. | ||||||
| - **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. | ||||||
| - **Instance‑specific**: Filters are local to the ProxySQL instance; there is no automatic synchronization across a cluster. | ||||||
| - **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. | ||||||
| - **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. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Usage Example | ||||||
|
|
||||||
| ### 1. Insert a filter | ||||||
|
|
||||||
| 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). | ||||||
|
|
||||||
| 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: | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The explanation of the
Suggested change
|
||||||
|
|
||||||
| ```sql | ||||||
| INSERT INTO coredump_filters (filename, line) VALUES ('lib/mysql_data_stream.cpp', 485); | ||||||
| ``` | ||||||
|
|
||||||
| ### 2. (Optional) Adjust rate‑limiting variables | ||||||
|
|
||||||
| Increase the threshold and shorten the interval if you expect to trigger the dump multiple times quickly: | ||||||
|
|
||||||
| ```sql | ||||||
| SET admin-coredump_generation_threshold = 50; | ||||||
| SET admin-coredump_generation_interval_ms = 1000; -- 1 second | ||||||
| ``` | ||||||
|
|
||||||
| These changes take effect immediately. | ||||||
|
|
||||||
| ### 3. Load filters to runtime | ||||||
|
|
||||||
| ```sql | ||||||
| LOAD COREDUMP TO RUNTIME; | ||||||
| ``` | ||||||
|
|
||||||
| ### 4. Trigger the condition | ||||||
|
|
||||||
| 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: | ||||||
|
|
||||||
| ``` | ||||||
| [INFO] Coredump filter location 'lib/mysql_data_stream.cpp:485' was hit. | ||||||
| [INFO] Generating coredump file 'core.<pid>.<counter>'... | ||||||
| [INFO] Coredump file 'core.<pid>.<counter>' was generated ... | ||||||
| ``` | ||||||
|
|
||||||
| ### 5. Inspect the core file | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| Analyze it with `gdb`: | ||||||
|
|
||||||
| ```bash | ||||||
| gdb /usr/bin/proxysql core.12345.0 | ||||||
| ``` | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Rate Limiting and Safety Features | ||||||
|
|
||||||
| To prevent disk filling and performance impact, core dump generation is protected by two mechanisms: | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| Both counters are reset when `LOAD COREDUMP TO RUNTIME` is executed (or when `proxy_coredump_reset_stats()` is called internally). | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Platform Support | ||||||
|
|
||||||
| Core dump generation is **only available** on the following platforms: | ||||||
|
|
||||||
| - **Operating system**: Linux | ||||||
| - **Architectures**: x86‑32 (`__i386__`), x86‑64 (`__x86_64__`), ARM (`__ARM_ARCH_3__`), MIPS (`__mips__`) | ||||||
|
|
||||||
| On other platforms (e.g., FreeBSD, macOS, Windows) the `generate_coredump()` macro will log a warning and do nothing. | ||||||
|
|
||||||
| The feature relies on the **coredumper** library (https://github.com/elastic/coredumper), which is bundled as a dependency. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Internal Implementation Details | ||||||
|
|
||||||
| ### Macros and Functions | ||||||
|
|
||||||
| - `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. | ||||||
| - `proxy_coredump_load_filters()`: Loads a set of `"filename:line"` strings into the internal hash table. | ||||||
| - `proxy_coredump_generate()`: Performs the actual core dump writing, subject to rate‑limiting checks. | ||||||
| - `proxy_coredump_reset_stats()`: Resets the generation counter and last‑creation timestamp. | ||||||
|
|
||||||
| ### Database‑to‑Runtime Flow | ||||||
|
|
||||||
| 1. `LOAD COREDUMP TO RUNTIME` calls `ProxySQL_Admin::load_coredump_to_runtime()`. | ||||||
| 2. Which calls `flush_coredump_filters_database_to_runtime()`. | ||||||
| 3. Reads `coredump_filters` table, builds the string set, and passes it to `proxy_coredump_load_filters()`. | ||||||
| 4. The runtime state is mirrored to `runtime_coredump_filters` via `dump_coredump_filter_values_table()`. | ||||||
|
|
||||||
| ### Where `generate_coredump()` is Used | ||||||
|
|
||||||
| Currently, the macro is placed in a few strategic “fatal error” locations: | ||||||
|
|
||||||
| - `MySQL_Data_Stream::check_data_flow()` – when data exists at both ends of a MySQL data stream. | ||||||
| - `PgSQL_Data_Stream::check_data_flow()` – analogous condition for PostgreSQL. | ||||||
|
|
||||||
| Developers can add more `generate_coredump()` calls in other debug‑sensitive code sections. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Troubleshooting | ||||||
|
|
||||||
| ### No core file is generated even though the filter was hit | ||||||
|
|
||||||
| 1. **Check platform support**: Verify ProxySQL is running on a supported Linux architecture. | ||||||
| 2. **Check rate‑limiting counters**: The global threshold may have been reached. Execute `LOAD COREDUMP TO RUNTIME` to reset the counters (or restart ProxySQL). | ||||||
| 3. **Check directory permissions**: The process must have write permission in the current working directory. | ||||||
| 4. **Check disk space**: Ensure there is sufficient free disk space. | ||||||
|
|
||||||
| ### Error “Coredump generation is not supported on this platform.” | ||||||
|
|
||||||
| The platform is not among the supported architectures. Use a different machine or consider using a debugger instead. | ||||||
|
|
||||||
| ### Filters are not being activated after `LOAD COREDUMP TO RUNTIME` | ||||||
|
|
||||||
| - Verify that the `filename` matches exactly the string that `__FILE__` expands to (relative path from the source root). | ||||||
| - Ensure the line number is correct (check the source code for the exact line where `generate_coredump()` appears). | ||||||
| - Inspect the `runtime_coredump_filters` table to confirm the filters were loaded. | ||||||
|
|
||||||
| ### High frequency of core dumps is affecting performance | ||||||
|
|
||||||
| Increase `admin‑coredump_generation_interval_ms` to space out the generation, or reduce `admin‑coredump_generation_threshold` to limit the total number. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Best Practices | ||||||
|
|
||||||
| 1. **Use for debugging only**: Enable coredump filters only during debugging sessions. Remove filters afterward to avoid unnecessary overhead. | ||||||
| 2. **Limit the threshold**: Keep `admin‑coredump_generation_threshold` low (e.g., 1‑5) unless you are investigating a recurring issue. | ||||||
| 3. **Set a reasonable interval**: A minimum interval of several seconds (e.g., 30000 ms) prevents storm generation. | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The text
Suggested change
|
||||||
| 4. **Document filter locations**: Keep a record of why each filter was inserted and under what condition it triggers. | ||||||
| 5. **Monitor disk usage**: Core files can be large; ensure the working directory has enough space and consider a dedicated partition. | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Related Features | ||||||
|
|
||||||
| - **Debug filters**: ProxySQL also supports `debug_filters` for enabling debug logs at specific file‑line locations. | ||||||
| - **Core dump on crash**: For crash‑induced core dumps, use system‑level configuration (e.g., `ulimit -c unlimited`, `sysctl kernel.core_pattern`). | ||||||
|
|
||||||
| --- | ||||||
|
|
||||||
| ## Summary | ||||||
|
|
||||||
| 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. | ||||||
|
|
||||||
| Remember that core dump generation is **platform‑dependent** and **rate‑limited**; always verify support and adjust the configuration variables according to your debugging needs. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable names like
admin‑coredump_generation_thresholduse a non-breaking hyphen (U+2011) instead of a standard hyphen-minus (U+002D). This can cause copy-paste errors for users trying to run commands. Please replace all non-breaking hyphens in variable names and code blocks with standard hyphens. For example,admin‑coredump_generation_thresholdshould beadmin-coredump_generation_threshold. This issue appears in multiple places in this file (e.g., lines 58, 59, 108, 168, 170, 181, 237, 244) and other documentation files in this PR.