If PreparedOp or ParticipantList object end up on servers that aren't or are no longer participants in the transaction, the objects may never be garbage collected because transaction recovery will not target these servers.
This might happen if:
a tablet is migrated while a transaction is in progress and the transaction's PreparedOps and ParticipantList log entries on the old master are not dropped after the migration completes.
the prepare request is sent to the wrong server and the ParticipantList is added preemptively.
Possible solution: Have the InProgressTransaction garbage collection mechanism (that triggers after a transaction timeout) check to make sure the transaction belongs on the residing server.
Doing the check might be expensive; must check each entry in the ParticipantList to make sure at least one belongs to a tablet owned by the current master.
Mechanism also needs to remove old PreparedOp object; there is currently no map from a transactionId to the objects.