pglogical.
לפני שמתחילים
אחרי שמגדירים את הרפליקציה של pglogical ויש פתרון מעשי לזמינות גבוהה (HA) ולתוכנית התאוששות מאסון (DR), ובהנחה שהרפליקציה הלוגית לא מספקת רפליקציה true ומקיפה של כל האובייקטים של מסד הנתונים, צריך לבדוק את ההגדרה הזו לפני שמתחילים להשתמש בה.
מידע נוסף על התוסף pglogical זמין במאמר מידע על pglogical.
למידע על שכפול נתונים באמצעות pglogical, אפשר לעיין במאמרים שכפול נתונים בין AlloyDB ל-PostgreSQL לבין AlloyDB Omni ושכפול נתונים בין AlloyDB Omni לבין מסדי נתונים אחרים.
מעבר לגיבוי הנתונים עם שכפול pglogical
מעבר הוא תהליך מבוקר שמשמש להחלפת התפקידים בין מסדי הנתונים של הספק והמנוי. כשמבצעים מעבר, התפקידים של שני מסדי הנתונים, ספק ומנוי, מתהפכים. הספק הופך למנוי והמנוי הופך לספק.
היכולת הזו של מעבר בין גרסאות חשובה לשדרוגים של מערכת ההפעלה, לשדרוגים של PostgreSQL או לבדיקות של מעבר לגיבוי בעקבות כשל.
כדי לעשות את זה בהגדרות של שכפול חד-כיווני, צריך להגדיר קשר חדש בין ספק ללקוח ולהסיר את הקשר הישן בין ספק ללקוח.
בניית ההגדרה החדשה של הספק/המנוי
עוצרים את הכתיבה של האפליקציה למערכת הספק כדי למנוע שינויים נוספים במסד הנתונים, ובודקים את השהיית הרפליקציה כדי לוודא שכל הטרנזקציות מופעלות מחדש בצומת המנוי:
SELECT application_name, state, sync_state, client_addr, client_hostname, pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag, pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag, pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag, pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag, now()-reply_time AS reply_delay FROM pg_stat_replication ORDER BY client_hostname;כשכל שדות ההשהיה מציגים אפס, המשמעות היא שהשכפול מעודכן והמסד מוכן למעבר לגיבוי.
הפלט אמור להיראות כך:
-[ RECORD 1 ]----+------------------------------ application_name | test_sub_1 state | streaming sync_state | async client_addr | 10.45.0.80 client_hostname | sent_lag | 0 receiving_lag | 0 replay_lag | 0 total_lag | 0 reply_delay | 00:00:26.203433המרת מסד הנתונים של המנויים למסד נתונים של ספק:
- להפסיק את המינוי הקיים של המנוי.
- מוסיפים את קבוצת הרפליקציה, אם צריך.
- מוסיפים את הטבלאות הנדרשות לקבוצת הרפליקציה.
- יוצרים מינוי חדש במסד הנתונים החדש של המינויים.
- מפנים את האפליקציות לספק החדש.
מפסיקים את המינוי במסד הנתונים של המנויים הקיימים, שהופך לספק החדש:
SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);(אופציונלי) יוצרים קבוצת רפליקציה שתואמת להגדרה של מסד הנתונים המקורי של הספק. אם אתם משתמשים בקבוצות ברירת המחדל של הרפליקציות, אתם לא צריכים לעשות את זה:
SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);מוסיפים טבלאות לקבוצת השכפול:
SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);מחליפים את מה שכתוב בשדות הבאים:
- REPLICATION_SET_NAME: השם של קבוצת השכפול.
- TABLE_NAME: שם הטבלה של בעלי הסכימה. לדוגמה,
ARRAY['public'].`
במסד הנתונים החדש של המנוי, שהיה בעבר מסד הנתונים של הספק, יוצרים את המינוי החדש כשהאפשרות
synchronize_dataמוגדרת ל-falseכדי למנוע את הטעינה הראשונית של הטבלה:SELECT pglogical.create_subscription ( subscription_name := '<subscription name>', replication_sets := array['default'], synchronize_data := false, provider_dsn := 'host=<hostname or IP> port=5432 dbname=<db name> user=pglogical_replication password=<password>');בודקים אם המינוי פועל בצומת של הספק:
SELECT application_name, state, sync_state, client_addr, client_hostname, pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag, pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag, pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag, pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag, now()-reply_time AS reply_delay FROM pg_stat_replication ORDER BY client_hostname;אם הרפליקציה פועלת, משנים את מחרוזות החיבור של האפליקציה כדי להשתמש במסד הנתונים של הספק החדש, ומפעילים מחדש את שכבות האפליקציה.
אם משנים את הנתונים בצומת של הספק הישן אחרי שהמנוי הופסק, השינויים האלה לא משוכפלים וזה גורם לאובדן נתונים. אם יש שינויים בנתונים שלא שוכפלו במסד הנתונים של הספק המקורי, או אם הספק המקורי (המנוי החדש) לא נמצא במצב שתואם למסד הנתונים של הספק החדש (המנוי הישן), צריך לבנות את מסד הנתונים של המנוי החדש מחדש.
הסרת הספק והמינוי הישנים
אם רוצים רפליקציה חד-כיוונית, צריך להסיר את ההגדרות הישנות של הספק/המנוי.
הסרת המינוי הישן אצל הספק החדש:
SELECT pglogical.drop_subscription('<subscription name>')מסירים את קבוצת הרפליקציה במנוי החדש או מסירים את כל הטבלאות מקבוצת הרפליקציה:
SELECT pglogical.drop_replication_set('<replication set name>')SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
רפליקציה דו-כיוונית
כדי לעבור בלי זמן השבתה, או כדי לוודא שלא יאבדו נתונים בגלל שינויים לא מתוכננים בנתונים, צריך להשתמש ברפליקציה דו-כיוונית. כשמטמיעים רפליקציה דו-כיוונית, צריך להביא בחשבון את פתרון ההתנגשויות, אלא אם יש אמצעי בקרה קפדניים שמונעים גישת כתיבה לשני הצמתים בו-זמנית.
אפשר להגדיר את תצורת פתרון הקונפליקטים באמצעות ההגדרות הבאות של pglogical.conflict_resolution:
-
error: המנוי מפסיק כשהמערכת מזהה התנגשות. -
apply_remote: תמיד יוחלו השינויים הנכנסים, ללא קשר לנתונים במסד הנתונים של המנויים. זוהי הגדרת ברירת המחדל. -
keep_local: תמיד מתעלמים מהנתונים הנכנסים שמתנגשים עם השינוי ומבטלים את השינוי שמתנגש. -
last_update_wins: גרסת הנתונים עם חותמת הזמן של ה-commit האחרון היא הנתונים שבוצע להם commit -
first_update_wins: גרסת הנתונים עם חותמת הזמן הכי ישנה היא הנתונים שנשמרים
כדי להגדיר רפליקציה דו-כיוונית, מגדירים את הספק והמנוי כך שהרפליקציה תתבצע בשני הכיוונים. המנוי המקורי הופך גם לספק עם אותה קבוצת רפליקציה כמו הספק המקורי. כדי ליצור קבוצת רפליקציה שמשכפלת את קבוצת הרפליקציה המקורית במסד הנתונים של הספק הראשוני, עיינו בקטע יצירת טבלה והוספה שלה לקבוצת הרפליקציה שמוגדרת כברירת מחדל במסד הנתונים של ספק AlloyDB ל-PostgreSQL.
אצל הספק המקורי, צריך להוסיף מנוי חדש. במאמר יצירת צומת ומנוי במסד נתונים של מנויים ב-AlloyDB Omni מוסבר איך ליצור מנוי חדש ולוודא שהפרמטר synchronize_data של הפקודה pglogical.create_subscription מוגדר לערך false. כך נמנעת העתקה ראשונית של הנתונים מהטבלה.
מעבר לגיבוי בעת כשל עם רפליקציה של pglogical
יתירות כשל מתרחשת כשמסד הנתונים של הספק לא זמין מסיבה כלשהי, ואתם צריכים להעביר את האפליקציה לשימוש במסד הנתונים של המנוי.
כדי למנוע החלה בטעות של נתונים כפולים במסד הנתונים של המנוי שהועבר, צריך להשבית את המינוי. כך אפשר לוודא ששינויים מספק ששוחזר לא יחולו בטעות כשהספק יהיה זמין שוב.
עוצרים את המנוי,
test_sub_1:SELECT pglogical.alter_subscription_disable(`test_sub_1`);בודקים שהסטטוס מוגדר ל
disabled:SELECT pglogical.show_subscription_status('test_sub_1');הפלט אמור להיראות כך:
show_subscription_status ---------------------------------------------------------------------------- (test_sub1,disabled,subscriber,"host=10.45.0.108 port=5432 dbname=my_test_db user=pglogical_replication",subscriber,{failover_set},{all})בודקים את מילת המפתח המושבתת בפלט הסטטוס.
כדאי ליצור הגדרה חדשה של ספק/מנוי כדי לשמור על זמינות גבוהה ועל יכולת התאוששות מאסון.
יוצרים קבוצת רפליקציה חדשה שמכילה את כל הטבלאות ששוכפלו במקור, כדי ליצור מנוי חדש כשמסד הנתונים של הספק הישן משוחזר ומומר למנוי חדש, או כשנוצר מנוי חדש.
אם אפשר לשחזר את מסד הנתונים של הספק הישן לזמן שבו אירע הכשל, צריך להגדיר את מסד הנתונים הזה כמנוי החדש. כדי ליצור מינוי, פועלים לפי אותם השלבים ומגדירים את הפרמטר
synchronize_dataשל הפקודהpglogical.create_subscriptionלערךfalseכדי להימנע מהעתקה של הטבלה הראשונית.מסירים את הגדרות הספק הישנות בצומת המשוחזר כדי למנוע הצטברות של קובץ WAL.
אם אתם משתמשים במסד הנתונים הישן של הספק, אתם יכולים להסיר את כל קבוצת השכפול או להסיר את כל הטבלאות מקבוצת השכפול אחת אחת:
SELECT pglogical.drop_replication_set('<replication set name>')SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')מעבירים את האפליקציה לכתיבה לצומת החדש.
המאמרים הבאים
- שכפול נתונים בין AlloyDB ל-PostgreSQL לבין AlloyDB Omni
- שכפול נתונים בין AlloyDB Omni לבין מסדי נתונים אחרים