You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
proxysql/doc/internal/MySQL_Logging_Prepared_Stat...

87 lines
5.5 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# **ProxySQL Prepared Statement Parameter Tracking Reference Manual**
This document describes the changes made to the logging of prepared statement parameters in ProxySQL.
Two logging formats are supported:
- **Binary Format (Format 1)** via `write_query_format_1()`
- **JSON Format (Format 2)** via `write_query_format_2_json()` (also using `extractStmtExecuteMetadataToJson()`)
## **1. Overview**
ProxySQL logs query events in two different formats.
For prepared statements (i.e. `COM_STMT_EXECUTE` events), the logging functions now log extra parameter details.
Both formats encode the number of parameters and, for each parameter, log its type and a human-readable string value, with special handling for `NULL` values.
## **2. Binary Format Details (**`write_query_format_1()`**)**
When logging a prepared statement execution in binary format, the following steps occur:
- **Encoded Basic Query Data:**
Standard fields such as event type, thread ID, username, schema name, client/server info, timestamps, query digest, and the query text itself are encoded using a variable-length encoding scheme.
- **Logging Prepared Statement Parameters:**
If the event type is `PROXYSQL_COM_STMT_EXECUTE` and valid statement metadata is present:
- The number of parameters is encoded using `mysql_encode_length()`.
- A **null bitmap** is constructed with one bit per parameter (set when the parameter is `NULL`).
- For each parameter:
- Two bytes are written to store the parameter's type.
- If the parameter is not `NULL`, the function `getValueForBind()` is used to convert the binary data into a human-readable string.
- The length of the converted value is encoded (again using `mysql_encode_length()`), and then the raw bytes of the converted value are written.
- **Sequential Write Process:**
All the fields are written sequentially. First, the total length of the event record is written (as a fixed-size 8-byte field), then each encoded field and the additional prepared statement parameter details.
## **3. JSON Format Details (**`write_query_format_2_json()`**)**
In JSON format, the logging function produces a JSON object that includes all standard query details plus additional fields for prepared statement parameters:
- **Base JSON Object Information:**
The JSON object includes key fields such as thread_id, username, schemaname, client, server information (if available), timestamps (starttime, endtime), duration, digest, etc.
- **Event Type:**
Depending on the event type, the field `"event"` is set to `"COM_STMT_EXECUTE"` (or `"COM_STMT_PREPARE"` / `"COM_QUERY"`) accordingly.
- **Logging Prepared Statement Parameters:**
If the event type is `PROXYSQL_COM_STMT_EXECUTE` and the session contains valid statement metadata:
- The helper function `extractStmtExecuteMetadataToJson(json &j)` is called.
- This function iterates over each parameter:
- For `NULL` parameters, it logs `"type": "NULL"` and `"value": null`.
- For non-`NULL` parameters, it uses getValueForBind() to obtain the parameter type (e.g., `"INT24"`, `"VARCHAR"`) and its string representation.
- The result is a JSON array attached to the key `"parameters"`, where each element is an object with keys `"type"` and `"value"`.
- **Output:**
Finally the JSON object is dumped as a single line in the log file using `j.dump()`.
## **4. Detailed Example**
For example, consider a prepared statement with two parameters. The resulting JSON log might look like:
```json
{
"hostgroup_id": 3,
"thread_id": 12345,
"event": "COM_STMT_EXECUTE",
"username": "dbuser",
"schemaname": "production",
"client": "192.0.2.1",
"server": "10.0.0.5",
"rows_affected": 1,
"query": "INSERT INTO foo (bar1, bar2) VALUES (?, ?)",
"starttime_timestamp_us": 1617181920000000,
"starttime": "2021-03-31 12:32:00.000000"
"endtime_timestamp_us": 1617181921000000,
"endtime": "2021-03-31 12:32:01.000000",
"duration_us": 1000000,
"digest": "0x0000000000000001", "client_stmt_id": 101,
"parameters": [
{
"type": "INT24",
"value": "42"
},
{
"type": "VARCHAR",
"value": "example value"
}
]
}
```
This JSON structure clearly shows each parameters type and value, which aids in debugging and analysis.
## **5. Usage Considerations**
- **Debuggability:**
The enhanced logging allows administrators to see the full details of the parameters that are bound to a prepared statement. This is crucial for troubleshooting and performance analysis.
- **Variable-Length Encoding:**
Both binary and JSON formats rely on helper functions (`mysql_encode_length()` and `getValueForBind()`) to ensure that variable-length integers and parameter values are handled efficiently and unambiguously.
- **Thread Safety and Performance:**
The logging functions acquire write locks just before writing to disk to minimize contention. The design ensures that logging does not adversely impact performance while retaining detailed information.
## **6. Summary**
The changes in both `write_query_format_1()` and `write_query_format_2_json()` provide a comprehensive way to log prepared statement parameters:
- In **binary format**, parameters are logged with a parameter count, a null bitmap, a two-byte parameter type, and then a variable-length encoded value.
- In **JSON format**, parameters appear as an array of objects under the `"parameters"` key, with each object containing `"type"` and `"value"` fields.
These enhancements aim to improve troubleshooting capabilities and ensure that all necessary information is captured for later analysis.