תארו לעצמכם: מסד הנתונים PostgreSQL 13 שלכם פועל תחת 10,000 בקשות בשנייה, ואתם צריכים לשדרג ל-PostgreSQL 15 מבלי לעצור את האפליקציה. גיבוי ושחזור טיפוסיים משמעותם שעות של השבתה—לקוחות אובדים, הכנסות נשחקות. כל שעת השבתה יכולה לעלות עד 250,000 דולר. אנו פותרים זאת עם הגירה ללא השבתה באמצעות שכפול לוגי, העברת נתונים בקבוצות, ומעבר אוטומטי. עם יותר מ-50 פרויקטים מוצלחים, אנו מבטיחים 99.9% שלמות נתונים ומספקים תוכנית מותאמת אישית לתשתית שלכם.
בשלוש השנים האחרונות, טיפלנו בהגירות עבור פרויקטים עם עומסים של 1,000 עד 50,000 בקשות בשנייה. מאמר זה מכסה את כל ההיבטים של שדרוג מסד נתונים—גם pg_upgrade וגם שכפול לוגי—ומראה כיצד לעדכן את מסד הנתונים שלכם ללא כאבים תוך שמירה על זמינות. צרו קשר לייעוץ, ונכין תוכנית הגירה אישית תוך יום אחד. המחיר מתחיל ב-5,000 דולר לשדרוג PostgreSQL בסיסי.
עקרונות של הגירות ללא השבתה
כל שינוי סכמה עוקב אחר שלבים תואמים לאחור:
- הוספת (עמודה, טבלה) חדשה — האפליקציה מתעלמת מהחדש.
- פריסת קוד שכותב לשני המקומות.
- העברת נתונים קיימים בקבוצות.
- פריסת קוד שקורא רק מהחדש.
- הסרת הישן.
אין DROP COLUMN או RENAME COLUMN בייצור בשלב אחד.
כיצד לבצע הגירת PostgreSQL ללא השבתה?
שיטה 1: pg_upgrade עם עותק משנה
pg_upgrade מהיר בערך פי 10 משכפול לוגי מבחינת זמן ביצוע, אך דורש חלון השבתה קצר להכנה ואינו מאפשר גלגול לאחור. "pg_upgrade משתמש בקישורים קשיחים כדי להימנע מהעתקת נתונים, מה שהופך אותו למהיר במיוחד."
# 1. Поднять новую версию PostgreSQL рядом
apt install postgresql-15
# 2. Остановить запись (короткий даунтайм для подготовки)
pg_ctl -D /var/lib/postgresql/14/main stop
# 3. pg_upgrade в режиме --link (без копирования файлов)
/usr/lib/postgresql/15/bin/pg_upgrade \
--old-datadir=/var/lib/postgresql/14/main \
--new-datadir=/var/lib/postgresql/15/main \
--old-bindir=/usr/lib/postgresql/14/bin \
--new-bindir=/usr/lib/postgresql/15/bin \
--link \
--check
# 4. Выполнить upgrade
/usr/lib/postgresql/15/bin/pg_upgrade \
--old-datadir=/var/lib/postgresql/14/main \
--new-datadir=/var/lib/postgresql/15/main \
--old-bindir=/usr/lib/postgresql/14/bin \
--new-bindir=/usr/lib/postgresql/15/bin \
--link
מצב # 1. Поднять новую версию PostgreSQL рядом apt install postgresql-15 # 2. Остановить запись (короткий даунтайм для подготовки) pg_ctl -D /var/lib/postgresql/14/main stop # 3. pg_upgrade в режиме --link (без копирования файлов) /usr/lib/postgresql/15/bin/pg_upgrade \ --old-datadir=/var/lib/postgresql/14/main \ --new-datadir=/var/lib/postgresql/15/main \ --old-bindir=/usr/lib/postgresql/14/bin \ --new-bindir=/usr/lib/postgresql/15/bin \ --link \ --check # 4. Выполнить upgrade /usr/lib/postgresql/15/bin/pg_upgrade \ --old-datadir=/var/lib/postgresql/14/main \ --new-datadir=/var/lib/postgresql/15/main \ --old-bindir=/usr/lib/postgresql/14/bin \ --new-bindir=/usr/lib/postgresql/15/bin \ --link משתמש בקישורים קשיחים במקום בהעתקה—עבור מסד נתונים של 100 ג'יגה-בייט, זה לוקח שניות במקום שעות. חיסרון: לא ניתן להפעיל את הגרסה הישנה לאחר מכן.
שיטה 2: שכפול לוגי (ללא השבתה אמיתית)
-- На старом сервере (PG 13)
CREATE PUBLICATION migration_pub FOR ALL TABLES;
-- На новом сервере (PG 15) — создать ту же схему
pg_dump -s -U postgres myapp | psql -U postgres -h new-server myapp
-- Подписка на репликацию
CREATE SUBSCRIPTION migration_sub
CONNECTION 'host=old-server dbname=myapp user=replication password=pass'
PUBLICATION migration_pub;
-- Следить за прогрессом первоначальной синхронизации
SELECT subname, received_lsn, latest_end_lsn FROM pg_stat_subscription;לאחר סנכרון:
-- Проверить лаг (должен быть близок к нулю)
SELECT now() - last_msg_receipt_time AS subscription_lag FROM pg_stat_subscription;
-- Переключение: остановить запись в старую БД, дождаться лага = 0
-- Обновить connection string в приложении
-- Удалить подписку
DROP SUBSCRIPTION migration_sub; השוואת שיטות הגירה
| שיטה | זמן ביצוע | השבתה | גלגול לאחור | משאבים נוספים |
|---|---|---|---|---|
| pg_upgrade | שניות (100 ג'יגה-בייט) | כן (עד 5 דקות) | לא | מינימליים |
| שכפול לוגי | שעות (התקנה) | לא | כן | שרת נוסף, דיסקים |
מדוע הגירות סכמה דורשות מספר שלבים?
הוספת עמודת NOT NULL
לא ניתן לעשות זאת בשלב אחד — ALTER TABLE תנעל את הטבלה לכל חישוב DEFAULT. גישה נכונה:
-- Шаг 1: добавить колонку с DEFAULT (PostgreSQL 11+ — instant)
ALTER TABLE users ADD COLUMN phone VARCHAR(20) DEFAULT NULL;
-- Шаг 2: заполнить данными батчами
DO $$
DECLARE
batch_size INT := 1000;
offset_val INT := 0;
BEGIN
LOOP
UPDATE users SET phone = '' WHERE id IN (
SELECT id FROM users WHERE phone IS NULL ORDER BY id LIMIT batch_size
);
EXIT WHEN NOT FOUND;
PERFORM pg_sleep(0.01);
END LOOP;
END $$;
-- Шаг 3: добавить NOT NULL constraint (быстро, если нет NULL)
ALTER TABLE users ALTER COLUMN phone SET NOT NULL; שינוי שם עמודה
-- Шаг 1: добавить новую колонку
ALTER TABLE orders ADD COLUMN customer_id BIGINT;
-- Шаг 2: заполнить данными (+ триггер для новых записей)
CREATE OR REPLACE FUNCTION sync_customer_id() RETURNS TRIGGER AS $$
BEGIN
NEW.customer_id := NEW.user_id;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER sync_customer_id_trigger
BEFORE INSERT OR UPDATE ON orders
FOR EACH ROW EXECUTE FUNCTION sync_customer_id();
-- Батчевое заполнение существующих записей
UPDATE orders SET customer_id = user_id WHERE customer_id IS NULL;
-- Шаг 3: задеплоить код, читающий customer_id
-- Шаг 4: удалить старую колонку и триггер
ALTER TABLE orders DROP COLUMN user_id;
DROP TRIGGER sync_customer_id_trigger ON orders; כלים להגירות מקוונות
| כלי | מסד נתונים | תכונות |
|---|---|---|
| gh-ost | MySQL | הגירת סכמה מקוונת ללא נעילות, מ-GitHub |
| pg-osc | PostgreSQL | אנלוגי ל-gh-ost עבור Postgres |
| Flyway | PostgreSQL, MySQL | הגירות עם גרסאות, תמיכה בביטול |
| Liquibase | PostgreSQL, MySQL | יומני שינויים ב-XML/YAML/JSON |
דוגמה לשימוש ב-gh-ost:
gh-ost \
--host=db-master \
--database=myapp \
--table=users \
--alter="ADD INDEX idx_email (email)" \
--execute בדיקת תוכנית ההגירה
# Восстановить production dump в staging
pg_restore -U postgres -d myapp_staging production.dump
# Проверить план миграции
psql -U postgres myapp_staging < migration_plan.sql
# Замерить время выполнения
\timing on
\i migration_plan.sql בדיקות נוספות לשכפול לוגי
- ודאו ש-wal_level = logical בשרת הישן. - ודאו שלמשתמש השכפול יש הרשאות פרסום. - עקבו אחר הפיגור באמצעות pg_stat_replication.ניטור ומוכנות לגלגול לאחור
לאחר התחלת שכפול לוגי, קריטי לנטר את פיגור השכפול ואת בריאות שני השרתים. אנו מגדירים Prometheus + Grafana עם לוח מחוונים עבור pg_stat_replication: פיגור העולה על 100 מגה-בייט מאותת להאט את ההגירה בקבוצות או להגדיל משאבים. במקביל, אנו שומרים תוכנית גלגול לאחור מוכנה: במקרה של חריגה, אנו יכולים להחזיר תנועה לשרת הישן תוך 30 שניות. מדדים טיפוסיים לניטור: received_lsn לעומת sent_lsn (פיגור בבתים), write_lag, flush_lag, ו-replay_lag מ-pg_stat_replication. עבור MySQL — Seconds_Behind_Source מ-SHOW SLAVE STATUS. פיגור אפס לפני מעבר מושג על ידי עצירת כתיבות במקור למשך 2–5 שניות—זהו הרגע היחיד של 'סיכון'. עבור מסדי נתונים גדולים (>=500 ג'יגה-בייט), סנכרון מוקדם באמצעות rsync או pg_basebackup מאיץ את הכנת המנוי הראשוני פי 3-5 בהשוואה לשכפול טהור. אנו מתעדים כל שלב ב-runbook ומכשירים את צוות הלקוח לשימוש בו.
מה כלול בעבודה
- ביקורת על סכמת מסד הנתונים הנוכחית וגרסאות DBMS.
- פיתוח תוכנית הגירה תואמת לאחור.
- התקנת שכפול לוגי או pg_upgrade.
- העברת נתונים בקבוצות עם אימות שלמות.
- ניטור פיגור ומעבר אוטומטי.
- תיעוד והכשרת צוות.
- הבטחת תוכנית גלגול לאחור למשך 30 יום.
לוחות זמנים ועלות
שדרוג PostgreSQL ללא השבתה עם שכפול לוגי: 2–3 ימים. הגירת סכמה מורכבת עם מספר שלבים: 1–2 שבועות (כולל בדיקות ביניים). עלות: החל מ-5,000 דולר לשדרוג PostgreSQL בסיסי. צרו קשר — נעריך את הפרויקט שלכם.







