Claude Code দিয়ে PostgreSQL মাইগ্রেশনগুলো নিরাপদভাবে করার জন্য কিভাবে প্রম্পট লিখবেন—expand/contract প্যাটার্ন, ব্যাকফিল, রোলব্যাক প্ল্যান এবং স্টেজিং-এ কী যাচাই করবেন সেই সব নির্দেশিকা।

PostgreSQL স্কিমা পরিবর্তন দেখতে সাধারণ মনে হয় যতক্ষণ না সেটা বাস্তব ট্র্যাফিক ও ডেটার মুখোমুখি হয়। ঝুঁকির মূল কারণ সাধারণত SQL নয়—বলতেই হবে যখন তোমার অ্যাপ কোড, ডেটাবেস স্টেট, এবং ডেপ্লয়মেন্ট সময়মিল নাও থাকে।
বেশিরভাগ ব্যর্থতা বাস্তব এবং কষ্টদায়ক: একটি ডেপ্লয় ভেঙে যায় কারণ পুরোনো কোড একটি নতুন কলামে পৌঁছায়, একটি মাইগ্রেশন হট টেবিল লক করে দেয় এবং টাইমআউট বাড়ে, অথবা একটি “দ্রুত” পরিবর্তন চুপচাপ ডেটা ড্রপ বা রিরাইট করে দেয়। এমনকি কোনো ক্র্যাশ না হলেও তুমি সূক্ষ্ম বাগ পাঠাতে পারো—ভুল ডিফল্ট, ভাঙা কনস্ট্রেইন্ট, বা মাঝখানে সম্পূর্ণ না করা ইনডেক্সগুলো।
AI-উৎপন্ন মাইগ্রেশন একটি অতিরিক্ত ঝুঁকি যোগ করে। টুলগুলো বৈধ SQL তৈরি করতে পারে, কিন্তু তা তোমার ওয়ার্কলোড, ডেটা ভলিউম, বা রিলিজ প্রসেসের জন্য নিরাপদ নাও হতে পারে। তারা টেবিল নাম আন্দাজ করতে পারে, দীর্ঘ-চলমান লক মিস করতে পারে, বা রোলব্যাক হালকাভাবে ব্যাখ্যা করতে পারে কারণ ডাউন মাইগ্রেশন কঠিন। যদি তুমি Claude Code ব্যবহার করো মাইগ্রেশনের জন্য, তাহলে গার্ডরেইল ও নির্দিষ্ট কনটেক্সট দরকার।
যখন এই পোস্টে বলা হচ্ছে একটি পরিবর্তন "নিরাপদ", তখন তার মানে তিনটা জিনিস:
লক্ষ্য হলো মাইগ্রেশনগুলো রুটিন কাজ হওয়া: পূর্বানুমেয়, টেস্টযোগ্য, এবং বিরক্তিকর (খুবই নির্ভরযোগ্য)।
কিছু অনস্বীকার্য নিয়ম দিয়ে শুরু করো। এগুলো মডেলকে ফোকাস রাখে এবং তোমাকে এমন পরিবর্তন পাঠানো থেকে রক্ষা করে যা শুধু তোমার ল্যাপটপে কাজ করে।
কাজগুলো ছোট ধাপে ভাগ করো। একটি স্কিমা পরিবর্তন, একটি ডেটা ব্যাকফিল, একটি অ্যাপ পরিবর্তন, এবং একটি ক্লিনআপ স্টেপ—প্রতিটিই আলাদা ঝুঁকি। এগুলোকে একত্র করলে কি ভেঙেছে দেখা কঠিন হয় এবং রোলব্যাক করাও কঠিন হয়।
ধ্বংসাত্মক পরিবর্তনের আগে অ্যাডিটিভ পরিবর্তনকে অগ্রাধিকার দাও। একটি কলাম, ইনডেক্স, বা টেবিল যোগ সাধারণত কম ঝুঁকিপূর্ণ। Rename বা drop-ই হল সেই জায়গা যেখানে আউটেজ হয়। নিরাপদ অংশটি আগে করো, অ্যাপ সরাও, তারপর কেবল তখনই পুরানো জিনিসগুলি সরাও যখন নিশ্চিত যে সেগুলো অপ্রচলিত।
অ্যাপকে একসাথে দুই রূপ সহ্য করতে পারার ব্যবস্থা করো। কোড এমনভাবে থাকা উচিত যে রোলআউট চলাকালে পুরানো কলাম অথবা নতুন কলাম—দুইটিই পঠনযোগ্য। এতে সাধারণ রেস কন্ডিশন এড়ায় যেখানে কিছু সার্ভার নতুন কোড চালায় কিন্তু ডেটাবেস এখনও পুরানো থাকে (বা বিপরীত)।
মাইগ্রেশনগুলোকে প্রোডাকশন কোড হিসেবে বিবেচনা করো, একটি দ্রুত স্ক্রিপ্ট হিসেবে নয়। এমনকি যদি তুমি Koder.ai-এর মতো প্ল্যাটফর্ম ব্যবহার করো (Go ব্যাকএন্ড সহ PostgreSQL, প্লাস React বা Flutter ক্লায়েন্ট), ডেটাবেস সবকিছুর দ্বারা শেয়ার করা। ভুলগুলো থেকে ক্ষতি বেশি।
একটি সংকুচিত নিয়ম সেট যদি প্রতিটি SQL অনুরোধের শুরুতে রাখো, হতে পারে এইরকমঃ
একটি বাস্তব উদাহরণ: আপনার অ্যাপ নির্ভর করে এমন একটি কলাম rename করার পরিবর্তে নতুন কলাম যোগ করো, তা ধীরে backfill করো, নতুন কোড deploy করো যা নতুন তারপর পুরোনো পড়ে, এবং পরে কেবল তখনই পুরানো কলাম সরাও যখন নিশ্চিত যে এটি ব্যবহার হচ্ছে না।
Claude অস্পষ্ট অনুরোধ থেকে ঠিকঠাক SQL লিখতে পারে, কিন্তু নিরাপদ মাইগ্রেশনের জন্য প্রসঙ্গ দরকার। আপনার প্রম্পটকে একটি ক্ষুদ্র ডিজাইন ব্রিফ হিসেবে বিবেচনা করো: কী আছে তা দেখাও, কী ভাঙলে চলবে না তা ব্যাখ্যা করো, এবং আপনার রোলআউটের জন্য "নিরাপদ" কী মানে তা সংজ্ঞায়িত করো।
শুরু করো শুধুমাত্র গুরুত্বপূর্ণ ডেটাবেস তথ্য পেস্ট করে। টেবিল ডেফিনিশন সহ প্রাসঙ্গিক ইনডেক্স ও কনস্ট্রেইন্ট (প্রাইমারি কী, ইউনিক কনস্ট্রেইন্ট, ফরেন কী, চেক কনস্ট্রেইন্ট, ট্রিগার) অন্তর্ভুক্ত করো। যদি সম্পর্কিত টেবিল থাকে, তাদের স্নিপেটও যোগ করো। একটি ছোট, সঠিক এক্সার্পট মডেলকে নাম আন্দাজ করা থেকে রক্ষা করে।
বাস্তব-জগতের স্কেল যোগ করো। সারির সংখ্যা, টেবিল সাইজ, রাইট রেট, এবং পিক ট্র্যাফিক পরিকল্পনাকে বদলে দেয়। "200M rows and 1k writes/sec" এক ধরণের মাইগ্রেশন; আর "20k rows and mostly reads" আরেক ধরণের। আপনার Postgres ভার্সন এবং মাইগ্রেশনগুলো কীভাবে চলে (এক ট্রানজ্যাকশন বনাম একাধিক ধাপ) বলাও।
অ্যাপ কিভাবে ডেটা ব্যবহার করে তা বর্ণনা করো: গুরুত্বপূর্ণ রিড, রাইট, এবং ব্যাকগ্রাউন্ড জব। উদাহরণ: "API reads by email," "workers update status," বা "reports scan by created_at." এগুলোই নির্ধারণ করে তুমি কবে expand/contract ব্যবহার করবে, ফিচার ফ্ল্যাগ দরকার কিনা, এবং ব্যাকফিল কতটা নিরাপদ হবে।
অবশেষে, কনস্ট্রেইন্ট ও ডেলিভারেবলগুলো স্পষ্টরূপে বলো। একটি সাধারণ স্ট্রাকচার কাজ করে ভাল:
একই সময়ে SQL এবং রুন প্ল্যান চাও—এতে মডেল অর্ডার, ঝুঁকি, এবং কী পরীক্ষা করতে হবে সে ব্যাপারে ভাবতে বাধ্য হবে।
Expand/contract মাইগ্রেশন প্যাটার্ন PostgreSQL ডেটাবেস পরিবর্তন করে এমনভাবে যাতে যখন পরিবর্তন চলছে অ্যাপ ভেঙে না যায়। একটি ঝুঁকিপূর্ণ একক সুইচের বদলে, ডেটাবেস একটি সময় পর্যন্ত পুরানো ও নতুন উভয় আকৃতি সমর্থন করে।
এটাকে ভাবো: নতুন জিনিসগুলো নিরাপদে যোগ করো (expand), ধীরে ধীরে ট্র্যাফিক ও ডেটা স্থানান্তর করো, এবং কেবল তখনই পুরানো অংশগুলো সরাও (contract) যখন সব ঠিক আছে। এটি AI-সহায়তায় কাজ করার সময় বিশেষত উপকারী কারণ এটি আপনাকে মাঝখেলার জঞ্জালের জন্য পরিকল্পনা করতে বাধ্য করে।
একটি ব্যবহারিক ফ্লো দেখতে এরকম:
এই প্যাটার্নটি ব্যবহার করো যখন ব্যবহারকারীরা এখনও পুরানো অ্যাপ কোড ব্যবহার করতে পারে—মাল্টি-ইনস্ট্যান্স ডিপ্লয়মেন্ট, মোবাইল অ্যাপ ধীরে আপডেট হওয়া, বা কোনো রিলিজ যেখানে মাইগ্রেশন মিনিট বা ঘণ্টা লাগতে পারে।
একটি সহায়ক কৌশল হলো দুইটি রিলিজের পরিকল্পনা: রিলিজ 1 এ expand ও compatibility করো যাতে ব্যাকফিল অসমাপ্ত থাকলেও কিছু ভাঙে না। রিলিজ 2 এ কেবল contract করো, সব নতুন কোড ও ডেটা ইনপ্লেস আছে নিশ্চিত করার পরে।
কপি করে ব্র্যাকেটে ভরো। এটি Claude Code-কে এমন SQL তৈরি করতে প্ররোচিত করে যা চালানো যাবে, কাজটি প্রমাণ করার জন্য চেক, এবং রোলব্যাক প্ল্যান যে বাস্তবসম্মত।
You are helping me plan a PostgreSQL expand-contract migration.
Context
- App: [what the feature does, who uses it]
- Database: PostgreSQL [version if known]
- Table sizes: [rough row counts], write rate: [low/medium/high]
- Zero/near-zero downtime required: [yes/no]
Goal
- Change: [describe the schema change]
- Current schema (relevant parts):
[paste CREATE TABLE or \d output]
- How the app will change (expand phase and contract phase):
- Expand: [new columns/indexes/triggers, dual-write, read preference]
- Contract: [when/how we stop writing old fields and remove them]
Hard safety requirements
- Prefer lock-safe operations. Avoid full table rewrites on large tables when possible.
- If any step can block writes, call it out explicitly and suggest alternatives.
- Use small, reversible steps. No “big bang” changes.
Deliverables
1) UP migration SQL (expand)
- Use clear comments.
- If you propose indexes, tell me if they should be created CONCURRENTLY.
- If you propose constraints, tell me whether to add them NOT VALID then VALIDATE.
2) Verification queries
- Queries to confirm the new schema exists.
- Queries to confirm data is being written to both old and new structures (if dual-write).
- Queries to estimate whether the change caused bloat/slow queries/locks.
3) Rollback plan (realistic)
- DOWN migration SQL (only if it is truly safe).
- If down is not safe, write a rollback runbook:
- how to stop the app change
- how to switch reads back
- what data might be lost or need re-backfill
4) Runbook notes
- Exact order of operations (including app deploy steps).
- What to monitor during the run (errors, latency, deadlocks, lock waits).
- “Stop/continue” checkpoints.
Output format
- Separate sections titled: UP.sql, VERIFY.sql, DOWN.sql (or ROLLBACK.md), RUNBOOK.md
প্র্যাকটিক্যাল জন্যে দুইটি অতিরিক্ত লাইন:
RISK: blocks writes লেবেল করতে বলো, এবং কখন চালাবেন (off-peak vs anytime) বলো।ছোট স্কিমা পরিবর্তনও ক্ষতিকারক হতে পারে যদি তা দীর্ঘ লক নেয়, বড় টেবিল পুনরায় লিখে, বা অর্ধেকেই ব্যর্থ হয়। Claude Code ব্যবহারের সময় নিরাপদ SQL চাইলে বলো যাতে রিরাইট এড়ানো যায় এবং অ্যাপ যখন ডেটাবেস ক্যাচ-अप করছে তখনও কাজ করে।
nullable কলাম যোগ করা সাধারণত নিরাপদ। কিছু Postgres ভার্সনগুলোতে non-null default যোগ করলে পুরো টেবিল রিরাইট হতে পারে, যা ঝুঁকিপূর্ণ।
নিরাপদ পদ্ধতি হল দুই ধাপে পরিবর্তন: কলাম NULL হিসেবে যোগ করো ডিফল্ট ছাড়া, ব্যাচে ব্যাকফিল করো, তারপর নতুন রোদের জন্য ডিফল্ট সেট করো এবং ডেটা পরিষ্কার হলে NOT NULL যোগ করো।
যদি ডিফল্ট তৎক্ষণাৎ প্রয়োগ করতে হবে, তোমার Postgres ভার্সনের জন্য লক আচরণ ব্যাখ্যা ও একটি ফলিং ব্যাকআপ পরিকল্পনা চাই।
বড় টেবিলে ইনডেক্স হলে CREATE INDEX CONCURRENTLY চাও যাতে রিড-রাইট চলতে থাকে। বলাও যে এটি ট্রানজ্যাকশনে চালানো যায় না, মানে তোমার মাইগ্রেশন টুলকে নন-ট্রানজ্যাকশনাল স্টেপ রাখতে হবে।
ফরেন কী-রক্ষার্থে সাধারণত নিরাপদ পথ হলো প্রথমে কনস্ট্রেইন্ট NOT VALID হিসেবে যোগ করা, পরে আলাদা করে ভ্যালিডেট করা—এতে প্রথম ধাপ দ্রুত হয় এবং নতুন রাইটগুলোর উপর FK আরোপিত থাকে।
যখন কনস্ট্রেইন্ট কঠোর করা হবে (NOT NULL, UNIQUE, CHECK), আগে পরিষ্কার করে তারপর প্রয়োগ করো। মাইগ্রেশনটি খারাপ সারি সনাক্ত করে ঠিক করবে এবং তারপর কঠোর নিয়ম প্রয়োগ করবে।
কোনো শর্ট চেকলিস্ট প্রম্পটে পেস্ট করার জন্য সংক্ষেপে:
ব্যাকফিলেই বেশিরভাগ মাইগ্রেশন সমস্যা দেখা যায়, ALTER TABLE-এর চাইতে। নিরাপদ প্রম্পটগুলো ব্যাকফিলকে নিয়ন্ত্রিত জব হিসেবে বিবেচনা করে: মাপযোগ্য, পুনরায় চালানো যায়, এবং প্রোডাকশনের উপর নমনীয়।
সহজ চালনাযোগ্য গ্রহণযোগ্য চেক দিয়ে শুরু করো: প্রত্যাশিত সারি সংখ্যা, একটি লক্ষ্যমাত্রা null রেট, এবং কিছু স্পট চেক (যেমন 20 র্যান্ডম ID-এর জন্য পুরানো বনাম নতুন মান তুলনা)।
তারপর একটি ব্যাচিং প্ল্যান চাও। ব্যাচগুলো লক ছোট রাখে এবং অপ্রত্যাশ্যতা কমায়। একটি ভাল অনুরোধ নির্ধারণ করে:
আইডেমপোটেন্স বাধ্যতামূলক করো কারণ ব্যাকফিল মাঝখানে ব্যর্থ হয়। SQL পুনরায় চালালে ডুপ্লিকেট বা ডেটা ক্ষতি না করে এমন হওয়া চাই—সাধারণ প্যাটার্ন: "update only where the new column is NULL" বা নির্ধারিত নিয়ম যেখানে একই ইনপুট সবসময় একক আউটপুট দেয়।
এছাড়াও ব্যাকফিল চলাকালে অ্যাপটি কিভাবে সঠিক থাকবে তা স্পষ্ট করো। যদি নতুন রাইটগুলো চলতেই থাকে, তোমাকে একটি ব্রিজ দরকার: অ্যাপে dual-write, একটি সাময়িক ট্রিগার, বা read-fallback লজিক (নতুন থাকলে পড়ো, না থাকলে পুরানো) — বলো কোন পদ্ধতিটা তুমি নিরাপদে ডেপ্লয় করতে পারো।
অবশেষে, ডিজাইনে পজ ও রিসাম বিল্ড-ইন করো। প্রগ্রেস ট্র্যাকিং এবং চেকপয়েন্ট বানাও, যেমন ছোট একটি টেবিল যা শেষ প্রক্রিয়াকৃত আইডি রাখে এবং একটি কুয়েরি যে অগ্রগতি রিপোর্ট করে (rows updated, last ID, start time)।
উদাহরণ: তুমি users.full_name যোগ করো যা first_name এবং last_name থেকে তৈরি হবে। একটি নিরাপদ ব্যাকফিল কেবল full_name IS NULL যেখানে আপডেট করে, ID রেঞ্জে চলে, শেষ আপডেট হওয়া ID লগ করে, এবং নতুন সাইনআপগুলো dual-write করে যতক্ষণ না switch-over সম্পন্ন হয়।
রোলব্যাক প্ল্যান শুধু "down migration লেখো" নয়। এটি দুইটি সমস্যা: স্কিমা পরিবর্তন undo করা এবং নতুন ভার্সন চলাকালীন পরিবর্তিত ডেটা হ্যান্ডেল করা। স্কিমা রোলব্যাক সাধারনত সম্ভব। ডেটা রোলব্যাক সাধারণত সম্ভব না, যদি না তুমি এর জন্য পরিকল্পনা করো।
রোলব্য্যাকের কী মানে তা স্পষ্ট করো। যদি তুমি একটি কলাম ড্রপ করো বা ইন-প্লেস মান রিরাইট করো, তাহলে বাস্তবসম্মত উত্তর চাও: "Rollback করলে অ্যাপের সামঞ্জস্য ফিরে পাবে, কিন্তু মূল ডেটা কেবল স্ন্যাপশট ছাড়া পুনরুদ্ধার করা যাবে না।" এই সততা তোমাকে নিরাপদ রাখে।
স্পষ্ট রোলব্য্যাক ট্রিগার নির্ধারণ করো যাতে ইনসিডেন্টে কেউ বিতর্ক না করে। উদাহরণ:
পুরো রোলব্যাক প্যাকেজ চাও: ডাউন SQL (শুধুমাত্র যদি নিরাপদ হয়), অ্যাপ স্টেপস যাতে সামঞ্জস্য থাকে, এবং ব্যাকগ্রাউন্ড জব কিভাবে বন্ধ করা যায়।
এই প্রম্পট প্যাটার্নটি সাধারণত যথেষ্ট:
Produce a rollback plan for this migration.
Include: down migration SQL, app config/code switches needed for compatibility, and the exact order of steps.
State what can be rolled back (schema) vs what cannot (data) and what evidence we need before deciding.
Include rollback triggers with thresholds.
শিপ করার আগে একটি হালকা "সেফটি স্ন্যাপশট" নাও যাতে তুমি আগে ও পরে তুলনা করতে পারো:
এবং কখন রোলব্যাক করা উচিত না তা স্পষ্ট করো। যদি তুমি কেবল একটি nullable কলাম যোগ করে থাকো এবং অ্যাপ dual-writing করে, তাহলে সামনে ঠিক করা (হটফিক্স কোড, ব্যাকফিল পজ করে পুনরায় চালানো) প্রায়ই revert করার চেয়ে নিরাপদ।
AI দ্রুত SQL লিখতে পারে, কিন্তু এটি তোমার প্রোডাকশন ডেটাবেস দেখতে পারে না। বেশিরভাগ ব্যর্থতা ঘটে যখন প্রম্পট অস্পষ্ট ও মডেল ফাঁক পূরণ করে।
একটি সাধারণ ফাঁদ হলো কারেন্ট স্কিমা স্কিপ করা। তুমি যদি টেবিল ডেফিনিশন, ইনডেক্স, ও কনস্ট্রেইন্ট পেস্ট না করো, SQL এমন কলাম টার্গেট করতে পারে যা নেই বা একটি ইউনিকনেস রুল মিস করে, ফলে ব্যাকফিল ধীর ও লক-ওয়েট ভারী হবে।
আরও একটি ভুল হলো expand, backfill, এবং contract সবকিছু এক ডেপ্লয়মেন্টে করা। এতে তোমার ইস্কেপ হ্যাচি চলে যায়। যদি ব্যাকফিল দীর্ঘ হয় বা মাঝপথে ত্রুটি করে, তুমি এমন অ্যাপের সাথে আটকে যাবে যা চূড়ান্ত অবস্থা আশা করে।
সবচেয়ে বেশি দেখাযাওয়া ইস্যুগুলো:
একটি বাস্তব উদাহরণ: "এক কলাম rename করুন এবং অ্যাপ আপডেট করুন।" যদি জেনারেটেড প্ল্যান rename এবং backfill একটিই ট্রানজ্যাকশনে করে, একটি ধীর ব্যাকফিল লক ধরে রেখেই লাইভ ট্র্যাফিক ভেঙে দিতে পারে। একটি নিরাপদ প্রম্পট ছোট ব্যাচ, স্পষ্ট টাইমআউট, এবং কনট্র্যাক্ট করার আগে verification কুয়েরি জোর করে।
স্টেজিং হলো সেই জায়গা যেখানে ছোট ডেভ ডাটাবেসে দেখা না যাওয়া সমস্যা পাওয়া যায়: দীর্ঘ লক, অপ্রত্যাশিত নাল, মিসিং ইনডেক্স, এবং ভুলে যাওয়া কোড পাথ।
প্রথমে যাচাই করো যে মাইগ্রেশনের পরে স্কিমা প্ল্যানের সাথে মেলে: কলাম, টাইপ, ডিফল্ট, কনস্ট্রেইন্ট, এবং ইনডেক্স। একটি দ্রুত চেকই যথেষ্ট নয়—একটি ইনডেক্স মিস করে গেলে একটি নিরাপদ ব্যাকফিল ধীর মিস্ত্রি হয়ে যেতে পারে।
তারপর বাস্তবসম্মত ডেটাসেটে মাইগ্রেশন চালাও। আদর্শভাবে সেটা প্রোডাকশনের সাম্প্রতিক কপি হবে (সংবেদনশীল ফিল্ড মাস্ক করা), না পারলে কমপক্ষে প্রোডাকশনের ভলিউম ও হটস্পটগুলো মিলবে। প্রতিটি স্টেপের টাইমিং রেকর্ড করো যাতে প্রোডাকশনে কী আশা করা উচিত জানা থাকে।
একটি সংক্ষিপ্ত স্টেজিং চেকলিস্ট:
শেষে, শুধু SQL না—বাস্তব ইউজার ফ্লো টেস্ট করো। তৈরি, আপডেট, এবং পড়ার অপারেশনগুলো যেগুলো পরিবর্তনের দ্বারা স্পর্শিত সেগুলো টেস্ট করো। যদি expand/contract প্ল্যান হয়, নিশ্চিত করো দুটি স্কিমায়ই কাজ যতক্ষণ না ক্লিনআপ হয়।
ধরো তোমার একটি users.name কলাম আছে যা পূর্ণ নাম সঞ্চয় করে যেমন "Ada Lovelace." তুমি চাও first_name এবং last_name, কিন্তু সাইনআপ, প্রোফাইল, বা অ্যাডমিন স্ক্রীন ভেঙে যাবে না রোলআউট চলাকালে।
নিরাপদ expand স্টেপ দিয়ে শুরু করো যা তখনও নিরাপদ থাকবে যদি কোনো কোড পরিবর্তন ডেপ্লয় না করাও হয়: nullable কলাম যোগ করো, পুরানো কলাম রেখো, এবং দীর্ঘ লক এড়াও।
ALTER TABLE users ADD COLUMN first_name text;
ALTER TABLE users ADD COLUMN last_name text;
তারপর অ্যাপ আচরণ আপডেট করো যাতে দুই স্কিমাকে সমর্থন করে। রিলিজ 1-এ অ্যাপ নতুন কলাম থেকে পড়বে যদি উপস্থিত থাকে, না হলে name-এ fallback করবে, এবং উভয় জায়গায় লিখবে যাতে নতুন ডেটা সঙ্গত থাকে।
পরের ধাপ হলো ব্যাকফিল। একটি ব্যাচ জব চালাও যা প্রতি রান ছোট চাঙ্ক আপডেট করে, প্রগ্রেস রেকর্ড করে, এবং নিরাপদে পজ করা যায়। উদাহরণস্বরূপ: ascending ID order-এ প্রতিবার 1,000 করে first_name NULL থাকা rows আপডেট করো এবং কতগুলো সারি বদলেছে লগ করো।
কনস্ট্রেইন্ট কড়া করার আগে স্টেজিং-এ ভেরিফাই করো:
first_name এবং last_name পূরণ করছে এবং এখনও name সেট করছেname উপস্থিত থাকেusers টেবিলে বেসিক কুয়েরিগুলো উল্লেখযোগ্যভাবে ধীর হয়নিরিলিজ 2-এ পড়া কেবল নতুন কলামে স্যুইচ করবে। কেবল তখনই কনস্ট্রেইন্ট (যেমন SET NOT NULL) যোগ করো এবং name ড্রপ করো, ভালো হলে আলাদা একটি ডেপ্লয়মেন্টে।
রোলব্যাকের জন্য, সোজা রাখা ভালো। ট্রানজিশনের সময় অ্যাপ name পড়েই রাখে, এবং ব্যাকফিল বন্ধ করা যায়। যদি রিলিজ 2 ফিরিয়ে আনতে হয়, পড়া আবার name-এ ফিরিয়ে আনা এবং নতুন কলামগুলো রেখে দেওয়া নিরাপদ।
প্রতিটি পরিবর্তনকে একটি ছোট রুনবুক হিসেবে বিবেচনা করো। লক্ষ্য পারফেক্ট প্রম্পট নয়—এমন একটি রুটিন যা সঠিক বিবরণ জোর করে: স্কিমা, কনস্ট্রেইন্ট, রুন প্ল্যান, এবং রোলব্যাক।
প্রতিটি মাইগ্রেশন অনুরোধে মানক করো কি অন্তর্ভুক্ত থাকতে হবে:
প্রতিটি ধাপের মালিক নির্ধারণ করো আগে থেকে যাতে কেউ না বলে "সবাই ভাবছিল আর কেউ করলো না": ডেভেলপাররা প্রম্পট ও মাইগ্রেশন কোডের মালিক, অপস প্রোডাকশন টাইমিং ও মনিটরিং-এর মালিক, QA স্টেজিং আচরণ ও এজ কেস যাচাই করে, এবং একজন ব্যক্তি চূড়ান্ত go/no-go সিদ্ধান্ত নিবে।
চ্যাটের মাধ্যমে অ্যাপ বানালে, SQL জেনারেট করার আগে সিকোয়েন্স আউটলাইন করা সাহায্য করে। Koder.ai ব্যবহারকারী যারা Planning Mode ব্যবহার করে, সেখানে সিকোয়েন্স লিখে রাখা প্রাকৃতিক এবং স্ন্যাপশট ও রোলব্যাক কনটেক্সট রোলআউটের বিস্তারকে কমায়।
শিপ করার পরে, ক্লিনআপ (contract) তাড়াতাড়ি নির্ধারণ করো যাতে পুরানো কলাম ও সাময়িক সামঞ্জস্য কোড মাসগুলো ধরে লেগে না থাকে।
একটি স্কিমা পরিবর্তন তখনই ঝুঁকিপূর্ণ হয়ে ওঠে যখন অ্যাপ কোড, ডেটাবেসের অবস্থা এবং ডেপ্লয়মেন্ট টাইমিং মেলানো বন্ধ করে।
সাধারণ ব্যর্থতার ধরনগুলোর মধ্যে:
একটি expand/contract পদ্ধতি ব্যবহার করুন:
এতে রোলআউট চলাকালে পুরানো ও নতুন উভয় অ্যাপ ভার্সন কাজ করতে পারে।
মডেল বৈধ SQL তৈরি করতে পারে, কিন্তু সেটা আপনার ওয়ার্কলোডের জন্য ঝুঁকিপূর্ণ হতে পারে।
AI-নির্দিষ্ট ঝুঁকি:
AI আউটপুটকে খসড়া হিসেবে নিন এবং চালানোর পরিকল্পনা, যাচাই, এবং রোলব্যাক ধাপগুলো চাহুন।
সেই তথ্যগুলোই পেস্ট করুন যা মাইগ্রেশন নির্ভর করে:
CREATE TABLE স্নিপেট (ইন্ডেক্স, FK, UNIQUE/CHECK কনস্ট্রেইন্ট, ট্রিগার সহ)নিয়মটি: তারা আলাদা করে দিন।
প্রায়োগিক বিভাজন:
সবকিছু একত্র করলে ব্যর্থতা ডায়াগনোস করা এবং রোলব্যাক কঠিন হয়।
এটি একটি সাধারণ প্যাটার্ন:
ADD COLUMN ... NULL কোঠায় ডিফল্ট ছাড়া (দ্রুত)NOT NULL যোগ করাকোনো ভার্সনে নন-নাল ডিফল্ট তাত্ক্ষণিকভাবে টেবিল রিরাইট করতে পারে। যদি তা দরকার হয়, লাইভ রন্টাইম/লক আচরণ ব্যাখ্যা চাও এবং নিরাপদ ব্যাকআপ প্ল্যান রাখো।
CREATE INDEX CONCURRENTLY বড়/হট টেবিলে ব্যবহার করুন, কিন্তু লক্ষ্য রাখবেন:
ভেরিফিকেশনের জন্য সহজ চেক রাখো: স্টেজিং-এ EXPLAIN দিয়ে ইনডেক্স ব্যবহৃত হচ্ছে কি না দেখো।
প্রাথমিকভাবে NOT VALID হিসেবে যোগ করো, পরে ভ্যালিডেট করো:
NOT VALID হলে প্রাথমিক ধাপে ব্যাঘাত কম থাকেVALIDATE CONSTRAINT চালাতে পারো যখন মনিটরিং করতে চাওএতে নতুন রাইটগুলোর উপর FK আরোপিত থাকে, কিন্তু ব্যয়বহুল ভ্যালিডেশন তুমি নিয়ন্ত্রণে চালাতে পারো।
একটি ভাল ব্যাকফিল হলো ব্যাচড, আইডেমপোটেন্ট, এবং রিসামেবল।
প্রায়োগিক প্রয়োজনীয়তা:
WHERE new_col IS NULL)ডিফল্ট রোলব্যাক লক্ষ্য: দ্রুত অ্যাপ সামঞ্জস্য পুনঃস্থাপন, যদিও ডেটা পুরোপুরি পূর্বাবস্থায় ফিরানো নাও হতে পারে।
একটি কাজ করার মত রোলব্যাক প্ল্যান থাকা উচিত:
সাধারণত সবচেয়ে নিরাপদ রোলব্যাক হলো পুরানো ফিল্ডে পড়া ফিরিয়ে আনা, নতুন কলামগুলি এখনও রেখে দেওয়া।
এতে মডেলকে আন্দাজ করতে বাধ্য করা যাবে না এবং সঠিক অর্ডার আসবে।
এতে ব্যাকফিল বাস্তবে টিকিয়ে রাখা যায়।