MySQL probe
The MySQL probe connects to a MySQL or MariaDB server, runs a SQL statement, and returns the result — a result set, an update count, or a server error. It is VirtuProbe’s first database protocol, which closes the loop on integration testing: after an HTTP call writes a record, a MySQL step can confirm the row actually landed.
Unlike the hand-rolled protocol probes, the MySQL probe is library-backed (MariaDB Connector/J, which speaks both MySQL and MariaDB) with connection pooling, so repeated sends and the steps of a chain reuse connections instead of reconnecting each time.

Connection settings
Section titled “Connection settings”| Field | Description |
|---|---|
| Host | Hostname or IP of the database server |
| Port | Server port (default: 3306) |
| Database | Default schema to connect to (optional) |
| TLS mode | Disabled, Required (encrypt without verifying the certificate), Verify CA, or Verify identity (verify the certificate chain and hostname) |
| Allow public-key retrieval | Let the driver fetch the server’s RSA public key over a plaintext connection. Required for caching_sha2_password (the MySQL 8 default) without TLS. Off by default — it exposes the exchange to a MITM. |
| Allow cleartext password plugin | Permit mysql_clear_password (used with PAM/LDAP auth). Off by default. |
Authentication
Section titled “Authentication”MySQL logins use the credential store — the username and password never live on the probe. This keeps secrets out of a shared directory-backed workspace (which stores probes as plain files) and out of exported evidence.
A database login is a username + password, which maps to a Basic credential (username in config, password in secrets). In the probe’s Auth row:
- Select an existing credential, or click New credential to create a Basic one (name, username, password).
- The effective credential panel shows what will be used and where it came from — this probe or the project default (the cascade: a probe with no credential falls back to the project’s default credential).
- Stored secrets are masked; click the eye to reveal a value on demand (behind a confirmation).
- Override for this run lets you type a different username/password for a single send without changing the stored credential — useful for trying alternate credentials against the same target.

If no credential is selected, the connection is attempted anonymously.
SQL statement
Section titled “SQL statement”Enter the statement in the SQL editor. Ctrl/Cmd+Enter runs it. {{variable}} placeholders are resolved from the active environment before the statement is sent — and, deliberately, this includes substitution into the SQL text itself, which is what enables both data-driven chaining and SQL-injection testing.
Response panel
Section titled “Response panel”- Query (
SELECT,SHOW, …) → a scrollable result-set table. Column names come from the driver; a SQLNULLrenders as an italicNULL. - Update / DDL (
INSERT,UPDATE,DELETE,CREATE, …) → the number of affected rows, plus any generated auto-increment keys. - Server error → a red panel with the message, the vendor error code, and the SQLSTATE. A rejected statement is a valid failed result, not a crash.
The status bar shows the row/affected count, the server version, and the client-side round-trip duration.

Extractors
Section titled “Extractors”Use these in chain steps to pull values out of a MySQL result for later steps or assertions:
| Extractor | Returns |
|---|---|
MYSQL_SUCCESS | "true" / "false" |
MYSQL_ROW_COUNT | number of rows returned by a query |
MYSQL_AFFECTED_ROWS | rows affected by an update/DDL (-1 for a query) |
MYSQL_COLUMN | a single cell — expression column, row.column, or row.colIndex (e.g. email, 0.email, 2.1) |
MYSQL_ERROR_CODE | the vendor error code (0 on success) |
MYSQL_JSON | the whole result set as a JSON array |
See Extractors for the full list.
Chains
Section titled “Chains”MySQL is a first-class chain step. A common pattern is HTTP → MySQL: call an API that creates a record, then run a SELECT and ASSERT on a MYSQL_COLUMN value to prove the write. {{variable}} values (including extractor output from earlier steps) resolve into the SQL, host, database, and query. Credentials resolve server-side at execution.
History
Section titled “History”Each send is recorded as a history entry with the statement as sent (resolved variables), the full result, and a timestamp. Click an entry to restore it.
Implementation notes
Section titled “Implementation notes”- Driver: MariaDB Connector/J (LGPL) — speaks MySQL and MariaDB. The query/extract/chain path has no need for wire-level control, so a library is the right tool here.
- Connection pooling: HikariCP, keyed by the connection signature (host/port/database/user/TLS). Reuse avoids reconnecting on every send. Note that pooling hands you a connection, not necessarily the same physical one, so per-session state (temporary tables,
@variables,USE) is not guaranteed to persist between chain steps. - caching_sha2_password: MySQL 8’s default auth plugin needs either TLS or Allow public-key retrieval on a plaintext socket.