diff --git a/docs/references/http_api_reference.mdx b/docs/references/http_api_reference.mdx
index 1218f5e42f..436f76baf1 100644
--- a/docs/references/http_api_reference.mdx
+++ b/docs/references/http_api_reference.mdx
@@ -2635,7 +2635,150 @@ A `500` HTTP status code indicates an error condition. The response includes a J
---
+## Show transactions
+**GET** `/instance/transactions`
+
+Shows running transactions on database.
+
+### Request
+
+- Method: GET
+- URL: `/instance/transactions`
+- Headers: `accept: application/json`
+
+#### Request example
+
+```shell
+curl --request GET \
+ --url http://localhost:23820/instance/transactions \
+ --header 'accept: application/json'
+```
+
+### Response
+
+
+
+
+The response includes a JSON object like the following:
+
+```shell
+{
+ "error_code":0,
+ "transactions": [
+ {
+ "transaction_id":"27275",
+ "transaction_text":""
+ },
+ {
+ "transaction_id":"27274",
+ "transaction_text":""
+ }
+ ]
+}
+```
+
+- `"error_code"`: `integer`
+ `0`: The operation succeeds.
+
+
+
+
+A `500` HTTP status code indicates an error condition. The response includes a JSON object like the following:
+
+```shell
+{
+ "error_code": 2005,
+ "error_message": "Not support in maintenance mode"
+}
+```
+
+- `"error_code"`: `integer`
+ A non-zero value indicates a specific error condition.
+- `"error_message"`: `string`
+ When `error_code` is non-zero, `"error_message"` provides additional details about the error.
+
+
+
+
+---
+
+## Show transaction
+
+**GET** `/instance/transactions/{trasaction_id}`
+
+Shows running transactions on database by transaction_id.
+
+### Request
+
+- Method: GET
+- URL: `/instance/transactions`
+- Headers: `accept: application/json`
+
+#### Request example
+
+```shell
+curl --request GET \
+ --url http://localhost:23820/instance/transactions/{transaction_id} \
+ --header 'accept: application/json'
+```
+
+#### Request parameters
+
+- `transaction_id`: (*Path parameter*)
+ The id of the running transaction.
+
+### Response
+
+
+
+
+The response includes a JSON object like the following:
+
+```shell
+{
+ "error_code":0,
+ "transaction": {
+ "transaction_id":"27275",
+ "transaction_text":""
+ }
+}
+```
+
+- `"error_code"`: `integer`
+ `0`: The operation succeeds.
+
+
+
+
+A `500` HTTP status code indicates an error condition. The response includes a JSON object like the following:
+
+```shell
+{
+ "error_code": 2005,
+ "error_message": "Not support in maintenance mode"
+}
+```
+
+- `"error_code"`: `integer`
+ A non-zero value indicates a specific error condition.
+- `"error_message"`: `string`
+ When `error_code` is non-zero, `"error_message"` provides additional details about the error.
+
+
+
+
+---
## Admin set node role
diff --git a/src/network/http_server.cpp b/src/network/http_server.cpp
index 67c116dc4c..0b02e6251a 100644
--- a/src/network/http_server.cpp
+++ b/src/network/http_server.cpp
@@ -3590,6 +3590,116 @@ class ShowFullCheckpointHandler final : public HttpRequestHandler {
}
};
+
+class ShowQueryHandler final : public HttpRequestHandler {
+public:
+SharedPtr handle(const SharedPtr &request) final {
+ auto infinity = Infinity::RemoteConnect();
+ DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });
+
+ nlohmann::json json_response;
+ nlohmann::json json_table;
+ HTTPStatus http_status;
+ String query_id = request->getPathVariable("query_id");
+ QueryResult result = infinity->Query(fmt::format("show query {}", query_id));
+
+ if (result.IsOk()) {
+ DataBlock *data_block = result.result_table_->GetDataBlockById(0).get();
+ auto column_cnt = result.result_table_->ColumnCount();
+ for (SizeT col = 0; col < column_cnt; ++col) {
+ const String &column_name = result.result_table_->GetColumnNameById(col);
+ Value value = data_block->GetValue(col, 0);
+ const String &column_value = value.ToString();
+ json_table[column_name] = column_value;
+ }
+ json_response["query"] = json_table;
+ json_response["error_code"] = 0;
+ http_status = HTTPStatus::CODE_200;
+ } else {
+ json_response["error_code"] = result.ErrorCode();
+ json_response["error_message"] = result.ErrorMsg();
+ http_status = HTTPStatus::CODE_500;
+ }
+
+ return ResponseFactory::createResponse(http_status, json_response.dump());
+ }
+};
+
+class ShowTransactionsHandler final : public HttpRequestHandler {
+public:
+SharedPtr handle(const SharedPtr &request) final {
+ auto infinity = Infinity::RemoteConnect();
+ DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });
+
+ nlohmann::json json_response;
+ HTTPStatus http_status;
+ QueryResult result = infinity->Query("show transactions");
+
+ if (result.IsOk()) {
+ SizeT block_rows = result.result_table_->DataBlockCount();
+ for (SizeT block_id = 0; block_id < block_rows; ++block_id) {
+ DataBlock *data_block = result.result_table_->GetDataBlockById(block_id).get();
+ auto row_count = data_block->row_count();
+ auto column_cnt = result.result_table_->ColumnCount();
+ for (int row = 0; row < row_count; ++row) {
+ nlohmann::json json_table;
+ for (SizeT col = 0; col < column_cnt; ++col) {
+ const String &column_name = result.result_table_->GetColumnNameById(col);
+ Value value = data_block->GetValue(col, row);
+ const String &column_value = value.ToString();
+ json_table[column_name] = column_value;
+ }
+ json_response["transactions"].push_back(json_table);
+ }
+ }
+ json_response["error_code"] = 0;
+ http_status = HTTPStatus::CODE_200;
+ } else {
+ json_response["error_code"] = result.ErrorCode();
+ json_response["error_message"] = result.ErrorMsg();
+ http_status = HTTPStatus::CODE_500;
+ }
+
+ return ResponseFactory::createResponse(http_status, json_response.dump());
+ }
+};
+
+class ShowTransactionHandler final : public HttpRequestHandler {
+public:
+SharedPtr handle(const SharedPtr &request) final {
+ auto infinity = Infinity::RemoteConnect();
+ DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });
+
+ nlohmann::json json_response;
+ nlohmann::json json_table;
+ HTTPStatus http_status;
+ String transaction_id = request->getPathVariable("transaction_id");
+ QueryResult result = infinity->Query(fmt::format("show transaction {}", transaction_id));
+
+ if (result.IsOk()) {
+ DataBlock *data_block = result.result_table_->GetDataBlockById(0).get();
+ auto column_cnt = result.result_table_->ColumnCount();
+ for (SizeT col = 0; col < column_cnt; ++col) {
+ const String &column_name = result.result_table_->GetColumnNameById(col);
+ Value value = data_block->GetValue(col, 0);
+ const String &column_value = value.ToString();
+ json_table[column_name] = column_value;
+ }
+ json_response["error_code"] = 0;
+ json_response["transaction"]= json_table;
+ http_status = HTTPStatus::CODE_200;
+ } else {
+ json_response["error_code"] = result.ErrorCode();
+ json_response["error_message"] = result.ErrorMsg();
+ http_status = HTTPStatus::CODE_500;
+ }
+
+ return ResponseFactory::createResponse(http_status, json_response.dump());
+ }
+};
+
+
+
class AdminShowCurrentNodeHandler final : public HttpRequestHandler {
public:
SharedPtr handle(const SharedPtr &request) final {
@@ -3926,6 +4036,9 @@ void HTTPServer::Start(const String &ip_address, u16 port) {
router->route("GET", "/instance/logs", MakeShared());
router->route("GET", "/instance/delta_checkpoint", MakeShared());
router->route("GET", "/instance/global_checkpoint", MakeShared());
+ router->route("GET", "/instance/queries/{query_id}", MakeShared());
+ router->route("GET", "/instance/transactions", MakeShared());
+ router->route("GET", "/instance/transactions/{transaction_id}", MakeShared());
// variable
router->route("GET", "/variables/global", MakeShared());