diff --git a/drainer/translator/mysql.go b/drainer/translator/mysql.go index afcc6ab19..ca6d1d4bc 100644 --- a/drainer/translator/mysql.go +++ b/drainer/translator/mysql.go @@ -256,7 +256,12 @@ func formatData(data types.Datum, ft types.FieldType) (types.Datum, error) { case mysql.TypeSet: data = types.NewDatum(data.GetMysqlSet().Value) case mysql.TypeBit: - data = types.NewDatum(data.GetBytes()) + // Encode bits as integers to avoid pingcap/tidb#10988 (which also affects MySQL itself) + val, err := data.GetBinaryLiteral().ToInt(nil) + if err != nil { + return types.Datum{}, err + } + data = types.NewUintDatum(val) } return data, nil diff --git a/tests/update_bit1/drainer.toml b/tests/update_bit1/drainer.toml new file mode 100644 index 000000000..233cf2390 --- /dev/null +++ b/tests/update_bit1/drainer.toml @@ -0,0 +1,18 @@ +detect-interval = 10 +data-dir = '/tmp/tidb_binlog_test/update_bit1' +pd-urls = 'http://127.0.0.1:2379' + +[syncer] +ignore-schemas = 'INFORMATION_SCHEMA,PERFORMANCE_SCHEMA,mysql' +txn-batch = 1 +worker-count = 1 +disable-dispatch = false +safe-mode = false +db-type = 'mysql' +replicate-do-db = ['update_bit1'] + +[syncer.to] +host = '127.0.0.1' +user = 'root' +password = '' +port = 3306 diff --git a/tests/update_bit1/run.sh b/tests/update_bit1/run.sh new file mode 100644 index 000000000..94f2624b3 --- /dev/null +++ b/tests/update_bit1/run.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +set -e + +cd "$(dirname "$0")" + +run_drainer & + +run_sql 'DROP DATABASE IF EXISTS update_bit1;' +run_sql 'CREATE DATABASE update_bit1;' +run_sql 'CREATE TABLE update_bit1.t(a BIT(1) NOT NULL);' +run_sql 'INSERT INTO update_bit1.t VALUES (0x01);' + +sleep 3 + +down_run_sql 'SELECT HEX(a) FROM update_bit1.t;' +check_contains 'HEX(a): 1' + +# Verify fix for TOOL-1346. + +run_sql 'UPDATE update_bit1.t SET a = 0x00;' + +sleep 3 + +down_run_sql 'SELECT HEX(a) FROM update_bit1.t;' +check_contains 'HEX(a): 0' + +killall drainer