يتناول هذا المقال إنشاء نسخ احتياطية أو استعادتها إلى/من حاوية S3 عبر نقطة نهاية S3.
الصياغة
-- core commands
BACKUP | RESTORE
--- what to backup/restore (or exclude)
TABLE [db.]table_name [AS [db.]table_name_in_backup] |
DICTIONARY [db.]dictionary_name [AS [db.]name_in_backup] |
DATABASE database_name [AS database_name_in_backup] |
TEMPORARY TABLE table_name [AS table_name_in_backup] |
VIEW view_name [AS view_name_in_backup] |
[EXCEPT TABLES ...] |
ALL [EXCEPT {TABLES|DATABASES}...] } [,...]
---
[ON CLUSTER 'cluster_name']
--- where to backup or restore to or from
TO|FROM
File('<path>/<filename>') |
Disk('<disk_name>', '<path>/') |
S3('<S3 endpoint>/<path>', '<Access key ID>', '<Secret access key>', '<extra_credentials>') |
AzureBlobStorage('<connection string>/<url>', '<container>', '<path>', '<account name>', '<account key>')
--- additional settings
[SETTINGS ...]
[ASYNC]راجع "ملخص الأوامر" لمزيد من التفاصيل عن كل أمر.
مثال للاستخدام
نسخة احتياطية تزايدية إلى نقطة نهاية S3
في هذا المثال، سننشئ نسخة احتياطية على نقطة نهاية S3 ثم نستعيدها منها مرة أخرى.
ستحتاج إلى المعلومات التالية لاستخدام هذه الطريقة:
| المَعلمة | مثال |
|---|---|
| نقطة نهاية S3 | https://backup-ch-docs.s3.us-east-1.amazonaws.com/backups/ |
| معرّف مفتاح الوصول | BKIOZLE2VYN3VXXTP9RC |
| مفتاح الوصول السري | 40bwYnbqN7xU8bVePaUCh3+YEyGXu8UOMV9ANpwL |
تُحدَّد وجهة النسخة الاحتياطية كما يلي:
S3('<s3 endpoint>/<directory>', '<access key id>', '<secret access key>', '<extra_credentials>')الإعداد
أنشئ قاعدة البيانات والجدول التاليين، ثم أدرج بعض البيانات العشوائية فيه.
CREATE DATABASE IF NOT EXISTS test_db;
CREATE TABLE test_db.test_table
(
`key` Int,
`value` String,
`array` Array(String)
)
ENGINE = MergeTree
ORDER BY tuple()INSERT INTO test_db.test_table SELECT *
FROM generateRandom('key Int, value String, array Array(String)')
LIMIT 1000أنشئ نسخة احتياطية أساسية
تتطلب النسخ الاحتياطية التزايدية نسخة احتياطية أساسية كنقطة انطلاق. المعلمة الأولى
لوجهة S3 هي نقطة نهاية S3، تليها قيمة الدليل داخل الحاوية
الذي سيُستخدم لهذه النسخة الاحتياطية. في هذا المثال، اسم الدليل هو my_backup.
شغّل الأمر التالي لإنشاء النسخة الاحتياطية الأساسية:
BACKUP TABLE test_db.test_table TO S3(
'https://backup-ch-docs.s3.us-east-1.amazonaws.com/backups/base_backup',
'<access key id>',
'<secret access key>'
)┌─id───────────────────────────────────┬─status─────────┐
│ de442b75-a66c-4a3c-a193-f76f278c70f3 │ BACKUP_CREATED │
└──────────────────────────────────────┴────────────────┘أضف المزيد من البيانات
تُملأ النسخ الاحتياطية التزايدية بالفرق بين النسخة الاحتياطية الأساسية والمحتوى الحالي للجدول الذي يُؤخذ له نسخة احتياطية. أضف المزيد من البيانات قبل أخذ النسخة الاحتياطية التزايدية:
INSERT INTO test_db.test_table SELECT *
FROM generateRandom('key Int, value String, array Array(String)')
LIMIT 100أنشئ نسخة احتياطية تزايدية
يشبه أمر النسخ الاحتياطي هذا أمر النسخة الاحتياطية الأساسية، لكنه يضيف SETTINGS base_backup وموقع النسخة الاحتياطية الأساسية. لاحظ أن وجهة النسخة الاحتياطية التزايدية ليست الدليل نفسه الخاص بالنسخة الأساسية، بل هي نقطة النهاية نفسها مع دليل هدف مختلف داخل الـ bucket. توجد النسخة الاحتياطية الأساسية في my_backup، وستُكتب النسخة التزايدية إلى my_incremental:
BACKUP TABLE test_db.test_table TO S3(
'https://backup-ch-docs.s3.us-east-1.amazonaws.com/backups/incremental_backup',
'<access key id>',
'<secret access key>'
)
SETTINGS base_backup = S3(
'https://backup-ch-docs.s3.us-east-1.amazonaws.com/backups/base_backup',
'<access key id>',
'<secret access key>'
)┌─id───────────────────────────────────┬─status─────────┐
│ f6cd3900-850f-41c9-94f1-0c4df33ea528 │ BACKUP_CREATED │
└──────────────────────────────────────┴────────────────┘الاستعادة من النسخة الاحتياطية التزايدية
يستعيد هذا الأمر النسخة الاحتياطية التزايدية إلى جدول جديد باسم test_table_restored.
لاحظ أنه عند استعادة نسخة احتياطية تزايدية، تُدرَج أيضًا النسخة الاحتياطية الأساسية.
حدِّد النسخة الاحتياطية التزايدية فقط عند الاستعادة:
RESTORE TABLE data AS test_db.test_table_restored FROM S3(
'https://backup-ch-docs.s3.us-east-1.amazonaws.com/backups/incremental_backup',
'<access key id>',
'<secret access key>'
)┌─id───────────────────────────────────┬─status───┐
│ ff0c8c39-7dff-4324-a241-000796de11ca │ RESTORED │
└──────────────────────────────────────┴──────────┘تحقّق من العدد
أُجريت عمليتا إدراج في الجدول الأصلي data، إحداهما لـ 1,000 صف والأخرى لـ 100 صف، ليصبح المجموع 1,100.
تحقّق من أن الجدول المُستعاد يحتوي على 1,100 صف:
SELECT count()
FROM test_db.test_table_restored┌─count()─┐
│ 1100 │
└─────────┘التحقق من المحتوى
يقارن هذا بين محتوى الجدول الأصلي test_table والجدول المستعاد test_table_restored:
SELECT throwIf((
SELECT groupArray(tuple(*))
FROM test_db.test_table
) != (
SELECT groupArray(tuple(*))
FROM test_db.test_table_restored
), 'Data does not match after BACKUP/RESTORE')