This is an automated email from the ASF dual-hosted git repository.

chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kyuubi.git


The following commit(s) were added to refs/heads/master by this push:
     new 3167692732 [KYUUBI #6829] Add metrics for batch pending max elapse time
3167692732 is described below

commit 3167692732b7fe6ba3928db3ec89ca8419ed030d
Author: Wang, Fei <[email protected]>
AuthorDate: Thu Dec 5 18:12:39 2024 +0800

    [KYUUBI #6829] Add metrics for batch pending max elapse time
    
    ### Why are the changes needed?
    
    1. add metrics `kyuubi.operartion.batch_pending_max_elapse` for the batch 
pending max elapse time, which is helpful for batch health monitoring, and we 
can send alert if the batch pending elapse time too long
    2. For `GET /api/v1/batches` api, limit the max time window for listing 
batches, which is helpful that, we want to reserve more metadata in kyuubi 
server end, for example: 90 days, but for list batches, we just want to allow 
user to search the last 7 days. It is optional. And if `create_time` is 
specified, order by `create_time` instead of `key_id`.
    
https://github.com/apache/kyuubi/blob/68a6f48da53dd0ad2e20b450a41ca600b8c1e1d2/kyuubi-server/src/main/resources/sql/mysql/metadata-store-schema-1.8.0.mysql.sql#L32
    
    ### How was this patch tested?
    
    GA.
    
    ### Was this patch authored or co-authored using generative AI tooling?
    
    No.
    
    Closes #6829 from turboFei/batch_pending_time.
    
    Closes #6829
    
    ee4f93125 [Wang, Fei] docs
    bf8169ad4 [Wang, Fei] comments
    f493a2af8 [Wang, Fei] new config
    ab7b6db65 [Wang, Fei] ut
    168017587 [Wang, Fei] in memory session
    510a30b6a [Wang, Fei] batchSearchWindow opt
    1e93dd276 [Wang, Fei] save
    
    Authored-by: Wang, Fei <[email protected]>
    Signed-off-by: Cheng Pan <[email protected]>
---
 docs/configuration/settings.md                     |  37 ++++----
 docs/monitor/metrics.md                            | 101 +++++++++++----------
 .../org/apache/kyuubi/config/KyuubiConf.scala      |  13 +++
 .../apache/kyuubi/metrics/MetricsConstants.scala   |   1 +
 .../kyuubi/operation/BatchJobSubmission.scala      |   8 ++
 .../kyuubi/server/KyuubiRestFrontendService.scala  |  15 ++-
 .../kyuubi/server/api/v1/BatchesResource.scala     |   5 +-
 .../kyuubi/server/metadata/MetadataManager.scala   |   9 +-
 .../kyuubi/server/metadata/MetadataStore.scala     |   5 +-
 .../server/metadata/jdbc/JDBCMetadataStore.scala   |   6 +-
 .../server/api/v1/BatchesResourceSuite.scala       |   1 +
 11 files changed, 125 insertions(+), 76 deletions(-)

diff --git a/docs/configuration/settings.md b/docs/configuration/settings.md
index fede369a84..acbc36197f 100644
--- a/docs/configuration/settings.md
+++ b/docs/configuration/settings.md
@@ -377,24 +377,25 @@ You can configure the Kyuubi properties in 
`$KYUUBI_HOME/conf/kyuubi-defaults.co
 
 ### Metadata
 
-|                       Key                       |                         
Default                          |                                              
                                                                                
                                                                                
                                                                                
           Meaning                                                              
                 [...]
-|-------------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [...]
-| kyuubi.metadata.cleaner.enabled                 | true                       
                              | Whether to clean the metadata periodically. If 
it is enabled, Kyuubi will clean the metadata that is in the terminate state 
with max age limitation.                                                        
                                                                                
                                                                                
                  [...]
-| kyuubi.metadata.cleaner.interval                | PT30M                      
                              | The interval to check and clean expired 
metadata.                                                                       
                                                                                
                                                                                
                                                                                
                      [...]
-| kyuubi.metadata.max.age                         | PT72H                      
                              | The maximum age of metadata, the metadata 
exceeding the age will be cleaned.                                              
                                                                                
                                                                                
                                                                                
                    [...]
-| kyuubi.metadata.recovery.threads                | 10                         
                              | The number of threads for recovery from the 
metadata store when the Kyuubi server restarts.                                 
                                                                                
                                                                                
                                                                                
                  [...]
-| kyuubi.metadata.request.async.retry.enabled     | true                       
                              | Whether to retry in async when metadata request 
failed. When true, return success response immediately even the metadata 
request failed, and schedule it in background until success, to tolerate 
long-time metadata store outages w/o blocking the submission request.           
                                                                                
                            [...]
-| kyuubi.metadata.request.async.retry.queue.size  | 65536                      
                              | The maximum queue size for buffering metadata 
requests in memory when the external metadata storage is down. Requests will be 
dropped if the queue exceeds. Only take affect when 
kyuubi.metadata.request.async.retry.enabled is `true`.                          
                                                                                
                                            [...]
-| kyuubi.metadata.request.async.retry.threads     | 10                         
                              | Number of threads in the metadata request async 
retry manager thread pool. Only take affect when 
kyuubi.metadata.request.async.retry.enabled is `true`.                          
                                                                                
                                                                                
                                             [...]
-| kyuubi.metadata.request.retry.interval          | PT5S                       
                              | The interval to check and trigger the metadata 
request retry tasks.                                                            
                                                                                
                                                                                
                                                                                
               [...]
-| kyuubi.metadata.store.class                     | 
org.apache.kyuubi.server.metadata.jdbc.JDBCMetadataStore | Fully qualified 
class name for server metadata store.                                           
                                                                                
                                                                                
                                                                                
                                              [...]
-| kyuubi.metadata.store.jdbc.database.schema.init | true                       
                              | Whether to init the JDBC metadata store 
database schema.                                                                
                                                                                
                                                                                
                                                                                
                      [...]
-| kyuubi.metadata.store.jdbc.database.type        | SQLITE                     
                              | The database type for server jdbc metadata 
store.<ul> <li>SQLITE: SQLite3, JDBC driver `org.sqlite.JDBC`.</li> <li>MYSQL: 
MySQL, JDBC driver `com.mysql.cj.jdbc.Driver` (fallback 
`com.mysql.jdbc.Driver`).</li> <li>POSTGRESQL: PostgreSQL, JDBC driver 
`org.postgresql.Driver`.</li> <li>CUSTOM: User-defined database type, need to 
specify corresponding JDBC driver.</li> Note that: The [...]
-| kyuubi.metadata.store.jdbc.driver               | &lt;undefined&gt;          
                              | JDBC driver class name for server jdbc metadata 
store.                                                                          
                                                                                
                                                                                
                                                                                
              [...]
-| kyuubi.metadata.store.jdbc.password                                          
                             || The password for server JDBC metadata store.    
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
-| kyuubi.metadata.store.jdbc.priority.enabled     | false                      
                              | Whether to enable the priority scheduling for 
batch impl v2. When false, ignore kyuubi.batch.priority and use the FIFO 
ordering strategy for batch job scheduling. Note: this feature may cause 
significant performance issues when using MySQL 5.7 as the metastore backend 
due to the lack of support for mixed order index. See more details at KYUUBI 
#5329.                              [...]
-| kyuubi.metadata.store.jdbc.url                  | 
jdbc:sqlite:&lt;KYUUBI_HOME&gt;/kyuubi_state_store.db    | The JDBC url for 
server JDBC metadata store. By default, it is a SQLite database url, and the 
state information is not shared across Kyuubi instances. To enable high 
availability for multiple kyuubi instances, please specify a production JDBC 
url. Note: this value support the variables substitution: `<KYUUBI_HOME>`.      
                                                           [...]
-| kyuubi.metadata.store.jdbc.user                                              
                             || The username for server JDBC metadata store.    
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+|                       Key                       |                         
Default                          |                                              
                                                                                
                                                                                
                                                                                
           Meaning                                                              
                 [...]
+|-------------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 [...]
+| kyuubi.metadata.cleaner.enabled                 | true                       
                              | Whether to clean the metadata periodically. If 
it is enabled, Kyuubi will clean the metadata that is in the terminate state 
with max age limitation.                                                        
                                                                                
                                                                                
                  [...]
+| kyuubi.metadata.cleaner.interval                | PT30M                      
                              | The interval to check and clean expired 
metadata.                                                                       
                                                                                
                                                                                
                                                                                
                      [...]
+| kyuubi.metadata.max.age                         | PT72H                      
                              | The maximum age of metadata, the metadata 
exceeding the age will be cleaned.                                              
                                                                                
                                                                                
                                                                                
                    [...]
+| kyuubi.metadata.recovery.threads                | 10                         
                              | The number of threads for recovery from the 
metadata store when the Kyuubi server restarts.                                 
                                                                                
                                                                                
                                                                                
                  [...]
+| kyuubi.metadata.request.async.retry.enabled     | true                       
                              | Whether to retry in async when metadata request 
failed. When true, return success response immediately even the metadata 
request failed, and schedule it in background until success, to tolerate 
long-time metadata store outages w/o blocking the submission request.           
                                                                                
                            [...]
+| kyuubi.metadata.request.async.retry.queue.size  | 65536                      
                              | The maximum queue size for buffering metadata 
requests in memory when the external metadata storage is down. Requests will be 
dropped if the queue exceeds. Only take affect when 
kyuubi.metadata.request.async.retry.enabled is `true`.                          
                                                                                
                                            [...]
+| kyuubi.metadata.request.async.retry.threads     | 10                         
                              | Number of threads in the metadata request async 
retry manager thread pool. Only take affect when 
kyuubi.metadata.request.async.retry.enabled is `true`.                          
                                                                                
                                                                                
                                             [...]
+| kyuubi.metadata.request.retry.interval          | PT5S                       
                              | The interval to check and trigger the metadata 
request retry tasks.                                                            
                                                                                
                                                                                
                                                                                
               [...]
+| kyuubi.metadata.search.window                   | &lt;undefined&gt;          
                              | The time window to restrict user queries to 
metadata within a specific period, starting from the current time to the past. 
It only affects `GET /api/v1/batches` API. You may want to set this to short 
period to improve query performance and reduce load on the metadata store when 
administer want to reserve the metadata for long time. The side-effects is 
that, the metadata created  [...]
+| kyuubi.metadata.store.class                     | 
org.apache.kyuubi.server.metadata.jdbc.JDBCMetadataStore | Fully qualified 
class name for server metadata store.                                           
                                                                                
                                                                                
                                                                                
                                              [...]
+| kyuubi.metadata.store.jdbc.database.schema.init | true                       
                              | Whether to init the JDBC metadata store 
database schema.                                                                
                                                                                
                                                                                
                                                                                
                      [...]
+| kyuubi.metadata.store.jdbc.database.type        | SQLITE                     
                              | The database type for server jdbc metadata 
store.<ul> <li>SQLITE: SQLite3, JDBC driver `org.sqlite.JDBC`.</li> <li>MYSQL: 
MySQL, JDBC driver `com.mysql.cj.jdbc.Driver` (fallback 
`com.mysql.jdbc.Driver`).</li> <li>POSTGRESQL: PostgreSQL, JDBC driver 
`org.postgresql.Driver`.</li> <li>CUSTOM: User-defined database type, need to 
specify corresponding JDBC driver.</li> Note that: The [...]
+| kyuubi.metadata.store.jdbc.driver               | &lt;undefined&gt;          
                              | JDBC driver class name for server jdbc metadata 
store.                                                                          
                                                                                
                                                                                
                                                                                
              [...]
+| kyuubi.metadata.store.jdbc.password                                          
                             || The password for server JDBC metadata store.    
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
+| kyuubi.metadata.store.jdbc.priority.enabled     | false                      
                              | Whether to enable the priority scheduling for 
batch impl v2. When false, ignore kyuubi.batch.priority and use the FIFO 
ordering strategy for batch job scheduling. Note: this feature may cause 
significant performance issues when using MySQL 5.7 as the metastore backend 
due to the lack of support for mixed order index. See more details at KYUUBI 
#5329.                              [...]
+| kyuubi.metadata.store.jdbc.url                  | 
jdbc:sqlite:&lt;KYUUBI_HOME&gt;/kyuubi_state_store.db    | The JDBC url for 
server JDBC metadata store. By default, it is a SQLite database url, and the 
state information is not shared across Kyuubi instances. To enable high 
availability for multiple kyuubi instances, please specify a production JDBC 
url. Note: this value support the variables substitution: `<KYUUBI_HOME>`.      
                                                           [...]
+| kyuubi.metadata.store.jdbc.user                                              
                             || The username for server JDBC metadata store.    
                                                                                
                                                                                
                                                                                
                                                                                
              [...]
 
 ### Metrics
 
diff --git a/docs/monitor/metrics.md b/docs/monitor/metrics.md
index 561014c370..8043fa0810 100644
--- a/docs/monitor/metrics.md
+++ b/docs/monitor/metrics.md
@@ -40,56 +40,57 @@ The metrics system is configured via 
`$KYUUBI_HOME/conf/kyuubi-defaults.conf`.
 
 These metrics include:
 
-|                  Metrics Prefix                  |             Metrics 
Suffix             |   Type    | Since |                                        
                                                                                
                Description                                                     
                                                                                
    |
-|--------------------------------------------------|----------------------------------------|-----------|-------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `kyuubi.exec.pool.threads.alive`                 |                           
             | gauge     | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> threads keepAlive in the backend executive 
thread pool</div>                                                               
                                                                                
           |
-| `kyuubi.exec.pool.threads.active`                |                           
             | gauge     | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> threads active in the backend executive thread 
pool</div>                                                                      
                                                                                
       |
-| `kyuubi.exec.pool.work_queue.size`               |                           
             | gauge     | 1.7.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> work queue size in the backend executive 
thread pool</div>                                                               
                                                                                
             |
-| `kyuubi.connection.total`                        |                           
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative connection count</div>             
                                                                                
                                                                                
       |
-| `kyuubi.connection.total`                        | `${sessionType}`          
             | counter   | 1.7.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative connection count with session type 
`${sessionType}`</div>                                                          
                                                                                
        |
-| `kyuubi.connection.opened`                       |                           
             | gauge     | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current active connection count</div>          
                                                                                
                                                                                
       |
-| `kyuubi.connection.opened`                       | `${user}`                 
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current active connections count requested by 
a `${user}`</div>                                                               
                                                                                
        |
-| `kyuubi.connection.opened`                       | 
`${user}`</br>`${sessionType}`         | counter   | 1.7.0 | <div style='width: 
150pt;word-wrap: break-word;white-space: normal'> current active connections 
count requested by a `${user}` with session type `${sessionType}`</div>         
                                                                                
                           |
-| `kyuubi.connection.opened`                       | `${sessionType}`          
             | counter   | 1.7.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current active connections count with session 
type `${sessionType}`</div>                                                     
                                                                                
        |
-| `kyuubi.connection.failed`                       |                           
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative failed connection count</div>      
                                                                                
                                                                                
       |
-| `kyuubi.connection.failed`                       | `${user}`                 
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative failed connections for a 
`${user}`</div>                                                                 
                                                                                
                  |
-| `kyuubi.connection.failed`                       | `${sessionType}`          
             | counter   | 1.7.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative failed connection count with 
session type `${sessionType}`</div>                                             
                                                                                
              |
-| `kyuubi.operation.total`                         |                           
             | counter   | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative opened operation count</div>       
                                                                                
                                                                                
       |
-| `kyuubi.operation.total`                         | `${operationType}`        
             | counter   | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative opened count for the operation 
`${operationType}`</div>                                                        
                                                                                
           |
-| `kyuubi.operation.opened`                        |                           
             | gauge     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  current opened operation count</div>          
                                                                                
                                                                                
       |
-| `kyuubi.operation.opened`                        | `${operationType}`        
             | counter   | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  current opened count for the operation 
`${operationType}`</div>                                                        
                                                                                
              |
-| `kyuubi.operation.failed`                        | 
`${operationType}`<br/>`.${errorType}` | counter   | 1.5.0 | <div style='width: 
150pt;word-wrap: break-word;white-space: normal'>  cumulative failed count for 
the operation `${operationType}` with a particular `${errorType}`, e.g. 
`execute_statement.AnalysisException`</div>                                     
                                 |
-| `kyuubi.operation.state`                         | `${operationState}`       
             | meter     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  kyuubi operation state rate </div>            
                                                                                
                                                                                
       |
-| `kyuubi.operation.exec_time`                     | `${operationType}`        
             | histogram | 1.7.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  execution time histogram for the operation 
`${operationType}`, now only `ExecuteStatement` is enabled.  </div>             
                                                                                
          |
-| `kyuubi.engine.total`                            |                           
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative created engines</div>              
                                                                                
                                                                                
       |
-| `kyuubi.engine.timeout`                          |                           
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative timeout engines</div>              
                                                                                
                                                                                
       |
-| `kyuubi.engine.failed`                           | `${user}`                 
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative explicitly failed engine count for 
a `${user}`</div>                                                               
                                                                                
       |
-| `kyuubi.engine.failed`                           | `${errorType}`            
             | counter   | 1.2.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative explicitly failed engine count for 
a particular `${errorType}`, e.g. `ClassNotFoundException`</div>                
                                                                                
        |
-| `kyuubi.backend_service.open_session`            |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `openSession` method 
execution time and rate </div>                                                  
                                                                                
          |
-| `kyuubi.backend_service.close_session`           |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `closeSession` method 
execution time and rate </div>                                                  
                                                                                
         |
-| `kyuubi.backend_service.get_info`                |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getInfo` method 
execution time and rate </div>                                                  
                                                                                
              |
-| `kyuubi.backend_service.execute_statement`       |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `executeStatement` 
method execution time and rate </div>                                           
                                                                                
            |
-| `kyuubi.backend_service.get_type_info`           |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getTypeInfo` method 
execution time and rate </div>                                                  
                                                                                
          |
-| `kyuubi.backend_service.get_catalogs`            |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getCatalogs` method 
execution time and rate </div>                                                  
                                                                                
          |
-| `kyuubi.backend_service.get_schemas`             |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getSchemas` method 
execution time and rate </div>                                                  
                                                                                
           |
-| `kyuubi.backend_service.get_tables`              |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getTables` method 
execution time and rate </div>                                                  
                                                                                
            |
-| `kyuubi.backend_service.get_table_types`         |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getTableTypes` method 
execution time and rate </div>                                                  
                                                                                
        |
-| `kyuubi.backend_service.get_columns`             |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getColumns` method 
execution time and rate </div>                                                  
                                                                                
           |
-| `kyuubi.backend_service.get_functions`           |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getFunctions` method 
execution time and rate </div>                                                  
                                                                                
         |
-| `kyuubi.backend_service.get_operation_status`    |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getOperationStatus` 
method execution time and rate </div>                                           
                                                                                
          |
-| `kyuubi.backend_service.cancel_operation`        |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `cancelOperation` 
method execution time and rate </div>                                           
                                                                                
             |
-| `kyuubi.backend_service.close_operation`         |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `closeOperation` method 
execution time and rate </div>                                                  
                                                                                
       |
-| `kyuubi.backend_service.get_result_set_metadata` |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getResultSetMetadata` 
method execution time and rate </div>                                           
                                                                                
        |
-| `kyuubi.backend_service.fetch_results`           |                           
             | timer     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `fetchResults` method 
execution time and rate </div>                                                  
                                                                                
         |
-| `kyuubi.backend_service.fetch_log_rows_rate`     |                           
             | meter     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `fetchResults` method 
that fetch log rows rate </div>                                                 
                                                                                
         |
-| `kyuubi.backend_service.fetch_result_rows_rate`  |                           
             | meter     | 1.5.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `fetchResults` method 
that fetch result rows rate </div>                                              
                                                                                
         |
-| `kyuubi.backend_service.get_primary_keys`        |                           
             | meter     | 1.6.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `get_primary_keys` 
method execution time and rate </div>                                           
                                                                                
            |
-| `kyuubi.backend_service.get_cross_reference`     |                           
             | meter     | 1.6.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `get_cross_reference` 
method execution time and rate </div>                                           
                                                                                
         |
-| `kyuubi.operation.state`                         | 
`${operationType}`<br/>`.${state}`     | meter     | 1.6.0 | <div style='width: 
150pt;word-wrap: break-word;white-space: normal'>  The `${operationType}` with 
a particular `${state}` rate, e.g. `BatchJobSubmission.pending`, 
`BatchJobSubmission.finished`. Note that, the terminal states are cumulative, 
but the intermediate ones are not. </div> |
-| `kyuubi.metadata.request.opened`                 |                           
             | counter   | 1.6.1 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current opened count for the metadata requests 
</div>                                                                          
                                                                                
       |
-| `kyuubi.metadata.request.total`                  |                           
             | meter     | 1.6.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> metadata requests time and rate </div>         
                                                                                
                                                                                
       |
-| `kyuubi.metadata.request.failed`                 |                           
             | meter     | 1.6.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> metadata requests failure time and rate </div> 
                                                                                
                                                                                
       |
-| `kyuubi.metadata.request.retrying`               |                           
             | meter     | 1.6.0 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> retrying metadata requests time and rate, it 
is not cumulative </div>                                                        
                                                                                
         |
+|                  Metrics Prefix                  |             Metrics 
Suffix             |   Type    | Since  |                                       
                                                                                
                 Description                                                    
                                                                                
     |
+|--------------------------------------------------|----------------------------------------|-----------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `kyuubi.exec.pool.threads.alive`                 |                           
             | gauge     | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> threads keepAlive in the backend executive 
thread pool</div>                                                               
                                                                                
           |
+| `kyuubi.exec.pool.threads.active`                |                           
             | gauge     | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> threads active in the backend executive thread 
pool</div>                                                                      
                                                                                
       |
+| `kyuubi.exec.pool.work_queue.size`               |                           
             | gauge     | 1.7.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> work queue size in the backend executive 
thread pool</div>                                                               
                                                                                
             |
+| `kyuubi.connection.total`                        |                           
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative connection count</div>             
                                                                                
                                                                                
       |
+| `kyuubi.connection.total`                        | `${sessionType}`          
             | counter   | 1.7.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative connection count with session type 
`${sessionType}`</div>                                                          
                                                                                
        |
+| `kyuubi.connection.opened`                       |                           
             | gauge     | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current active connection count</div>          
                                                                                
                                                                                
       |
+| `kyuubi.connection.opened`                       | `${user}`                 
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current active connections count requested by 
a `${user}`</div>                                                               
                                                                                
        |
+| `kyuubi.connection.opened`                       | 
`${user}`</br>`${sessionType}`         | counter   | 1.7.0  | <div 
style='width: 150pt;word-wrap: break-word;white-space: normal'> current active 
connections count requested by a `${user}` with session type 
`${sessionType}`</div>                                                          
                                                          |
+| `kyuubi.connection.opened`                       | `${sessionType}`          
             | counter   | 1.7.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current active connections count with session 
type `${sessionType}`</div>                                                     
                                                                                
        |
+| `kyuubi.connection.failed`                       |                           
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative failed connection count</div>      
                                                                                
                                                                                
       |
+| `kyuubi.connection.failed`                       | `${user}`                 
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative failed connections for a 
`${user}`</div>                                                                 
                                                                                
                  |
+| `kyuubi.connection.failed`                       | `${sessionType}`          
             | counter   | 1.7.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative failed connection count with 
session type `${sessionType}`</div>                                             
                                                                                
              |
+| `kyuubi.operation.total`                         |                           
             | counter   | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative opened operation count</div>       
                                                                                
                                                                                
       |
+| `kyuubi.operation.total`                         | `${operationType}`        
             | counter   | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative opened count for the operation 
`${operationType}`</div>                                                        
                                                                                
           |
+| `kyuubi.operation.opened`                        |                           
             | gauge     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  current opened operation count</div>          
                                                                                
                                                                                
       |
+| `kyuubi.operation.opened`                        | `${operationType}`        
             | counter   | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  current opened count for the operation 
`${operationType}`</div>                                                        
                                                                                
              |
+| `kyuubi.operation.failed`                        | 
`${operationType}`<br/>`.${errorType}` | counter   | 1.5.0  | <div 
style='width: 150pt;word-wrap: break-word;white-space: normal'>  cumulative 
failed count for the operation `${operationType}` with a particular 
`${errorType}`, e.g. `execute_statement.AnalysisException`</div>                
                                                      |
+| `kyuubi.operation.state`                         | `${operationState}`       
             | meter     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  kyuubi operation state rate </div>            
                                                                                
                                                                                
       |
+| `kyuubi.operation.exec_time`                     | `${operationType}`        
             | histogram | 1.7.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  execution time histogram for the operation 
`${operationType}`, now only `ExecuteStatement` is enabled.  </div>             
                                                                                
          |
+| `kyuubi.engine.total`                            |                           
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative created engines</div>              
                                                                                
                                                                                
       |
+| `kyuubi.engine.timeout`                          |                           
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative timeout engines</div>              
                                                                                
                                                                                
       |
+| `kyuubi.engine.failed`                           | `${user}`                 
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'>  cumulative explicitly failed engine count for 
a `${user}`</div>                                                               
                                                                                
       |
+| `kyuubi.engine.failed`                           | `${errorType}`            
             | counter   | 1.2.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> cumulative explicitly failed engine count for 
a particular `${errorType}`, e.g. `ClassNotFoundException`</div>                
                                                                                
        |
+| `kyuubi.backend_service.open_session`            |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `openSession` method 
execution time and rate </div>                                                  
                                                                                
          |
+| `kyuubi.backend_service.close_session`           |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `closeSession` method 
execution time and rate </div>                                                  
                                                                                
         |
+| `kyuubi.backend_service.get_info`                |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getInfo` method 
execution time and rate </div>                                                  
                                                                                
              |
+| `kyuubi.backend_service.execute_statement`       |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `executeStatement` 
method execution time and rate </div>                                           
                                                                                
            |
+| `kyuubi.backend_service.get_type_info`           |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getTypeInfo` method 
execution time and rate </div>                                                  
                                                                                
          |
+| `kyuubi.backend_service.get_catalogs`            |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getCatalogs` method 
execution time and rate </div>                                                  
                                                                                
          |
+| `kyuubi.backend_service.get_schemas`             |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getSchemas` method 
execution time and rate </div>                                                  
                                                                                
           |
+| `kyuubi.backend_service.get_tables`              |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getTables` method 
execution time and rate </div>                                                  
                                                                                
            |
+| `kyuubi.backend_service.get_table_types`         |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getTableTypes` method 
execution time and rate </div>                                                  
                                                                                
        |
+| `kyuubi.backend_service.get_columns`             |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getColumns` method 
execution time and rate </div>                                                  
                                                                                
           |
+| `kyuubi.backend_service.get_functions`           |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getFunctions` method 
execution time and rate </div>                                                  
                                                                                
         |
+| `kyuubi.backend_service.get_operation_status`    |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getOperationStatus` 
method execution time and rate </div>                                           
                                                                                
          |
+| `kyuubi.backend_service.cancel_operation`        |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `cancelOperation` 
method execution time and rate </div>                                           
                                                                                
             |
+| `kyuubi.backend_service.close_operation`         |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `closeOperation` method 
execution time and rate </div>                                                  
                                                                                
       |
+| `kyuubi.backend_service.get_result_set_metadata` |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `getResultSetMetadata` 
method execution time and rate </div>                                           
                                                                                
        |
+| `kyuubi.backend_service.fetch_results`           |                           
             | timer     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `fetchResults` method 
execution time and rate </div>                                                  
                                                                                
         |
+| `kyuubi.backend_service.fetch_log_rows_rate`     |                           
             | meter     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `fetchResults` method 
that fetch log rows rate </div>                                                 
                                                                                
         |
+| `kyuubi.backend_service.fetch_result_rows_rate`  |                           
             | meter     | 1.5.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `fetchResults` method 
that fetch result rows rate </div>                                              
                                                                                
         |
+| `kyuubi.backend_service.get_primary_keys`        |                           
             | meter     | 1.6.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `get_primary_keys` 
method execution time and rate </div>                                           
                                                                                
            |
+| `kyuubi.backend_service.get_cross_reference`     |                           
             | meter     | 1.6.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> kyuubi backend service `get_cross_reference` 
method execution time and rate </div>                                           
                                                                                
         |
+| `kyuubi.operation.state`                         | 
`${operationType}`<br/>`.${state}`     | meter     | 1.6.0  | <div 
style='width: 150pt;word-wrap: break-word;white-space: normal'>  The 
`${operationType}` with a particular `${state}` rate, e.g. 
`BatchJobSubmission.pending`, `BatchJobSubmission.finished`. Note that, the 
terminal states are cumulative, but the intermediate ones are not. </div> |
+| `kyuubi.metadata.request.opened`                 |                           
             | counter   | 1.6.1  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> current opened count for the metadata requests 
</div>                                                                          
                                                                                
       |
+| `kyuubi.metadata.request.total`                  |                           
             | meter     | 1.6.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> metadata requests time and rate </div>         
                                                                                
                                                                                
       |
+| `kyuubi.metadata.request.failed`                 |                           
             | meter     | 1.6.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> metadata requests failure time and rate </div> 
                                                                                
                                                                                
       |
+| `kyuubi.metadata.request.retrying`               |                           
             | meter     | 1.6.0  | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> retrying metadata requests time and rate, it 
is not cumulative </div>                                                        
                                                                                
         |
+| `kyuubi.operartion.batch_pending_max_elapse`     |                           
             | gauge     | 1.10.1 | <div style='width: 150pt;word-wrap: 
break-word;white-space: normal'> the batch pending max elapsed time on current 
kyuubi instance </div>                                                          
                                                                                
        |
 
 Before v1.5.0, if you use these metrics:
 - `kyuubi.statement.total`
diff --git 
a/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala 
b/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala
index e26033bf0f..a493d7c457 100644
--- a/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala
+++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/config/KyuubiConf.scala
@@ -2023,6 +2023,19 @@ object KyuubiConf {
       .intConf
       .createWithDefault(65536)
 
+  val METADATA_SEARCH_WINDOW: OptionalConfigEntry[Long] =
+    buildConf("kyuubi.metadata.search.window")
+      .doc("The time window to restrict user queries to metadata within a 
specific period, " +
+        "starting from the current time to the past. It only affects `GET 
/api/v1/batches` API. " +
+        "You may want to set this to short period to improve query performance 
and reduce load " +
+        "on the metadata store when administer want to reserve the metadata 
for long time. " +
+        "The side-effects is that, the metadata created outside the window 
will not be " +
+        "invisible to users. If it is undefined, all metadata will be visible 
for users.")
+      .version("1.10.1")
+      .timeConf
+      .checkValue(_ > 0, "must be positive number")
+      .createOptional
+
   val ENGINE_EXEC_WAIT_QUEUE_SIZE: ConfigEntry[Int] =
     buildConf("kyuubi.backend.engine.exec.pool.wait.queue.size")
       .doc("Size of the wait queue for the operation execution thread pool in 
SQL engine" +
diff --git 
a/kyuubi-metrics/src/main/scala/org/apache/kyuubi/metrics/MetricsConstants.scala
 
b/kyuubi-metrics/src/main/scala/org/apache/kyuubi/metrics/MetricsConstants.scala
index f615467f3f..336060e8f7 100644
--- 
a/kyuubi-metrics/src/main/scala/org/apache/kyuubi/metrics/MetricsConstants.scala
+++ 
b/kyuubi-metrics/src/main/scala/org/apache/kyuubi/metrics/MetricsConstants.scala
@@ -64,6 +64,7 @@ object MetricsConstants {
   final val OPERATION_TOTAL: String = OPERATION + "total"
   final val OPERATION_STATE: String = OPERATION + "state"
   final val OPERATION_EXEC_TIME: String = OPERATION + "exec_time"
+  final val OPERATION_BATCH_PENDING_MAX_ELAPSE: String = OPERATION + 
"batch_pending_max_elapse"
 
   final private val BACKEND_SERVICE = KYUUBI + "backend_service."
   final val BS_FETCH_LOG_ROWS_RATE = BACKEND_SERVICE + "fetch_log_rows_rate"
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/operation/BatchJobSubmission.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/operation/BatchJobSubmission.scala
index 129fbc8d9a..aa17c5436a 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/operation/BatchJobSubmission.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/operation/BatchJobSubmission.scala
@@ -424,6 +424,14 @@ class BatchJobSubmission(
       Utils.deleteDirectoryRecursively(session.resourceUploadFolderPath.toFile)
     }
   }
+
+  def getPendingElapsedTime: Long = {
+    if (state == OperationState.PENDING) {
+      System.currentTimeMillis() - createTime
+    } else {
+      0L
+    }
+  }
 }
 
 object BatchJobSubmission {
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
index 5b8b1686ad..b93dcf7b5b 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/KyuubiRestFrontendService.scala
@@ -31,12 +31,14 @@ import org.eclipse.jetty.servlet.{ErrorPageErrorHandler, 
FilterHolder}
 import org.apache.kyuubi.{KyuubiException, Utils}
 import org.apache.kyuubi.config.KyuubiConf
 import org.apache.kyuubi.config.KyuubiConf._
+import 
org.apache.kyuubi.metrics.MetricsConstants.OPERATION_BATCH_PENDING_MAX_ELAPSE
+import org.apache.kyuubi.metrics.MetricsSystem
 import org.apache.kyuubi.server.api.v1.ApiRootResource
 import org.apache.kyuubi.server.http.authentication.{AuthenticationFilter, 
KyuubiHttpAuthenticationFactory}
 import org.apache.kyuubi.server.ui.{JettyServer, JettyUtils}
 import org.apache.kyuubi.service.{AbstractFrontendService, Serverable, 
Service, ServiceUtils}
 import org.apache.kyuubi.service.authentication.{AuthTypes, AuthUtils}
-import org.apache.kyuubi.session.{KyuubiSessionManager, SessionHandle}
+import org.apache.kyuubi.session.{KyuubiBatchSession, KyuubiSessionManager, 
SessionHandle}
 import org.apache.kyuubi.util.{JavaUtils, ThreadUtils}
 import 
org.apache.kyuubi.util.ThreadUtils.scheduleTolerableRunnableWithFixedDelay
 
@@ -202,6 +204,14 @@ class KyuubiRestFrontendService(override val serverable: 
Serverable)
     }
   }
 
+  private def getBatchPendingMaxElapse(): Long = {
+    val batchPendingElapseTimes = sessionManager.allSessions().map {
+      case session: KyuubiBatchSession => 
session.batchJobSubmissionOp.getPendingElapsedTime
+      case _ => 0L
+    }
+    if (batchPendingElapseTimes.isEmpty) 0L else batchPendingElapseTimes.max
+  }
+
   def waitForServerStarted(): Unit = {
     // block until the HTTP server is started, otherwise, we may get
     // the wrong HTTP server port -1
@@ -220,6 +230,9 @@ class KyuubiRestFrontendService(override val serverable: 
Serverable)
         isStarted.set(true)
         startBatchChecker()
         recoverBatchSessions()
+        MetricsSystem.tracing { ms =>
+          ms.registerGauge(OPERATION_BATCH_PENDING_MAX_ELAPSE, 
getBatchPendingMaxElapse, 0)
+        }
       } catch {
         case e: Exception => throw new KyuubiException(s"Cannot start 
$getName", e)
       }
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/BatchesResource.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/BatchesResource.scala
index e3e981abdc..499110cf68 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/BatchesResource.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/api/v1/BatchesResource.scala
@@ -67,6 +67,7 @@ private[v1] class BatchesResource extends ApiRequestContext 
with Logging {
     fe.getConf.get(ENGINE_SECURITY_ENABLED)
   private lazy val resourceFileMaxSize = 
fe.getConf.get(BATCH_RESOURCE_FILE_MAX_SIZE)
   private lazy val extraResourceFileMaxSize = 
fe.getConf.get(BATCH_EXTRA_RESOURCE_FILE_MAX_SIZE)
+  private lazy val metadataSearchWindow = 
fe.getConf.get(METADATA_SEARCH_WINDOW)
 
   private def batchV2Enabled(reqConf: Map[String, String]): Boolean = {
     fe.getConf.get(BATCH_SUBMITTER_ENABLED) &&
@@ -420,13 +421,15 @@ private[v1] class BatchesResource extends 
ApiRequestContext with Logging {
         s"The valid batch state can be one of the following: 
${VALID_BATCH_STATES.mkString(",")}")
     }
 
+    val createTimeFilter =
+      math.max(createTime, metadataSearchWindow.map(System.currentTimeMillis() 
- _).getOrElse(0L))
     val filter = MetadataFilter(
       sessionType = SessionType.BATCH,
       engineType = batchType,
       username = batchUser,
       state = batchState,
       requestName = batchName,
-      createTime = createTime,
+      createTime = createTimeFilter,
       endTime = endTime)
     val batches = sessionManager.getBatchesFromMetadataStore(filter, from, 
size, desc)
     new GetBatchesResponse(from, batches.size, batches.asJava)
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataManager.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataManager.scala
index 8d939aefc0..9ca1948dec 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataManager.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataManager.scala
@@ -139,8 +139,13 @@ class MetadataManager extends 
AbstractService("MetadataManager") {
       from: Int,
       size: Int,
       desc: Boolean = false): Seq[Batch] = {
-    withMetadataRequestMetrics(_metadataStore.getMetadataList(filter, from, 
size, desc)).map(
-      buildBatch)
+    withMetadataRequestMetrics(_metadataStore.getMetadataList(
+      filter,
+      from,
+      size,
+      // if create_file field is set, order by create_time, which is faster, 
otherwise by key_id
+      orderBy = if (filter.createTime > 0) Some("create_time") else 
Some("key_id"),
+      direction = if (desc) "DESC" else "ASC")).map(buildBatch)
   }
 
   def countBatch(
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataStore.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataStore.scala
index d350050f14..b9fb52f779 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataStore.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/MetadataStore.scala
@@ -58,13 +58,16 @@ trait MetadataStore extends Closeable {
    * @param from the metadata offset.
    * @param size the size to get.
    * @param desc the order of metadata list.
+   * @param orderBy the order by column, default is the auto increment primary 
key, `key_id`.
+   * @param direction the order direction, default is `ASC`.
    * @return selected metadata list.
    */
   def getMetadataList(
       filter: MetadataFilter,
       from: Int,
       size: Int,
-      desc: Boolean = false): Seq[Metadata]
+      orderBy: Option[String] = Some("key_id"),
+      direction: String = "ASC"): Seq[Metadata]
 
   /**
    * Count the metadata list with filter conditions.
diff --git 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/jdbc/JDBCMetadataStore.scala
 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/jdbc/JDBCMetadataStore.scala
index e3db01f87e..af965a220f 100644
--- 
a/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/jdbc/JDBCMetadataStore.scala
+++ 
b/kyuubi-server/src/main/scala/org/apache/kyuubi/server/metadata/jdbc/JDBCMetadataStore.scala
@@ -257,15 +257,15 @@ class JDBCMetadataStore(conf: KyuubiConf) extends 
MetadataStore with Logging {
       filter: MetadataFilter,
       from: Int,
       size: Int,
-      desc: Boolean = false): Seq[Metadata] = {
+      orderBy: Option[String] = Some("key_id"),
+      direction: String = "ASC"): Seq[Metadata] = {
     val queryBuilder = new StringBuilder
     val params = ListBuffer[Any]()
     queryBuilder.append("SELECT ")
     queryBuilder.append(METADATA_COLUMNS)
     queryBuilder.append(s" FROM $METADATA_TABLE")
     queryBuilder.append(s" ${assembleWhereClause(filter, params)}")
-    queryBuilder.append(" ORDER BY key_id ")
-    queryBuilder.append(if (desc) "DESC " else "ASC ")
+    orderBy.foreach(o => queryBuilder.append(s" ORDER BY $o $direction "))
     queryBuilder.append(dialect.limitClause(size, from))
     val query = queryBuilder.toString
     JdbcUtils.withConnection { connection =>
diff --git 
a/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/BatchesResourceSuite.scala
 
b/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/BatchesResourceSuite.scala
index 1a376e93e5..4d32de7026 100644
--- 
a/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/BatchesResourceSuite.scala
+++ 
b/kyuubi-server/src/test/scala/org/apache/kyuubi/server/api/v1/BatchesResourceSuite.scala
@@ -486,6 +486,7 @@ abstract class BatchesResourceSuiteBase extends 
KyuubiFunSuite
       .queryParam("from", "0")
       .queryParam("size", "1")
       .queryParam("desc", "true")
+      .queryParam("createTime", "1")
       .request(MediaType.APPLICATION_JSON_TYPE)
       .header(AUTHORIZATION_HEADER, basicAuthorizationHeader("anonymous"))
       .get()

Reply via email to