@@ -340,14 +340,6 @@ struct rw_trx_hash_element_t
340340
341341
342342 trx_id_t id; /* lf_hash_init() relies on this to be first in the struct */
343-
344- /* *
345- Transaction serialization number.
346-
347- Assigned shortly before the transaction is moved to COMMITTED_IN_MEMORY
348- state. Initially set to TRX_ID_MAX.
349- */
350- Atomic_counter<trx_id_t > no;
351343 trx_t *trx;
352344 srw_mutex mutex;
353345};
@@ -443,7 +435,6 @@ class rw_trx_hash_t
443435 ut_ad (element->trx == 0 );
444436 element->trx = trx;
445437 element->id = trx->id ;
446- element->no = TRX_ID_MAX;
447438 trx->rw_trx_hash_element = element;
448439 }
449440
@@ -512,7 +503,6 @@ class rw_trx_hash_t
512503 if (element->trx )
513504 validate_element (element->trx );
514505 element->mutex .wr_unlock ();
515- ut_ad (element->id < element->no );
516506 return arg->action (element, arg->argument );
517507 }
518508#endif
@@ -849,6 +839,109 @@ class thread_safe_trx_ilist_t
849839 alignas (CPU_LEVEL1_DCACHE_LINESIZE) ilist<trx_t > trx_list;
850840};
851841
842+ class rw_trx_ids_t
843+ {
844+ struct rw_trx_id
845+ {
846+ Atomic_relaxed<trx_id_t > id{TRX_ID_MAX};
847+ Atomic_relaxed<trx_id_t > no{TRX_ID_MAX};
848+ trx_t *trx;
849+ rw_trx_id (trx_t *t): trx(t) {}
850+ };
851+ std::vector<rw_trx_id, ut_allocator<rw_trx_id>>
852+ ids{ut_allocator<rw_trx_id>(mem_key_trx_sys_t_rw_trx_ids)};
853+ mutable srw_spin_lock latch;
854+
855+ public:
856+ void assign_new_trx_no (const trx_t *trx) noexcept
857+ {
858+ ut_ad (trx->rw_trx_ids_slot != std::numeric_limits<uint32_t >::max ());
859+ ut_ad (trx->id < trx->no );
860+ trx->mutex_lock ();
861+ ut_ad (ids[trx->rw_trx_ids_slot ].id == trx->id );
862+ ut_ad (ids[trx->rw_trx_ids_slot ].no == TRX_ID_MAX);
863+ ids[trx->rw_trx_ids_slot ].no = trx->no ;
864+ trx->mutex_unlock ();
865+ }
866+ void snapshot_ids (trx_ids_t &view_ids, const trx_id_t max_trx_id,
867+ trx_id_t &min_trx_no) const noexcept
868+ {
869+ view_ids.clear ();
870+ latch.rd_lock (SRW_LOCK_CALL);
871+ view_ids.reserve (ids.size ());
872+ for (const auto &it : ids)
873+ {
874+ trx_id_t id= it.id ;
875+ if (id < max_trx_id)
876+ {
877+ view_ids.push_back (id);
878+ const trx_id_t no= it.no ;
879+ if (no < min_trx_no)
880+ min_trx_no= no;
881+ }
882+ }
883+ latch.rd_unlock ();
884+ }
885+ void register_rw (const trx_t *trx) noexcept
886+ {
887+ ut_ad (trx->rw_trx_ids_slot != std::numeric_limits<uint32_t >::max ());
888+ ut_ad (trx->no == TRX_ID_MAX);
889+ trx->mutex_lock ();
890+ ut_ad (ids[trx->rw_trx_ids_slot ].id == TRX_ID_MAX);
891+ ut_ad (ids[trx->rw_trx_ids_slot ].no == TRX_ID_MAX);
892+ ids[trx->rw_trx_ids_slot ].id = trx->id ;
893+ trx->mutex_unlock ();
894+ }
895+ void deregister_rw (const trx_t *trx) noexcept
896+ {
897+ ut_ad (trx->rw_trx_ids_slot != std::numeric_limits<uint32_t >::max ());
898+ trx->mutex_lock ();
899+ ut_ad (ids[trx->rw_trx_ids_slot ].id != TRX_ID_MAX);
900+ ut_ad (ids[trx->rw_trx_ids_slot ].id == trx->id );
901+ ut_ad (ids[trx->rw_trx_ids_slot ].no == trx->no );
902+ ids[trx->rw_trx_ids_slot ].id = TRX_ID_MAX;
903+ ids[trx->rw_trx_ids_slot ].no = TRX_ID_MAX;
904+ trx->mutex_unlock ();
905+ }
906+ void register_trx (trx_t *trx) noexcept
907+ {
908+ ut_ad (trx->rw_trx_ids_slot == std::numeric_limits<uint32_t >::max ());
909+ ut_ad (trx->no == TRX_ID_MAX);
910+ latch.wr_lock (SRW_LOCK_CALL);
911+ trx->rw_trx_ids_slot = static_cast <uint32_t >(ids.size ());
912+ ids.emplace_back (trx);
913+ latch.wr_unlock ();
914+ }
915+ void deregister_trx (trx_t *trx) noexcept
916+ {
917+ ut_ad (trx->rw_trx_ids_slot != std::numeric_limits<uint32_t >::max ());
918+ ut_ad (trx->no == TRX_ID_MAX);
919+ latch.wr_lock (SRW_LOCK_CALL);
920+ if (trx->rw_trx_ids_slot + 1 < ids.size ())
921+ {
922+ trx_t *move_trx= ids.back ().trx ;
923+ move_trx->mutex_lock ();
924+ ids[trx->rw_trx_ids_slot ]= std::move (ids.back ());
925+ move_trx->rw_trx_ids_slot = trx->rw_trx_ids_slot ;
926+ move_trx->mutex_unlock ();
927+ }
928+ ids.pop_back ();
929+ latch.wr_unlock ();
930+ trx->rw_trx_ids_slot = std::numeric_limits<uint32_t >::max ();
931+ }
932+ void create () noexcept
933+ {
934+ ut_ad (ids.size () == 0 );
935+ memset ((void *) &latch, 0 , sizeof (latch));
936+ latch.SRW_LOCK_INIT (rw_trx_ids_latch_key);
937+ }
938+ void destroy () noexcept
939+ {
940+ ut_ad (ids.size () == 0 );
941+ latch.destroy ();
942+ }
943+ };
944+
852945/* * The transaction system central memory data structure. */
853946class trx_sys_t
854947{
@@ -876,6 +969,8 @@ class trx_sys_t
876969 /* * False if there is no undo log to purge or rollback */
877970 bool undo_log_nonempty;
878971public:
972+ rw_trx_ids_t rw_trx_ids;
973+
879974 /* * List of all transactions. */
880975 thread_safe_trx_ilist_t trx_list;
881976
@@ -1057,7 +1152,8 @@ class trx_sys_t
10571152 */
10581153 void assign_new_trx_no (trx_t *trx)
10591154 {
1060- trx->rw_trx_hash_element ->no = get_new_trx_id_no_refresh ();
1155+ trx->no = get_new_trx_id_no_refresh ();
1156+ rw_trx_ids.assign_new_trx_no (trx);
10611157 refresh_rw_trx_hash_version ();
10621158 }
10631159
@@ -1078,27 +1174,19 @@ class trx_sys_t
10781174 of rw_trx_hash.iterate_no_dups(). It means that some transaction
10791175 identifiers may appear multiple times in ids.
10801176
1081- @param[in,out] caller_trx used to get access to rw_trx_hash_pins
10821177 @param[out] ids array to store registered transaction identifiers
10831178 @param[out] max_trx_id variable to store m_max_trx_id value
10841179 @param[out] mix_trx_no variable to store min(no) value
10851180 */
10861181
1087- void snapshot_ids (trx_t *caller_trx, trx_ids_t * ids, trx_id_t * max_trx_id,
1088- trx_id_t * min_trx_no)
1182+ void snapshot_ids (trx_ids_t & ids, trx_id_t & max_trx_id,
1183+ trx_id_t & min_trx_no)
10891184 {
1090- snapshot_ids_arg arg (ids);
1091-
1092- while ((arg.m_id = get_rw_trx_hash_version ()) != get_max_trx_id ())
1185+ while ((max_trx_id= get_rw_trx_hash_version ()) != get_max_trx_id ())
10931186 ut_delay (1 );
1094- arg.m_no = arg.m_id ;
1095-
1096- ids->clear ();
1097- ids->reserve (rw_trx_hash.size () + 32 );
1098- rw_trx_hash.iterate(caller_trx, copy_one_id, &arg);
10991187
1100- *max_trx_id= arg. m_id ;
1101- *min_trx_no= arg. m_no ;
1188+ min_trx_no= max_trx_id ;
1189+ rw_trx_ids. snapshot_ids (ids, max_trx_id, min_trx_no) ;
11021190 }
11031191
11041192
@@ -1166,8 +1254,9 @@ class trx_sys_t
11661254 void register_rw (trx_t *trx)
11671255 {
11681256 trx->id = get_new_trx_id_no_refresh ();
1169- rw_trx_hash. insert (trx);
1257+ rw_trx_ids. register_rw (trx);
11701258 refresh_rw_trx_hash_version ();
1259+ rw_trx_hash.insert (trx);
11711260 }
11721261
11731262
@@ -1178,9 +1267,11 @@ class trx_sys_t
11781267 MVCC snapshot won't see this transaction anymore.
11791268 */
11801269
1181- void deregister_rw (trx_t *trx)
1270+ void deregister_rw (trx_t *trx) noexcept
11821271 {
1272+ rw_trx_ids.deregister_rw (trx);
11831273 rw_trx_hash.erase (trx);
1274+ trx->no = TRX_ID_MAX;
11841275 }
11851276
11861277
@@ -1204,6 +1295,7 @@ class trx_sys_t
12041295 void register_trx (trx_t *trx)
12051296 {
12061297 trx_list.push_front (*trx);
1298+ rw_trx_ids.register_trx (trx);
12071299 }
12081300
12091301
@@ -1214,6 +1306,7 @@ class trx_sys_t
12141306 */
12151307 void deregister_trx (trx_t *trx)
12161308 {
1309+ rw_trx_ids.deregister_trx (trx);
12171310 trx_list.remove (*trx);
12181311 }
12191312
@@ -1266,31 +1359,6 @@ class trx_sys_t
12661359private:
12671360 static my_bool find_same_or_older_callback (void *el, void *i) noexcept ;
12681361
1269-
1270- struct snapshot_ids_arg
1271- {
1272- snapshot_ids_arg (trx_ids_t *ids): m_ids(ids) {}
1273- trx_ids_t *m_ids;
1274- trx_id_t m_id;
1275- trx_id_t m_no;
1276- };
1277-
1278-
1279- static my_bool copy_one_id (void * el, void *a)
1280- {
1281- auto element= static_cast <const rw_trx_hash_element_t *>(el);
1282- auto arg= static_cast <snapshot_ids_arg*>(a);
1283- if (element->id < arg->m_id )
1284- {
1285- trx_id_t no= element->no ;
1286- arg->m_ids ->push_back (element->id );
1287- if (no < arg->m_no )
1288- arg->m_no = no;
1289- }
1290- return 0 ;
1291- }
1292-
1293-
12941362 /* * Getter for m_rw_trx_hash_version, must issue ACQUIRE memory barrier. */
12951363 trx_id_t get_rw_trx_hash_version ()
12961364 {
0 commit comments