Skip to content

MySQL

Signals reads conversion and customer data straight from a MySQL database on a schedule and sends the columns you nominate to your ad platforms.

Reading it directly means there is no file job to maintain and nothing to go stale between runs. Signals reads only; nothing is written back.

You can point it at a table, or at a query. The query path is what you want when the shape Signals needs does not match anything you already have.

Reading a replica keeps the scheduled load off the primary and brings one timing detail with it. A replica trails the primary by the current replication delay, so a conversion committed a few seconds before a read has not reached the replica yet. Which command reports that distance depends on the release. SHOW REPLICA STATUS, added in MySQL 8.0.22, reports it as Seconds_Behind_Source; on releases before that the command is SHOW SLAVE STATUS and the column is Seconds_Behind_Master; and MySQL 8.4 removed the older form, leaving only the replica spelling. Read the figure off the host you nominated before treating a missing hour of rows as a delivery failure.

In Studio, open Sources, find the Database category, and click the MySQL tile.

FieldWhat it isWhere to find it
Authentication NameYour own label for this set of credentials.You choose it. Name it for the database it belongs to.
UsernameThe database user Signals connects as.Created in the database by your administrator.
PasswordThe password for that user.Set when the user was created.

Two statements produce that account. Create the user, then give it read privileges on the single database it needs:

CREATE USER 'datahash'@'%' IDENTIFIED BY '...';
GRANT SELECT ON appdb.* TO 'datahash'@'%';

Naming appdb.* is the part people get wrong. ON *.* reads as the same instruction and is not: it hands the account every schema on the instance, the internal mysql schema among them. An over-wide privilege raises no error and produces no warning, so nothing prompts anyone to narrow it later. The '%' host part deserves a second look for the same reason, since it accepts connections from any address. Where your network policy expects an account to be pinned to its caller, replace '%' with the source addresses the connection arrives from, and get those addresses from your Datahash representative before creating the account rather than inferring them from a failed attempt.

Note which authentication plugin the account was created with before you leave the database. MySQL 8.0 changed the default, and a client that cannot negotiate the new one fails in a way that looks like a rejected password, which the Troubleshooting section covers.

Select the Integration Type, which is the kind of data your records hold. Offline Events is the common choice. Give the instance a name, then choose the table path or the query path. On either path you enter the Host Name, Port and Database Name, and then either the Table Name or a SQL query.

The integration type decides the columns Signals expects and which destinations the connection can feed, so it is worth settling before anyone models the data. It also decides which file format you get on the next screen.

Port is 3306 on a server nobody has reconfigured. Managed instances are what to check: some publish a different number at their endpoint, and some route through a proxy that listens elsewhere, so copy the port from the endpoint your provider shows rather than filling in the default from memory.

Encryption is a property of the account, not of this screen. REQUIRE SSL attached to the MySQL user compels TLS for that user alone, whatever the server permits for everyone else, so an instance that still accepts unencrypted sessions in general refuses an unencrypted one from this account.

Enter the connection details including the table name, then complete the setup. The name is typed rather than picked from a list, so it has to match the database exactly.

Enter the connection details without the table name, then write the query. Preview the results before finishing, and read the column names in the output rather than just the row count: a query that runs but returns the wrong names will fail silently once the connection is live.

One instance reads one table or query for one integration type. To read another, add another instance from the Manage existing instance table. To change an existing one, open it from there, click the edit option in the menu to the top right, update the fields and click Finish.

Download the file format from the setup screen and shape the table to it. The column names are what Signals matches on, so a column that has been renamed or cased differently is not recognized and the row it belongs to is dropped rather than reported.

On the query path the same rule applies to the column aliases your query returns. Aliasing to the expected names is the usual way to reconcile data you cannot or should not restructure.

Personal identifiers are normalized and hashed before they are sent to a destination.

  • Use a dedicated read-only user scoped to the data Datahash reads, rather than an application account.
  • Prefer the query path with explicit column aliases over pointing at a raw table. It lets your team change the underlying model without breaking the connection.
  • Clean the data in the view or query: lowercase email, phone in E.164, no stray whitespace. Hashing a badly formatted value produces a hash that will never match.
  • Rotate the password periodically and update the connection afterwards.

The connection times out rather than reporting bad credentials. That points at reachability rather than authentication. Confirm the host is exposed, the port is open, and any firewall or allow list permits the connection.

Credentials are rejected. Check the user can read the data from a client of its own first. Most failures here are permissions rather than typos.

Access is denied for a user whose password is known to be right. MySQL 8.0 made caching_sha2_password the default authentication plugin, and a client library written before that change cannot negotiate it. The server refuses the handshake and reports it exactly as it reports a bad password, which is why the first response is usually to reset a password that was never wrong. Read the plugin off the account with SELECT user, host, plugin FROM mysql.user and compare it against what the connecting client supports. Upgrading the client is the fix that keeps working, because the older plugin is on its way out: mysql_native_password is disabled by default in MySQL 8.4, where a server has to be started with --mysql-native-password=ON to offer it at all, and MySQL 9.0 removed it. On a server old enough to still carry it, ALTER USER 'datahash'@'%' IDENTIFIED WITH mysql_native_password BY '...' moves the existing account onto the older method. Alter the account rather than dropping and recreating it, which would discard the SELECT privilege granted above and trade an authentication error for a permissions one.

Names or addresses outside Latin script do not survive the write. MySQL’s utf8 has long been an alias for the three-byte utf8mb3, which cannot hold a four-byte character at all, so emoji and anything beyond the basic multilingual plane have nowhere to go in such a column. What the server does about it depends on the SQL mode. Under STRICT_TRANS_TABLES, on by default since 5.7, the write is rejected outright with ERROR 1366, Incorrect string value, and the row never lands. With strict mode off, or with a connection character set of utf8mb3 discarding the bytes in transit, the same value is stored truncated and reported only as a warning, which is the path that ends in a hash no destination can match. SHOW FULL COLUMNS shows the collation per column; a utf8mb3 collation on an email, name or address column is the finding. Convert the column to utf8mb4 before spending any more time on match rates.

The table name is rejected. It is typed rather than selected, so it has to match exactly.

The query previews correctly but nothing is delivered. The column names it returns do not match the expected schema. Alias them to the names in the downloaded file format.

It was working and stopped. The password may have been changed or the user disabled. A dedicated service user avoids this.