PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PITR करते समय, क्या PostgreSQL में विराम देना/फिर से शुरू करना संभव होगा?

हाँ, वास्तव में संभव है और PostgreSQL द्वारा स्मार्ट तरीके से संभाला जाता है। इसे प्रदर्शित करने के लिए, पहले मुझे PostgreSQL में पॉइंट इन टाइम रिकवरी की मानक तकनीक को अपनाने की आवश्यकता है। असाधारण लेखकों द्वारा विभिन्न पुस्तकों/लेखों/ब्लॉगों को बहुत अच्छी तरह से प्रदर्शित किया गया है, इसलिए मैं इसे कैसे करना है, इसके विवरण में नहीं जा रहा हूं, हालांकि, सीधे विषय पर जा रहा हूं, यानी, उसी तकनीक के साथ ठीक होने के दौरान कैसे रोकें। तर्कसंगत रूप से, मैंने पीआईटीआर से एक गणितीय अभिव्यक्ति को "पीआईटीआर =(अंतिम फाइल सिस्टम बैकअप (एलएफबी) + वाल आर्काइव्स एलएफबी + अन-आर्काइव्ड वाल के वर्तमान $ PGDATA / pg_xlogs में उत्पन्न)" के रूप में प्रस्तुत किया है। बेहतर समझ के लिए, मैंने इसे ग्राफ में रखा है, इस तथ्य के प्रकाश में कि यह विचार को और अधिक स्पष्ट करता है:(क्षमा करें, यह ब्लॉग थोड़ा लंबा है, अनजाने में यह अवधारणा के विवरण में जाने के दौरान हुआ)

PITR चरण, जिनका पालन मैं थोड़े से परिवर्तनों के साथ करने जा रहा हूँ जिनके बारे में मैं जल्द ही बात करूँगा:

चरण 1. नवीनतम फ़ाइल सिस्टम-स्तरीय बैकअप (FSB) को किसी भी स्थान पर पुनर्स्थापित करें जहां पुनर्प्राप्ति करने की योजना है।
चरण 2. यदि FSB टार है, तो उसे अनटार करें, और संग्रह_स्थिति को छोड़कर pg_xlog निर्देशिका को साफ़ करें। यदि बैकअप ने इस निर्देशिका को बाहर कर दिया है, तो FSB में खाली pg_xlog निर्देशिका बनाएँ।
चरण 3. क्रैश क्लस्टर $PGDATA/pg_xlog से गैर-संग्रहीत WAL को $FSB/pg_xlog (चरण 2) में कॉपी करें
चरण 4. FSB निर्देशिका से postmaster.pid हटाएं।
चरण 5. FSB निर्देशिका में पुनर्प्राप्ति.conf फ़ाइल बनाएँ।
चरण 6. क्लस्टर (FSB) प्रारंभ करें।

हमें सवाल उठाना चाहिए, जब वसूली को रोकना आवश्यक है? हो सकता है, एकाधिक आधार पुनर्स्थापनों या रोल-फ़ॉरवर्ड पुनर्प्राप्ति को रोकने के लिए, लेकिन किसी विशेष तालिका डेटा या रुचि के बीच में या रोलबैक की जांच करें कि यह कितनी दूर पुनर्प्राप्त हुआ है :)। याद रखें, पुनर्प्राप्ति में विराम का अर्थ है, इसे ठीक होने के दौरान कनेक्ट करने की अनुमति देना। इसे रेखांकित करने के लिए, मैंने एक विशेष तालिका पंक्तियों के सुधार के चार्ट में एक दुर्घटना तक की स्थिति को पुन:प्रस्तुत किया है।

उपरोक्त आरेख से, इसकी स्वीकार्य एक डेमो तालिका पंक्तियाँ 10,00,000 थीं जब फ़ाइल सिस्टम-स्तरीय बैकअप ($ PGDATA) लिया गया और क्रैश से पहले 40,00,000 पंक्तियाँ। अपने स्थानीय VM में, मैंने तारीख के बजाय TIME के ​​आधार पर स्थिति बनाई है।

