標籤:指令碼 shell oracle
利用SHELL指令碼實現將Oracle資料庫的每日EXPDP匯出檔案複製到遠程伺服器
趙全文 網名:guestart
我們有一套生產環境的Oracle資料庫,雖然每天都有RMAN備份,但是也招架不住開發人員隔三差五就說要恢複幾張表的前幾天的資料到生產環境當中,針對這樣的需求,用RMAN來恢複某幾張表的資料就顯的特別費勁了。於是我決定用Oracle資料庫的邏輯備份工具EXPDP(資料泵匯出)專門匯出特定使用者下的所有表的資料,並在每天淩晨4點通過LINUX作業系統的CRONTAB的計劃任務定時執行來完成。這樣,開發人員再有需要恢複某幾張表的時候,直接用IMPDP(資料泵匯入)工具匯入某些表即可。這裡,千萬注意,匯入時一定要加參數REMAP_TABLE,其目的在於給要匯入的表起一個和原表容易區分的名字,避免覆蓋原表的資料。建議命名方式為原表名_當前日期,這樣可讀性更強。見參數REMAP_TABLE使用說明:
650) this.width=650;" src="https://s1.51cto.com/wyfs02/M02/8D/FF/wKioL1iy2vnh8ll-AAA9Nj2z6tA976.png-wh_500x0-wm_3-wmp_4-s_4282534755.png" title="11.png" alt="wKioL1iy2vnh8ll-AAA9Nj2z6tA976.png-wh_50" />
650) this.width=650;" src="https://s2.51cto.com/wyfs02/M00/8D/FF/wKioL1iy2xWiC9W6AAAUT1bE6AE284.png-wh_500x0-wm_3-wmp_4-s_139014653.png" title="12.png" alt="wKioL1iy2xWiC9W6AAAUT1bE6AE284.png-wh_50" />
上面是解決了能夠滿足開發人員要恢複某些表的問題,但這樣的匯出檔案(*.DMP)每天產生的容量就很大,而且是存放在本地,可想而知,本地的儲存空間容量有限,也不能一直保留每天產生的DMP檔案,時間長了,伺服器的磁碟儲存空間會撐爆滴。於是,採用一種DMP檔案的清除保留原則,即在本地僅保留一份當天的DMP資料泵匯出檔案,把當天的DMP檔案通過SCP命令遠程複製到另一台LINUX伺服器(專門存放DMP檔案,容量有50T,每塊磁碟3.6T,共有14塊磁碟),複製完以後,同時清除昨天的DMP檔案,讓本機伺服器始終保留一份當天的DMP檔案,這樣本機伺服器的磁碟空間容量的問題就迎刃而解了。
如果每天手工用SCP命令複製的話,至於查看複製了多少,什麼時候覆制完,也是一個不可控的環節。在這裡把SCP命令的操作寫到一個SHELL指令碼裡同時產生複製進度的記錄檔,並每天定時執行這個SH指令碼,不用人工去幹預,這樣效率就大大提高了。
由於遠程伺服器的磁碟空間也就那麼多50T左右,其中每一塊磁碟有3.6T,當第一塊磁碟的空間不多的時候,比如把昨天的DMP檔案複製到這塊磁碟以後,它的可用空間已佔93%,也就是剩餘空間只有7%時,今天產生的DMP檔案應該存放到第二塊磁碟了。所以這種情況,應該在SH指令碼中必須進行條件判斷。也就是要查看當前使用磁碟的剩餘空間還有多少G,以及當天產生的DMP檔案總共有多少G,前者的容量應該大於後者的容量,才能將這些DMP檔案儲存在這塊磁碟裡。否則,說明該塊磁碟空間不足,必須將DMP檔案儲存在下一塊磁碟裡。
當然,要讀取遠程伺服器的當前儲存DMP檔案所在磁碟的剩餘空間的容量,就要使用SSH串連遠程伺服器,如果本機伺服器沒有配置SSH信任遠程伺服器的功能,要SSH串連遠程伺服器時,需要輸入遠程伺服器的密碼才能串連,這就是所謂的伺服器之間的互動現象。而在我們下面即將展現的SH指令碼當中是不允許出現互動情形的,否則,就喪失了指令碼的自動化功能。
為此,我們先配置本機伺服器SSH信任遠程伺服器的功能,讓本機伺服器使用SSH命令能夠直接連到遠程伺服器。操作步驟見所示:
650) this.width=650;" src="https://s2.51cto.com/wyfs02/M00/8D/FF/wKioL1iy3CuR1caSAABZ_8m2Pho848.png-wh_500x0-wm_3-wmp_4-s_1448388675.png" title="1.png" alt="wKioL1iy3CuR1caSAABZ_8m2Pho848.png-wh_50" />
上面箭頭指示的3個地方,都直接斷行符號即可。將本機伺服器產生的SSH公開金鑰檔案內容複寫到遠程伺服器時,報錯了。
650) this.width=650;" src="https://s3.51cto.com/wyfs02/M02/8D/FF/wKioL1iy3IaA-Kz0AAANV9uVTuo602.png-wh_500x0-wm_3-wmp_4-s_3959494843.png" title="3.png" alt="wKioL1iy3IaA-Kz0AAANV9uVTuo602.png-wh_50" />
經過查詢Google文檔,發現是沒有用參數-i指定本機伺服器產生的SSH公開金鑰檔案,查看當前伺服器的作業系統是RedHat Linux Server 5.4 x86_64。(而在CentOS 6.6 Server x86_64的作業系統上,直接就可以使用ssh-copy-id 遠程主機名稱 而不報錯)其中,查詢Google的操作步驟見,
650) this.width=650;" src="https://s4.51cto.com/wyfs02/M00/8E/01/wKiom1iy3PKAxXNVAACgVX0TTmI873.png-wh_500x0-wm_3-wmp_4-s_3357526183.png" title="4.png" alt="wKiom1iy3PKAxXNVAACgVX0TTmI873.png-wh_50" />
650) this.width=650;" src="https://s1.51cto.com/wyfs02/M02/8E/01/wKiom1iy3RKx5NpAAAEU7bXTUEk171.png-wh_500x0-wm_3-wmp_4-s_331821710.png" title="5.png" alt="wKiom1iy3RKx5NpAAAEU7bXTUEk171.png-wh_50" />
650) this.width=650;" src="https://s4.51cto.com/wyfs02/M00/8D/FF/wKioL1iy3TDRH2_jAACF0PDKZ7I431.png-wh_500x0-wm_3-wmp_4-s_702992998.png" title="6.png" alt="wKioL1iy3TDRH2_jAACF0PDKZ7I431.png-wh_50" />
現在將本機伺服器產生的SSH公開金鑰檔案內容複寫到遠程伺服器,輸入yes斷行符號,並輸入遠程伺服器的oracle使用者的密碼。見所示,
650) this.width=650;" src="https://s4.51cto.com/wyfs02/M01/8E/01/wKiom1iy3YCRAeprAABgOLJEJIs636.png-wh_500x0-wm_3-wmp_4-s_2839507760.png" title="7.png" alt="wKiom1iy3YCRAeprAABgOLJEJIs636.png-wh_50" />
下面用SSH命令直接連接遠程伺服器,如,
650) this.width=650;" src="https://s3.51cto.com/wyfs02/M02/8D/FF/wKioL1iy3l7RI0ZiAAAPmWi4hFs444.png-wh_500x0-wm_3-wmp_4-s_1400922439.png" title="9.png" alt="wKioL1iy3l7RI0ZiAAAPmWi4hFs444.png-wh_50" />
在配置了本機伺服器SSH信任遠程伺服器的功能以後,下面把通過SCP命令遠程複製EXPDP檔案的SH指令碼內容展示一下,嘿嘿!
由於該SH指令碼內容過多,所以我把它分成四部分來介紹,
1.個人資訊(算是給自己做一個宣傳吧)、指令碼的名字和一些功能介紹以及使用注意事項,見,
650) this.width=650;" src="https://s2.51cto.com/wyfs02/M00/8E/01/wKiom1iy3sjzLU1OAADQafM83V0472.png-wh_500x0-wm_3-wmp_4-s_3860437069.png" title="13.png" alt="wKiom1iy3sjzLU1OAADQafM83V0472.png-wh_50" />
2.匯入Oracle使用者下的.bash_profile環境設定檔和定義所有要使用的SHELL外部變數所在絕對路徑的全域變數,見所示,
650) this.width=650;" src="https://s1.51cto.com/wyfs02/M00/8E/01/wKiom1iy3y3wcHt1AABcPSSknks831.png-wh_500x0-wm_3-wmp_4-s_2405507566.png" title="14.png" alt="wKiom1iy3y3wcHt1AABcPSSknks831.png-wh_50" />
3.切換到DMP檔案所在的目錄、定義 當前日期和DMP檔案所在目錄總容量的SHELL全域變數、遠程伺服器磁碟字串、SCP命令產生的LOG檔案等,見,
650) this.width=650;" src="https://s4.51cto.com/wyfs02/M00/8D/FF/wKioL1iy33-h7QomAABmZTIINiQ570.png-wh_500x0-wm_3-wmp_4-s_3438697065.png" title="15.png" alt="wKioL1iy33-h7QomAABmZTIINiQ570.png-wh_50" />
4.定義全域函數SCP_EXPDP_PARALLEL(帶並行匯出DMP檔案的SCP複製功能),並在最後進行調用它,見,
其中,在整個函數裡,使用了兩層FOR迴圈,外層是用來切換 遠程伺服器 的下一塊磁碟,內層是用來複製 當天產生的DMP檔案內容,並把前一天的DMP檔案全部清除,因為本機伺服器的磁碟儲存空間有限,採用只保留當天的DMP檔案,所以每次查看EXPDP目錄,你會發現只有一份當天的DMP檔案,這樣也就達到了我要實現的目的。
紅色標註的那個IF條件判斷語句,就是我在前面說明的磁碟空間容量比較,如果遠程伺服器上當前所在磁碟的剩餘可用空間容量 大於 本機伺服器上當天的DMP檔案總容量,就把DMP檔案複製到這塊磁碟,否則,就執行else語句裡的continue命令,即跳出本次內層for迴圈,讀取下一塊磁碟,把DMP檔案複製到下一塊磁碟。
那麼,SCP命令在執行過程中的複製進度百分比是在每時每刻都變化著的,這個過程是無法直接寫到LOG記錄檔裡的,不信大家試一試?
這裡,必須用SCRIPT命令隨時抓取SCP命令執行的變化值並記錄到相應的LOG記錄檔,即在SCRIPT命令後面使用“-a參數 LOG檔案位置”來實現將變化值追加寫到LOG檔案,而在SCRIPT命令後面使用“-c參數 SCP命令”來實現遠程複製操作。
650) this.width=650;" src="https://s2.51cto.com/wyfs02/M02/8E/02/wKiom1iy4DSiRMJsAAB4KMIYLQA123.png-wh_500x0-wm_3-wmp_4-s_3664563069.png" title="16.png" alt="wKiom1iy4DSiRMJsAAB4KMIYLQA123.png-wh_50" />
如果您覺得此篇文章對您有協助,歡迎關注公眾號:guestart的DBA學習筆記,您的支援是對我最大的鼓勵!
650) this.width=650;" src="https://s2.51cto.com/wyfs02/M00/8E/02/wKiom1iy4KaSp_hbAADnPdGUWRk770.jpg" title="訂閱號二維碼.jpg" alt="wKiom1iy4KaSp_hbAADnPdGUWRk770.jpg" />
本文出自 “藍色憂鬱” 部落格,轉載請與作者聯絡!
利用SHELL指令碼實現將Oracle資料庫的每日EXPDP匯出檔案複製到遠程伺服器