Bug #57441 | backup of data after reported binlog pos when using non-tx table in transaction | ||
---|---|---|---|
Submitted: | 13 Oct 2010 17:47 | Modified: | 20 Mar 2012 2:53 |
Reporter: | Victor Kirkebo | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Enterprise Backup | Severity: | S3 (Non-critical) |
Version: | 3.5 | OS: | Any |
Assigned to: | Thava Alagu | CPU Architecture: | Any |
[13 Oct 2010 17:47]
Victor Kirkebo
[14 Oct 2010 16:27]
Sveta Smirnova
Thank you for the report. When trying to run test from source directory I get error: Trying to set up a reference system with port=10750 ======================================================================= Could not find MySQL daemon client: '/users/ssmirnova/blade12/src/mysql-5.1-meb/libexec/mysqld' What should I fix to avoid this?
[21 Oct 2010 20:06]
Sveta Smirnova
Thank you for the feedback. You were right: files were not copied. Verified as described. I did additional modification to test file: added echo socket=/tmp/10760.sock >> $TST_PATH/backup/backup-my.cnf at line 81, so it can run while I have another mysqld using /tmp/mysql.sock
[9 Nov 2010 7:49]
Thava Alagu
The real problem is not that backup reports "old" binlog position. The problem is that we take the snapshot of MYISAM tables at binlog position "X", but it has physical changes caused by uncommitted triggers. When you rollback the trigger statement later, the changes to non-transactional tables are not rolled back. This is just the way triggers are implemented. I don't think the problem is critical for MySQL backup. There is no inconsistencies in innodb tables which is what it is primarily meant for. However we do have a problem by declaring the backup corresponds to binlog position X where some MyISAM tables may contain extraneous updates caused by some uncommitted trigger statements. It is important to note that the problem is restricted to "uncommitted trigger" statements only-- not any uncommitted statements. I think this should be documented, but not sure if it is important enough to fix it as there is no easy way to fix this for backup and consistency of MyISAM tables is not our focus. It is interesting to note that this is not specifically a problem for replication. Anyway, the binlog behaviour was much influenced by replication implementation to make sure the inability to completely rollback triggers won't break replication at slaves. The root cause of the problem is that the way triggers are implemented. Rolling back trigger statements does not rollback updates in non-transactional tables. It issues warning messages when such rollbacks are done. Just a modified SQL statements from Victor's test case illustrates the behaviour of trigger statements wrt how binlog grows: mysql> mysql> drop database if exists tst; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> create database tst; Query OK, 1 row affected (0.05 sec) mysql> use tst; Database changed mysql> mysql> create table t1(id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY (id), f1 varchar(10) ) engine=InnoDB; Query OK, 0 rows affected (0.03 sec) mysql> create table log(id INT) engine=MyISAM; Query OK, 0 rows affected (0.01 sec) mysql> mysql> delimiter // mysql> mysql> create trigger ins_trg after insert on t1 for each row -> begin -> insert into log(id) values(new.id); -> end// Query OK, 0 rows affected (0.01 sec) mysql> mysql> delimiter ; mysql> mysql> set autocommit=0; Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 741 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> insert into t1(f1) values("step1"); Query OK, 1 row affected (0.01 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 741 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> select * from log; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> rollback; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 1002 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> show warnings; +---------+------+---------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------+ | Warning | 1196 | Some non-transactional changed tables couldn't be rolled back | +---------+------+---------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> select * from log; +------+ | id | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> insert into t1(f1) values("step2"); Query OK, 1 row affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 1002 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> select * from log; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.00 sec) mysql> commit; Query OK, 0 rows affected (0.01 sec) mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 1220 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> select * from log; +------+ | id | +------+ | 1 | | 2 | +------+ 2 rows in set (0.00 sec) mysql>
[4 Dec 2010 12:11]
Thava Alagu
This has to be documented as a limitation of Point-In-Time recovery capability of the backup. It can be worded something like below: Under certain conditions, the physical backup taken by MyISAM may contain some extraneous updates which is not exactly in sync with the binlog position that the backup records. This can happen if following condtions are met during backup: (1) there are open transactions involving transactional and transactional tables and (2) the triggers which are fired on updates to transactional tables causes updates to non-transactional tables and (3) statement based bin logging is in effect.
[4 Dec 2010 13:28]
Thava Alagu
Actually the conditions just described are not the only conditions because the problem is not specific to triggers and not specific to binlog format either. It occurs when update statements mix transactional and non-transactional tables and autocommit is disabled. Consider the following: set autocommit=0; create table isam(i int) engine=MyISAM; create table ib(i int) engine=InnoDB; insert into isam values(1); insert into ib values(2); begin; show master status; ==> Say, binlog pos X insert into isam select * from ib; insert into isam select * from ib; show master status; ==> The binlog pos reported is still X; But MyISAM physical table gets updated. select sleep(60); ==> Backup taken now contains extra 2 updates in isam table, but associates with old binlog pos at the start of transaction. commit; show master status; The above behaviour is same for all binlog formats: row, statement and mixed. There is no easy way to fix this for backup and hence we need to accept this limitations in supporting PTR - point-in-time recovery and document it accordingly. Hence more refined statement of limitation would be: While the binlog position of the backup taken is accurate with respect to transactional tables, it may not be accurate for non-transactional tables under following conditions while taking backup: (1) There are open transactions with autocommit turned off AND (2) The transactions involve both transactional and non-transactional tables. In such cases, the binlog position is not updated until the transaction commits. In the meantime, the physical updates to MyISAM table happens without updating binlog position. As a result, the backup taken may contain extraneous updates in MyISAM tables which correspond to the real updates that would have taken place after the reported binlog position by backup.
[20 Mar 2012 2:53]
John Russell
Added under "Known Bugs and Limitations": In some cases, backups of non-transactional tables such as MyISAM tables could contain additional uncommitted data. If autocommit is turned off, and both InnoDB tables and non-transactional tables are modified within the same transaction, data can be written to the non-transactional table before the binlog position is updated. The binlog position is updated when the transaction is committed, but the non-transactional data is written immediately. If the backup occurs while such a transaction is open, the backup data contains the updates made to the non-transactional table.