Snowflake 8 — Time Travel, Cloning, Streams & Tasks, Data Sharing
Vì sao bốn tính năng này thay đổi cuộc chơi
Các bài trước trong series đã nói về kiến trúc, warehouse, nạp dữ liệu và bảo mật. Những phần đó Snowflake làm tốt nhưng không thực sự độc nhất. Bốn tính năng trong bài này mới là thứ khiến một DBA Oracle hay Teradata lần đầu chuyển sang phải sững người: khả năng truy vấn dữ liệu như nó tồn tại trong quá khứ, nhân bản một database 50 TB trong một giây mà không tốn thêm byte nào, bắt thay đổi bảng và tự chạy pipeline theo lịch, và chia sẻ dữ liệu sống cho đối tác mà không cần copy ra ngoài.
Điểm chung của cả bốn: chúng đều đứng trên nền tảng kiến trúc immutable micro-partition của Snowflake. Dữ liệu không bao giờ bị ghi đè tại chỗ — mỗi lần thay đổi tạo ra micro-partition mới, còn phiên bản cũ vẫn nằm đó cho tới khi hết hạn lưu. Chính đặc tính này là chìa khóa của toàn bộ bài viết.
Time Travel — quay ngược thời gian
Time Travel cho phép truy vấn, khôi phục, hoặc clone dữ liệu tại một thời điểm trong quá khứ, trong khoảng retention period. Vì micro-partition cũ chưa bị xóa, Snowflake chỉ cần trỏ metadata về đúng thời điểm bạn yêu cầu.
Ba cách chỉ định thời điểm
Cú pháp dùng mệnh đề AT hoặc BEFORE gắn sau tên bảng. Đây là cú pháp Snowflake, không chạy trên sandbox PostgreSQL — chỉ minh họa:
-- Truy vấn bảng như 5 phút trước
SELECT * FROM transactions AT(OFFSET => -60*5);
-- Truy vấn tại một timestamp cụ thể
SELECT * FROM transactions
AT(TIMESTAMP => '2026-06-30 08:00:00'::timestamp_tz);
-- Truy vấn trạng thái NGAY TRƯỚC một statement gây lỗi
SELECT * FROM transactions
BEFORE(STATEMENT => '01b2c3d4-0000-...');
OFFSET => N— N giây tính từ hiện tại (số âm = lùi về quá khứ).TIMESTAMP => ...— một mốc thời gian tuyệt đối.STATEMENT => '<query_id>'— trạng thái ngay trước khi câu lệnh cóquery_idđó chạy. Cực hữu ích khi biết chính xác câuUPDATE/DELETEnào làm hỏng dữ liệu.
Sự khác biệt: AT bao gồm cả thời điểm chỉ định; BEFORE loại trừ nó (trạng thái ngay liền trước).
Retention period theo edition
Retention mặc định là 1 ngày, cấu hình qua tham số DATA_RETENTION_TIME_IN_DAYS ở cấp account, database, schema hoặc table.
| Edition | Max retention | Ghi chú |
|---|---|---|
| Standard | 1 ngày | Không nâng được quá 1 |
| Enterprise trở lên | tối đa 90 ngày | Cho bảng permanent |
| Transient / temporary table | tối đa 1 ngày (thường đặt 0) | Không có Fail-safe |
Lưu ý về chi phí: mỗi ngày retention giữ thêm các phiên bản micro-partition cũ, nên kéo dài retention làm tăng storage. Với bảng biến động mạnh (ví dụ staging load hàng giờ), giữ 90 ngày có thể phình storage gấp nhiều lần. Bảng dimension quan trọng thì để dài; bảng staging tạm thì đặt DATA_RETENTION_TIME_IN_DAYS = 0 hoặc dùng transient table. Chủ đề này nối tiếp phần chi phí trong Quản trị chi phí & credit.
UNDROP — cứu vật thể vừa lỡ xóa
Không chỉ dữ liệu trong bảng, mà cả object bị DROP cũng nằm trong Time Travel. Trong retention period, ta khôi phục tức thì bằng UNDROP:
-- Lỡ tay xóa cả bảng — khôi phục ngay
UNDROP TABLE loan_application_details;
-- Cũng dùng được cho schema và database
UNDROP SCHEMA risk_mart;
UNDROP DATABASE edw_prod;
Đây là cứu cánh khét tiếng: không cần restore từ backup, không cần mở ticket cho hạ tầng, chỉ một câu lệnh và bảng quay lại y nguyên trong vài giây.
Fail-safe — lưới an toàn cuối cùng
Sau khi retention period của Time Travel hết hạn, dữ liệu chưa biến mất ngay mà rơi vào vùng Fail-safe: một khoảng 7 ngày cố định, không cấu hình được, chỉ áp dụng cho permanent table.
Điểm khác biệt cốt lõi so với Time Travel:
- Bạn không truy vấn hay tự khôi phục được từ Fail-safe. Chỉ Snowflake Support mới khôi phục được, qua yêu cầu hỗ trợ, và có thể mất hàng giờ tới vài ngày.
- Fail-safe là biện pháp cho thảm họa vận hành (mất dữ liệu do lỗi hệ thống), không phải công cụ truy vấn hàng ngày.
- Fail-safe vẫn tiêu storage — bạn trả tiền cho 7 ngày này. Đây là lý do transient/temporary table (không có Fail-safe) rẻ hơn cho dữ liệu tạm.
Vòng đời một micro-partition: active → Time Travel → Fail-safe → xóa. Tổng thời gian dữ liệu còn có thể cứu = retention + 7 ngày.
Zero-copy Cloning — nhân bản không tốn storage
CLONE tạo một bản sao độc lập về mặt logic của table/schema/database tức thì, và ban đầu không tốn thêm storage. Bí quyết vẫn là micro-partition immutable: bản clone chỉ là một tập metadata mới trỏ vào cùng các micro-partition với bản gốc.
-- Clone toàn bộ database prod sang UAT trong 1 giây
CREATE DATABASE edw_uat CLONE edw_prod;
-- Clone kèm Time Travel: lấy trạng thái prod lúc 6h sáng nay
CREATE TABLE tmp_txn CLONE transactions
AT(TIMESTAMP => '2026-07-02 06:00:00'::timestamp_tz);
Copy-on-write — khi nào mới tốn tiền
Clone chỉ tiêu storage cho phần dữ liệu bị thay đổi sau khi clone (copy-on-write). Nếu clone UAT rồi chỉ đọc để test, chi phí storage gần như bằng 0. Khi UAT ghi/sửa một bảng, chỉ những micro-partition bị đụng mới được tách riêng.
Vì sao đây là "vũ khí" cho ngân hàng
- Dựng UAT/test tức thì: thay vì chờ hạ tầng copy 50 TB qua đêm (như thời on-prem), một câu
CLONEcho ra môi trường UAT y hệt prod trong vài giây. Sau khi test xong thìDROP. - Sandbox thử nghiệm phá hoại: analyst clone một schema, chạy thử migration/backfill, nếu hỏng thì bỏ đi mà không đụng gì tới prod.
- Backup logic tại điểm mốc: clone bảng tại
AT(TIMESTAMP => ...)để "đóng băng" trạng thái cuối kỳ báo cáo trước khi chạy job nguy hiểm.
Lưu ý: privilege không tự sao chép hoàn toàn giống bản gốc; cần cấp lại quyền phù hợp trên object clone theo mô hình RBAC ở Bảo mật & quản trị.
Streams — Change Data Capture nội bộ
Stream là một object theo dõi thay đổi (DML: insert/update/delete) trên một bảng nguồn kể từ lần đọc gần nhất — tức là CDC (Change Data Capture) built-in, không cần công cụ ngoài. Stream không lưu bản sao dữ liệu, nó chỉ giữ một con trỏ offset và trưng ra các dòng đã đổi cùng metadata.
Ba cột metadata một stream thêm vào:
METADATA$ACTION—INSERThoặcDELETE.METADATA$ISUPDATE—TRUEnếu dòng nằm trong một cặp update (update được biểu diễn thành DELETE + INSERT).METADATA$ROW_ID— định danh dòng bất biến, giúp lần vết một dòng qua các thay đổi.
-- Tạo stream theo dõi bảng giao dịch thô
CREATE STREAM txn_stream ON TABLE transactions_raw;
-- Đọc các thay đổi kể từ lần consume trước
SELECT id, amount, METADATA$ACTION, METADATA$ISUPDATE
FROM txn_stream;
Điểm quan trọng: stream chỉ dịch offset về phía trước khi được consume trong một transaction có ghi dữ liệu (thường là câu INSERT ... SELECT FROM stream). Đọc SELECT thuần để xem trước thì offset không đổi. Đây là cơ chế đảm bảo không mất thay đổi giữa hai lần chạy pipeline.
Tasks — bộ lập lịch trong Snowflake
Task là object chạy một câu SQL (hoặc gọi stored procedure) theo lịch cron hoặc theo quan hệ phụ thuộc với task khác, tạo thành một DAG chạy hoàn toàn bên trong Snowflake — không cần Airflow cho các pipeline đơn giản.
CREATE TASK load_txn_fact
WAREHOUSE = etl_wh
SCHEDULE = 'USING CRON 0 * * * * Asia/Ho_Chi_Minh' -- mỗi giờ
WHEN SYSTEM$STREAM_HAS_DATA('txn_stream') -- chỉ chạy khi có data mới
AS
INSERT INTO txn_fact
SELECT id, account_id, amount, created_at
FROM txn_stream
WHERE METADATA$ACTION = 'INSERT';
Hai điểm đắt giá:
WHEN SYSTEM$STREAM_HAS_DATA(...)— task chỉ khởi động warehouse nếu stream thực sự có dữ liệu mới, tránh đốt credit cho lần chạy rỗng.- Task tạo mới ở trạng thái suspended; phải
ALTER TASK ... RESUMEmới chạy. Với DAG,RESUMEtask gốc để kích hoạt cả nhánh con.
Kết hợp Stream + Task = ELT incremental
Đây là mẫu kiến trúc phổ biến nhất: dữ liệu vào bảng raw (qua Snowpipe hoặc COPY), stream bắt phần mới, task định kỳ merge phần mới đó vào bảng fact/dimension. Toàn bộ ELT chạy trong Snowflake, incremental và idempotent.
So với việc điều phối bằng công cụ ngoài (xem Kafka — kiến trúc cho phần streaming đầu vào, hay dbt — tổng quan cho transformation phức tạp), Stream + Task phù hợp cho pipeline gọn nằm trọn trong Snowflake; pipeline lớn nhiều tầng phụ thuộc thì vẫn nên dùng orchestrator chuyên dụng.
Secure Data Sharing — chia sẻ dữ liệu không copy
Đây là tính năng thay đổi cách các tổ chức trao đổi dữ liệu. Với Secure Data Sharing, provider chia sẻ dữ liệu sống cho consumer mà không hề copy hay di chuyển byte nào. Consumer đọc trực tiếp trên micro-partition của provider; provider trả tiền storage, consumer trả tiền compute khi query.
Cơ chế qua object SHARE:
-- Bên PROVIDER (ngân hàng mẹ)
CREATE SHARE loan_share;
GRANT USAGE ON DATABASE edw_prod TO SHARE loan_share;
GRANT USAGE ON SCHEMA edw_prod.risk_mart TO SHARE loan_share;
GRANT SELECT ON VIEW edw_prod.risk_mart.v_loan_summary TO SHARE loan_share;
ALTER SHARE loan_share ADD ACCOUNTS = subsidiary_account;
Lưu ý chỉ chia sẻ view an toàn (secure view) để che cột nhạy cảm, không chia sẻ trực tiếp bảng thô.
Reader Account cho đối tác chưa dùng Snowflake
Nếu đối tác chưa có tài khoản Snowflake, provider tạo Reader Account — một tài khoản chỉ đọc do provider quản lý và trả chi phí compute thay cho họ. Đối tác đăng nhập, chạy query trên dữ liệu được share nhưng không tạo được object riêng.
Snowflake Marketplace
Trên nền Secure Data Sharing, Marketplace là nơi các nhà cung cấp niêm yết dataset (dữ liệu kinh tế vĩ mô, tỷ giá, dân số, tín dụng...) để tổ chức khác subscribe và query ngay, không cần ETL. Với ngân hàng, đây là kênh làm giàu dữ liệu nội bộ bằng dữ liệu bên thứ ba đã được chuẩn hóa.
Snowpark — đẩy code xuống chạy trong Snowflake
Nói ngắn gọn để trọn bức tranh: Snowpark là bộ API cho phép viết logic bằng Python / Scala / Java rồi để Snowflake dịch và chạy ngay bên trong engine (push-down), thay vì kéo dữ liệu ra ngoài rồi xử lý. Nó hữu ích cho biến đổi phức tạp, feature engineering, hay chạy mô hình ML gần nơi dữ liệu ở — giảm data movement và tận dụng warehouse sẵn có. Chi tiết Snowpark vượt phạm vi bài này.
Use case thực tế
Bối cảnh: Cuối quý II/2026, một analyst của NCB chạy nhầm một câu DELETE không có WHERE đầy đủ trên bảng loan_application_details (khoảng 4,2 triệu dòng), lúc 14:07. Đến 14:35 bộ phận báo cáo phát hiện dashboard tín dụng tụt bất thường.
Quy trình khôi phục:
- Xác định thủ phạm — tra
QUERY_HISTORYtìmquery_idcủa câu DELETE lúc 14:07. - Khôi phục bằng Time Travel — thay vì restore backup (mất hàng giờ), clone bảng về trạng thái ngay trước câu lệnh đó:
Bảng khôi phục sẵn sàng trong ~3 giây, không tốn storage (zero-copy).
CREATE TABLE loan_app_recovered CLONE loan_application_details BEFORE(STATEMENT => '<query_id-cua-cau-DELETE>'); - Đối chiếu & swap — kiểm tra
COUNT(*)khớp 4,2 triệu dòng, rồi swap bảng khôi phục vào chỗ cũ. Tổng downtime dữ liệu: dưới 30 phút, không cần đội hạ tầng.
Song song đó, đội DE dựng môi trường UAT để test bản migration schema mới: CREATE DATABASE edw_uat CLONE edw_prod; cho ra bản sao 38 TB trong ~5 giây, storage phát sinh gần 0 vì UAT chỉ đọc và sửa vài bảng nhỏ. Sau UAT, DROP DATABASE edw_uat để dọn.
Chia sẻ cho công ty con: báo cáo tổng hợp danh mục cho vay (đã ẩn PII qua secure view) được share qua SHARE object tới tài khoản Snowflake của công ty con — họ query dữ liệu live mỗi sáng mà không cần NCB export file, không có bản copy nào rời khỏi tài khoản gốc, đáp ứng yêu cầu kiểm soát rò rỉ dữ liệu.
Ghi nhớ
- Time Travel dựa trên micro-partition immutable: truy vấn quá khứ bằng
AT/BEFORE(OFFSET / TIMESTAMP / STATEMENT), khôi phục object đã xóa bằngUNDROP. - Retention: mặc định 1 ngày; Standard tối đa 1, Enterprise+ tối đa 90 ngày. Retention dài = storage nhiều hơn.
- Fail-safe: 7 ngày cố định sau Time Travel, chỉ Snowflake khôi phục, chỉ cho permanent table. Không phải công cụ truy vấn thường ngày.
- Zero-copy Cloning: nhân bản DB/schema/table tức thì, storage ban đầu = 0, chỉ tốn khi ghi (copy-on-write). Lý tưởng cho UAT/test/sandbox; nhớ cấp lại privilege.
- Stream = CDC nội bộ (offset + cột
METADATA$ACTION/ISUPDATE/ROW_ID); offset chỉ tiến khi được consume trong transaction ghi. - Task = lập lịch cron/DAG trong Snowflake; dùng
WHEN SYSTEM$STREAM_HAS_DATA(...)để không đốt credit chạy rỗng; task mới ở trạng thái suspended, phảiRESUME. - Stream + Task = pipeline ELT incremental gọn nằm trọn trong Snowflake; pipeline lớn vẫn nên dùng orchestrator ngoài.
- Secure Data Sharing: chia sẻ dữ liệu live, no-copy qua
SHARE; Reader Account cho đối tác chưa có Snowflake (provider trả compute); Marketplace để subscribe dữ liệu bên thứ ba. - Snowpark: viết Python/Scala/Java chạy push-down ngay trong Snowflake, giảm data movement.
Bài viết liên quan
CSV/JSON/Parquet/Avro, lưu trữ theo hàng vs cột, nén, và OLTP vs OLAP.
Data Engineering là gì, vai trò trong vòng đời dữ liệu, và bức tranh hệ sinh thái công cụ.
Vì sao xử lý phân tán, mô hình Spark (RDD/DataFrame), lazy evaluation, shuffle và tối ưu.
Đảm bảo chất lượng & minh bạch dữ liệu bằng dbt: data tests dựng sẵn (unique, not_null, relationships, accepted_values), singular test, unit test, và tài liệu tự sinh kèm lineage graph.