github.com/matrixorigin/matrixone@v1.2.0/pkg/sql/colexec/table_function/system_view.go (about) 1 // Copyright 2023 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package table_function 16 17 import ( 18 "context" 19 "encoding/hex" 20 "fmt" 21 qclient "github.com/matrixorigin/matrixone/pkg/queryservice/client" 22 "strconv" 23 "strings" 24 "time" 25 26 "github.com/matrixorigin/matrixone/pkg/clusterservice" 27 "github.com/matrixorigin/matrixone/pkg/common/moerr" 28 "github.com/matrixorigin/matrixone/pkg/common/mpool" 29 "github.com/matrixorigin/matrixone/pkg/container/batch" 30 "github.com/matrixorigin/matrixone/pkg/container/vector" 31 pblock "github.com/matrixorigin/matrixone/pkg/pb/lock" 32 logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 33 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 34 "github.com/matrixorigin/matrixone/pkg/pb/query" 35 "github.com/matrixorigin/matrixone/pkg/queryservice" 36 plan2 "github.com/matrixorigin/matrixone/pkg/sql/plan" 37 "github.com/matrixorigin/matrixone/pkg/vm" 38 "github.com/matrixorigin/matrixone/pkg/vm/engine/disttae" 39 "github.com/matrixorigin/matrixone/pkg/vm/process" 40 ) 41 42 const ( 43 lockStatusWait = "wait" // nobody holds the lock but somebody waits on it 44 lockStatusAcquired = "acquired" // somebody holds the lock 45 lockStatusNone = "none" // nobody waits and holds the lock 46 ) 47 48 func getLockStatus(li *query.LockInfo) string { 49 hasHolders := len(li.GetHolders()) != 0 50 hasWaiters := len(li.GetWaiters()) != 0 51 if !hasHolders && !hasWaiters { 52 return lockStatusNone 53 } else if hasHolders { 54 return lockStatusAcquired 55 } else { 56 return lockStatusWait 57 } 58 } 59 60 func getRangeKeys(li *query.LockInfo) ([]byte, []byte) { 61 keys := li.GetKeys() 62 llen := len(keys) 63 if llen >= 2 { 64 return keys[0], keys[1] 65 } else if llen >= 1 { 66 return keys[0], []byte{} 67 } else { 68 return []byte{}, []byte{} 69 } 70 } 71 72 func getPointKey(li *query.LockInfo) []byte { 73 keys := li.GetKeys() 74 llen := len(keys) 75 if llen >= 1 { 76 return keys[0] 77 } 78 return []byte{} 79 } 80 81 func moLocksPrepare(proc *process.Process, arg *Argument) error { 82 arg.ctr.state = dataProducing 83 if len(arg.Args) > 0 { 84 return moerr.NewInvalidInput(proc.Ctx, "moConfigurations: no argument is required") 85 } 86 for i := range arg.Attrs { 87 arg.Attrs[i] = strings.ToUpper(arg.Attrs[i]) 88 } 89 return nil 90 } 91 92 func moLocksCall(_ int, proc *process.Process, arg *Argument, result *vm.CallResult) (bool, error) { 93 switch arg.ctr.state { 94 case dataProducing: 95 96 rsps, err := getLocks(proc) 97 if err != nil { 98 return false, err 99 } 100 101 //alloc batch 102 bat := batch.NewWithSize(len(arg.Attrs)) 103 for i, col := range arg.Attrs { 104 col = strings.ToLower(col) 105 idx, ok := plan2.MoLocksColName2Index[col] 106 if !ok { 107 return false, moerr.NewInternalError(proc.Ctx, "bad input select columns name %v", col) 108 } 109 110 tp := plan2.MoLocksColTypes[idx] 111 bat.Vecs[i] = proc.GetVector(tp) 112 } 113 bat.Attrs = arg.Attrs 114 115 //fill batch from lock info 116 for _, rsp := range rsps { 117 if rsp == nil || len(rsp.LockInfoList) == 0 { 118 continue 119 } 120 for _, lock := range rsp.LockInfoList { 121 if lock == nil { 122 continue 123 } 124 cnId := rsp.GetCnId() 125 //sessionId := "" 126 txnId := "" 127 tableId := fmt.Sprintf("%d", lock.GetTableId()) 128 129 //table name 130 //tableName := "" 131 //lock key 132 lockKey := "point" 133 if lock.GetIsRangeLock() { 134 lockKey = "range" 135 } 136 137 //lock content 138 lockContent := "" 139 if lock.GetIsRangeLock() { 140 k1, k2 := getRangeKeys(lock) 141 lockContent = hex.EncodeToString(k1) + "," + hex.EncodeToString(k2) 142 } else { 143 lockContent = hex.EncodeToString(getPointKey(lock)) 144 } 145 146 //lock mode 147 lockMode := lock.GetLockMode().String() 148 //lock status 149 lockStatus := getLockStatus(lock) 150 //lock wait 151 lockWait := "" 152 153 hList := lock.GetHolders() 154 hLen := len(hList) 155 wList := lock.GetWaiters() 156 wLen := len(wList) 157 158 record := make([][]byte, len(plan2.MoLocksColNames)) 159 record[plan2.MoLocksColTypeCnId] = []byte(cnId) 160 //record[plan2.MoLocksColTypeSessionId] = []byte(sessionId) 161 record[plan2.MoLocksColTypeTxnId] = []byte(txnId) 162 record[plan2.MoLocksColTypeTableId] = []byte(tableId) 163 //record[plan2.MoLocksColTypeTableName] = []byte(tableName) 164 record[plan2.MoLocksColTypeLockKey] = []byte(lockKey) 165 record[plan2.MoLocksColTypeLockContent] = []byte(lockContent) 166 record[plan2.MoLocksColTypeLockMode] = []byte(lockMode) 167 record[plan2.MoLocksColTypeLockStatus] = []byte(lockStatus) 168 record[plan2.MoLocksColTypeLockWait] = []byte(lockWait) 169 170 if hLen == 0 && wLen == 0 { 171 //one record 172 if err := fillLockRecord(proc, arg.Attrs, bat, record); err != nil { 173 return false, err 174 } 175 } else if hLen == 0 && wLen != 0 { 176 //wLen records 177 for j := 0; j < wLen; j++ { 178 record[plan2.MoLocksColTypeLockWait] = []byte(hex.EncodeToString(wList[j].GetTxnID())) 179 if err := fillLockRecord(proc, arg.Attrs, bat, record); err != nil { 180 return false, err 181 } 182 } 183 } else if hLen != 0 && wLen == 0 { 184 //hLen records 185 for j := 0; j < hLen; j++ { 186 record[plan2.MoLocksColTypeTxnId] = []byte(hex.EncodeToString(hList[j].GetTxnID())) 187 if err := fillLockRecord(proc, arg.Attrs, bat, record); err != nil { 188 return false, err 189 } 190 } 191 } else { 192 //hLen * wLen records 193 for j := 0; j < hLen; j++ { 194 for k := 0; k < wLen; k++ { 195 record[plan2.MoLocksColTypeTxnId] = []byte(hex.EncodeToString(hList[j].GetTxnID())) 196 record[plan2.MoLocksColTypeLockWait] = []byte(hex.EncodeToString(wList[k].GetTxnID())) 197 if err := fillLockRecord(proc, arg.Attrs, bat, record); err != nil { 198 return false, err 199 } 200 } 201 } 202 } 203 } 204 } 205 206 bat.SetRowCount(bat.Vecs[0].Length()) 207 result.Batch = bat 208 arg.ctr.state = dataFinished 209 return false, nil 210 211 case dataFinished: 212 result.Batch = nil 213 return true, nil 214 default: 215 return false, moerr.NewInternalError(proc.Ctx, "unknown state %v", arg.ctr.state) 216 } 217 } 218 219 func fillLockRecord(proc *process.Process, attrs []string, bat *batch.Batch, record [][]byte) error { 220 for colIdx, attr := range attrs { 221 realColIdx := plan2.MoLocksColName2Index[strings.ToLower(attr)] 222 if err := vector.AppendBytes(bat.Vecs[colIdx], record[realColIdx], false, proc.GetMPool()); err != nil { 223 return err 224 } 225 } 226 return nil 227 } 228 229 // getLocks get lock info from all cn 230 func getLocks(proc *process.Process) ([]*query.GetLockInfoResponse, error) { 231 var err error 232 var nodes []string 233 234 selectSuperTenant(clusterservice.NewSelector(), "root", nil, 235 func(s *metadata.CNService) { 236 nodes = append(nodes, s.QueryAddress) 237 }) 238 239 genRequest := func() *query.Request { 240 req := proc.QueryClient.NewRequest(query.CmdMethod_GetLockInfo) 241 req.GetLockInfoRequest = &query.GetLockInfoRequest{} 242 return req 243 } 244 245 rsps := make([]*query.GetLockInfoResponse, 0) 246 247 handleValidResponse := func(nodeAddr string, rsp *query.Response) { 248 if rsp != nil && rsp.GetLockInfoResponse != nil { 249 rsps = append(rsps, rsp.GetLockInfoResponse) 250 } 251 } 252 253 err = requestMultipleCn(proc.Ctx, nodes, proc.QueryClient, genRequest, handleValidResponse, nil) 254 return rsps, err 255 } 256 257 func moConfigurationsPrepare(proc *process.Process, arg *Argument) error { 258 arg.ctr.state = dataProducing 259 if len(arg.Args) > 0 { 260 return moerr.NewInvalidInput(proc.Ctx, "moConfigurations: no argument is required") 261 } 262 for i := range arg.Attrs { 263 arg.Attrs[i] = strings.ToUpper(arg.Attrs[i]) 264 } 265 return nil 266 } 267 268 func moConfigurationsCall(_ int, proc *process.Process, arg *Argument, result *vm.CallResult) (bool, error) { 269 switch arg.ctr.state { 270 case dataProducing: 271 272 if proc.Hakeeper == nil { 273 return false, moerr.NewInternalError(proc.Ctx, "hakeeper is nil") 274 } 275 276 //get cluster details 277 details, err := proc.Hakeeper.GetClusterDetails(proc.Ctx) 278 if err != nil { 279 return false, err 280 } 281 282 //alloc batch 283 bat := batch.NewWithSize(len(arg.Attrs)) 284 for i, col := range arg.Attrs { 285 col = strings.ToLower(col) 286 idx, ok := plan2.MoConfigColName2Index[col] 287 if !ok { 288 return false, moerr.NewInternalError(proc.Ctx, "bad input select columns name %v", col) 289 } 290 291 tp := plan2.MoConfigColTypes[idx] 292 bat.Vecs[i] = proc.GetVector(tp) 293 } 294 bat.Attrs = arg.Attrs 295 296 mp := proc.GetMPool() 297 298 //fill batch for cn 299 for _, cnStore := range details.GetCNStores() { 300 if cnStore.GetConfigData() != nil { 301 err = fillMapToBatch("cn", cnStore.GetUUID(), arg.Attrs, cnStore.GetConfigData().GetContent(), bat, mp) 302 if err != nil { 303 return false, err 304 } 305 } 306 } 307 308 //fill batch for tn 309 for _, tnStore := range details.GetTNStores() { 310 if tnStore.GetConfigData() != nil { 311 err = fillMapToBatch("tn", tnStore.GetUUID(), arg.Attrs, tnStore.GetConfigData().GetContent(), bat, mp) 312 if err != nil { 313 return false, err 314 } 315 } 316 } 317 318 //fill batch for log 319 for _, logStore := range details.GetLogStores() { 320 if logStore.GetConfigData() != nil { 321 err = fillMapToBatch("log", logStore.GetUUID(), arg.Attrs, logStore.GetConfigData().GetContent(), bat, mp) 322 if err != nil { 323 return false, err 324 } 325 } 326 } 327 328 // fill batch for proxy 329 for _, proxyStore := range details.GetProxyStores() { 330 if proxyStore.GetConfigData() != nil { 331 err = fillMapToBatch( 332 "proxy", 333 proxyStore.GetUUID(), 334 arg.Attrs, 335 proxyStore.GetConfigData().GetContent(), 336 bat, 337 mp, 338 ) 339 if err != nil { 340 return false, err 341 } 342 } 343 } 344 345 bat.SetRowCount(bat.Vecs[0].Length()) 346 result.Batch = bat 347 arg.ctr.state = dataFinished 348 return false, nil 349 350 case dataFinished: 351 result.Batch = nil 352 return true, nil 353 default: 354 return false, moerr.NewInternalError(proc.Ctx, "unknown state %v", arg.ctr.state) 355 } 356 } 357 358 func fillMapToBatch(nodeType, nodeId string, attrs []string, kvs map[string]*logservicepb.ConfigItem, bat *batch.Batch, mp *mpool.MPool) error { 359 var err error 360 for _, value := range kvs { 361 for i, col := range attrs { 362 col = strings.ToLower(col) 363 switch plan2.MoConfigColType(plan2.MoConfigColName2Index[col]) { 364 case plan2.MoConfigColTypeNodeType: 365 if err = vector.AppendBytes(bat.Vecs[i], []byte(nodeType), false, mp); err != nil { 366 return err 367 } 368 case plan2.MoConfigColTypeNodeId: 369 if err = vector.AppendBytes(bat.Vecs[i], []byte(nodeId), false, mp); err != nil { 370 return err 371 } 372 case plan2.MoConfigColTypeName: 373 if err = vector.AppendBytes(bat.Vecs[i], []byte(value.GetName()), false, mp); err != nil { 374 return err 375 } 376 case plan2.MoConfigColTypeCurrentValue: 377 if err = vector.AppendBytes(bat.Vecs[i], []byte(value.GetCurrentValue()), false, mp); err != nil { 378 return err 379 } 380 case plan2.MoConfigColTypeDefaultValue: 381 if err = vector.AppendBytes(bat.Vecs[i], []byte(value.GetDefaultValue()), false, mp); err != nil { 382 return err 383 } 384 case plan2.MoConfigColTypeInternal: 385 if err = vector.AppendBytes(bat.Vecs[i], []byte(value.GetInternal()), false, mp); err != nil { 386 return err 387 } 388 } 389 } 390 } 391 return err 392 } 393 394 func moTransactionsPrepare(proc *process.Process, arg *Argument) error { 395 arg.ctr.state = dataProducing 396 if len(arg.Args) > 0 { 397 return moerr.NewInvalidInput(proc.Ctx, "moTransactions: no argument is required") 398 } 399 for i := range arg.Attrs { 400 arg.Attrs[i] = strings.ToUpper(arg.Attrs[i]) 401 } 402 return nil 403 } 404 405 func getRangeContent(li *query.TxnLockInfo) ([]byte, []byte) { 406 keys := li.GetRows() 407 llen := len(keys) 408 if llen >= 2 { 409 return keys[0], keys[1] 410 } else if llen >= 1 { 411 return keys[0], []byte{} 412 } else { 413 return []byte{}, []byte{} 414 } 415 } 416 417 func getPointContent(li *query.TxnLockInfo) []byte { 418 keys := li.GetRows() 419 llen := len(keys) 420 if llen >= 1 { 421 return keys[0] 422 } 423 return []byte{} 424 } 425 426 func moTransactionsCall(_ int, proc *process.Process, arg *Argument, result *vm.CallResult) (bool, error) { 427 switch arg.ctr.state { 428 case dataProducing: 429 430 rsps, err := getTxns(proc) 431 if err != nil { 432 return false, err 433 } 434 435 //alloc batch 436 bat := batch.NewWithSize(len(arg.Attrs)) 437 for i, col := range arg.Attrs { 438 col = strings.ToLower(col) 439 idx, ok := plan2.MoTransactionsColName2Index[col] 440 if !ok { 441 return false, moerr.NewInternalError(proc.Ctx, "bad input select columns name %v", col) 442 } 443 444 tp := plan2.MoTransactionsColTypes[idx] 445 bat.Vecs[i] = proc.GetVector(tp) 446 } 447 bat.Attrs = arg.Attrs 448 for _, rsp := range rsps { 449 if rsp == nil || len(rsp.TxnInfoList) == 0 { 450 continue 451 } 452 453 for _, txn := range rsp.TxnInfoList { 454 if txn == nil { 455 continue 456 } 457 458 cnId := rsp.GetCnId() 459 txnId := "" 460 if txn.GetMeta() != nil { 461 txnId = hex.EncodeToString(txn.GetMeta().GetID()) 462 } 463 createTs := txn.GetCreateAt().Format(time.RFC3339Nano) 464 snapshotTs := "" 465 if txn.GetMeta() != nil { 466 snapshotTs = txn.GetMeta().GetSnapshotTS().DebugString() 467 } 468 preparedTs := "" 469 if txn.GetMeta() != nil { 470 preparedTs = txn.GetMeta().GetPreparedTS().DebugString() 471 } 472 commitTs := "" 473 if txn.GetMeta() != nil { 474 commitTs = txn.GetMeta().GetCommitTS().DebugString() 475 } 476 txnMode := "" 477 if txn.GetMeta() != nil { 478 txnMode = txn.GetMeta().GetMode().String() 479 } 480 isolation := "" 481 if txn.GetMeta() != nil { 482 isolation = txn.GetMeta().GetIsolation().String() 483 } 484 userTxn := strconv.FormatBool(txn.GetUserTxn()) 485 txnStatus := "" 486 if txn.GetMeta() != nil { 487 txnStatus = txn.GetMeta().GetStatus().String() 488 } 489 490 waitLocksCnt := len(txn.GetWaitLocks()) 491 record := make([][]byte, len(plan2.MoTransactionsColNames)) 492 record[plan2.MoTransactionsColTypeCnId] = []byte(cnId) 493 record[plan2.MoTransactionsColTypeTxnId] = []byte(txnId) 494 record[plan2.MoTransactionsColTypeCreateTs] = []byte(createTs) 495 record[plan2.MoTransactionsColTypeSnapshotTs] = []byte(snapshotTs) 496 record[plan2.MoTransactionsColTypePreparedTs] = []byte(preparedTs) 497 record[plan2.MoTransactionsColTypeCommitTs] = []byte(commitTs) 498 record[plan2.MoTransactionsColTypeTxnMode] = []byte(txnMode) 499 record[plan2.MoTransactionsColTypeIsolation] = []byte(isolation) 500 record[plan2.MoTransactionsColTypeUserTxn] = []byte(userTxn) 501 record[plan2.MoTransactionsColTypeTxnStatus] = []byte(txnStatus) 502 503 if waitLocksCnt == 0 { 504 //one record 505 record[plan2.MoTransactionsColTypeTableId] = []byte{} 506 record[plan2.MoTransactionsColTypeLockKey] = []byte{} 507 record[plan2.MoTransactionsColTypeLockContent] = []byte{} 508 record[plan2.MoTransactionsColTypeLockMode] = []byte{} 509 510 if err := fillTxnRecord(proc, arg.Attrs, bat, record); err != nil { 511 return false, err 512 } 513 } else { 514 //multiple records 515 516 for _, lock := range txn.GetWaitLocks() { 517 options := lock.GetOptions() 518 if options == nil { 519 continue 520 } 521 522 //table id 523 tableId := fmt.Sprintf("%d", lock.GetTableId()) 524 record[plan2.MoTransactionsColTypeTableId] = []byte(tableId) 525 526 //lock key 527 lockKey := "point" 528 if options.GetGranularity() == pblock.Granularity_Range { 529 lockKey = "range" 530 } 531 record[plan2.MoTransactionsColTypeLockKey] = []byte(lockKey) 532 533 //lock content 534 lockContent := "" 535 if options.GetGranularity() == pblock.Granularity_Range { 536 //first range 537 k1, k2 := getRangeContent(lock) 538 lockContent = hex.EncodeToString(k1) + "," + hex.EncodeToString(k2) 539 } else { 540 lockContent = hex.EncodeToString(getPointContent(lock)) 541 } 542 record[plan2.MoTransactionsColTypeLockContent] = []byte(lockContent) 543 544 //lock mode 545 lockMode := options.GetMode().String() 546 record[plan2.MoTransactionsColTypeLockMode] = []byte(lockMode) 547 548 if err := fillTxnRecord(proc, arg.Attrs, bat, record); err != nil { 549 return false, err 550 } 551 } 552 } 553 554 } 555 } 556 557 bat.SetRowCount(bat.Vecs[0].Length()) 558 result.Batch = bat 559 arg.ctr.state = dataFinished 560 return false, nil 561 562 case dataFinished: 563 return true, nil 564 default: 565 return false, moerr.NewInternalError(proc.Ctx, "unknown state %v", arg.ctr.state) 566 } 567 } 568 569 func fillTxnRecord(proc *process.Process, attrs []string, bat *batch.Batch, record [][]byte) error { 570 for colIdx, attr := range attrs { 571 realColIdx := plan2.MoTransactionsColName2Index[strings.ToLower(attr)] 572 if err := vector.AppendBytes(bat.Vecs[colIdx], record[realColIdx], false, proc.GetMPool()); err != nil { 573 return err 574 } 575 } 576 return nil 577 } 578 579 // getTxns get txn info from all cn 580 func getTxns(proc *process.Process) ([]*query.GetTxnInfoResponse, error) { 581 var err error 582 var nodes []string 583 584 selectSuperTenant(clusterservice.NewSelector(), "root", nil, 585 func(s *metadata.CNService) { 586 nodes = append(nodes, s.QueryAddress) 587 }) 588 589 genRequest := func() *query.Request { 590 req := proc.QueryClient.NewRequest(query.CmdMethod_GetTxnInfo) 591 req.GetTxnInfoRequest = &query.GetTxnInfoRequest{} 592 return req 593 } 594 595 rsps := make([]*query.GetTxnInfoResponse, 0) 596 597 handleValidResponse := func(nodeAddr string, rsp *query.Response) { 598 if rsp != nil && rsp.GetTxnInfoResponse != nil { 599 rsps = append(rsps, rsp.GetTxnInfoResponse) 600 } 601 } 602 603 err = requestMultipleCn(proc.Ctx, nodes, proc.QueryClient, genRequest, handleValidResponse, nil) 604 return rsps, err 605 } 606 607 func moCachePrepare(proc *process.Process, arg *Argument) error { 608 arg.ctr.state = dataProducing 609 if len(arg.Args) > 0 { 610 return moerr.NewInvalidInput(proc.Ctx, "moCache: no argument is required") 611 } 612 for i := range arg.Attrs { 613 arg.Attrs[i] = strings.ToUpper(arg.Attrs[i]) 614 } 615 return nil 616 } 617 618 func moCacheCall(_ int, proc *process.Process, arg *Argument, result *vm.CallResult) (bool, error) { 619 switch arg.ctr.state { 620 case dataProducing: 621 622 rsps, err := getCacheStats(proc) 623 if err != nil { 624 return false, err 625 } 626 627 //alloc batch 628 bat := batch.NewWithSize(len(arg.Attrs)) 629 for i, col := range arg.Attrs { 630 col = strings.ToLower(col) 631 idx, ok := plan2.MoCacheColName2Index[col] 632 if !ok { 633 return false, moerr.NewInternalError(proc.Ctx, "bad input select columns name %v", col) 634 } 635 636 tp := plan2.MoCacheColTypes[idx] 637 bat.Vecs[i] = proc.GetVector(tp) 638 } 639 bat.Attrs = arg.Attrs 640 for _, rsp := range rsps { 641 if rsp == nil || len(rsp.CacheInfoList) == 0 { 642 continue 643 } 644 645 for _, cache := range rsp.CacheInfoList { 646 if cache == nil { 647 continue 648 } 649 650 if err = fillCacheRecord(proc, arg.Attrs, bat, cache); err != nil { 651 return false, err 652 } 653 } 654 } 655 656 bat.SetRowCount(bat.Vecs[0].Length()) 657 result.Batch = bat 658 arg.ctr.state = dataFinished 659 return false, nil 660 661 case dataFinished: 662 result.Batch = nil 663 return true, nil 664 default: 665 return false, moerr.NewInternalError(proc.Ctx, "unknown state %v", arg.ctr.state) 666 } 667 } 668 669 func fillCacheRecord(proc *process.Process, attrs []string, bat *batch.Batch, cache *query.CacheInfo) error { 670 var err error 671 for colIdx, attr := range attrs { 672 switch plan2.MoCacheColType(plan2.MoCacheColName2Index[strings.ToLower(attr)]) { 673 case plan2.MoCacheColTypeNodeType: 674 if err = vector.AppendBytes(bat.Vecs[colIdx], []byte(cache.GetNodeType()), false, proc.GetMPool()); err != nil { 675 return err 676 } 677 case plan2.MoCacheColTypeNodeId: 678 if err = vector.AppendBytes(bat.Vecs[colIdx], []byte(cache.GetNodeId()), false, proc.GetMPool()); err != nil { 679 return err 680 } 681 case plan2.MoCacheColTypeType: 682 if err = vector.AppendBytes(bat.Vecs[colIdx], []byte(cache.GetCacheType()), false, proc.GetMPool()); err != nil { 683 return err 684 } 685 case plan2.MoCacheColTypeUsed: 686 if err = vector.AppendFixed(bat.Vecs[colIdx], cache.GetUsed(), false, proc.GetMPool()); err != nil { 687 return err 688 } 689 case plan2.MoCacheColTypeFree: 690 if err = vector.AppendFixed(bat.Vecs[colIdx], cache.GetFree(), false, proc.GetMPool()); err != nil { 691 return err 692 } 693 case plan2.MoCacheColTypeHitRatio: 694 if err = vector.AppendFixed(bat.Vecs[colIdx], cache.GetHitRatio(), false, proc.GetMPool()); err != nil { 695 return err 696 } 697 } 698 } 699 700 return err 701 } 702 703 // getCacheStats get txn info from all cn, tn 704 func getCacheStats(proc *process.Process) ([]*query.GetCacheInfoResponse, error) { 705 var err error 706 var nodes []string 707 708 selectSuperTenant(clusterservice.NewSelector(), "root", nil, 709 func(s *metadata.CNService) { 710 nodes = append(nodes, s.QueryAddress) 711 }) 712 713 listTnService(func(s *metadata.TNService) { 714 nodes = append(nodes, s.QueryAddress) 715 }) 716 717 genRequest := func() *query.Request { 718 req := proc.QueryClient.NewRequest(query.CmdMethod_GetCacheInfo) 719 req.GetCacheInfoRequest = &query.GetCacheInfoRequest{} 720 return req 721 } 722 723 rsps := make([]*query.GetCacheInfoResponse, 0) 724 725 handleValidResponse := func(nodeAddr string, rsp *query.Response) { 726 if rsp != nil && rsp.GetCacheInfoResponse != nil { 727 rsps = append(rsps, rsp.GetCacheInfoResponse) 728 } 729 } 730 731 err = requestMultipleCn(proc.Ctx, nodes, proc.QueryClient, genRequest, handleValidResponse, nil) 732 return rsps, err 733 } 734 735 var selectSuperTenant = func(selector clusterservice.Selector, 736 username string, 737 filter func(string) bool, 738 appendFn func(service *metadata.CNService)) { 739 clusterservice.GetMOCluster().GetCNService( 740 clusterservice.NewSelectAll(), func(s metadata.CNService) bool { 741 appendFn(&s) 742 return true 743 }) 744 } 745 746 var listTnService = func(appendFn func(service *metadata.TNService)) { 747 disttae.ListTnService(appendFn) 748 } 749 750 var requestMultipleCn = func(ctx context.Context, nodes []string, qc qclient.QueryClient, genRequest func() *query.Request, handleValidResponse func(string, *query.Response), handleInvalidResponse func(string)) error { 751 return queryservice.RequestMultipleCn(ctx, nodes, qc, genRequest, handleValidResponse, handleInvalidResponse) 752 }