我們有一套生產環境的Oracle數據庫,雖然每天都有RMAN備份,但是也招架不住開發人員隔三差五就說要恢復幾張表的前幾天的數據到生產環境當中,針對這樣的需求,用RMAN來恢復某幾張表的數據就顯的特別費勁了。于是我決定用Oracle數據庫的邏輯備份工具EXPDP(數據泵導出)專門導出特定用戶下的所有表的數據,并在每天凌晨4點通過LINUX操作系統的CRONTAB的計劃任務定時執行來完成。這樣,開發人員再有需要恢復某幾張表的時候,直接用IMPDP(數據泵導入)工具導入某些表即可。這里,千萬注意,導入時一定要加參數REMAP_TABLE,其目的在于給要導入的表起一個和原表容易區分的名字,避免覆蓋原表的數據。建議命名方式為原表名_當前日期,這樣可讀性更強。見下圖參數REMAP_TABLE使用說明:
上面是解決了能夠滿足開發人員要恢復某些表的問題,但這樣的導出文件(*.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命令能夠直接連到遠程服務器。操作步驟見下圖所示:
上面箭頭指示的3個地方,都直接回車即可。將本地服務器生成的SSH公鑰文件內容復制到遠程服務器時,報錯了。
經過查詢Google文檔,發現是沒有用參數-i指定本地服務器生成的SSH公鑰文件,查看當前服務器的操作系統是RedHat Linux Server 5.4 x86_64。(而在CentOS 6.6 Server x86_64的操作系統上,直接就可以使用ssh-copy-id 遠程主機名 而不報錯)其中,查詢Google的操作步驟見下圖,
現在將本地服務器生成的SSH公鑰文件內容復制到遠程服務器,輸入yes回車,并輸入遠程服務器的oracle用戶的密碼。見下圖所示,
下面用SSH命令直接連接遠程服務器,如下圖,
在配置了本地服務器SSH信任遠程服務器的功能以后,下面把通過SCP命令遠程復制EXPDP文件的SH腳本內容展示一下,嘿嘿!
由于該SH腳本內容過多,所以我把它分成四部分來介紹,
1.個人信息(算是給自己做一個宣傳吧)、腳本的名字和一些功能介紹以及使用注意事項,見下圖,
2.導入Oracle用戶下的.bash_profile環境配置文件和定義所有要使用的SHELL外部變量所在絕對路徑的全局變量,見下圖所示,
3.切換到DMP文件所在的目錄、定義 當前日期和DMP文件所在目錄總容量的SHELL全局變量、遠程服務器磁盤字符串、SCP命令生成的LOG文件等,見下圖,
4.定義全局函數SCP_EXPDP_PARALLEL(帶并行導出DMP文件的SCP復制功能),并在最后進行調用它,見下圖,
其中,有3點需要關注,
(1)在整個函數里,使用了兩層FOR循環,外層是用來切換 遠程服務器 的下一塊磁盤,內層是用來復制 當天生成的DMP文件內容,并把前一天的DMP文件全部清除,因為本地服務器的磁盤存儲空間有限,采用只保留當天的DMP文件,所以每次查看EXPDP目錄,你會發現只有一份當天的DMP文件,這樣也就達到了我要實現的目的。
(2)紅色標注的那個IF條件判斷語句,就是我在前面說明的磁盤空間容量比較,如果遠程服務器上當前所在磁盤的剩余可用空間容量 大于 本地服務器上當天的DMP文件總容量,就把DMP文件復制到這塊磁盤,否則,就執行else語句里的continue命令,即跳出本次內層for循環,讀取下一塊磁盤,把DMP文件復制到下一塊磁盤。
(3)SCP命令在執行過程中的復制進度百分比是在每時每刻都變化著的,這個過程是無法直接寫到LOG日志文件里的,不信大家試一試?這里,必須用SCRIPT命令隨時抓取SCP命令執行的變化值并記錄到相應的LOG日志文件,即在SCRIPT命令后面使用“-a參數 LOG文件位置”來實現將變化值追加寫到LOG文件,而在SCRIPT命令后面使用“-c參數 SCP命令”來實現遠程復制操作。
以上就是我分享的全部內容,另外,我把那個SHELL腳本scp_expdp_parallel_local_to_remote.sh的源代碼,大家如果需要可自行下載。