天天看點

Oracle 資料庫備份實戰

最近公司的客戶希望使用oracle資料庫,是以我們隻好将資料從mysql資料庫遷移到oracle資料庫,并對oracle資料庫制定了一個備份政策,之前雖然對oracle很熟悉,但做備份政策還是第一次,是以詳細記錄下來并分享,歡迎大家指教。我們使用rman進行熱備份,并啟用了閃回表。平時在操作重要資料前,還會通過資料泵(expdp/impdp)進行一次邏輯備份。

備份模式

實體備份與邏輯備份

實體備份: 實體備份是磁盤塊為基本機關将資料從主機複制到備機。

邏輯備份: 邏輯備份是以檔案為基本機關将資料從主機複制到備機,通過sql或者flatfile檔案為中轉進行遷移。

高效性:

實體備份是位于檔案系統之下和硬體磁盤驅動之上。增加了一個軟驅動,它忽略了檔案和結構,處理過程簡潔,是以在執行過程中所花費在搜尋操作上的開銷較少,備份的性能很高。

邏輯備份是基于檔案級别的備份,由于每個檔案都是由不同的邏輯塊組成。每一個邏輯的檔案塊存儲在連續的實體磁盤塊上,但組成一個檔案的不同邏輯塊極有可能存儲在分散的磁盤塊上。邏輯備份在對非連續存儲磁盤上的檔案進行備份時需要額外的查找操作。這些額外的操作增加了磁盤的開銷,降低了磁盤的吞吐率。是以,跟實體備份相比較,備份性能較差。

實體備份避免了當檔案出現一個小的改動的時候,就需要對整個檔案做備份,隻是會去做改動部分的備份,有效的提高了備份效率,節省了備份時間。

邏輯備份模式下,檔案即使一個很小的改變,也需将整個檔案備份。這樣如果一個檔案很大的情況下,就會大幅度的降低備份效率,增加磁盤開銷和備份時間。

實時性:

實體備份可以做到高效的實時備份,因為在每次主機往磁盤寫資料的時候,都需要同時将資料寫入到備機,這種寫入操作都是基于磁盤扇區的,是以,很快就能被識别。隻有在備機完成之後,才會傳回給上層的應用系統來繼續下一步工作。

邏輯備份是很難做到實時備份的,因為它的每次修改都是基于檔案的,而檔案的哪部分被修改,系統很難實時捕獲到,是以備份的時候需要把整個檔案讀一遍再發到備機 ,實時的效率不是很高。

支援度:

實體備份是在檔案系統之下對資料進行複制,是以它不受檔案系統限制,可以支援各種檔案系統包括RAW分區。

邏輯備份是以單個檔案為機關對資料進行複制,是以它受檔案系統限制,僅能對部分支援的檔案系統做備份,不支援RAW分區。

