Import MySQL data failed with error 1839
I have master slave setup of MySQL with GTID configured. I took back data backup of master and importing it to individual Test server. It is failing to import as
ERROR 1839 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_MODE = ON
I tried with --set-gtid-purged=OFF
and AUTO
, but no luck.
Solution 1:
If you run a
SHOW MASTER STATUS\G
you'll see something like this:
mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000299
Position: 780437462
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 075d81d6-8d7f-11e3-9d88-b4b52f517ce4:1-616637650,
e907792a-8417-11e3-a037-b4b52f51dbf8:1-25385296642
1 row in set (0.00 sec)
Becuase when GTID is enabled all the servers got their own uuid, and there are transactions. I suppose you created the dump with mysqldump, and if you look at the beginning of that file, you'll find something similiar as this:
--
-- GTID state at the beginning of the backup
--
SET @@GLOBAL.GTID_PURGED='075d81d6-8d7f-11e3-9d88-b4b52f517ce4:1-616648986,
e907792a-8417-11e3-a037-b4b52f51dbf8:1-25385296642';
This is the command which cannot be executed.
You have the following options:
Remove this command from the mysql dump file. Simply delete it. All the inserts will appear on slave as it's local transactions
-
If you want to prevent this happening, you can also reset master on slave
mysql> RESET MASTER;
This command will clean up the 'Executed_Gtid_Set' variable on slave, so you can import the dumpfile directly, and the previously mentioned set_global_gtid_purged variable takes action
When you create the mysqldump, you can skip the GTID setup part as adding the
--set-gtid-purged=OFF
parameter for mysqldump.
NOTE:
if the GTID subset differs on master between master and slave (if you want to use this in a replication setup) then the replication will not work, I'd recommend a binary dump and restore, as setting the slave's GTID exactly to the master's.
With GTID there are a lot of new problems emerge, but your replica setup will be more consistent. It is worth working with that.
Solution 2:
If you are like me and you don't want to re-run your dump because it was a very long operation you can just remove those lines after the fact.
find . -name '*.sql' -type f -exec perl -0 -i.bak -pe 's/SET \@\@GLOBAL\.GTID_PURGED=\x27.*?\x27;//gs' {} +
Run this in the folder with your .sql files. It will save the old veresion as .bak.
This worked for me.
Solution 3:
I have a huge database, so, like @Goddard,
I have a backup/dump spread across several files.
I have low disk space,
so I export my dump in compressed format (i.e., .sql.gz
).
@Goddard's solution appeals to me, but, as I am running on low disk space,
I can't afford to extract those files to .sql and then apply changes.
Instead of that I'll execute the following adaptation of @Goddard's answer
to import .sql.gz
files, removing the GTID query as I go.
find "$DIR" -name "*.sql.gz" | while read table
do
echo "$table"
zcat "$table" | perl -pe 's/SET \@\@GLOBAL\.GTID_PURGED=\x27.*?\x27;//gs' | \
mysql -h "$HOST" -u "$USER" -p"$PASS" -P "$PORT" "$DB"
done