PostgreSQL 18 में लगभग तुरंत database clone लागू करना
(boringsql.com)- PostgreSQL 18, फ़ाइल कॉपी रणनीति (FILE_COPY) और फ़ाइल सिस्टम clone फ़ीचर को मिलाकर database को लगभग तुरंत clone कर सकता है
- नया configuration value
file_copy_method = cloneइस्तेमाल करने पर XFS, ZFS, APFS जैसे आधुनिक file system के clone फ़ीचर (FICLONE) का उपयोग किया जा सकता है - benchmark नतीजों में, 6GB database को clone करते समय मौजूदा WAL_LOG तरीका लगभग 67 सेकंड लेता है, जबकि clone तरीका लगभग 0.2 सेकंड में पूरा होता है
- clone किया गया database शुरुआत में वही physical block साझा करता है, लेकिन write होने पर copy-on-write के ज़रिए अलग हो जाता है
- हालांकि, सिर्फ तब clone किया जा सकता है जब कोई active connection न हो, और यह केवल एक ही file system के भीतर काम करता है
PostgreSQL की template-आधारित cloning संरचना
- PostgreSQL में
CREATE DATABASE dbnameकमांड चलाने पर अंदरूनी रूप सेtemplate1database को clone करके नया database बनाया जाता है- यह
CREATE DATABASE dbname TEMPLATE template1के समान व्यवहार है
- यह
template1की जगह किसी दूसरे database को चुना जा सकता है, इसलिए custom template का उपयोग करके cloning संभव है- PostgreSQL 18 में इसी template system को लगभग तुरंत clone किए जा सकने वाले ढांचे तक बढ़ाया गया है
CREATE DATABASE ... STRATEGY
- PostgreSQL 15 से
CREATE DATABASE ... STRATEGYparameter जोड़ा गया, जिससे cloning method चुनना संभव हुआ- default
WAL_LOGहै, जो Write-Ahead Log के ज़रिए block-level cloning करता है - यह तरीका I/O load कम करता है और concurrency support बेहतर बनाता है, लेकिन बड़े clone में धीमा है
- default
STRATEGY=FILE_COPYदेने पर पुराने file copy तरीके पर लौटा जा सकता है, और PostgreSQL 18 में इसी के आधार पर नया cloning option जोड़ा गया है
FILE_COPY और file_copy_method
- PostgreSQL 18 की
file_copy_methodsetting OS-level file cloning method को नियंत्रित करती है- default
copyहै, जो हर byte को पढ़कर नई जगह लिखता है cloneपर बदलने से file system का clone फ़ीचर (FICLONE) इस्तेमाल होता है, जिससे तुरंत clone और अतिरिक्त space खर्च नहीं होता
- default
- supported file system: XFS, ZFS, APFS, FreeBSD ZFS
- configuration प्रक्रिया
- संबंधित file system पर PostgreSQL cluster बनाएं
file_copy_method = cloneसेट करके reload करें
benchmark नतीजे
- लगभग 6GB आकार का test database (
source_db) बनाने के बाद दो तरीकों की तुलना की गईWAL_LOGतरीका: 67,000ms (लगभग 67 सेकंड)FILE_COPY+cloneतरीका: 212ms
- समान data size पर लगभग 300 गुना से अधिक performance improvement देखा गया
- clone किया गया database (
fast_clone) लगभग कोई अतिरिक्त disk space इस्तेमाल नहीं करता
clone किए गए data का काम करने का तरीका
file_copy_method = cloneइस्तेमाल करने पर सिर्फ file system metadata clone होता है, इसलिए दोनों database एक ही physical block साझा करते हैं- PostgreSQL जो database size दिखाता है, वह logical size (लगभग 6GB) के रूप में समान रहता है
- write होने पर copy-on-write (COW) काम करता है और संबंधित page अलग हो जाता है
- वह page जिसमें बदली गई row शामिल है
- वह page जिसमें नया tuple लिखा जाता है
- index page, FSM, visibility map page आदि
VACUUMचलाने पर भी अतिरिक्त page separation होता है
XFS में shared block की जांच
filefrag -vकमांड से दो database के physical block shared हैं या नहीं यह जांचा जा सकता है- शुरुआती स्थिति में सभी extents
sharedके रूप में दिखते हैं - कुछ row update करने पर पहले 40 block (लगभग 160KB) अलग होकर अलग physical address पर चले जाते हैं
- बाकी extents अब भी shared रहते हैं
- शुरुआती स्थिति में सभी extents
सावधानियां और सीमाएं
- clone बनाते समय source database पर active connection नहीं होना चाहिए
- यह PostgreSQL की सीमा है, file system की समस्या नहीं
- production environment में आम तौर पर अलग template database इस्तेमाल किया जाता है
- cloning केवल एक ही file system के भीतर संभव है
- अगर कई tablespace अलग-अलग mount point पर हों, तो सामान्य copy इस्तेमाल होगी
- cloud managed services (AWS RDS, Google Cloud SQL आदि) में file system access उपलब्ध नहीं होने के कारण यह फ़ीचर इस्तेमाल नहीं किया जा सकता
- अपने VM या bare metal environment में पूरा control संभव है
निष्कर्ष
- PostgreSQL 18 का
file_copy_method = cloneफ़ीचर सीधे OS-level clone capability का उपयोग करके
बड़े database clone समय को नाटकीय रूप से कम करता है - testing, development और learning environment में तुरंत clone और reset किए जा सकने वाले database workflow बनाए जा सकते हैं
- हालांकि, active connection की सीमा और single file system को ध्यान में रखकर operation design करना होगा
1 टिप्पणियां
Hacker News टिप्पणियाँ
जो लोग इंतज़ार नहीं कर सकते या PG18 में पूरी instance isolation चाहते हैं, उनके लिए मैंने ZFS snapshot का इस्तेमाल करके instant branching टूल Velo बनाया है
यह किसी भी PostgreSQL version पर काम करता है, और हर branch का अपना अलग container और port होता है
100GB DB के लिए इसे बनाने में लगभग 2~5 सेकंड लगते हैं
PG18 के तरीके से इसका अंतर यह है कि यह single instance साझा नहीं करता, बल्कि पूरा server isolation देता है
GitHub लिंक
पहले जब कंपनी RDS पर migrate कर रही थी, तब हमने ऐसा ही एक system खुद बनाया था
production migration के दौरान अक्सर दिक्कतें आती थीं, इसलिए उन्हें रोकने के लिए हमने ये steps automate किए थे
इस process की वजह से हम बहुत से production-specific bugs पकड़ पाए, जो local या CI में नहीं मिलते थे
बाद में इसे एक simple Ruby script से automate किया गया, और सुना है वह script आज भी इस्तेमाल हो रही है
मुझे अभी पता चला कि template cloning strategy configurable है
मैंने Neon का इस्तेमाल करके real-time integration environment बनाया था, और मेरे Golang project pgtestdb में हर test के लिए schema migration पूरी तरह लागू की गई Postgres DB बनाई जाती है
पहले एक startup में मैंने btrfs से instant staging DB बनते देखी थी, इसलिए ऐसा similar idea बार-बार सामने आना दिलचस्प लगता है
इस तरह की fast cloning और testing Postgres और Sqlite की बड़ी ताकत है, और अच्छा होता अगर Clickhouse या MySQL में भी यह आसान होता
आजकल PostgreSQL लगभग हर SQL use case को cover करने वाला universal DB लगता है
ऊपर से यह free भी है
अब सच में सोचता हूँ कि क्या किसी और SQL DB को चुनने की कोई खास वजह बची है
Clickhouse analytics के लिए कहीं तेज़ है, और Cassandra जैसे DB write-heavy workload में बेहतर हैं
यानी हर DB की अपनी ताकत अब भी है
data बढ़ने पर performance degradation या migration issues आते हैं
मेरे मामले में built-in partitioning की performance कमज़ोर थी, इसलिए मुझे खुद custom partitioning implement करनी पड़ी
load बढ़ने पर इस choice के कई नकारात्मक असर दिखते हैं
Uber की ब्लॉग पोस्ट में भी यह topic आया था
फिर भी cloud environment में मुझे Postgres पर सबसे ज़्यादा भरोसा है
इसलिए बड़े पैमाने की OLTP deployments में अब भी MySQL ज़्यादा इस्तेमाल होता है (जैसे: YouTube, Uber)
immutable data structure (HAMT) का इस्तेमाल करें तो filesystem के प्रकार से बिना मतलब instant clone करने वाला DB बनाया जा सकता है
मैंने इसे सिर्फ theory नहीं कहा, बल्कि सच में implement भी किया है
समझ नहीं आता कि ऐसे HAMT-based DB ज़्यादा क्यों नहीं हैं
संबंधित दस्तावेज़ लिंक
मुझे पता नहीं था कि Postgres v15 में WAL_LOG default बन गया है
parallel CI test environment में FILE_COPY strategy पर वापस जाना ज़्यादा समझदारी लगता है
मैंने अपने पुराने project integresql में इससे जुड़ा issue उठाया था
मैंने local में Postgres-based app test करने के लिए एक simple GUI tool pgtt बनाया था
यह development environment setup को काफी simple बना देता है
लगता है यह बार-बार होने वाले SQL migration काम में मदद कर सकता है
मैंने ब्लॉग के दूसरे लेख भी पढ़े, और कुल मिलाकर वे शानदार हैं
खासकर मुझे पहली बार Postgres के range type के बारे में पता चला
सोच रहा हूँ कि क्या MariaDB में भी ऐसी सुविधा है
हर test के बाद DB को initial state में वापस लाना धीमा पड़ रहा है, इसलिए इस पर विचार कर रहा हूँ
production में MariaDB इस्तेमाल हो रही है, इसलिए DB बदलना आसान नहीं है
फिर भी Postgres वाला approach बेहतर लगता है
यह तरीका काफी efficient है
AWS में भी similar feature है
Aurora clone दस्तावेज़
integration testing के लिए यह practical नहीं है