पूर्व-आवश्यकता:
1. फाइल सिस्टम-लेवल बैकअप जब डेमो टेबल में 10,00,000 पंक्तियां हों।
2. उस बिंदु से आगे, WAL क्रैश से पहले संग्रहीत करता है जहां DEMO तालिका में 40,00,000 पंक्तियाँ होती हैं।
3. वाल अभिलेखागार स्थान:/opt/PostgreSQL/9.3/अभिलेखागार।
4. डेटा निर्देशिका :/opt/PostgreSQL/9.3/डेटा (PGDATA)
5. बैकअप स्थान:/opt/PostgreSQL/9.3/बैकअप

ध्यान रखें, पॉज़ रिकवरी के साथ काम करने के लिए मुख्य क्लस्टर ($ PGDATA) "wal_level" को "hot_standby" पर और पुनर्प्राप्ति क्लस्टर (फ़ाइल सिस्टम-स्तरीय बैकअप) "hot_standby" को "ON" पर सेट करने पर अनिवार्य परिवर्तन की आवश्यकता होती है। मैंने इन परिवर्तनों को मुख्य क्लस्टर में किया है, प्रभावी होने के लिए क्लस्टर को पुनरारंभ किया है और बैकअप शुरू किया है। यदि आपको कोई आपत्ति नहीं है, तो इसे केवल एक डेमो के रूप में नोट करें, इसलिए मेरे WAL अभिलेखागार विशाल संख्या के नहीं हो सकते हैं क्योंकि वे कुछ संख्या में हैं। मैंने यहां वाल आर्काइव्स को भी सूचीबद्ध किया है, जो बैकअप के समय से क्रैश होने तक उत्पन्न हुए थे।

-bash-4.1$ psql -c "select count(*), now() from demo;"
count | now
---------+-------------------------------
1000000 | 2014-04-04 15:06:04.036928-07
(1 row)

-bash-4.1$ pg_basebackup -D /opt/PostgreSQL/9.3/backup/data_pitr -- I have my $PGDATA, $PGUSER, $PGPORT set, so its a straight command in my case
NOTICE: pg_stop_backup complete, all required WAL segments have been archived

WAL अभिलेखागार और $PGDATA/pg_xlog

. की वर्तमान स्थिति
-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/archives
-rw------- 1 postgres postgres 16M Apr 4 16:01 00000001000000000000001C
-rw------- 1 postgres postgres 16M Apr 4 16:01 00000001000000000000001D
-rw------- 1 postgres postgres 289 Apr 4 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001E

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/data/pg_xlog | tail -4
-rw------- 1 postgres postgres 289 Apr 4 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001E
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001F
drwx------ 2 postgres postgres 4.0K Apr 4 16:13 archive_status

अब ठीक है, हमारे पास बैकअप प्रति है, INSERT को समय को नोट करके तीन भागों में कुछ रिकॉर्ड करने देता है, इसलिए यह पुनर्प्राप्ति को रोकने में मदद करेगा और साथ ही FSB के समय से उत्पादित WAL को भी देखेगा।

-bash-4.1$ psql -c "insert into demo values (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "select count(*),now() from demo;"
count | now
---------+-------------------------------
2000000 | 2014-04-04 16:06:34.941615-07
(1 row)
-bash-4.1$ psql -c "insert into demo values (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "select count(*),now() from demo;"
count | now
---------+-------------------------------
3000000 | 2014-04-04 16:10:31.136725-07
(1 row)
-bash-4.1$ psql -c "insert into demo values (generate_series(1,1000000));"
INSERT 0 1000000
-bash-4.1$ psql -c "select count(*),now() from demo;"
count | now
---------+-------------------------------
4000000 | 2014-04-04 16:13:00.136725-07
(1 row)

INSERT के दौरान उत्पादित WAL की संख्या की जाँच करें।

-bash-4.1$ ls -lrth /opt/PostgreSQL/9.3/archives
-rw------- 1 postgres postgres 289 Apr 4 16:06 00000001000000000000001E.000000C8.backup
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001E
-rw------- 1 postgres postgres 16M Apr 4 16:06 00000001000000000000001F
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000020
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000021
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000022
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000023
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000024
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000025
-rw------- 1 postgres postgres 16M Apr 4 16:06 000000010000000000000026
-rw------- 1 postgres postgres 16M Apr 4 16:10 000000010000000000000027
-rw------- 1 postgres postgres 16M Apr 4 16:10 000000010000000000000028
-rw------- 1 postgres postgres 16M Apr 4 16:10 000000010000000000000029
-rw------- 1 postgres postgres 16M Apr 4 16:10 00000001000000000000002A
-rw------- 1 postgres postgres 16M Apr 4 16:13 00000001000000000000002B