(原文摘自:https://yq.aliyun.com/articles/167057?utm_content=m_28176)

備份方式

資料泵備份、熱備份和冷備份

資料泵備份

屬于邏輯備份,以檔案為備份機關,expdb的導出模式有:

1、表模式:導出使用者所有表或者指定的表。

2、使用者模式:導出使用者所有對象以及對象中的資料。

3、導出表空間:導出資料庫中特定的表空間。

4、整個資料庫:導出資料庫中所有對象。

我們以使用者模式為例:

1、建立邏輯目錄,該指令不會在作業系統建立真正的目錄(要先建立真正的目錄),最好以system等管理者建立邏輯目錄。

SQL> sqlplus root/root@orcl

SQL> conn as sysdba;(輸入sys使用者名、密碼)

SQL> create directory dump_dir as \'/data/exp+imp\';

2、檢視管理者目錄(作業系統下該目錄必須存在,假如不存在,則出錯)

SQL>select * from dba_directories;

3、給root使用者賦予在指定目錄的操作權限,最好以system等管理者賦予。

SQL>grant read,write on directory dump_dir to root;

4、導出資料

expdp root/root@orcl schemas=root dumpfile=expdp201810291556.dmp log=expdp201810291556.log directory=dump_dir;

5、導入資料

在另一台主機需要建相同的檔案夾dump_dir,從使用者root導入到使用者root,不同使用者使用REMAP_SCHEMA=orcldev:orcltwo。

impdp root/root@orcl directory=dump_dir dumpfile=expdp201810291556.dmp schemas=root table_exists_action=replace

實際在使用expdb/impdb時有很多參數可以選擇,這裡不多講述,大家自行參考oracle相關資料。

(參考部落格:http://lizhiyu.iteye.com/blog/2203081)

熱備份和冷備份

冷備份指在資料庫系統shutdown之後,使用作業系統的指令對表空間進行拷貝進行備份。冷備份隻能恢複到之前的某一備份點,而該備份點到出現問題之間這段時間的資料是無法恢複的。

熱備份指在資料庫系統不停機的情況下進行備份。熱備份隻能在歸檔模式下進行。熱備份可以在資料庫系統崩潰時根據歸檔日志恢複到之前的任一時間點。熱備份通常用于資料的重要性較高、資料庫系統為7 X 24不間歇工作模式時。

我們使用RMAN來實作熱備份。RMAN可以用來備份和還原資料庫檔案、歸檔日志和控制檔案。它也可以用來執行完全或不完全的資料庫恢複。但RMAN不能用于備份初始化參數檔案和密碼檔案。RMAN備份和還原的實質是去啟動oracle中的程序,使用驅動程序去備份和還原資料。

       在進行熱備份時我們會同時備份控制檔案、資料檔案、重做日志。

資料檔案:

每一個Oracle資料庫都要有一個或者多個實體的資料檔案,這些資料檔案裡存儲的就是Oracle資料庫裡的資料。就好比你有一個檔案夾,裡面有幾個txt的文本檔案,文本檔案裡記錄的你這個月的每一筆花銷。如果把檔案夾看做是資料庫,那麼txt檔案就是資料檔案,而txt檔案裡面記錄的每一筆花銷就是資料了。

然而表、索引等等其實都是資料庫的邏輯結構,這些表、索引都被實體的存儲在了資料檔案裡面。

資料檔案有三個特性:

1、一個資料檔案隻能屬于一個資料庫。

2、資料庫中的資料檔案可以被設定成自動的增長。

3、一個或者多個資料檔案就組成了資料庫的一個邏輯單元叫做---表空間。

資料檔案裡的資料,在需要的時候就會被讀取到内容Oracle的緩沖區中,比如當我們想檢視一天資料時,而這條資料恰好又不在Oracle的緩沖區中,那麼Oracle就會把這條資料從資料檔案中讀取到Oracle的緩沖區中來。

當更改或者新增一天資料時,也不是馬上就寫到資料檔案裡面,這麼做是為了減少對磁盤的通路,提高效率,資料先存儲在緩沖區,然後在一次都寫入資料檔案,這個過程有一個dbwn背景程序來控制。

控制檔案:

每一個資料庫都擁有控制檔案,它和資料檔案一樣重要。控制檔案裡記錄的是對資料庫實體結構的詳細資訊,例如它包括如下三個資訊:

1、資料庫的名稱

2、資料檔案的名字和存在位置,重做日志檔案的名字和存儲位置

3、資料庫建立的時間辨別

Oracle可以使用多重的控制檔案,也就是說它可以同時維護多個完全一樣的控制檔案,這麼做就是為了防止資料檔案損壞而造成的資料庫故障。比如Oracle同時維護3個控制檔案,當其中有1個控制檔案出問題了,就比較好解決,把出問題的删了,在複制一份沒有問題的就可以了。

每當Oracle資料庫的執行個體啟動的時候,它就會通過控制檔案來識别,要想執行資料庫的一些操作,必須需要哪些資料檔案和重做日志檔案,以及這些資料檔案和重做日志檔案都存在在什麼位置。當資料庫的實體構成發生改變的時候,比如新增加了一個資料檔案或者重做日志檔案,那麼控制檔案就會自動的更新來記錄這些變化。另外在資料庫恢複的時候也會用到控制檔案。

重做日志檔案:

每個Oracle資料庫都擁有一組檔案,其中包括2個或者多個重做日志檔案(其實也可以擁有多組,用途跟多個控制檔案一樣)。這組檔案整體被稱為資料庫的重做日志,而重做日志又是由一條一條的重做記錄組成的,所有也被稱為重做記錄。

重做日志的主要作用就是記錄所有的資料變化,當一個故障導緻被修改過的資料沒有從記憶體中永久的寫到資料檔案裡,那麼資料的變化是可以從重做日志中獲得的,進而保證了對資料修改的不丢失。

為了防止重做日志自身的問題導緻故障,是以Oracle擁有多重重做日志功能,也就是可以同時儲存多組完全相同的重做日志在不同的磁盤上。

重做日志裡的資訊隻是用于恢複由于系統或者媒體故障所引起的資料沒法寫入資料檔案的資料。比如突然斷電導緻資料庫的關閉,那麼記憶體中的資料就不能寫入到資料檔案中,記憶體中的資料就會丢失。但當資料庫重新啟動時丢失的資料是可以被恢複的,可以從最近的重做日志中讀取丢失資訊然後應用到資料檔案中,這樣就把資料庫恢複到斷電前的狀态。

在恢複操作中恢複重做日志資訊的過程叫做復原。

熱備步驟

--show parameter db_name;
--sqlplus以sysdba身份連接配接orcl
conn /@orcl as sysdba;
--重新開機監聽:lsnrctl stop/lsnrctl start 

--1、開啟歸檔模式(sqlplus工具,sys使用者)
    --檢視閃回恢複區的資訊。
    show parameter db_recover
    --增大閃回恢複區
    alter system set db_recovery_file_dest_size=3G;
    --修改歸檔日志的存放路徑
    alter system set log_archive_dest_1=\'location=/data/oracleArchive\';
    
    
    --檢視目前日志操作模式
    SELECT log_mode from v$database;
    --啟用歸檔日志前要先停止資料庫
    shutdown immediate;
    --資料庫以mount方式啟動
    startup mount;
    --啟用資料庫歸檔
    alter database archivelog;
    --打開資料庫
    alter database open;
    --檢視歸檔日志資訊
    archive log list;

--2、開啟補充日志
    --檢視目前資料庫中補充日志狀态
    select SUPPLEMENTAL_LOG_DATA_MIN min,
       SUPPLEMENTAL_LOG_DATA_PK  pk,
       SUPPLEMENTAL_LOG_DATA_UI  ui,
       SUPPLEMENTAL_LOG_DATA_FK  fk,
       SUPPLEMENTAL_LOG_DATA_ALL "all"
    from v$database;
    --最小補充日志是最基本的一種資料庫級補充日志,
    --啟用最小補充日志
    alter database add supplemental log data ;
    --關閉最小補充日志
    --alter database drop supplemental log data ;
    --主鍵補充日志
    alter database add supplemental log data (primary key) columns ;
    --唯一索引補充日志
    alter database add supplemental log data (unique) columns ;
    --外鍵補充日志
    alter database add supplemental log data (foreign key) columns ;
    --全體字段補充日志
    alter database add supplemental log data (all) columns;

--3、資料庫備份,方式為全庫方式
  --檔案結構:
  /data/oracleArchive
  /data/rmanbak/rman_ts
  /data/rmanbak/log
  /data/oracleBackup
  /data/oracleBackup/backup1
  /data/oracleBackup/backup2
  --a.開啟歸檔模式
  --b.建立恢複目錄的表空間rman_ts(sys使用者):
    create tablespace rman_ts datafile \'/data/rmanbak/rman_ts.dbf\' size 20G;
  --c.建立rman使用者并授權
    create user rman identified by root default tablespace rman_ts temporary tablespace temp;
    grant connect, recovery_catalog_owner, resource to rman;
  --d.建立恢複目錄
    rman catalog rman/root target orcl
    create catalog tablespace rman_ts
  --e.注冊目标資料庫
    register database;
  --f.使用rman進行完全資料庫備份:
  --自動備份需要寫腳本且定時執行,參見檔案oracle_rman_backup.sh:


  --g.使用rman進行恢複
  --歸檔日志:
  run{
    allocate channel dev1 type disk;
    restore archivelog all;
    release channel dev1;
  }
  --恢複資料庫,需要将資料庫mount或将資料檔案offline
  --rman target sys/root@orcl
  --rman> shutdown immediate
  --rman> startup mount
  --RMAN> restore database; --恢複到某一備份
  --RMAN> recover database; --從某一備份根據重做日志恢複到指定時間點
  --RMAN> alter database open;
  run{
    allocate channel dev1 type disk;
    set until time "to_date(\'2018-09-21 14:45:50\',\'yyyy-mm-dd hh24:mi:ss\')";--可以設定恢複到某一時間點
    restore database;
    recover database;
    release channel dev1;
  }

  --select * from equ as of timestamp to_timestamp(\'2018-09-21 14:45:50\',\'yyyy-mm-dd hh24:mi:ss\');
  --flashback table equ to timestamp(to_date(\'2018-09-26 14:45:50\',\'yyyy-mm-dd hh24:mi:ss\'));  --根據閃回表恢複指定表的資料到指定時間點      
oracle_rman_backup.sh      
#在node1每晚進行全量備份,同時删除過期備份和歸檔日志檔案
#!/bin/bash
ORACLE_SID=ORCL
ORACLE_HOME=/data/oracle/product/11.2.0/db_1
ORACLE_BASE=/data/oracle
export ORACLE_SID
export ORACLE_HOME
export ORACLE_BASE
backtime=`date +%Y%m%d`
echo $backtime
$ORACLE_HOME/bin/rman target sys/root@orcl log=/data/rmanbak/log/node1_backupall_$backtime.log<<EOF
run{
    configure default device type to disk;
    configure device type disk parallelism 2;
    configure channel 1 device type disk format \'/data/oracleBackup/back1/backup_%U\';
    configure channel 2 device type disk format \'/data/oracleBackup/back2/backup_%U\';
    configure controlfile autobackup on;
    configure controlfile autobackup format for device type disk to \'/data/oracleBackup/back1/ctl_%F\';
    configure retention policy to recovery window of 7 days;
}
run{ 
    backup database ;
    backup archivelog all  delete input;
    report obsolete; 
    delete noprompt  obsolete; 
    crosscheck backup;
    crosscheck archivelog all;
    delete noprompt expired backup;
}
EOF
echo "backup complete!"
#當有多個節點進行備份時互相copy日志
#scp /oracle/rmanbak/log/node1_backupall_$backtime.log oracle@OracleNode2:/oracle/rmanbak/log/
exit



#RAC rman backup scripts
#每晚1點開始備份
##crontab -e
##0 1 * * * /data/rmanbak/oracle_rman_backup.sh >> /data/rmanbak/log/oracle_rman_backup.log      

參考:

部落格:http://lizhiyu.iteye.com/blog/2203081

https://yq.aliyun.com/articles/167057?utm_content=m_28176