Oracle

Oracle备份与恢复线上实战

浅时光博客 · 2月14日 · 2020年 · 13.5w 次已读

一、查看逻辑目录


查看管理员目录是否存在

[root@localhost ~]# su - oracle
[oracle@localhost ~]$ sqlplus "/as sysdba"

SQL> select * from dba_directories;

二、执行备份


举例:某用户对象占用了4G左右的空间,实际导出后的DUMP文件约为3G,我们尝试在导出该用户时指定并行度为4,设置单个文件原文链接:https://dqzboy.com不超过1G,则语法如下

# 以下方式为全库备份
[root@localhost ~]# su - oracle
[oracle@localhost ~]$ expdp 用户/密码 directory=dump_dir dumpfile=expdp_20200216_%U.dmp logfile=expdp_20200216.log filesize=1G parallel=4 full=y

参数说明:

  • expdp: 数据泵 ,服务端工具, 只能在oracle服务端使用,不能在客户端使用; 并行导出,比exp速度快,但是所有用expdp导出的dmp文件只能用impdp的方式导入
  • filesize:指定每个dmp文件的大小
  • parallel:并行进行备份,必须结合filesize参数使用,不然会触发ORA-39095错误,parallel的值的定义可以通过show parameter cpu查看CPU核数进行设置
  • %U:如果指定了filesize参数,则每个导出的 dump 文件都会有一个大小上限,并且不可扩展。如果 dump 文件集需要更多的空间,使用了 %U 替换变量,则只要存储设备上空间足够将自动新建一个filesize参数所指定的大小的 dump 文件
  • full:全库备份

  • 可以通过schemas按用户导出
    • 如果按用户导出语句如下:
[oracle@localhost ~]$ expdp user/passwd@orcl schemas=user dumpfile=expdp_20200216_%U.dmp directory=dump_dir logfile=expdp.log filesize=1G parallel=4

三、编辑脚本


[oracle@localhost ~]$ vim oracle_bak.sh
#!/bin/bash
SJ=`date '+%Y%m%d'`
expdp 用户/密码 directory=dump_dir dumpfile=expdp_${SJ}_%U.dmp logfile=expdp_${SJ}.log filesize=1G parallel=4 full=y

cd /home/oracle/backup
tar -czf expdp_${SJ}.tar.gz expdp_${SJ}_*.dmp

#本机保留7天dmp数据
find /home/oracle/backup -name "*.dmp" -mtime +7 -exec rm -rf {} \;
find /home/oracle/backup -name "*.log" -mtime +7 -exec rm -rf {} \;
find /home/oracle/backup -name "*.tar.gz" -mtime +7 -exec rm -rf {} \;

# 脚本测试没问题够,就可以结合crontab进行定时备份了

四、执行导入


注意:导入时,需要将导出的dmp文件保存在逻辑目录对应的真实系统目录下,不然导入提示没有这个文件或目录

[oracle@localhost ~]$ cd /home/oracle/backup
[oracle@localhost backup]$ impdp 用户/密码 directory=dump_dir dumpfile=expdp_20200216_01.dmp, expdp_20200216_02.dmp, expdp_20200216_03.dmp, expdp_20200216_04.dmp logfile=impdp_20200216.log parallel=5

五、恢复至新实例


  • 导入的前提条件
    • oracel server端的字符集; oracle client端的字符集; dmp文件的字符集
    • 在做数据导入的时候,需要这三个字符集都一致才能正确导入

1:查看源实例表空间

[root@localhost ~]# su - oracle
[oracle@localhost ~]$ sqlplus "/as sysdba"
  • 查看表空间名称以及大小
SQL> select t.tablespace_name,round(sum(bytes/(1024*1024)),0)ts_size from dba_tablespaces t,dba_data_files d where t.tablespace_name = d.tablespace_name group by t.tablespace_name;
  • 查看表空间物理文件的名称及大小
SQL> select tablespace_name,file_id, file_name,round(bytes/(1024*1024),0) total_space from dba_data_files order by tablespace_name;

2:新实例创建表空间

SQL> CREATE TABLESPACE YPST_SCM DATAFILE '/home/oracle/app/oradata/orcl/YPST_SCM.DBF' SIZE 20G AUTOEXTEND ON;

3:查看源实例字符集

SQL> select userenv('language') from dual;

4:修改新实例字符集

