Bug #82938 Document are not correct in the case of innodb_support_xa=true.
Submitted: 10 Sep 2016 8:23 Modified: 14 Sep 2016 14:16
Reporter: Takanori Sejima Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.7 OS:Any
Assigned to: CPU Architecture:Any
Tags: crash recovery

[10 Sep 2016 8:23] Takanori Sejima
Description:
When innodb_support_xa == true(always enabled as of MySQL 5.7.10) and log_bin=true, as part of crash recovery, InnoDB will commit transaction which is in the prepared state. 

@see Figure 1. Two-Phase Commit Protocol(2PC)
http://mysqlmusings.blogspot.jp/2012/06/binary-log-group-commit-in-mysql-56.html

In the case of InnoDB, at the time of the "prepare",  innodb_xa_prepare() is executed, it write MYSQL_XID and mlog to UNDO LOG. Then, the time of "write", the XID is recorded as Xid_log_event to binary log. If the server crashes between "fsync" and "commit", since LOG_EVENT_BINLOG_IN_USE_F flag has been set in the header of the binary log, MYSQL_BIN_LOG::recover() is executed. Then, the transaction has left in a PREPARED state in UNDO LOG, if the XID was in the binary log, and innodb_commit_by_xid() is executed, InnoDB will commit transaction which is in the prepared state. 

See Comment:
https://github.com/mysql/mysql-server/blob/mysql-5.7.12/sql/binlog.cc#L7712-L7724

However, there is an sentence
https://dev.mysql.com/doc/refman/5.7/en/innodb-recovery.html
```
As part of crash recovery, InnoDB rolls back any transactions that were not committed or in XA PREPARE state when the server crashed. 
```

And, 
https://dev.mysql.com/doc/refman/5.7/en/binary-log.html
```
The InnoDB logs are synchronized by default, and sync_binlog=1 can be used to synchronize the binary log. The effect of this option is that at restart after a crash, after doing a rollback of transactions, the MySQL server removes rolled back InnoDB transactions from the binary log. 
```

These descriptions are not correct as the behavior of the crash recovery in the case of innodb_support_xa = true.

How to repeat:

01. build MySQL server with -DWITH_DEBUG=1.
02. set log_bin and server_id in my.cnf.
03. start mysqld_safe.
04. create test table.
05. attach mysqld by gdb.
06. rbreak sync_binlog_file and continue.
07. insert test data into test table.
08. return from sync_binlog_file().
09. kill mysqld by gdb.
10. innodb_commit_by_xid() will executed, and complete commit of test data , and write message“commit xid”to error_log.

https://github.com/mysql/mysql-server/blob/mysql-5.7.12/sql/xa.cc#L117
[14 Sep 2016 14:16] MySQL Verification Team
Hi!

If you read our manual, you will find out that XA transactions are global transactions, not managed by one instance only. XA transactions are totally managed on the client-side, and some of our Connectors have tools to manage it. XA transactions can involve many servers and are there to make sure that the entire XA transaction is committed successfully on all servers.

If anything goes wrong, it is up to the client's program to remedy the situation.