{"push_id":866597770,"size":1,"distinct_size":1,"ref":"refs/heads/3.x-pxc-456","head":"598d8fca4d9a293124fea9faffb4faf5c3aec3e7","before":"43a7f2bbed4a4346ae6fab53196c2e80ff3c9b78","commits":[{"sha":"598d8fca4d9a293124fea9faffb4faf5c3aec3e7","author":{"email":"b1f80d0d6abea91ddc55a38e42ca9d3f6f9d1fca@percona.com","name":"Krunal Bauskar"},"message":"- PXC#456: WSREP: FSM: no such a transition ROLLED_BACK -> ROLLED_BACK with\n  LOAD DATA INFILE\n\n  Issue:\n  -----\n\n  LDI for that matter DML statement can fail due to multiple reasons.\n  Some probable reasons are:\n  - Creating table w/o pk and setting wsrep_certify_nonPK = off\n  - Existing bug that causes partitioned table LDI to fail.\n  ....etc.\n\n  Statement failure will skip append_key which besides appending key also\n  set valid trx_id.\n  Such failed statements are rolled back with trx_id = default.\n  Galera-Plugin try to check if there is an existing Trx Object with\n  given trx_id before creating a new one.\n\n  If there are 2 independent connections (connected to same cluster node)\n  and both of these connections execute a failing statement then\n  both of them will try to rollback with trx_id = default.\n\n  Logic that cached trx_id to trx-object never considered this situation\n  and one of the such connection will get reference to a object that belongs\n  to other connection which is logically wrong as both connection are unrelated.\n  This also causes operational in-consistency as latter connection accesses\n  state already modified by former connection.\n  (Causing the famous ROLLBACK -> ROLLBACK assert).\n\n  Solution(s):\n  -----------\n\n  (I am listing all possible solution with one we have selected)\n\n  * trx-map should use pair of <trx_id, conn_id> as map key.\n\n  * trx-map should use multi-map with trx_id -> TrxObject\n    TrxObject can use valid conn_id (vs -1 for now).\n    For valid trx_id there only 1 trx_id -> TrxObject pair\n    for default there could be multiple trx_id -> TrxObjects pair\n    so proper pair is selected based on conn_id.\n\n  [Both of the above approach needs interface change so ruled out for now]\n\n  * Re-arrange the logic to discard_trx object while holding lock on trx\n    so that latter connection will get reference to the object but will\n    not be able to operate on it till former one is done.\n    (Logically 2 connections are sharing the objects which itself is wrong\n     but if this can be made possible with some tweak in the code it will\n     introduce flow control as it involves exception handling).\n\n  * Introduce a separate map that will cache pthread_id -> TrxObject if\n    trx_id = default.\n  (Given the limited changes involved we opted for this solution though\n   we would love to sort this out with upstream using interface change\n   solutions mentioned above).","distinct":true,"url":"https://api.github.com/repos/kbauskar/galera/commits/598d8fca4d9a293124fea9faffb4faf5c3aec3e7"}]}