4.1、修改server端字符集(不建议使用)

  • 关闭数据库
SQL>SHUTDOWN IMMEDIATE;
  • 启动到Mount
SQL> STARTUP MOUNT;
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL> ALTER DATABASE OPEN;
  • 出现报错:
ORA-12712: new character set must be a superset of old character set
  • 解决方案:强制转换
SQL> ALTER DATABASE character set INTERNAL_USE ZHS16GBK;

注意:这样很可能让你的数据库中原有的中文显示乱码,所文章来源(Source):https://dqzboy.com以还请慎重

  • 如果是从子集到父集,需要使用INTERNAL_USE 参数,跳过超子集检测
SQL> ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK;
SQL> ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE ZHS16GBK;

SQL>SHUTDOWN IMMEDIATE;
 
SQL>STARTUP
  • 再次查看server端字符集
SQL> select userenv('language') from dual;

4.2、客户端字符集设置方法

# 编辑oracle用户的profile文件
[oracle@localhost ~]$ vim /home/oracle/.bash_profile
NLS_LANG=AMERICAN_AMERICA.ZHS16GBK; 
export NLS_LANG
[oracle@localhost ~]$ source /home/oracle/.bash_profile
[oracle@localhost ~]$ echo $NLS_LANG
AMERICAN_AMERICA.ZHS16GBK

5:新实例创建备份目录

  • 注意:
    • 1、与第一步中在源实例中查看到的管理员目录保持一致
    • 2、目标库不须先建立相应用户,impdp导入会自动创建相应用户
# su - oracle
$ mkdir /home/oracle/backup
用管理员身份登录到sqlplus
$ sqlplus /nolog
SQL> conn sys/oracle as sysdba
创建逻辑目录
SQL> create directory dump_dir as '/home/oracle/backup';
查看管理员目录是否存在
SQL> select * from dba_directories;

6:执行导入dmp文件

  • 注意1:将备份文件拷贝至新实例所在的机器中,主要一定拷贝至数据库中指定的逻辑目录下,不然导入会失败,提示找不到文件;我这里逻辑目录对应的物理目录为/home/oracle/backup,我将备份的dmp文件都传至该目录下
  • 注意2:parallel参数只有但你导出的文件有多个时,导入的时候加该参数才有意义,如果导出的备份文件只有一个,那么导入的时候添加该参数将失去意义
[oracle@localhost ~]$ impdp 用户/密码 directory=dump_dir dumpfile=expdp_20200216_01.dmp, expdp_20200216_02.dmp, expdp_20200216_03.dmp, expdp_20200216_04.dmp logfile=impdp_20200216.log parallel=5

本文作者:浅时光博客
原文链接:https://www.dqzboy.com/615.html
版权声明:知识共享署名-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)协议进行许可,转载时请以>超链接形式标明文章原始出处和作者信息
免责声明:本站内容仅供个人学习与研究,严禁用于商业或非法目的。请在下载后24小时内删除相应内容。继续浏览或下载即表明您接受上述条件,任何后果由用户自行承担。

9 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!

  1. kiingen未知2020-9-6 · 20:59

    然后全库迁移过来路径就是修改的路径位置

    • 浅时光博客2020-9-6 · 21:08

      通过命令修改:alter database rename file ‘/源/xx.dbf’ to ‘/目标/xx.dbf’;

      • kiingen未知2020-9-6 · 21:09

        谢谢

        • 浅时光博客2020-9-6 · 21:11

          客气了哈,有问题留言,看到了我会及时回复的

  2. kiingen未知2020-9-6 · 20:58

    请问源数据库怎么修改全库迁移中的datafile文件路径

  3. kingen未知2020-9-6 · 20:26

    请问原库中的datafile(*.DBF文件)和全库备份文件,在迁移数据库的时候怎么指定dbf文件路径(需要把dbf文件放到dump_dir下面),使用select name from v$datafile; 查看的时候dump文件和datafile都在同意目录下

    • 浅时光博客2020-9-6 · 20:55

      需要在源数据库上进行修改

  4. kingen未知2020-9-6 · 20:21

    请问下 impdp 全库导入的时候是不是需要把原库datafile文件也要拷贝到迁移的机器放到dump_dir下面,或者是导入全库的时候怎么指定datafile目录

    • 浅时光博客2020-9-7 · 0:05

      导入到新机器实例时,保证数据库字符集,数据目录与源数据库实例一致即可