資料維護

更新時間:
Copy as MD

OSS Tables提供自動維護功能,自動執行壓縮、快照管理和未引用檔案清理三種最佳化任務。這些功能持續最佳化Table的查詢效能並降低儲存成本,無需配置外部計算資源。

自動維護功能包含三種最佳化任務,分別作用於不同的資源層級:

  • 未引用檔案清理:Bucket層級配置。自動識別並刪除不再被任何錶快照引用的對象。

  • 壓縮:表層級配置。將小檔案合并為大檔案,提升查詢效能。

  • 快照管理:表層級配置。自動清理到期快照,減少中繼資料檔案數量和儲存開銷。

建立Table BucketTable後,系統自動應用以下預設維護配置。

維護功能

配置層級

參數

預設值

未引用檔案清理

Bucket層級

status

enabled

unreferencedDays

3

nonCurrentDays

10

壓縮

表層級

status

enabled

targetFileSizeMB

512

strategy

auto

快照管理

表層級

status

enabled

maxSnapshotAgeHours

120

minSnapshotsToKeep

1

服務關聯角色

OSS Tables的自動維護功能(壓縮、未引用檔案清理、快照管理)由後台服務執行,該服務需要通過服務關聯角色AliyunServiceRoleForOssTableMaintenance擷取Table Bucket的存取權限。更多關於服務關聯角色的資訊,請參見服務關聯角色

授權方式

首次訪問OSS控制台的Table Bucket 列表頁面時,如果當前帳號尚未建立該服務關聯角色,頁面頂部會顯示提示:缺少許可權:AliyunServiceRoleForOssTableMaintenance,單擊提示中的立即建立即可完成授權。授權完成後,OSS Tables後台維護服務將自動開始工作。

說明

如果使用RAM使用者操作,需確保該使用者具備建立服務關聯角色的許可權。可由主帳號為RAM使用者添加以下權限原則:

{
  "Version": "1",
  "Statement": [
    {
      "Action": "ram:CreateServiceLinkedRole",
      "Resource": "*",
      "Effect": "Allow",
      "Condition": {
        "StringEquals": {
          "ram:ServiceName": "tablemaintenance.oss.aliyuncs.com"
        }
      }
    }
  ]
}

許可權說明

該服務關聯角色的權限原則(AliyunServiceRolePolicyForOssTableMaintenance)包含以下許可權,用於讀取表配置、執行資料維護和更新中繼資料:

許可權(Action)

用途

oss:GetTableBucketMaintenanceConfiguration

讀取Bucket層級維護配置

oss:GetTableMaintenanceConfiguration

讀取Table層級維護配置

oss:ListTableBuckets

列舉Table Bucket

oss:GetTableBucket

擷取Table Bucket資訊

oss:ListTables

列舉Table

oss:GetTable

擷取Table資訊

oss:GetTableData

讀取表資料檔案(執行壓縮和清理)

oss:PutTableData

寫入表資料檔案(壓縮後產生新檔案)

oss:GetTableMetadataLocation

擷取中繼資料檔案位置

oss:UpdateTableMetadataLocation

更新中繼資料檔案位置(維護完成後提交變更)

未引用檔案清理

未引用檔案清理是Bucket層級的最佳化操作,作用於Table Bucket下的所有Table。未引用檔案清理功能會識別並刪除所有未被任何錶快照引用的對象。在資料寫入、更新或刪除過程中,可能會因為寫入作業失敗、快照到期等原因產生不再被任何中繼資料引用的資料檔案(如Parquet、Avro、ORC檔案)。這些孤立檔案持續佔用儲存空間。

重要

開啟未引用檔案清理後,如果向Table BucketPUT了任何不屬於表的Parquet、Avro、ORC檔案,這些檔案也將被視為未引用檔案並被自動清理。

未引用檔案清理採用兩階段處理機制:首先將未被引用的檔案標記為non-current狀態(由unreferencedDays控制),然後在檔案處於non-current狀態指定天數後執行刪除(由nonCurrentDays控制)。

未引用檔案清理的配置參數如下表所示。

參數

說明

取值範圍

預設值

status

是否啟用未引用檔案清理。

enableddisabled。

enabled

unreferencedDays

檔案不被任何中繼資料引用後,標記為non-current狀態的等待天數。

1~2147483647。

3

nonCurrentDays

檔案被標記為non-current狀態後,執行刪除操作的等待天數。

1~2147483647。

10

控制台

通過OSS管理主控台,直接查看和修改Table Bucket的自動維護配置。

操作步驟如下:

  1. 登入OSS管理主控台,在左側導覽列選擇Table Bucket 列表

  2. 單擊目標Table Bucket名稱,進入Bucket詳情頁。

  3. 選擇資料維護 Tab頁。

  4. 未引用檔案清理地區,查看當前配置狀態:

    • 狀態:顯示該功能是否已啟用。

    • 未引用天數:檔案不被任何中繼資料引用後,標記為non-current狀態的等待天數。預設值為3天。

    • 非當前天數:檔案被標記為non-current狀態後,執行刪除操作的等待天數。預設值為10天。

  5. 單擊編輯按鈕,修改未引用檔案清理的配置參數,完成後單擊儲存

ossutil

通過ossutil修改未引用檔案清理配置:

ossutil tables-api put-table-bucket-maintenance-configuration \
  --table-bucket-arn {ARN} \
  --type icebergUnreferencedFileRemoval \
  --value '{"status":"enabled","settings":{"icebergUnreferencedFileRemoval":{"unreferencedDays":5,"nonCurrentDays":15}}}'

SDK

以下代碼展示了如何通過SDK查詢和修改Table Bucket的未引用檔案清理配置。

Python

查詢未引用檔案清理配置:

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="get table bucket maintenance configuration sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    result = client.get_table_bucket_maintenance_configuration(
        oss_tables.models.GetTableBucketMaintenanceConfigurationRequest(
            table_bucket_arn=args.table_bucket_arn,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' table bucket arn: {result.table_bucket_arn},'
          f' configuration: {result.configuration}')


if __name__ == "__main__":
    main()

修改未引用檔案清理配置:

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="put table bucket maintenance configuration sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)
parser.add_argument('--type', help='The maintenance type, e.g., icebergUnreferencedFileRemoval.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    value = {
        'status': 'enabled',
        'settings': {
            'icebergUnreferencedFileRemoval': {
                'unreferencedDays': 7,
                'nonCurrentDays': 30
            }
        }
    }

    result = client.put_table_bucket_maintenance_configuration(
        oss_tables.models.PutTableBucketMaintenanceConfigurationRequest(
            table_bucket_arn=args.table_bucket_arn,
            type=args.type,
            value=value,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id}')
    print(f'successfully updated maintenance configuration for: {args.table_bucket_arn}')


if __name__ == "__main__":
    main()

Go

查詢未引用檔案清理配置:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
}

func main() {
	flag.Parse()
	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)

	result, err := client.GetTableBucketMaintenanceConfiguration(context.TODO(), &tables.GetTableBucketMaintenanceConfigurationRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
	})

	if err != nil {
		log.Fatalf("failed to get table bucket maintenance configuration %v", err)
	}

	log.Printf("get table bucket maintenance configuration result:%#v\n", result)
}

修改未引用檔案清理配置:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
}

func main() {
	flag.Parse()
	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)

	result, err := client.PutTableBucketMaintenanceConfiguration(context.TODO(), &tables.PutTableBucketMaintenanceConfigurationRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
		Type:           oss.Ptr("icebergUnreferencedFileRemoval"),
		Value: &tables.MaintenanceValue{
			Settings: &tables.MaintenanceSettings{
				IcebergUnreferencedFileRemoval: &tables.SettingsDetail{
					UnreferencedDays: oss.Ptr(4),
					NonCurrentDays:   oss.Ptr(10),
				},
			},
			Status: oss.Ptr("enabled"),
		},
	})

	if err != nil {
		log.Fatalf("failed to put table bucket maintenance configuration %v", err)
	}

	log.Printf("put table bucket maintenance configuration result:%#v\n", result)
}

Java

查詢未引用檔案清理配置:

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class GetTableBucketMaintenanceConfigurationSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            GetTableBucketMaintenanceConfigurationRequest request = GetTableBucketMaintenanceConfigurationRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .build();

            GetTableBucketMaintenanceConfigurationResult result = client.getTableBucketMaintenanceConfiguration(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Successfully got maintenance configuration for table bucket: %s%n", tableBucketARN);
            System.out.printf("Table Bucket ARN: %s%n", result.tableBucketARN());

            result.configuration().forEach((key, value) -> {
                System.out.printf("Configuration Type: %s, Status: %s%n", key, value.status());
            });
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

修改未引用檔案清理配置:

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class PutTableBucketMaintenanceConfigurationSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";
        String type = "icebergUnreferencedFileRemoval";
        String status = "enabled";
        int unreferencedDays = 3;
        int nonCurrentDays = 3;

        IcebergUnreferencedFileRemovalSettings removalSettings = IcebergUnreferencedFileRemovalSettings.newBuilder()
                .unreferencedDays(unreferencedDays)
                .nonCurrentDays(nonCurrentDays)
                .build();

        TableBucketMaintenanceSettings settings = TableBucketMaintenanceSettings.newBuilder()
                .icebergUnreferencedFileRemoval(removalSettings)
                .build();

        TableBucketMaintenanceConfigurationValue value = TableBucketMaintenanceConfigurationValue.newBuilder()
                .status(status)
                .settings(settings)
                .build();

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            PutTableBucketMaintenanceConfigurationRequest request = PutTableBucketMaintenanceConfigurationRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .type(type)
                    .value(value)
                    .build();

            PutTableBucketMaintenanceConfigurationResult result = client.putTableBucketMaintenanceConfiguration(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Successfully configured maintenance for table bucket: %s%n", tableBucketARN);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

API

通過以下API操作:

壓縮

壓縮是表層級的最佳化操作。在Apache Iceberg表中,頻繁的流式寫入或小批量寫入會產生大量小檔案,導致查詢時需要開啟和掃描過多的檔案,降低查詢效率。壓縮將多個小檔案合并為目標大小的檔案,減少檔案數量,提升查詢效能,同時降低中繼資料開銷。

壓縮的配置參數如下表所示。

參數

說明

取值範圍

預設值

status

是否啟用自動壓縮。

enableddisabled。

enabled

targetFileSizeMB

合并後的目標檔案大小(單位:MB)。合并任務會將小於該大小的檔案合并為接近該大小的檔案。

1~2147483647。

512

strategy

壓縮策略。不同策略決定檔案的合并方式和排序行為。

auto、binpack、sortz-order。當設定為sortz-order時,表的metadata中必須已定義sort order。

auto

壓縮策略的含義:

  • auto:系統自動選擇最優的壓縮策略。對具有排序次序的表應用排序壓縮策略。對沒有排序次序的表應用二進位包壓縮策略。

  • binpack:僅按檔案大小進行合并,不改變資料排序。合并速度最快,適用於對排序無要求的情境。

  • sort:按照表中定義的sort order對資料進行排序後合并。適用於範圍查詢情境。需要表的metadata中已定義sort order。

  • z-order:使用Z-Order曲線對多個列同時排序後合并。適用於多維度查詢情境。需要表的metadata中已定義sort order。

查看和配置壓縮。

控制台

Table的資料維護頁面查看和修改壓縮配置。

  1. 登入OSS管理主控台,在左側導覽列選擇Table Bucket 列表

  2. 單擊目標Table Bucket名稱,在Table 列表中單擊目標Table名稱進入Table詳情頁。

  3. 選擇資料維護 Tab頁。

  4. 壓縮地區,查看當前配置狀態:

    • 狀態:顯示功能是否已啟用。

    • 目標檔案大小:合并後的目標檔案大小,預設為512 MB。

    • 壓縮策略:當前使用的壓縮策略,預設為 auto。

    • 作業狀態:顯示最近一次壓縮作業的執行狀態和時間。

  5. 單擊編輯按鈕,修改壓縮的配置參數,完成後單擊儲存

ossutil

通過ossutil修改壓縮配置:

ossutil tables-api put-table-maintenance-configuration \
  --table-bucket-arn {ARN} \
  --namespace mynamespace \
  --name mytable \
  --type icebergCompaction \
  --value '{"status":"enabled","settings":{"icebergCompaction":{"targetFileSizeMB":256,"strategy":"binpack"}}}'

SDK

以下代碼展示了如何通過SDK查詢和修改Table的壓縮配置。

Python

查詢壓縮配置:

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="get table maintenance configuration sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)
parser.add_argument('--namespace', help='The namespace of the table.', required=True)
parser.add_argument('--name', help='The name of the table.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    result = client.get_table_maintenance_configuration(
        oss_tables.models.GetTableMaintenanceConfigurationRequest(
            table_bucket_arn=args.table_bucket_arn,
            namespace=args.namespace,
            name=args.name,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' table arn: {result.table_arn},'
          f' configuration: {result.configuration}')


if __name__ == "__main__":
    main()

修改壓縮配置:

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="put table maintenance configuration sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)
parser.add_argument('--namespace', help='The namespace of the table.', required=True)
parser.add_argument('--name', help='The name of the table.', required=True)
parser.add_argument('--type', help='The maintenance type, e.g., icebergCompaction.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    value = {
        'status': 'enabled',
        'settings': {
            'icebergCompaction': {
                'targetFileSizeMB': 512,
                'strategy': 'auto'
            }
        }
    }

    result = client.put_table_maintenance_configuration(
        oss_tables.models.PutTableMaintenanceConfigurationRequest(
            table_bucket_arn=args.table_bucket_arn,
            namespace=args.namespace,
            name=args.name,
            type=args.type,
            value=value,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id}')
    print(f'successfully updated maintenance configuration for: {args.namespace}/{args.name}')


if __name__ == "__main__":
    main()

Go

查詢壓縮配置:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
	namespace      string
	name           string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
	flag.StringVar(&namespace, "namespace", "", "The name of the namespace.")
	flag.StringVar(&name, "name", "", "The name of the table.")
}

func main() {
	flag.Parse()

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(namespace) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, namespace name required")
	}

	if len(name) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table name required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)

	result, err := client.GetTableMaintenanceConfiguration(context.TODO(), &tables.GetTableMaintenanceConfigurationRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
		Namespace:      oss.Ptr(namespace),
		Name:           oss.Ptr(name),
	})

	if err != nil {
		log.Fatalf("failed to get table maintenance configuration %v", err)
	}

	log.Printf("get table maintenance configuration result:%#v\n", result)
}

修改壓縮配置:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
	namespace      string
	name           string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
	flag.StringVar(&namespace, "namespace", "", "The name of the namespace.")
	flag.StringVar(&name, "name", "", "The name of the table.")
}

func main() {
	flag.Parse()

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(namespace) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, namespace name required")
	}

	if len(name) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table name required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)

	// icebergCompaction type
	result, err := client.PutTableMaintenanceConfiguration(context.TODO(), &tables.PutTableMaintenanceConfigurationRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
		Namespace:      oss.Ptr(namespace),
		Name:           oss.Ptr(name),
		Type:           oss.Ptr("icebergCompaction"),
		Value: &tables.TableMaintenanceValue{
			Status: oss.Ptr("enabled"),
			Settings: &tables.TableMaintenanceSettings{
				IcebergCompaction: &tables.IcebergCompactionSettingsDetail{
					TargetFileSizeMB: oss.Ptr(400),
					Strategy:         oss.Ptr("auto"),
				},
			},
		},
	})

	// icebergSnapshotManagement type
	//result, err := client.PutTableMaintenanceConfiguration(context.TODO(), &tables.PutTableMaintenanceConfigurationRequest{
	//	TableBucketARN: oss.Ptr(tableBucketArn),
	//	Namespace:      oss.Ptr(namespace),
	//	Name:           oss.Ptr(name),
	//	Type:           oss.Ptr("icebergSnapshotManagement"),
	//	Value: &tables.TableMaintenanceValue{
	//		Status: oss.Ptr("enabled"),
	//		Settings: &tables.TableMaintenanceSettings{
	//			IcebergSnapshotManagement: &tables.IcebergSnapshotManagementSettingsDetail{
	//				MaxSnapshotAgeHours: oss.Ptr(350),
	//				MinSnapshotsToKeep:  oss.Ptr(1),
	//			},
	//		},
	//	},
	//})

	if err != nil {
		log.Fatalf("failed to put table maintenance configuration %v", err)
	}

	log.Printf("put table maintenance configuration result:%#v\n", result)
}

Java

查詢壓縮配置:

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class GetTableMaintenanceConfigurationSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";
        String namespace = "mynamespace";
        String name = "mytable";

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            GetTableMaintenanceConfigurationRequest request = GetTableMaintenanceConfigurationRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .namespace(namespace)
                    .name(name)
                    .build();

            GetTableMaintenanceConfigurationResult result = client.getTableMaintenanceConfiguration(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Table ARN: %s%n", result.tableARN());

            if (result.configuration() != null && !result.configuration().isEmpty()) {
                System.out.println("Maintenance configurations:");
                result.configuration().forEach((type, config) -> {
                    System.out.printf("  Type: %s, Status: %s%n", type, config.status());
                    if (config.settings() != null) {
                        if (config.settings().icebergCompaction() != null) {
                            System.out.printf("    Compaction - TargetFileSizeMB: %d, Strategy: %s%n",
                                    config.settings().icebergCompaction().targetFileSizeMB(),
                                    config.settings().icebergCompaction().strategy());
                        }
                        if (config.settings().icebergSnapshotManagement() != null) {
                            System.out.printf("    SnapshotManagement - MinSnapshotsToKeep: %d, MaxSnapshotAgeHours: %d%n",
                                    config.settings().icebergSnapshotManagement().minSnapshotsToKeep(),
                                    config.settings().icebergSnapshotManagement().maxSnapshotAgeHours());
                        }
                    }
                });
            } else {
                System.out.println("No maintenance configuration found.");
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

修改壓縮配置:

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class PutTableMaintenanceConfigurationSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";
        String namespace = "mynamespace";
        String name = "mytable";
        String type = "icebergCompaction";
        String status = "enabled";
        int targetFileSizeMB = 256;
        String strategy = "auto";

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            IcebergCompactionSettings compactionSettings = IcebergCompactionSettings.newBuilder()
                    .targetFileSizeMB(targetFileSizeMB)
                    .strategy(strategy)
                    .build();
            TableMaintenanceSettings settings = TableMaintenanceSettings.newBuilder()
                    .icebergCompaction(compactionSettings)
                    .build();

            TableMaintenanceConfigurationValue value = TableMaintenanceConfigurationValue.newBuilder()
                    .status(status)
                    .settings(settings)
                    .build();

            PutTableMaintenanceConfigurationRequest request = PutTableMaintenanceConfigurationRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .namespace(namespace)
                    .name(name)
                    .type(type)
                    .value(value)
                    .build();

            PutTableMaintenanceConfigurationResult result = client.putTableMaintenanceConfiguration(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Successfully put table maintenance configuration for table: %s/%s, type: %s%n", namespace, name, type);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

API

壓縮配置通過以下API操作:

快照管理

快照管理是表層級的最佳化操作。Apache Iceberg每次寫入操作都會產生一個新的快照(Snapshot),用於記錄資料的某個時間點狀態。隨著寫入次數增加,過多的快照會消耗大量儲存空間並增加中繼資料操作的開銷。快照管理自動清理到期快照,在保證資料安全的前提下減少儲存成本。

快照管理採用資料安全優先原則:當minSnapshotsToKeepmaxSnapshotAgeHours兩個條件衝突時,優先滿足最小保留快照數量,確保不會因清理快照而丟失必要的資料恢複能力。

快照管理的配置參數如下表所示。

參數

說明

取值範圍

預設值

status

是否啟用快照管理。

enableddisabled。

enabled

maxSnapshotAgeHours

快照最長保留時間(單位:小時)。超過該時間的快照將被清理。

1~2147483647。

120

minSnapshotsToKeep

最少保留的快照數量。即使快照已超過最大保留時間,也會保留該數量的最近快照。

1~2147483647。

1

查看和配置快照管理。

控制台

Table的資料維護頁面查看和修改快照管理配置。

  1. 登入OSS管理主控台,在左側導覽列選擇Table Bucket 列表

  2. 單擊目標Table Bucket名稱,在Table 列表中單擊目標Table名稱進入Table詳情頁。

  3. 選擇資料維護 Tab頁。

  4. 快照管理地區,查看當前配置狀態:

    • 狀態:顯示功能是否已啟用。

    • 最大快照保留時間:快照的最大保留時間,預設為120小時。

    • 最少保留快照數:至少保留的快照數量,預設為1個。

    • 作業狀態:顯示最近一次快照清理作業的執行狀態和時間。

  5. 單擊編輯按鈕,修改快照管理的配置參數,完成後單擊儲存

ossutil

通過ossutil修改快照管理配置:

ossutil tables-api put-table-maintenance-configuration \
  --table-bucket-arn {ARN} \
  --namespace mynamespace \
  --name mytable \
  --type icebergSnapshotManagement \
  --value '{"status":"enabled","settings":{"icebergSnapshotManagement":{"maxSnapshotAgeHours":72,"minSnapshotsToKeep":3}}}'

SDK

以下代碼展示了如何通過SDK查詢和修改Table的快照管理配置。快照管理與壓縮使用相同的表級維護配置介面(GetTableMaintenanceConfiguration / PutTableMaintenanceConfiguration)。

Python

查詢快照管理配置:

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="get table maintenance configuration sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)
parser.add_argument('--namespace', help='The namespace of the table.', required=True)
parser.add_argument('--name', help='The name of the table.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    result = client.get_table_maintenance_configuration(
        oss_tables.models.GetTableMaintenanceConfigurationRequest(
            table_bucket_arn=args.table_bucket_arn,
            namespace=args.namespace,
            name=args.name,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' table arn: {result.table_arn},'
          f' configuration: {result.configuration}')


if __name__ == "__main__":
    main()

修改快照管理配置:

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="put table maintenance configuration sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)
parser.add_argument('--namespace', help='The namespace of the table.', required=True)
parser.add_argument('--name', help='The name of the table.', required=True)
parser.add_argument('--type', help='The maintenance type, e.g., icebergSnapshotManagement.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    value = {
        'status': 'enabled',
        'settings': {
            'icebergSnapshotManagement': {
                'maxSnapshotAgeHours': 72,
                'minSnapshotsToKeep': 3
            }
        }
    }

    result = client.put_table_maintenance_configuration(
        oss_tables.models.PutTableMaintenanceConfigurationRequest(
            table_bucket_arn=args.table_bucket_arn,
            namespace=args.namespace,
            name=args.name,
            type=args.type,
            value=value,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id}')
    print(f'successfully updated maintenance configuration for: {args.namespace}/{args.name}')


if __name__ == "__main__":
    main()

Go

查詢快照管理配置:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
	namespace      string
	name           string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
	flag.StringVar(&namespace, "namespace", "", "The name of the namespace.")
	flag.StringVar(&name, "name", "", "The name of the table.")
}

func main() {
	flag.Parse()

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(namespace) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, namespace name required")
	}

	if len(name) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table name required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)

	result, err := client.GetTableMaintenanceConfiguration(context.TODO(), &tables.GetTableMaintenanceConfigurationRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
		Namespace:      oss.Ptr(namespace),
		Name:           oss.Ptr(name),
	})

	if err != nil {
		log.Fatalf("failed to get table maintenance configuration %v", err)
	}

	log.Printf("get table maintenance configuration result:%#v\n", result)
}

修改快照管理配置:

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
	namespace      string
	name           string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
	flag.StringVar(&namespace, "namespace", "", "The name of the namespace.")
	flag.StringVar(&name, "name", "", "The name of the table.")
}

func main() {
	flag.Parse()

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(namespace) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, namespace name required")
	}

	if len(name) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table name required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)



	// icebergSnapshotManagement type
	result, err := client.PutTableMaintenanceConfiguration(context.TODO(), &tables.PutTableMaintenanceConfigurationRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
		Namespace:      oss.Ptr(namespace),
		Name:           oss.Ptr(name),
		Type:           oss.Ptr("icebergSnapshotManagement"),
		Value: &tables.TableMaintenanceValue{
			Status: oss.Ptr("enabled"),
			Settings: &tables.TableMaintenanceSettings{
				IcebergSnapshotManagement: &tables.IcebergSnapshotManagementSettingsDetail{
					MaxSnapshotAgeHours: oss.Ptr(350),
					MinSnapshotsToKeep:  oss.Ptr(1),
				},
			},
		},
	})

	if err != nil {
		log.Fatalf("failed to put table maintenance configuration %v", err)
	}

	log.Printf("put table maintenance configuration result:%#v\n", result)
}

Java

查詢快照管理配置:

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class GetTableMaintenanceConfigurationSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";
        String namespace = "mynamespace";
        String name = "mytable";

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            GetTableMaintenanceConfigurationRequest request = GetTableMaintenanceConfigurationRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .namespace(namespace)
                    .name(name)
                    .build();

            GetTableMaintenanceConfigurationResult result = client.getTableMaintenanceConfiguration(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Table ARN: %s%n", result.tableARN());

            if (result.configuration() != null && !result.configuration().isEmpty()) {
                System.out.println("Maintenance configurations:");
                result.configuration().forEach((type, config) -> {
                    System.out.printf("  Type: %s, Status: %s%n", type, config.status());
                    if (config.settings() != null) {
                        if (config.settings().icebergCompaction() != null) {
                            System.out.printf("    Compaction - TargetFileSizeMB: %d, Strategy: %s%n",
                                    config.settings().icebergCompaction().targetFileSizeMB(),
                                    config.settings().icebergCompaction().strategy());
                        }
                        if (config.settings().icebergSnapshotManagement() != null) {
                            System.out.printf("    SnapshotManagement - MinSnapshotsToKeep: %d, MaxSnapshotAgeHours: %d%n",
                                    config.settings().icebergSnapshotManagement().minSnapshotsToKeep(),
                                    config.settings().icebergSnapshotManagement().maxSnapshotAgeHours());
                        }
                    }
                });
            } else {
                System.out.println("No maintenance configuration found.");
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

修改快照管理配置:

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class PutTableMaintenanceConfigurationSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";
        String namespace = "mynamespace";
        String name = "mytable";
        String type = "icebergSnapshotManagement";
        String status = "enabled";
        int maxSnapshotAgeHours = 72;
        int minSnapshotsToKeep = 3;

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            IcebergSnapshotManagementSettings snapshotManagementSettings = IcebergSnapshotManagementSettings.newBuilder()
                    .maxSnapshotAgeHours(maxSnapshotAgeHours)
                    .minSnapshotsToKeep(minSnapshotsToKeep)
                    .build();
            TableMaintenanceSettings settings = TableMaintenanceSettings.newBuilder()
                    .icebergSnapshotManagement(snapshotManagementSettings)
                    .build();

            TableMaintenanceConfigurationValue value = TableMaintenanceConfigurationValue.newBuilder()
                    .status(status)
                    .settings(settings)
                    .build();

            PutTableMaintenanceConfigurationRequest request = PutTableMaintenanceConfigurationRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .namespace(namespace)
                    .name(name)
                    .type(type)
                    .value(value)
                    .build();

            PutTableMaintenanceConfigurationResult result = client.putTableMaintenanceConfiguration(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Successfully put table maintenance configuration for table: %s/%s, type: %s%n", namespace, name, type);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

API

快照管理配置通過以下API操作:

運行機制

  • 觸發時機:維護任務由系統後台自動調度執行,非固定時間點觸發。通常情況下,針對同一個Table的同一種維護任務大約每24小時運行一次。當系統負載高時,維護任務可能會延後啟動。

  • 資源佔用:自動維護任務不佔用使用者側的吞吐和QPS配額,不影響生產任務的正常運行。

  • 事務隔離:維護任務基於Iceberg的快照隔離機制運行。在合并檔案的同時,生產任務可以繼續寫入新資料。讀取任務也不受影響,查詢引擎會自動選擇最新的有效快照。

查詢維護任務狀態

查詢Table的三種維護任務(壓縮、快照管理、未引用檔案清理)的執行狀態。每種維護任務獨立返回各自的狀態資訊。

控制台

Table的資料維護頁面查看各維護任務的作業狀態。

  1. 登入OSS管理主控台,在左側導覽列選擇Table Bucket 列表

  2. 單擊目標Table Bucket名稱,在Table 列表中單擊目標Table名稱進入Table詳情頁。

  3. 選擇資料維護 Tab頁。

  4. 在各維護模組地區查看作業狀態資訊:

    • 壓縮:顯示壓縮任務的執行狀態(如"失敗"或"成功")及最後已耗用時間。

    • 快照管理:顯示快照清理任務的執行狀態及最後已耗用時間。

    • 未引用檔案清理:Bucket層級配置,單擊Table Bucket編輯配置連結跳轉到Table Bucket的資料維護頁面查看。

ossutil

ossutil tables-api get-table-maintenance-job-status \
  --table-bucket-arn acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket \
  --namespace mynamespace \
  --name mytable

SDK

Python

import argparse
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.tables as oss_tables

parser = argparse.ArgumentParser(description="get table maintenance job status sample")
parser.add_argument('--region', help='The region in which the table bucket is located.', required=True)
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS Tables.')
parser.add_argument('--table-bucket-arn', help='The ARN of the table bucket.', required=True)
parser.add_argument('--namespace', help='The namespace of the table.', required=True)
parser.add_argument('--name', help='The name of the table.', required=True)

def main():
    args = parser.parse_args()

    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    cfg.region = args.region
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    client = oss_tables.Client(cfg)

    result = client.get_table_maintenance_job_status(
        oss_tables.models.GetTableMaintenanceJobStatusRequest(
            table_bucket_arn=args.table_bucket_arn,
            namespace=args.namespace,
            name=args.name,
        )
    )

    print(f'status code: {result.status_code},'
          f' request id: {result.request_id},'
          f' table arn: {result.table_arn},'
          f' status: {result.status}')


if __name__ == "__main__":
    main()

Go

package main

import (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/tables"
)

var (
	region         string
	tableBucketArn string
	namespace      string
	name           string
)

func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&tableBucketArn, "table-bucket-arn", "", "The arn of the table bucket.")
	flag.StringVar(&namespace, "namespace", "", "The name of the namespace.")
	flag.StringVar(&name, "name", "", "The name of the table.")
}

func main() {
	flag.Parse()

	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	if len(tableBucketArn) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table bucket arn required")
	}

	if len(namespace) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, namespace name required")
	}

	if len(name) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, table name required")
	}

	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	client := tables.NewTablesClient(cfg)

	result, err := client.GetTableMaintenanceJobStatus(context.TODO(), &tables.GetTableMaintenanceJobStatusRequest{
		TableBucketARN: oss.Ptr(tableBucketArn),
		Namespace:      oss.Ptr(namespace),
		Name:           oss.Ptr(name),
	})

	if err != nil {
		log.Fatalf("failed to get table maintenance job status %v", err)
	}

	log.Printf("get table maintenance job status result:%#v\n", result)
}

Java

import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.tables.OSSTablesClient;
import com.aliyun.sdk.service.oss2.tables.models.*;

public class GetTableMaintenanceJobStatusSample {

    public static void main(String[] args) throws Exception {
        String region = "cn-hangzhou";
        String tableBucketARN = "acs:osstables:cn-hangzhou:1234567890:bucket/mytable-bucket";
        String namespace = "mynamespace";
        String name = "mytable";

        try (OSSTablesClient client = OSSTablesClient.newBuilder()
                .credentialsProvider(new EnvironmentVariableCredentialsProvider())
                .region(region)
                .build()) {
            GetTableMaintenanceJobStatusRequest request = GetTableMaintenanceJobStatusRequest.newBuilder()
                    .tableBucketARN(tableBucketARN)
                    .namespace(namespace)
                    .name(name)
                    .build();

            GetTableMaintenanceJobStatusResult result = client.getTableMaintenanceJobStatus(request);

            System.out.printf("Status code:%d, request id:%s%n",
                    result.statusCode(), result.requestId());
            System.out.printf("Table ARN: %s%n", result.tableARN());

            if (result.jobStatus() != null && !result.jobStatus().isEmpty()) {
                System.out.println("Maintenance job status:");
                result.jobStatus().forEach((type, status) -> {
                    System.out.printf("  Type: %s, Status: %s%n", type, status.status());
                    if (status.lastRunTimestamp() != null) {
                        System.out.printf("    LastRunTimestamp: %s%n", status.lastRunTimestamp());
                    }
                    if (status.failureMessage() != null && !status.failureMessage().isEmpty()) {
                        System.out.printf("    FailureMessage: %s%n", status.failureMessage());
                    }
                });
            } else {
                System.out.println("No maintenance job status found.");
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

API

使用GetTableMaintenanceJobStatus介面查詢維護任務狀態。