मान लें कि इस बिंदु पर दुर्घटना हुई और आपको FSB + WAL अभिलेखागार + अनारक्षित वाल (यदि कोई हो) का उपयोग करके पुनर्प्राप्ति करना है। पुनर्प्राप्ति के दौरान, मैं केवल पढ़ने के लिए मोड में डेटाबेस से कनेक्ट करके डेमो तालिका की 20,00,000, 30,00,000 और 40,00,000 पंक्तियों की प्रत्येक पुनर्प्राप्ति को देखने के लिए तीन बार रुकना चाहता हूं। पुनर्प्राप्ति के प्रत्येक पुनरारंभ के लिए पुनर्प्राप्ति क्लस्टर को पुनर्प्राप्ति.conf/recovery_target_time में नई समयरेखा से टकराकर पुनरारंभ करने की आवश्यकता है। साथ ही, $FSB/postgresql.conf में, हमें hot_standby=on सेट करना होगा। यह रही मेरी रिकवरी.कॉन्फ फाइल:

-bash-4.1$ more recovery.conf
pause_at_recovery_target = true
#recovery_target_time = '2014-04-04 16:06:34' # For 2 lakh records
#recovery_target_time = '2014-04-04 16:10:31' # For 3 lakh records
#recovery_target_time = '2014-04-04 16:13:00' # For 4 lakh records
restore_command = 'cp /opt/PostgreSQL/9.3/archives/%f %p'

आइए 20,00,000 रिकॉर्ड के लिए पुनर्प्राप्ति प्रारंभ करें:

-bash-4.1$ /opt/PostgreSQL/9.3/bin/pg_ctl -D /opt/PostgreSQL/9.3/data_pitr/ start
server starting

Now in logs:

-bash-4.1$ more postgresql-2014-04-04_162524.log
2014-04-04 16:25:24 PDT-24187---[] LOG: starting point-in-time recovery to 2014-02-06 18:48:56-08
2014-04-04 16:25:24 PDT-24187---[] LOG: restored log file "00000001000000000000001E" from archive
2014-04-04 16:25:24 PDT-24187---[] LOG: redo starts at 0/1E0000C8
2014-04-04 16:25:24 PDT-24187---[] LOG: consistent recovery state reached at 0/1E000190
2014-04-04 16:25:24 PDT-24185---[] LOG: database system is ready to accept read only connections
2014-04-04 16:25:24 PDT-24187---[] LOG: restored log file "00000001000000000000001F" from archive
2014-04-04 16:25:24 PDT-24187---[] LOG: restored log file "000000010000000000000020" from archive
2014-04-04 16:25:25 PDT-24187---[] LOG: restored log file "000000010000000000000021" from archive
2014-04-04 16:25:25 PDT-24187---[] LOG: restored log file "000000010000000000000022" from archive
2014-04-04 16:25:25 PDT-24187---[] LOG: recovery stopping before commit of transaction 1833, time 2014-04-04 16:06:23.893487-07
2014-04-04 16:25:25 PDT-24187---[] LOG: recovery has paused
2014-04-04 16:25:25 PDT-24187---[] HINT: Execute pg_xlog_replay_resume() to continue

बढ़िया, लॉग में देखें कि यह रुक गया है और एक स्मार्ट HINT फिर से शुरू करने के लिए कह रहा है। यहां, यदि रिकवरी संतोषजनक थी, तो आप "सेलेक्ट pg_xlog_replay_resume ();" (आप इसे देख सकते हैं) पर कॉल करके इसे फिर से शुरू कर सकते हैं। आइए अब फिर से शुरू न करें, हालांकि सर्वर से कनेक्ट करके पुनर्प्राप्त की गई पंक्तियों की संख्या की जांच करें।

-bash-4.1$ psql -c "select count(*),pg_is_in_recovery() from demo;"
count | pg_is_in_recovery
---------+-------------------
2000000 | t
(1 row)

अच्छा, यह उस बिंदु पर पहुंच गया है और जहां मैंने अनुरोध किया था वहां रुक गया। 30,000,000 पंक्तियों को पुनर्प्राप्त करने के लिए एक और कदम आगे बढ़ते हैं। अब, अगली समयावधि पुनर्प्राप्ति.conf/recovery_target_time में सेट करें और क्लस्टर को पुनरारंभ करें।

2014-04-04 16:28:40 PDT-24409---[] LOG:  restored log file "00000001000000000000002A" from archive
2014-04-04 16:28:40 PDT-24409---[] LOG: recovery stopping before commit of transaction 1836, time 2014-04-04 16:10:40.141175-07
2014-04-04 16:28:40 PDT-24409---[] LOG: recovery has paused
2014-04-04 16:28:40 PDT-24409---[] HINT: Execute pg_xlog_replay_resume() to continue.

-bash-4.1$ psql -c "select count(*),pg_is_in_recovery() from demo;"
count | pg_is_in_recovery
---------+-------------------
3000000 | t
(1 row)

अच्छा..., 40,00,000 पंक्तियों पर विराम देने का अंतिम प्रयास करते हैं।

2014-04-04 20:09:07 PDT-4723---[] LOG:  restored log file "00000001000000000000002B" from archive
cp: cannot stat `/opt/PostgreSQL/9.3/archives/00000001000000000000002C': No such file or directory
2014-04-04 20:09:07 PDT-4723---[] LOG: redo done at 0/2B0059A0
2014-04-04 20:09:07 PDT-4723---[] LOG: last completed transaction was at log time 2014-04-04 16:11:12.264512-07
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000001000000000000002B" from archive
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000002.history" from archive
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000003.history" from archive
2014-04-04 20:09:07 PDT-4723---[] LOG: restored log file "00000004.history" from archive
cp: cannot stat `/opt/PostgreSQL/9.3/archives/00000005.history': No such file or directory
2014-04-04 20:09:07 PDT-4723---[] LOG: selected new timeline ID: 5
cp: cannot stat `/opt/PostgreSQL/9.3/archives/00000001.history': No such file or directory
2014-04-04 20:09:07 PDT-4723---[] LOG: archive recovery complete
2014-04-04 20:09:08 PDT-4721---[] LOG: database system is ready to accept connections
2014-04-04 20:09:08 PDT-4764---[] LOG: autovacuum launcher started

-bash-4.1$ psql -c "select count(*),pg_is_in_recovery() from demo;"
count | pg_is_in_recovery
---------+-------------------
4000000 | f
(1 row)

उफ़, क्या हुआ, क्यों नहीं रुका और इसकी क्या शिकायत है?. ध्यान रखें, अगर रिकवरी_टारगेट_टाइम के समय कोई वाल आर्काइव मौजूद नहीं है तो यह रुकेगा और उम्मीद नहीं करेगा क्योंकि यह अंतिम बिंदु पर आ गया है और डेटाबेस को पढ़ें/लिखने के लिए खोलें। लॉग में, बिना ज्यादा खिंचाव के यह फाइल "00000000100000000000000002सी” के लिए शिकार कर रहा था जो उपलब्ध नहीं है, क्योंकि उस समय क्लस्टर क्रैश हो गया था। कुछ लोग इस व्यवहार को स्वीकार नहीं कर सकते हैं लेकिन इसके तथ्य और समझ में आता है जब कोई WAL अभिलेखागार मौजूद नहीं है तो पुनर्प्राप्ति को रोकने का कोई कारण नहीं है। यदि WAL संग्रह न होने के बाद भी रुकने की आवश्यकता है, तो स्टैंडबाय_मोड ='ऑन' (HOT_STANDBY) का उपयोग करें, इस विधि में यह पुनर्प्राप्ति से बाहर नहीं आएगा, लेकिन WAL अभिलेखागार की प्रतीक्षा करें।

आशा है कि यह उपयोगी था।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. जावा एसक्यूएल त्रुटि:संबंध तालिका_नाम मौजूद नहीं है

  2. रूबी-ऑन-रेल के साथ उपयोग के लिए विंडोज़ पर पोस्टग्रेज़ स्थापित करना

  3. PostgreSQL ट्रिगर्स को यूजर आईडी पास करना

  4. पीडीओ बनाम पीजी_* कार्य

  5. सम्मिलित करें ... चयन से ... रिटर्निंग आईडी मैपिंग