@@ -816,6 +816,12 @@ type RUDetails struct {
816816 tiflashRU * uatomic.Float64
817817 // tikvRUV2 stores TiKV RU v2 value in scaled units.
818818 tikvRUV2 * uatomic.Float64
819+ // The following fields preserve TiKV-side RUv2 raw counters that TiDB
820+ // needs for statement-level detail output and TiDB-side RUv2 calculation.
821+ resourceManagerReadCnt int64
822+ resourceManagerWriteCnt int64
823+ tikvStorageProcessedKeysGet int64
824+ tikvStorageProcessedKeysBatchGet int64
819825}
820826
821827// NewRUDetails creates a new RUDetails.
@@ -843,13 +849,18 @@ func NewRUDetailsWith(rru, wru float64, waitDur time.Duration) *RUDetails {
843849
844850// Clone implements the RuntimeStats interface.
845851func (rd * RUDetails ) Clone () * RUDetails {
846- return & RUDetails {
852+ cloned := & RUDetails {
847853 readRU : uatomic .NewFloat64 (rd .readRU .Load ()),
848854 writeRU : uatomic .NewFloat64 (rd .writeRU .Load ()),
849855 ruWaitDuration : uatomic .NewDuration (rd .ruWaitDuration .Load ()),
850856 tiflashRU : uatomic .NewFloat64 (rd .tiflashRU .Load ()),
851857 tikvRUV2 : uatomic .NewFloat64 (rd .tikvRUV2 .Load ()),
852858 }
859+ atomic .StoreInt64 (& cloned .resourceManagerReadCnt , atomic .LoadInt64 (& rd .resourceManagerReadCnt ))
860+ atomic .StoreInt64 (& cloned .resourceManagerWriteCnt , atomic .LoadInt64 (& rd .resourceManagerWriteCnt ))
861+ atomic .StoreInt64 (& cloned .tikvStorageProcessedKeysGet , atomic .LoadInt64 (& rd .tikvStorageProcessedKeysGet ))
862+ atomic .StoreInt64 (& cloned .tikvStorageProcessedKeysBatchGet , atomic .LoadInt64 (& rd .tikvStorageProcessedKeysBatchGet ))
863+ return cloned
853864}
854865
855866// Merge implements the RuntimeStats interface.
@@ -859,6 +870,10 @@ func (rd *RUDetails) Merge(other *RUDetails) {
859870 rd .ruWaitDuration .Add (other .ruWaitDuration .Load ())
860871 rd .tiflashRU .Add (other .tiflashRU .Load ())
861872 rd .tikvRUV2 .Add (other .tikvRUV2 .Load ())
873+ atomic .AddInt64 (& rd .resourceManagerReadCnt , other .ResourceManagerReadCnt ())
874+ atomic .AddInt64 (& rd .resourceManagerWriteCnt , other .ResourceManagerWriteCnt ())
875+ atomic .AddInt64 (& rd .tikvStorageProcessedKeysGet , other .TiKVStorageProcessedKeysGet ())
876+ atomic .AddInt64 (& rd .tikvStorageProcessedKeysBatchGet , other .TiKVStorageProcessedKeysBatchGet ())
862877}
863878
864879// String implements fmt.Stringer interface.
@@ -904,6 +919,90 @@ func (rd *RUDetails) AddTiKVRUV2(delta float64) {
904919 rd .tikvRUV2 .Add (delta )
905920}
906921
922+ // AddResourceManagerReadCnt records TiKV read RPCs charged to resource management.
923+ func (rd * RUDetails ) AddResourceManagerReadCnt (delta int64 ) {
924+ if rd == nil || delta == 0 {
925+ return
926+ }
927+ atomic .AddInt64 (& rd .resourceManagerReadCnt , delta )
928+ }
929+
930+ // ResourceManagerReadCnt returns TiKV read RPCs charged to resource management.
931+ func (rd * RUDetails ) ResourceManagerReadCnt () int64 {
932+ if rd == nil {
933+ return 0
934+ }
935+ return atomic .LoadInt64 (& rd .resourceManagerReadCnt )
936+ }
937+
938+ // AddResourceManagerWriteCnt records TiKV write RPCs charged to resource management.
939+ func (rd * RUDetails ) AddResourceManagerWriteCnt (delta int64 ) {
940+ if rd == nil || delta == 0 {
941+ return
942+ }
943+ atomic .AddInt64 (& rd .resourceManagerWriteCnt , delta )
944+ }
945+
946+ // ResourceManagerWriteCnt returns TiKV write RPCs charged to resource management.
947+ func (rd * RUDetails ) ResourceManagerWriteCnt () int64 {
948+ if rd == nil {
949+ return 0
950+ }
951+ return atomic .LoadInt64 (& rd .resourceManagerWriteCnt )
952+ }
953+
954+ // AddTiKVStorageProcessedKeysBatchGet records TiKV batch-get processed keys.
955+ func (rd * RUDetails ) AddTiKVStorageProcessedKeysBatchGet (delta int64 ) {
956+ if rd == nil || delta == 0 {
957+ return
958+ }
959+ atomic .AddInt64 (& rd .tikvStorageProcessedKeysBatchGet , delta )
960+ }
961+
962+ // TiKVStorageProcessedKeysBatchGet returns TiKV batch-get processed keys.
963+ func (rd * RUDetails ) TiKVStorageProcessedKeysBatchGet () int64 {
964+ if rd == nil {
965+ return 0
966+ }
967+ return atomic .LoadInt64 (& rd .tikvStorageProcessedKeysBatchGet )
968+ }
969+
970+ // AddTiKVStorageProcessedKeysGet records TiKV get processed keys.
971+ func (rd * RUDetails ) AddTiKVStorageProcessedKeysGet (delta int64 ) {
972+ if rd == nil || delta == 0 {
973+ return
974+ }
975+ atomic .AddInt64 (& rd .tikvStorageProcessedKeysGet , delta )
976+ }
977+
978+ // TiKVStorageProcessedKeysGet returns TiKV get processed keys.
979+ func (rd * RUDetails ) TiKVStorageProcessedKeysGet () int64 {
980+ if rd == nil {
981+ return 0
982+ }
983+ return atomic .LoadInt64 (& rd .tikvStorageProcessedKeysGet )
984+ }
985+
986+ // UpdateTiKVRUV2RawDetails accumulates TiKV-side RUv2 raw counters into RUDetails.
987+ func UpdateTiKVRUV2RawDetails (ctx context.Context , details * kvrpcpb.ExecDetailsV2 , resourceManagerReadCnt , resourceManagerWriteCnt int64 ) {
988+ if ctx == nil {
989+ return
990+ }
991+ ruDetails , _ := ctx .Value (RUDetailsCtxKey ).(* RUDetails )
992+ if ruDetails == nil {
993+ return
994+ }
995+
996+ ruDetails .AddResourceManagerReadCnt (resourceManagerReadCnt )
997+ ruDetails .AddResourceManagerWriteCnt (resourceManagerWriteCnt )
998+ if details == nil || details .RuV2 == nil {
999+ return
1000+ }
1001+ ru := details .RuV2
1002+ ruDetails .AddTiKVStorageProcessedKeysBatchGet (int64 (ru .StorageProcessedKeysBatchGet ))
1003+ ruDetails .AddTiKVStorageProcessedKeysGet (int64 (ru .StorageProcessedKeysGet ))
1004+ }
1005+
9071006// Update updates the RU runtime stats with the given consumption info.
9081007func (rd * RUDetails ) Update (consumption * rmpb.Consumption , waitDuration time.Duration ) {
9091008 if rd == nil || consumption == nil {
0 commit comments