2015-03-30 8 views
7

उपयोग-मामले वास्तव में इसे ansible के साथ स्वचालित करने के लिए। मैं डेटाबेस डंप केवल आयात करना चाहता हूं जब डेटाबेस पूरी तरह खाली हो (अंदर कोई टेबल नहीं)। निश्चित रूप से एसक्यूएल स्टेटमेंट निष्पादित करने का हमेशा एक तरीका है, लेकिन यह अंतिम उपाय है, मेरा मानना ​​है कि इसके लिए और अधिक सुरुचिपूर्ण समाधान होना चाहिए।PgSQL - डेटाबेस डंप को केवल तभी आयात करें जब डेटाबेस पूरी तरह से खाली हो?

pg_restore मैनुअल इस विकल्प को तब तक प्रदान नहीं करता है जब तक मैं देखता हूं।

यहाँ कैसे मैं ansible के साथ ऐसा करने की योजना बना रहा हूँ:

- name: db_restore | Receive latest DB backup 
    shell: s3cmd --skip-existing get `s3cmd ls s3://{{ aws_bucket }}/ | grep sentry | tail -1 | awk '{print $4}'` sql.latest.tgz 
    args: 
     chdir: /root/ 
     creates: sql.latest.tgz 

    - name: db_restore | Check if file exists 
    stat: path=/root/sql.latest.tgz 
    register: sql_latest 

    - name: db_restore | Restore latest DB backup if backup file found 
    shell: PGPASSWORD={{ dbpassword }} tar -xzOf /root/sentry*.tgz db.sql | psql -U{{ dbuser }} -h{{ pgsql_server }} --set ON_ERROR_STOP=on {{ dbname }} 
    when: sql_latest.stat.exists 
    ignore_errors: True 

आदर्श रूप में यह अगर डीबी खाली जांच होनी चाहिए। इस उद्देश्य के लिए कोई उत्तरदायी मॉड्यूल मौजूद नहीं है। Google भी चुप्पी में है .. वर्तमान समाधान वास्तव में भी काम करता है, आयात विफल होने पर यह त्रुटि देगा, और मैं केवल त्रुटि को अनदेखा कर सकता हूं, लेकिन झूठा अलार्म देखने के लिए यह थोड़ा दर्दनाक है।

+0

"खाली" एक अस्पष्ट शब्द है। यहां तक ​​कि एक "खाली" डेटाबेस में संग्रहित वस्तुओं का एक गुच्छा परिभाषित किया जा सकता है। 'Pg_restore' यह निर्धारित करेगा कि" पर्याप्त खाली "है? – zerkms

+0

एक प्रश्न तय :) खाली = टेबल के बिना डेटाबेस।ताजा बनाया गया – holms

+0

मुझे उम्मीद नहीं होगी कि "बिना टेबल के" एक अतिरिक्त संकीर्ण आवश्यकता है। दूसरा व्यक्ति बिना किसी अनुक्रम के एक खाली डेटाबेस का इलाज करेगा। – zerkms

उत्तर

3

डेटाबेस को खाली के रूप में मानने के लिए, हमें पता होना चाहिए कि सृजन के बिंदु से कुछ भी नहीं जोड़ा गया है। चूंकि पोस्टग्रेर्स इस पर ट्रैक नहीं करते हैं (जैसा कि पहले से ही @ क्राइग रिंगर द्वारा उल्लेख किया गया है) मैं जवाब देने के संबंध में एक अलग दृष्टिकोण की सलाह देता हूं।

तो, जैसे कोई हैंडलर तंत्र का उपयोग करें:

- name: Create zabbbix postgres DB 
    postgresql_db: name="{{zabbix_db_name}}" 
    notify: 
    - Init zabbix database 
+1

एकमात्र समस्या जो सूचित करती है प्लेबुक के अंत में आती है .. क्योंकि ऐप भी प्रावधान डीबी के बिना शुरू नहीं होता है। अधिसूचनाओं को बलपूर्वक निष्पादित करने का कोई तरीका? – holms

+0

दुर्भाग्य से अब मुझे लगता है कि यह असंभव है। लेकिन ताजा हैंडलर के रूप में नए संस्करण के लिए सुझाव दिया गया: https://github.com/ansible/ansible/issues/10829 – Hubbitus

+0

इस समय आप हैंडलर चलाने के लिए मजबूर करने के लिए "मेटा: flush_handlers" का उपयोग करना चाहेंगे (https://groups.google.com/मंच/#! विषय/ansible-परियोजना/0lMtduWbxwU) – Hubbitus

5

वास्तव में ऐसी कोई चीज़ नहीं है जैसे "खाली"; इसमें आमतौर पर अंतर्निहित प्रकार होते हैं, डिफ़ॉल्ट पीएल/पीजीएसक्यूएल भाषा, आदि, भले ही आप template0 से बनाते हैं। यदि आप एक अलग टेम्पलेट से बनाते हैं तो वहां बहुत कुछ हो सकता है।

पोस्टग्रेएसक्यूएल डीबी को पहले गैर-टेम्पलेट लिखने का रिकॉर्ड नहीं रखता है, इसलिए आप "निर्मित होने के बाद से बदल नहीं सकते" कह सकते हैं।

यही कारण है कि पर --if-empty विकल्प नहीं है। यह वास्तव में समझ में नहीं आता है।

psql को से पूछने के लिए psql निष्पादित करने के लिए सबसे अच्छा विकल्प दूर है और यह निर्धारित करें कि public स्कीमा में कोई तालिका है या नहीं। या, इससे भी बेहतर, विशिष्ट टेबल और प्रकारों की उपस्थिति के लिए पूछताछ आपको डंप द्वारा बनाई जाएगी।

उदा।

psql -qAt mydbname -c "select 1 from information_schema.tables where table_schema = 'public' and table_name = 'testtable';" 

फिर आप stdout पर वापस शून्य/nonzero पंक्तियों के लिए परीक्षण कर सकते हैं। या इसे psql से बूलियन प्राप्त करने के लिए SELECT EXISTS(...) में लपेटें। या DO ब्लॉक का उपयोग करें जो ERROR एस है यदि तालिका मौजूद है यदि आपको psql से शून्य/nonzero निकास स्थिति की आवश्यकता है।

2

चूंकि यह बताने के लिए, अगर एक डेटाबेस, "खाली" है के रूप में दूसरों के द्वारा समझाया कठिन है, इसलिए यह देखना बहुत आसान है, यदि डेटाबेस मौजूद है, फिर एक चरण में बनाएँ और पुनर्स्थापित करें। मैं इसे इस तरह कर रहा हूं:

- name: Check my_database database already exists 
    become: yes 
    become_user: postgres 
    shell: psql -l | grep my_database 
    ignore_errors: true 
    register: my_database_db_existence 
- debug: var=my_database_db_existence 

- name: Copy backup of the my-database database 
    shell: your-s3-command here 
    when: my_database_db_existence | failed 

- name: Restore my_database database on first run 
    become_user: postgres 
    shell: createdb -O my_user my_database && psql -d my_database -f /path/to/my_dump.sql 
    when: my_database_db_existence | failed 

पीएस कार्यान्वयन में प्रत्येक उत्तरदायी कार्य को समझाते हुए detailed blog post भी लिखा।

संबंधित मुद्दे