4040#include " myisam.h"
4141#include " probes_mysql.h"
4242#include < mysql/psi/mysql_table.h>
43+ #include < pfs_transaction_provider.h>
44+ #include < mysql/psi/mysql_transaction.h>
4345#include " debug_sync.h" // DEBUG_SYNC
4446#include " sql_audit.h"
4547#include " ha_sequence.h"
6264#include " wsrep_trans_observer.h" /* wsrep transaction hooks */
6365#endif /* WITH_WSREP */
6466
67+ /* *
68+ @def MYSQL_TABLE_LOCK_WAIT
69+ Instrumentation helper for table io_waits.
70+ @param OP the table operation to be performed
71+ @param FLAGS per table operation flags.
72+ @param PAYLOAD the code to instrument.
73+ @sa MYSQL_END_TABLE_WAIT.
74+ */
75+ #ifdef HAVE_PSI_TABLE_INTERFACE
76+ #define MYSQL_TABLE_LOCK_WAIT (OP, FLAGS, PAYLOAD ) \
77+ { \
78+ if (m_psi != NULL ) \
79+ { \
80+ PSI_table_locker *locker; \
81+ PSI_table_locker_state state; \
82+ locker= PSI_TABLE_CALL (start_table_lock_wait) \
83+ (& state, m_psi, OP, FLAGS, \
84+ __FILE__, __LINE__); \
85+ PAYLOAD \
86+ if (locker != NULL ) \
87+ PSI_TABLE_CALL (end_table_lock_wait)(locker); \
88+ } \
89+ else \
90+ { \
91+ PAYLOAD \
92+ } \
93+ }
94+ #else
95+ #define MYSQL_TABLE_LOCK_WAIT (OP, FLAGS, PAYLOAD ) \
96+ PAYLOAD
97+ #endif
98+
99+
65100/*
66101 While we have legacy_db_type, we have this array to
67102 check for dups and to find handlerton from legacy_db_type.
@@ -1201,7 +1236,8 @@ void ha_pre_shutdown()
12011236 times per transaction.
12021237
12031238*/
1204- void trans_register_ha (THD *thd, bool all, handlerton *ht_arg)
1239+ void trans_register_ha (THD *thd, bool all, handlerton *ht_arg,
1240+ const ulonglong *trxid)
12051241{
12061242 THD_TRANS *trans;
12071243 Ha_trx_info *ha_info;
@@ -1232,6 +1268,25 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
12321268 if (thd->transaction .implicit_xid .is_null ())
12331269 thd->transaction .implicit_xid .set (thd->query_id );
12341270
1271+ /*
1272+ Register transaction start in performance schema if not done already.
1273+ By doing this, we handle cases when the transaction is started implicitly in
1274+ autocommit=0 mode, and cases when we are in normal autocommit=1 mode and the
1275+ executed statement is a single-statement transaction.
1276+
1277+ Explicitly started transactions are handled in trans_begin().
1278+
1279+ Do not register transactions in which binary log is the only participating
1280+ transactional storage engine.
1281+ */
1282+ if (thd->m_transaction_psi == NULL && ht_arg->db_type != DB_TYPE_BINLOG)
1283+ {
1284+ thd->m_transaction_psi = MYSQL_START_TRANSACTION (&thd->m_transaction_state ,
1285+ thd->get_xid (), trxid, thd->tx_isolation , thd->tx_read_only ,
1286+ !thd->in_multi_stmt_transaction_mode ());
1287+ DEBUG_SYNC (thd, " after_set_transaction_psi_before_set_transaction_gtid" );
1288+ // gtid_set_performance_schema_values(thd);
1289+ }
12351290 DBUG_VOID_RETURN;
12361291}
12371292
@@ -1457,7 +1512,11 @@ int ha_commit_trans(THD *thd, bool all)
14571512 Free resources and perform other cleanup even for 'empty' transactions.
14581513 */
14591514 if (is_real_trans)
1515+ {
14601516 thd->transaction .cleanup ();
1517+ MYSQL_COMMIT_TRANSACTION (thd->m_transaction_psi );
1518+ thd->m_transaction_psi = NULL ;
1519+ }
14611520#ifdef WITH_WSREP
14621521 if (wsrep_is_active (thd) && is_real_trans && !error)
14631522 wsrep_commit_empty (thd, all);
@@ -1651,12 +1710,15 @@ int ha_commit_trans(THD *thd, bool all)
16511710#endif /* WITH_WSREP */
16521711 DBUG_EXECUTE_IF (" crash_commit_before_unlog" , DBUG_SUICIDE (););
16531712 if (tc_log->unlog (cookie, xid))
1654- {
16551713 error= 2 ; /* Error during commit */
1656- goto end;
1657- }
16581714
16591715done:
1716+ if (is_real_trans)
1717+ {
1718+ MYSQL_COMMIT_TRANSACTION (thd->m_transaction_psi );
1719+ thd->m_transaction_psi = NULL ;
1720+ }
1721+
16601722 DBUG_EXECUTE_IF (" crash_commit_after" , DBUG_SUICIDE (););
16611723
16621724 mysql_mutex_assert_not_owner (&LOCK_prepare_ordered);
@@ -1694,6 +1756,8 @@ int ha_commit_trans(THD *thd, bool all)
16941756 ha_rollback_trans (thd, all);
16951757 else
16961758 {
1759+ MYSQL_ROLLBACK_TRANSACTION (thd->m_transaction_psi );
1760+ thd->m_transaction_psi = NULL ;
16971761 WSREP_DEBUG (" rollback skipped %p %d" ,thd->rgi_slave ,
16981762 thd->rgi_slave ->is_parallel_exec );
16991763 }
@@ -1913,6 +1977,13 @@ int ha_rollback_trans(THD *thd, bool all)
19131977 }
19141978 (void ) wsrep_after_rollback (thd, all);
19151979#endif /* WITH_WSREP */
1980+
1981+ if (all || !thd->in_active_multi_stmt_transaction ())
1982+ {
1983+ MYSQL_ROLLBACK_TRANSACTION (thd->m_transaction_psi );
1984+ thd->m_transaction_psi = NULL ;
1985+ }
1986+
19161987 /* Always cleanup. Even if nht==0. There may be savepoints. */
19171988 if (is_real_trans)
19181989 {
@@ -2360,6 +2431,10 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
23602431 ha_info->reset (); /* keep it conveniently zero-filled */
23612432 }
23622433 trans->ha_list = sv->ha_list ;
2434+
2435+ if (thd->m_transaction_psi != NULL )
2436+ MYSQL_INC_TRANSACTION_ROLLBACK_TO_SAVEPOINT (thd->m_transaction_psi , 1 );
2437+
23632438 DBUG_RETURN (error);
23642439}
23652440
@@ -2411,6 +2486,9 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
24112486 */
24122487 sv->ha_list = trans->ha_list ;
24132488
2489+ if (!error && thd->m_transaction_psi != NULL )
2490+ MYSQL_INC_TRANSACTION_SAVEPOINTS (thd->m_transaction_psi , 1 );
2491+
24142492 DBUG_RETURN (error);
24152493}
24162494
@@ -2435,6 +2513,10 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
24352513 error=1 ;
24362514 }
24372515 }
2516+
2517+ if (thd->m_transaction_psi != NULL )
2518+ MYSQL_INC_TRANSACTION_RELEASE_SAVEPOINT (thd->m_transaction_psi , 1 );
2519+
24382520 DBUG_RETURN (error);
24392521}
24402522
0 commit comments