分析SQL中的DBA
本篇內容主要講解“分析SQL中的DBA”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“分析SQL中的DBA”吧!
1.程序備份
場景:一旦程序所在主機故障,需要在新環境下重新部署程序時,程序備份的作用就體現出來了。
其實我這里程序所連接的底層數據庫是Oracle RAC架構,可直接在RAC另一個節點部署一套程序。因為之前程序使用的文件默認在/home/oracle下,該目錄還有很多其他與程序無關的文件,比較混亂,現考慮將程序整理到統一目錄下整體打包,便于備份,遇到故障也可以方便快速重新部署。
我這里統一放置目錄:/home/oracle/baby,并將程序按照當前版本號進行打包備份,最后拷貝備份的程序包到NAS留存。
1.1 統一放置目錄:/home/oracle/baby
[oracle@jystdrac2baby]$pwd /home/oracle/baby [oracle@jystdrac2baby]$ls-lrth total76K -rw-r--r--1oracleoinstall36Dec2209:47d1.sql -rw-r--r--1oracleoinstall71Dec2209:47i1.sql -rw-r--r--1oracleoinstall91Dec2209:47i2.sql -rw-r--r--1oracleoinstall59Dec2209:47u1.sql -rw-r--r--1oracleoinstall199Dec2209:47v1.sql -rw-r--r--1oracleoinstall218Dec2209:47v2.sql -rw-r--r--1oracleoinstall396Dec2209:47v3.sql -rw-r--r--1oracleoinstall465Dec2209:47v4.sql -rw-r--r--1oracleoinstall132Dec2209:47v_estimate.sql -rwxr-xr-x1oracleoinstall302Dec2209:54baby_delete.sh -rwxr-xr-x1oracleoinstall296Dec2209:55baby_insert.sh -rwxr-xr-x1oracleoinstall335Dec2209:55baby_insert_diy.sh -rwxr-xr-x1oracleoinstall545Dec2209:56baby_help.sh -rwxr-xr-x1oracleoinstall305Dec2209:57baby_update.sh -rwxr-xr-x1oracleoinstall293Dec2209:57baby_view.sh -rwxr-xr-x1oracleoinstall252Dec2209:58baby_view_diy.sh -rw-r--r--1oracleoinstall244Dec2213:30bash_profile -rw-r--r--1oracleoinstall273Dec2609:10backup_exp_t_baby.sh -rw-r--r--1oracleoinstall154Dec2609:53readme [oracle@jystdrac2baby]$cd..
1.2 將程序按照當前版本號進行打包備份
[oracle@jystdrac2~]$tar-zcvfbaby_v2.02.tar.gzbaby/ baby/ baby/readme baby/u1.sql baby/v4.sql baby/baby_view_diy.sh baby/d1.sql baby/v3.sql baby/baby_update.sh baby/v2.sql baby/v_estimate.sql baby/i1.sql baby/bash_profile baby/baby_insert_diy.sh baby/baby_insert.sh baby/i2.sql baby/v1.sql baby/baby_help.sh baby/baby_view.sh baby/baby_delete.sh baby/backup_exp_t_baby.sh [oracle@jystdrac2~]$ls-lrthbaby_v2.02.tar.gz -rw-r--r--150110001.9KDec2611:46baby_v2.02.tar.gz
1.3 最后拷貝備份的程序包到NAS留存
[oracle@jystdrac2~]$cpbaby_v2.02.tar.gz/public/backup/
2.數據備份
場景:上面已經做了程序備份,但出現故障時我們只恢復程序是不夠的,還需要之前產生的業務數據。所以我們還需要業務數據的備份。
可以采用exp/expdp定時邏輯備份,因為我這里數據量很小,所以直接采用更簡單的exp備份。
比如每天12點使用exp備份出當前表t_baby的數據:
設置crontab定時任務:
[oracle@jystdrac2~]$crontab-l 012***/bin/sh/home/oracle/baby/backup_exp_t_baby.sh
exp備份腳本:
[oracle@jystdrac2~]$cat/home/oracle/baby/backup_exp_t_baby.sh backupdate=`date+%Y%m%d` exportORACLE_SID=demo2 exportORACLE_BASE=/opt/app/oracle exportORACLE_HOME=/opt/app/oracle/product/11.2.0/dbhome_1 exportPATH=$PATH:$ORACLE_HOME/bin exptest/testtables=t_babyfile=/public/backup/t_baby_$backupdate.dmplog=/public/backup/t_baby_$backupdate.log
備份出的文件類似這樣:
[oracle@jystdrac2backup]$ls-lrtht_baby* -rw-rw-rw-15011000626Dec2612:00t_baby_20191226.log -rw-rw-rw-1501100016KDec2612:00t_baby_20191226.dmp
3.數據實時同步
場景:如果只有上面步驟的定時邏輯備份,其實還是無法滿足完全的數據恢復的。
比如今天中午12點做了備份,晚上18點出現了故障,數據丟失。通過邏輯備份只能恢復到今天中午12點的數據,而12點到18點之間的數據將會丟失。
如果采用物理RMAN備份呢?其實也同樣存在這樣的問題,因為日志歸檔并不是實時的,如果故障不可恢復,聯機重做日志也丟失,RMAN也是不完全恢復到最近的歸檔日志,也同樣會有丟失部分數據的風險。
那怎么辦呢?如何進行數據實時同步到另外的環境呢?目前可以想到兩種主流的解決方案:
-
1)數據庫DG實時同步
-
2)數據表OGG同步
數據庫DG實時同步是物理的方式,數據表OGG同步是邏輯的方式。
一般情況下,如果兩個方案只能選擇其一時,我們會強烈推薦客戶選用物理方式的實時同步,因為邏輯方式按經驗來看遇到的問題遠比物理方式要高。
而在我這個場景下,數據量很小,其實完全可以二者都選擇。
至于DG和OGG環境搭建的部分我這里不再詳細展開,如有問題,可參考之前的文章:
-
模擬生產搭建Standby RAC實驗環境(11.2.0.4 DG)
-
OGG學習筆記02-單向復制配置實例
4.已知問題解決
在這個計算喂奶間隔的程序投入使用了一段時間后,還發現一些問題亟待解決:
4.1 系統時間不準確
系統運行幾天后,操作系統的時間會和真實時間相差幾分鐘,這個暫時通過定時同步阿里云的NTP服務器來解決。
--使用ntpdate命令與阿里云時間服務器(ntp2.aliyun.com)同步 [root@jystdrac1~]#date SunDec2208:48:51CST2019 [root@jystdrac1~]#ntpdatentp2.aliyun.com 22Dec08:52:31ntpdate[24481]:steptimeserver203.107.6.88offset206.232030sec [root@jystdrac1~]#date SunDec2208:52:35CST2019 --使用crontab定時,每小時與阿里云時間服務器同步一次,同步日志追加到/tmp/ntpdate.log日志文件 crontab-l 0****ntpdatentp2.aliyun.com>>/tmp/ntpdate.log
當然,這里其實還可以設置NTP微調(-x)模式,保證RAC穩定性不受其調整的影響。
4.2 數據一致性問題
這個也可以說是程序設計時的bug。
現象:當前程序連接的數據庫底層是單實例,或始終在RAC的同一個節點上運行,就不會有任何問題;但如果在RAC的兩個節點交叉運行插入數據,序列就會出現問題導致計算結果產生訛誤。
先稱之為是RAC環境下sequence的問題解決:
比如:在節點1插入記錄,ID為235,再到節點2插入記錄,ID卻為192.
[oracle@jystdrac2~]$i Insertarowusingcurrenttime: 1rowcreated. Commitcomplete. ViewToday'sResult: IDFEED_TIMELLAG(min)LAG(h) ------------------------------------------ 19212-2618:21N568994.82 22712-2602:22N2253.75 22812-2604:48N1462.43 22912-2607:31N1642.73 23012-2610:02N1512.51 23112-2611:49N1071.79 23212-2614:10N1412.34 23312-2617:38N2083.47 23412-2618:18N41.68 23512-2618:19N0.01 10rowsselected.
可以看到在節點2后插入的記錄ID值反而小,導致程序本身間隔計算也出現了訛誤,明顯這樣是有問題的。
其實問題也非常明顯,實例1和實例2獲取s1的sequence是不連續的,分別在兩個實例上查詢:
--實例1: test@DEMO>selects1.nextvalfromdual; NEXTVAL ---------- 239 --實例2: test@DEMO>selects1.nextvalfromdual; NEXTVAL ---------- 193
查詢下sequence的創建語句:
test@DEMO>selectdbms_metadata.get_ddl('SEQUENCE','S1')fromdual;
DBMS_METADATA.GET_DDL('SEQUENCE','S1')
--------------------------------------------------------------------------------
CREATESEQUENCE"TEST"."S1"MINVALUE1MAXVALUE9999999999999999999999999999INCREMENTBY1STA
RTWITH241CACHE20NOORDERNOCYCLE
可以看到序列默認是NOORDER,如果設為ORDER,測試反復在兩個實例上交叉讀序列的nextval,都能保證序列值是順序的,就不會再出現最初的情況。
所以解決方案就是重建sequence s1,修改為ORDER。
dropSEQUENCEs1; CREATESEQUENCEs1MINVALUE1MAXVALUE9999999999999999999999999999INCREMENTBY1STARTWITH261CACHE20ORDERNOCYCLE;
再次驗證(select s1.nextval from dual;),確認此時序列是有序的:
--實例1: test@DEMO>selects1.nextvalfromdual; NEXTVAL ---------- 261 --實例2: test@DEMO>selects1.nextvalfromdual; NEXTVAL ---------- 262
但還需要注意如果將序列改為ORDER,在實際業務壓力大時很可能會造成嚴重性能問題,這估計也是不加任何參數創建的sequence默認就是NOORDER的原因。
總結
以上是生活随笔為你收集整理的分析SQL中的DBA的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Word打字被覆盖了怎么解决
- 下一篇: 对某机构为“转移内部矛盾”而嫁祸于我们的