Skip to content

[Bug] Replica start fails with NotNullViolation on t_error_log.t_table_pkey when using MySQL 5.7 (binlog_row_metadata not available) #196

Description

@go-lazyer

When starting the replica with chameleon start_replica --config default --source mysql, the read process stays alive but the replay process dies immediately. The error is a PostgreSQL NotNullViolation on column t_table_pkey of the sch_chameleon.t_error_log table.

The root cause appears to be that the fn_replay_mysql function attempts to insert a NULL value into the t_table_pkey column when it cannot extract primary key metadata from the MySQL binlog event. This happens because MySQL 5.7 does not support the binlog_row_metadata system variable, which was introduced in MySQL 8.0.21. The mysql-replication library used by pg_chameleon requires this parameter to be set to FULL to properly decode row events.

Environment:

pg_chameleon version: 2.0.21

MySQL version: 5.7.x (does not support binlog_row_metadata)

PostgreSQL version: 18

Python version: 3.11

OS: Debian 12.11 64位

MySQL Configuration:

ini
binlog_format = ROW
binlog_row_image = FULL

binlog_row_metadata is NOT available in MySQL 5.7

Error Log:

text
2026-06-24 18:30:51 MainProcess ERROR: Read process alive: True - Replay process alive: False
2026-06-24 18:30:51 MainProcess ERROR: Stack trace: Traceback (most recent call last):
File "/home/hanchanghong/pg_chameleon_env/lib/python3.11/site-packages/pg_chameleon/lib/global_lib.py", line 551, in replay_replica
tables_error = self.pg_engine.replay_replica()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/hanchanghong/pg_chameleon_env/lib/python3.11/site-packages/pg_chameleon/lib/pg_lib.py", line 1222, in replay_replica
self.pgsql_cur.execute(sql_replay, (replay_max_rows, self.i_id_source, exit_on_error))
psycopg2.errors.NotNullViolation: null value in column "t_table_pkey" of relation "t_error_log" violates not-null constraint
DETAIL: Failing row contains (12, 35, 9, bai_root, public, null, mysql-bin.285451, 51451482, 2026-06-24 18:30:41.111467, 'UPDATE public.bai_root SET "UNKNOWN_COL0"=''002b84f93f6948f88a4..., 42601 - syntax error at or near ";").
CONTEXT: SQL statement "INSERT INTO sch_chameleon.t_error_log ..."
PL/pgSQL function sch_chameleon.fn_replay_mysql(integer,integer,boolean) line 264 at SQL statement
Analysis:

The replay process executes the PL/pgSQL function fn_replay_mysql.

This function attempts to insert a row into t_error_log, selecting v_r_statements.t_pk_data as the value for t_table_pkey.

t_pk_data is NULL for the binlog event being processed, causing the NOT NULL constraint violation.

The UPDATE statement in the error shows "UNKNOWN_COL0", indicating that the column metadata from the binlog could not be properly decoded.

This is consistent with the known requirement from the underlying mysql-replication library that binlog_row_metadata must be set to FULL.

However, this parameter does not exist in MySQL 5.7. The __check_mysql_config function in pg_chameleon's mysql_lib module does not appear to check for this compatibility issue.

Steps to Reproduce:

Set up a MySQL 5.7 source with binlog_format=ROW and binlog_row_image=FULL.

Configure pg_chameleon 2.0.21 to replicate from this source.

Run chameleon init_replica --config default --source mysql (this succeeds).

Run chameleon start_replica --config default --source mysql.

The error occurs and the replay process dies.

Expected Behavior:

pg_chameleon should either:

Support MySQL 5.7 gracefully by handling the absence of binlog_row_metadata (e.g., by using an alternative method to obtain primary key metadata), or

Explicitly check for MySQL version and binlog_row_metadata support during the configuration check and provide a clear error message indicating that MySQL 8.0.21+ is required, rather than failing with a NOT NULL violation.

Possible Fix Suggestions:

Documentation: Clearly state in the requirements that MySQL 8.0.21+ (with binlog_row_metadata=FULL) is required, or provide a workaround for MySQL 5.7.

Configuration Check: Enhance __check_mysql_config in mysql_lib.py to detect MySQL version and warn/error if binlog_row_metadata is not available and binlog_row_image is set to FULL.

Code Fix: Investigate whether the mysql-replication library can be used in a way that is compatible with MySQL 5.7's binlog format, or handle the NULL t_pk_data case more gracefully in fn_replay_mysql.

Additional Context:

This issue has been reported by other users in the community, with the suggested fix being to set binlog_row_metadata=FULL. However, this is not possible on MySQL 5.7, making pg_chameleon 2.0.21 effectively incompatible with MySQL 5.7 out of the box.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions