ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

如何通过备份与恢复把自管 ClickHouse 迁移到 ClickHouse Cloud

如何通过备份与恢复把自管 ClickHouse 迁移到 ClickHouse Cloud 如何通过备份与恢复把自管 ClickHouse 迁移到 ClickHouse Cloud【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse这篇文档解决的问题是把自管self-managed / OSSClickHouse 集群的数据迁移到 ClickHouse Cloud方式是先把数据备份到云对象存储本文以 S3 为例再在 Cloud 服务上从 S3 恢复。适用前提是你有一个多分片/多副本的 ClickHouse 集群本文示例是 2 分片、2 副本、一个 S3 桶和对应的 IAM 用户并且能够新建一个 ClickHouse Cloud 服务。完成后源库的数据会以SharedMergeTree表的形式出现在 Cloud 服务里可以直接查询验证行数。ClickHouse 官方提供两条迁移路线用remoteSecure()函数直接拉/推数据或者用BACKUP/RESTORE命令经由云对象存储中转。本文只覆盖第二条路线。注意一个硬性边界这条路线要求源端是一个集群因为恢复时表会从MergeTree转换为ReplicatedMergeTree最终落到 Cloud 的SharedMergeTree。如果你只有单实例应改用remoteSecure()那篇指南本文的流程不适用。两种迁移方式中选用哪一条方式适用场景关键命令remoteSecure()拉/推单实例或不想引入对象存储INSERT INTO ... SELECT * FROM remoteSecure(...)BACKUP/RESTORE经 S3集群、需要留一份对象存储备份BACKUP DATABASE ... TO S3(...)、RESTORE DATABASE ... FROM S3(...)本文主路径走第二行。下面所有命令都默认源端是集群、中转存储是 S3如果用的是 GCP 的 S3 兼容存储TO S3()/FROM S3()语法同样适用Azure 则改用TO AzureBlobStorage()语法。准备条件已安装 Docker用来拉起示例集群如果你已有集群可以跳过集群搭建直接看引擎转换。已有一个 S3 桶和一个能对该桶做s3:*操作的 IAM 用户含 Access Key 和 Secret Access Key。桶名在 AWS 全局唯一必须保持Block all Public Access开启。创建步骤见 How to create an AWS IAM user and S3 bucket。能够新建一个 ClickHouse Cloud 服务。本文为了可复现用官方 examples 仓库里的 2 分片 2 副本 docker-compose 配方拉起一个集群。若你已有等价集群可忽略这段搭建步骤。# 在本地克隆 examples 仓库后进入 2S_2R 配方目录 cd examples/docker-compose-recipes/recipes/cluster_2S_2R docker compose up从新终端窗口连接到第一个节点docker exec -it clickhouse-01 clickhouse-client在自管集群上把表转换为 ReplicatedMergeTreeCloud 用的是SharedMergeTree恢复备份时ClickHouse 会自动把ReplicatedMergeTree表转成SharedMergeTree。所以备份前源端表必须已经是ReplicatedMergeTree。跑在集群上的表通常已经是ReplicatedMergeTree如果不是需要先把MergeTree表转过来。下面用一个具体的MergeTree表演示转换。表和数据是官方示例数据集纽约出租车数据的一部分仅用于让转换步骤有真实数据可操作——如果你已有自己的MergeTree表直接把它换成你的db.table即可不必照搬示例的建表和加载。建库、建表并写入示例数据CREATE DATABASE nyc_taxi; CREATE TABLE nyc_taxi.trips_small_adapted ( trip_id UInt32, pickup_datetime DateTime, dropoff_datetime DateTime, pickup_longitude Nullable(Float64), pickup_latitude Nullable(Float64), dropoff_longitude Nullable(Float64), dropoff_latitude Nullable(Float64), passenger_count UInt8, trip_distance Float32, fare_amount Float32, extra Float32, tip_amount Float32, tolls_amount Float32, total_amount Float32, payment_type Enum(CSH 1, CRE 2, NOC 3, DIS 4, UNK 5), pickup_ntaname LowCardinality(String), dropoff_ntaname LowCardinality(String) ) ENGINE MergeTree PRIMARY KEY (pickup_datetime, dropoff_datetime);INSERT INTO nyc_taxi.trips_small_adapted SELECT trip_id, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, passenger_count, trip_distance, fare_amount, extra, tip_amount, tolls_amount, total_amount, payment_type, pickup_ntaname, dropoff_ntaname FROM s3( https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi/trips_{0..2}.gz, TabSeparatedWithNames );执行转换先DETACH再按复制表方式ATTACH最后恢复副本元数据。DETACH TABLE nyc_taxi.trips_small_adapted; ATTACH TABLE nyc_taxi.trips_small_adapted AS REPLICATED; SYSTEM RESTORE REPLICA nyc_taxi.trips_small_adapted;确认引擎已变为ReplicatedMergeTreeSELECT engine FROM system.tables WHERE name trips_small_adapted AND database nyc_taxi;┌─engine──────────────┐ │ ReplicatedMergeTree │ └─────────────────────┘如果你的部署在多分片之间使用了分布式表需要每个节点上有一个本地ReplicatedMergeTree表、再在其上建Distributed表作为查询入口CREATE DATABASE IF NOT EXISTS nyc_taxi ON CLUSTER cluster_2S_2R; CREATE TABLE nyc_taxi.trips_small_dist_local ON CLUSTER cluster_2S_2R ( trip_id UInt32, pickup_datetime DateTime, dropoff_datetime DateTime, pickup_longitude Nullable(Float64), pickup_latitude Nullable(Float64), dropoff_longitude Nullable(Float64), dropoff_latitude Nullable(Float64), passenger_count UInt8, trip_distance Float32, fare_amount Float32, extra Float32, tip_amount Float32, tolls_amount Float32, total_amount Float32, payment_type Enum(CSH 1, CRE 2, NOC 3, DIS 4, UNK 5), pickup_ntaname LowCardinality(String), dropoff_ntaname LowCardinality(String) ) ENGINE ReplicatedMergeTree(/clickhouse/tables/{database}/{table}/{shard}, {replica}) PRIMARY KEY (pickup_datetime, dropoff_datetime);CREATE TABLE nyc_taxi.trips_small_dist ON CLUSTER cluster_2S_2R ( -- 列定义同上 ) ENGINE Distributed(cluster_2S_2R, nyc_taxi, trips_small_dist_local, rand());数据通过分布式表写入INSERT INTO nyc_taxi.trips_small_dist SELECT trip_id, pickup_datetime, dropoff_datetime, pickup_longitude, pickup_latitude, dropoff_longitude, dropoff_latitude, passenger_count, trip_distance, fare_amount, extra, tip_amount, tolls_amount, total_amount, payment_type, pickup_ntaname, dropoff_ntaname FROM s3( https://datasets-documentation.s3.eu-west-3.amazonaws.com/nyc-taxi/trips_{0..2}.gz, TabSeparatedWithNames );在 ClickHouse Cloud 上准备目标服务和 S3 访问角色数据最终要恢复到一个新的 Cloud 服务里。打开 ClickHouse Cloud 控制台新建一个服务。选择所需区域与配置点击Create service。打开该服务的 SQL 控制台为恢复 S3 备份配置安全访问。恢复时需要让 Cloud 服务能访问你的 S3 桶做法是创建一个访问角色access role并拿到它的 role ARN。这一步的完整步骤见 Accessing S3 data securely在该指南里通过 CloudFormation 栈或手动创建 IAM 角色最后从角色的 Outputs 中复制RoleArn。拿到 ARN 后把之前创建的那个 S3 桶策略更新为同时放行两个主体{ Version: 2012-10-17, Id: Policy123456, Statement: [ { Sid: abc123, Effect: Allow, Principal: { AWS: [ arn:aws:iam::123456789123:role/ClickHouseAccess-001, arn:aws:iam::123456789123:user/docs-s3-user ] }, Action: s3:*, Resource: [ arn:aws:s3:::ch-docs-s3-bucket, arn:aws:s3:::ch-docs-s3-bucket/* ] } ] }两个 ARN 各管一段IAM 用户示例里的docs-s3-user让自管 ClickHouse 集群能把备份写到 S3。ClickHouse Cloud 角色示例里的ClickHouseAccess-001让 Cloud 服务能从 S3 恢复。上面 JSON 中的桶名、ARN、账号 ID 都是文档示例值替换成你自己的。文档同时建议源 S3 与 Cloud 服务位于同一区域以减少数据传输成本。在每个分片上执行备份每个分片必须独立备份连接到每个分片上的一个节点用各自独立的目的地路径运行备份命令。命令里的BUCKET_URL、KEY_ID、SECRET_KEY要替换成你自己的 S3 地址与 AWS 凭据。分片 1BACKUP DATABASE nyc_taxi TO S3( BUCKET_URL/backup_s1.zip, KEY_ID, SECRET_KEY )分片 2BACKUP DATABASE nyc_taxi TO S3( BUCKET_URL/backup_s2.zip, KEY_ID, SECRET_KEY )如果配置正确会返回一个包含备份唯一 id 和状态的结果下面是文档示例实际 id 与时间戳不同Query id: efcaf053-75ed-4924-aeb1-525547ea8d45 ┌─id───────────────────────────────────┬─status─────────┐ │ e73b99ab-f2a9-443a-80b4-533efe2d40b3 │ BACKUP_CREATED │ └──────────────────────────────────────┴────────────────┘状态为BACKUP_CREATED即表示这一分片的备份已完成。去 S3 桶里看会看到新生成的文件夹数据和元数据分开存放说明备份确实落盘了以下是几个分支按需选用单节点、无分布式表一条命令备份整个库即可不需要分片拆成两条BACKUP DATABASE nyc_taxi TO S3( BUCKET_URL, KEY_ID, SECRET_KEY )做整服务迁移除了所有用户库表还把账号、角色、配置 profile、行级策略、配额、自定义函数一并备份排除system等库BACKUP TABLE system.users, TABLE system.roles, TABLE system.settings_profiles, TABLE system.row_policies, TABLE system.quotas, TABLE system.functions, ALL EXCEPT DATABASES INFORMATION_SCHEMA, information_schema, system TO S3( BUCKET_ID, KEY_ID, SECRET_ID ) SETTINGS compression_methodlzma, compression_level3;其中BUCKET_ID/KEY_ID/SECRET_ID同样是替换为你自己的值文档此处示例变量名与前面的BUCKET_URL不一致按你自己的桶地址与凭据填写即可。这条命令备份的范围所有用户库与表、账号与密码、角色与权限、settings profiles、行级策略、配额、用户自定义函数。大库用异步备份对很大的库可加ASYNC让备份在后台执行、命令立即返回一个备份 IDBACKUP DATABASE my_database TO S3(https://your-bucket.s3.amazonaws.com/backup.zip, key, secret) ASYNC;返回的 ID 用于监控进度文档示例实际 ID 不同SELECT * FROM system.backups WHERE id abc123-def456-789此外也可以做增量备份。备份与恢复的总体机制全量/增量、同步/异步、压缩、并发控制、系统表与访问表的特殊处理见 Backup and restore in ClickHouse。恢复到 ClickHouse Cloud在 Cloud 服务上把每个分片的备份依次恢复。ROLE_ARN填上一步从 secure S3 访问指南拿到的 role ARN。关键细节从第二个以及之后每个分片开始必须加SETTINGS allow_non_empty_tablestrue让分片数据追加到已恢复的表上而不是因为表已存在而报错。分片 1RESTORE DATABASE nyc_taxi FROM S3( BUCKET_URL/backup_s1.zip, extra_credentials(role_arn ROLE_ARN) )分片 2RESTORE DATABASE nyc_taxi FROM S3( BUCKET_URL/backup_s2.zip, extra_credentials(role_arn ROLE_ARN) ) SETTINGS allow_non_empty_tablestrue;非分布式部署若没有分布式表单条命令即可恢复整个库RESTORE DATABASE nyc_taxi FROM S3( BUCKET_URL, extra_credentials(role_arn ROLE_ARN) )整服务恢复与整服务备份对应把账号、角色等一并恢复RESTORE TABLE system.users, TABLE system.roles, TABLE system.settings_profiles, TABLE system.row_policies, TABLE system.quotas, ALL EXCEPT DATABASES INFORMATION_SCHEMA, information_schema, system FROM S3( BUCKET_URL, extra_credentials(role_arn ROLE_ARN) )恢复完成后在 Cloud 服务上查本地表验证数据是否到位下面3000317是文档示例结果你的行数取决于实际数据不要把它当成固定预期-- ClickHouse Cloud restores everything in your local table SELECT count() from nyc_taxi.trips_small_dist_local; -- 文档示例输出 -- 3000317迁移后处理与验证由于 Cloud 内部用SharedMergeTree原来的Distributed表不再需要。可以删掉它换成一个保留原表名的视图让现有查询语句继续可用下面行数是文档示例DROP TABLE nyc_taxi.trips_small_dist; CREATE VIEW nyc_taxi.trips_small_dist AS SELECT * FROM nyc_taxi.trips_small_dist_local; SELECT count() from nyc_taxi.trips_small_dist; -- 文档示例输出 -- 3000317非分布式的ReplicatedMergeTree表会被恢复成SharedMergeTree直接查原表名即可SELECT count() FROM nyc_taxi.trips_small_adapted; -- 文档示例输出 -- 3000317限制与排查必须是集群。这条 BACKUP/RESTORE 路线要求源端是集群因为表要转成ReplicatedMergeTree单实例应走remoteSecure()那条指南。兼容行为差异。如果迁移后发现自管与 Cloud 的行为不一致可能与compatibility设置有关。Cloud 里该值在服务创建时确定、之后不在服务层面变化如需修改需走官方支持渠道申请。进度与失败排查。备份命令返回id和status用该 id 查system.backups可看进度或失败原因system.backup_log记录每次备份/恢复操作的详细事件。对ASYNC的长时间备份尤其有用。对象存储厂商。TO S3()同时适用于 AWS 与 GCPAzure 用TO AzureBlobStorage()语法。备份目标已存在会失败。覆盖已存在的备份文件会报BACKUP_ALREADY_EXISTS因此本文示例为每个分片用了不同的目的地路径backup_s1.zip/backup_s2.zip。按上面的顺序执行完你就能在 Cloud 服务上查到与源端一致的数据行数并通过视图保留原分布式表的查询入口。数据已落盘到 S3这份备份本身也留作了一份可再次恢复的对象存储副本。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表