亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

oracle學習筆記

發布時間:2020-07-26 06:16:41 來源:網絡 閱讀:2402 作者:小蝦米216 欄目:關系型數據庫

oracle安裝

1.         安裝virtualbox

# yum install gcc kernel-devel kernel-headers

# yum install virtualbox-5....

# /etc/init.d/vboxdrv setup               手動編譯內核模塊,安裝時自動完成

# usermod -G vboxusers root

2.         安裝linux

創建虛擬機:

名稱:oracle11gR2_RHEL6.4_x64

類型:linux 64bit

內存:2048MB

硬盤大小:100GB

 

設置:

啟動順序:硬盤,網絡

網絡:網卡1,橋接eth0

去除聲音、usb設備

 

安裝:desktop方式

主機名:node1.test.comip使用dhcpswap4GB,其余給/

3.         調整linux系統:

關閉防火墻:

# service iptables stop

# service ip6tables stop

# chkconfig iptables off

# chkconfig ip6tables off

管理工具中disabled防火墻

關閉selinux

# vi /etc/selinux/config

SELINUX=disabled

配置yum

# rm -f /etc/yum.repos.d/*

# wget ftp://172.16.8.100/rhel6.repo -P /etc/yum.repos.d/

或者:

# vi /etc/yum.repos.d/rhel6.repo

[Server]

name=Server

baseurl=file:///media/"RHEL_6.5 x86_64 Disc 1"/Server

enabled=1

gpgcheck=0

安裝vb增強功能:

# yum -y install gcc kernel-devel

# ln -s /usr/src/kernels/2.6.32-431.el6.x86_64/ /usr/src/linux

 

設備-->安裝增強功能

右鍵eject彈出光盤

 

4.         確認root身份:

# id

5.         硬件配置:

# grep MemTotal /proc/meminfo

# grep SwapTotal /proc/meminfo

# vi /etc/fstab(永久修改)

tmpfs        /dev/shm          tmpfs        defaults,size=2G                0 0

# mount -o remount /dev/shm

臨時修改

# mount -t tmpfs shmfs -o size=2g /dev/shm

 

# uname -m

# df -h

6.         rpm檢查并安裝:

# cat /etc/redhat-release

# uname -r

 

# rpm -qa | grep glibc

# yum install glibc

# yum install glibc.i686

 

binutils-2.20.51.0.2-5.11.el6 (x86_64)

compat-libcap1-1.10-1 (x86_64)

compat-libstdc++-33-3.2.3-69.el6 (x86_64)

compat-libstdc++-33-3.2.3-69.el6.i686

gcc-4.4.4-13.el6 (x86_64)

gcc-c++-4.4.4-13.el6 (x86_64)

glibc-2.12-1.7.el6 (i686)

glibc-2.12-1.7.el6 (x86_64)

glibc-devel-2.12-1.7.el6 (x86_64)

glibc-devel-2.12-1.7.el6.i686

ksh

libgcc-4.4.4-13.el6 (i686)

libgcc-4.4.4-13.el6 (x86_64)

libstdc++-4.4.4-13.el6 (x86_64)

libstdc++-4.4.4-13.el6.i686

libstdc++-devel-4.4.4-13.el6 (x86_64)

libstdc++-devel-4.4.4-13.el6.i686

libaio-0.3.107-10.el6 (x86_64)

libaio-0.3.107-10.el6.i686

libaio-devel-0.3.107-10.el6 (x86_64)

libaio-devel-0.3.107-10.el6.i686

make-3.81-19.el6

sysstat-9.0.4-11.el6 (x86_64)

7.         創建用戶:

# groupadd -g 1000 oinstall

# groupadd -g 1001 dba

# groupadd -g 1002 oper

# useradd -u 1000 -g oinstall -G dba,oper oracle

# passwd oracle

8.         修改內核參數:

# vi /etc/sysctl.conf

fs.aio-max-nr = 1048576

fs.file-max = 6815744

kernel.shmall = 2097152

kernel.shmmax = 536870912

kernel.shmmni = 4096

kernel.sem = 250 32000 100 128

net.ipv4.ip_local_port_range = 9000 65500

net.core.rmem_default = 262144

net.core.rmem_max = 4194304

net.core.wmem_default = 262144

net.core.wmem_max = 1048576

# sysctl -p

9.         修改資源限制:

# vi /etc/security/limits.conf

oracle          soft    nofile          1024

oracle          hard    nofile          65536

oracle          soft    nproc           2047

oracle          hard    nproc           16384

oracle          soft    stack           10240

oracle          hard    stack           32768

10.     創建目錄:

# mkdir -p /u01/app/oracle

# chown -R oracle:oinstall /u01

# chmod -R 775 /u01

11.     修改概要文件:

# vi ~oracle/.bash_profile

export ORACLE_SID=orcl

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1

export ORACLE_HOSTNAME=node1.test.com

export ORACLE_UNQNAME=orcl

export PATH=$PATH:$ORACLE_HOME/bin

export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib

export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

export NLS_LANG=american_america.AL32UTF8

export NLS_DATE_FORMAT='yyyy-mm-dd hh34:mi:ss'

export EDITOR=vi

export

12.     使用hosts文件解析主機名:

# hostname

node1.test.com

# vi /etc/hosts

192.168.0.1          node1.test.com          node1

# ping node1

# ping node1.test.com

13.     解壓縮安裝包:

# cd /installation

# unzip p10404530_112030_Linux-x86-64_[12]of7.zip

或者:

在物理主機中解壓縮2個安裝包,然后共享給虛擬機,命令如下:

# mkdir /database

# mount -t vboxsf database /database

14.     圖形界面安裝:

# xhost +

# su - oracle

$ cd /database/

$ ./runInstaller

root身份執行兩個腳本

15.     創建監聽和數據庫:

圖形界面下創建監聽,oracle執行:

$ netca

$ lsnrctl status

$ netstat -tlnp | grep 1521

圖形界面創建dboracle執行:

$ dbca

16.     測試:

sqlplus測試:

$ sqlplus sys/sys@orcl as sysdba

$sqlplus/as sysdba

SQL> show user

SQL> select count(*) from hr.employees;

SQL> exit

瀏覽器測試:

https://192.168.0.1:1158/em

sys/password  sysdba

 

安裝rlwrap

root身份安裝

# yum install rlwrap-0.42-1.el6.x86_64.rpm

# vi ~oracle/.bashrc

alias sqlplus='rlwrap sqlplus'

alias rman='rlwrap rman'

 

# su - oracle

$ sqlplus / as sysdba

 

root身份安裝

# yum install flash-plugin-11.2.202.508-release.x86_64.rpm

 

sqldeveloper測試:

root身份安裝

# yum install jdk-8u51-linux-x64.rpm

# yum install sqldeveloper-4.1.1.19.59-1.noarch.rpm

 

# /usr/local/bin/sqldeveloper

輸入jdk的路徑 /usr/java/jdk1.8.0_51/

 

點左上角+號,創建新連接:

sys/password,連接類型:basic,角色:sysdba

192.168.0.1端口1521   sidorcl

測試,保存。

 

17.     添加啟動腳本:

# vi /etc/oratab  N改為Y

orcl:/u01/app/oracle/product/11.2.0/db_1:Y

 

# vi /etc/rc.d/init.d/oracle

 

#!/bin/bash

#chkconfig:35 99 01

case "$1" in

  start)

        echo -n "Starting Oracle Database& Listener:"

        su - oracle -c 'dbstart $ORACLE_HOME' >/dev/null

        echo "[ ok ]"

 

        echo -n "Starting Oracle EM dbconsole:"

        su - oracle -c "emctl start dbconsole" >/dev/null

        echo "[ ok ]"

 

        touch /var/lock/subsys/oracle

        ;;

  stop)

        echo -n "Shutting Down Oracle EM dbconsole:"

        su - oracle -c "emctl stop dbconsole" >/dev/null

        echo "[ ok ]"

 

        echo -n "Shutting Down Oracle Database& Listener:"

        su - oracle -c 'dbshut $ORACLE_HOME' >/dev/null

        echo "[ ok ]"

 

        rm -f /var/lock/subsys/oracle

        ;;

  *)

        echo "Usage: oracle {start|stop}"

        exit 1

esac

 

 

# chmod 755 /etc/rc.d/init.d/oracle

# chkconfig --add oracle

# chkconfig --list oracle

 

18.     刪除口令有效期:

#su - oracle

$ sqlplus / as sysdba

SQL> alter profile default limit PASSWORD_LIFE_TIME unlimited;

19.     修改virtualbox的網絡設置(可選):

全局設置à添加hostonly網絡,設置ip為:192.168.0.253,取消dhcplinuxonly

虛擬機網絡改為hostonly

虛擬機中將網卡的ip改為靜態,192.168.0.1

# vi /etc/sysconfig/network-scripts/ifcfg-eth0

BOOTPROTO=none

IPADDR=192.168.0.1

PREFIX=24

# ifdown eth0;ifup eth0

# vi /etc/hosts

192.168.0.1     node1.test.com        node1

SQL

select查詢語句

1.         查看hr用戶名下的表,解鎖hr用戶:

$ sqlplus / as sysdbaSQL> conn / as sysdba

SQL> show user

SQL> select table_name from dba_tables where owner='HR';

SQL> select * from hr.employees;

SQL> alter user hr account unlock identified by hr;

$ sqlplus hr/hr或者SQL> conn hr/hr

SQL> show user

SQL> select * from tab;

SQL> desc employees

 

練習:

查看scott用戶名下的表,解鎖scott用戶:

scott/tiger

2.         使用sqlplus的全屏編輯功能:

$ echo $EDITOR

SQL>select * from hr.employees;

SQL> ed

SQL> /                         執行

3.         基礎select語句:

SQL> select * from employees;

SQL> desc employees

SQL> select LAST_NAME, SALARY, COMMISSION_PCT from employees;

SQL> desc departments

SQL> select department_id, department_name from departments;

SQL> select distinct DEPARTMENT_ID from employees;

SQL> select last_name, salary*12*(1+commission_pct) total_salary, department_id from employees;

SQL> select first_name||', '||last_name from employees;

SQL> select first_name||', '||last_name fullname from employees;

 

練習:

輸出下列員工信息:

Eleni(first_name) Zlotkey(last_name) employeeid is ... at department .. total salary is …

4.         使用連字符構造語句:

SQL> select table_name from user_tables;

SQL> select 'grant select on hr.'||table_name||' to scott;' from user_tables;

 

SQL> spool /home/oracle/grant.sql

SQL> set head off 去除標題

SQL> set feed off 去除回饋

SQL> select 'grant select on hr.'||table_name||' to scott;' from user_tables;

SQL> spool off

$ vi /home/oracle/grant.sql     手動去除沒用的行,相當于除去標題和回饋,

SQL> @/home/oracle/grant.sql   執行sql腳本

5.         單引號的處理:

SQL> select 'I'm teaher' from dual;

ERROR:

ORA-01756: quoted string not properly terminated

SQL> select 'I''m teaher' from dual;

SQL> select q'{I'm teaher}' from dual;                []<>()都可以

whereorderby

數字條件:

SQL> select salary from employees where employee_id=100;

字符串大小寫敏感:

SQL> select last_name, salary from employees where last_name='King';

SQL>select table_name, tablespace_name from user_tables where table_name='EMPLOYEES';

日期是格式敏感:

SQL> alter session set nls_date_format='RR-Mon-dd';

SQL> select last_name from employees where hire_date='2006-05-23';

SQL> select last_name from employees where hire_date=to_date('2006-05-23', 'yyyy-mm-dd');

區間查詢:

SQL> select last_name from employees where salary>=3400 and salary<=4000;

SQL> select last_name from employees where salary between 3400 and 4000;

SQL> select last_name from employees where salary between 3000 and 5000 and department_id=50;

in

SQL> select last_name from employees where department_id=30 or department_id=40 or department_id=50;

SQL> select last_name from employees where department_id in (30, 40, 50);

通配符:

SQL> select last_name, job_id from employees where job_id like '%\_MAN' escape '\';禁止轉義符后面的符號的特殊含義,like _通配某一個字符,like %通配某些字符

null作為條件:

SQL> select last_name from employees where commission_pct is null;

SQL> select last_name from employees where commission_pct is not null;

and/or/not

SQL> select last_name, job_id, department_id, salary from employees where job_id='SA_REP' or department_id=50 and salary>=8000;

SQL> select last_name, job_id, department_id, salary from employees where (job_id='SA_REP' or department_id=50) and salary>=8000;

排序:

SQL> select last_name, salary from employees order by salary;升序

SQL> select last_name, salary from employees order by salary  desc;降序

SQL> select last_name, salary from employees order by last_name;

SQL> select last_name, hire_date from employees order by hire_date;

SQL> select last_name, salary, commission_pct from employees order by salary desc, commission_pct desc;

SQL> select last_name, salary*12*(1+commission_pct) from employees order by 2;

SQL> select last_name, salary*12*(1+commission_pct) total_salary from employees order by total_salary;

 

練習:

選擇部門30中的雇員

列出所有職員(CLERK)的姓名、編號和部門

找出薪金大于5000的雇員

找出獎金高于0.1的雇員

找出部門50中的所有員工和部門30中的經理的詳細資料

找出收取獎金的雇員的不同工作職位每種職位顯示一次

找出不收取獎金或收取的工資低于5000的雇員

顯示last_name不帶有'R'的雇員姓名

select last_name name from employees where not last_name like '%R%'

顯示所有雇員的姓名、工作和薪金,按工作的降序順序排序,而工作相同時按薪金升序

單行函數

SQL> select upper(first_name), lower(last_name), length(last_name) from employees;

 

SQL> select (sysdate-hire_date)/7 from employees;

SQL> select trunc((sysdate-hire_date)/30, 0) from employees;

SQL> select trunc(months_between(sysdate,hire_date), 0) from employees;

SQL> select sysdate+3650 from dual;

SQL> select add_months(sysdate, 120) from dual;

SQL> select next_day('2015-09-01', 'friday') from dual;

SQL> select next_day('2015-10-01', 6) from dual;

SQL> select last_day(sysdate) from dual;

 

SQL> select round(to_date('2015-10-10','yyyy-mm-dd'), 'MONTH') from dual;

SQL> select round(to_date('2015-10-16','yyyy-mm-dd'), 'MONTH') from dual;

SQL> select round(to_date('2015-10-10','yyyy-mm-dd'), 'YEAR') from dual;

SQL> select round(sysdate, 'DAY') from dual;

 

練習:

找出各月最后三天內受雇的所有雇員

extract(month from hire_date+4) != extract(month from hire_date)

找出早于25年之前受雇的雇員

months_between(sysdate, hire_date)/300>=25

顯示正好為6個字符的雇員姓名

length(last_name)=6

顯示所有雇員的姓名的前三個字符

substr(last_name, 1, 3)

顯示所有雇員的姓名,用a替換所有'A'

replace(last_name, 'A', 'a')

類型轉換和其他函數

SQL> select to_char(salary, '$999,999.00') from employees;

SQL> select last_name, to_char(hire_date, 'dd-Mon-RR') from employees;

SQL> select to_char(sysdate, 'yyyy-mm-dd hh34:mi:ss') from dual;

SQL> select to_char(sysdate, 'yyyy-mm-dd hh:mi:ss AM') from dual;

SQL> select last_name from employees where hire_date=to_date('2006-05-23', 'yyyy-mm-dd');

SQL> select to_number('$123,456.78', '$999,999.00') from dual;

 

練習:

查詢2006年入職員工:

select last_name

from employees

where hire_date between to_date('2006-01-01', 'yyyy-mm-dd')

and  to_date('2006-12-31', 'yyyy-mm-dd');

 

select last_name

from employees

where to_char(hire_date, 'yyyy')='2006';

 

select last_name

from employees

where extract(year from hire_date)=2006;

 

--不推薦

select last_name

from employees

where hire_date like '2006%';

 

查詢歷年9月份入職的員工:

select last_name

from employees

where to_char(hire_date, 'mm')='09';

 

select last_name from employees where extract(month from hire_date)=9;

 

其他函數:

nvl

nvl(val1, val2)

if val1 is not null

then

    return val1;

else

    return val2;

SQL> select last_name, salary*12*(1+nvl(commission_pct, 0)) total_salary from employees;

 

練習:

顯示所有員工部門編號,沒有部門的顯示“未分配部門”

select nvl(to_char(department_id),'未分配部門') from employees

 

casedecode

IT_PROG +1000

SA_REP+1500

ST_CLERK +2000

其他人工資不變

 

select salary+1000 from employees where job_id='IT_PROG';

 

select last_name, job_id, salary,

case job_id

  when 'IT_PROG' then salary+1000

  when 'SA_REP' then salary+1500

  when 'ST_CLERK' then salary+2000

  else salary

end new_salary

from employees;

 

select last_name, job_id, salary,

decode( job_id,

  'IT_PROG', salary+1000,

  'SA_REP',  salary+1500,

  'ST_CLERK', salary+2000,

  salary) new_salary

from employees;

練習:

按照員工工資,對員工分級顯示:

A       20001-25000

B       15001-20000

C       10001-15000

D      5001-10000

E       0-5000

答案:

select last_name,salary,

decode(trunc(salary/5000,0),

0,'E',

1,'D',

2,'C',

3,'B',

4,'A',

salary) n_sal

from employees

答案拓展:

select last_name,salary,

decode(trunc(salary/5000,0),

0,'E',

1,'D',

2,'C',

3,'B',

4,'A',salary) n_sal

from employees

order by salary desc,n_sal

分組函數

SQL> select count(*), sum(salary), avg(salary), min(salary), max(salary) from employees;

 

SQL> create table t1(x int);

SQL> insert into t1 values (null);

SQL> insert into t1 values (1);

SQL> commit;

SQL> select count(*) from t1;

SQL> select count(x) from t1;

SQL> select max(x) from t1;

SQL> select min(x) from t1;

SQL> select sum(x) from t1;

SQL> select avg(x) from t1;

 

SQL> select avg(salary), avg(nvl(commission_pct, 0)) from employees;

SQL> select count(distinct department_id) from employees; 去除重復值

 

Groupby分組:

SQL> select department_id, avg(salary) from employees group by department_id;

多列分組:

SQL> select department_id, job_id, max(salary) from employees group by department_id, job_id;

SQL> select department_id, job_id, max(salary), last_name from employees group by department_id, job_id;            錯誤語法

 

練習:

公司中不同職位的數量

select job_id,count(job_id)

from employees

group by job_id

 

計算每個部門的人數

select department_id,count(last_name)

from employees

group by department_id

 

select department_id,count(department_id)

from employees

group by department_id

 

按年份分組,求員工的工資總和

 

select to_char(hire_date,'yyyy') year,sum(salary)

from employees

group by to_char(hire_date,'yyyy')

order by year

 

selec extract(year from hire_date) year,sum(salary)

from employees

group by extract(year from hire_date)

order by year

 

Having語句:

SQL> select department_id, avg(salary) from employees where avg(salary)>=5000 group by department_id;     錯誤語句

SQL> select department_id, avg(salary) from employees group by department_id having avg(salary)>=5000;

 

練習:

按部門求出所有有部門的普通員工的平均工資,部門平均工資少于5000的不顯示,最終結果按平均工資的降序排列。

select  department_id,trunc(avg(salary)) avg_sal

from  employees

where department_id is not null

group by department_id

having trunc(avg(salary))  >= 5000

order by avg_sal desc

 

select department_id, avg(salary) avg_sal

from employees

where job_id not like '%\_MGR' escape '\' and department_id is not null

group by department_id

having avg(salary)>=5000

order by avg_sal desc;

多表連接

emp                                                              dept:

empno      ename      deptno                        deptno     dname

100            abc            10                                 10              sales

101            def             10                                 20              market

102            xyz             20                                 30              it

103            opq            null

 

for emp in 100 .. 103

  for dept in 10 .. 30

    emp.deptno=dept.deptno

 

100         abc         10              10          sales

101         def         10              10          sales

102         xyz         20              20          market

 

 

訂單表:

CustID  StoreID     ProdID  ChannelID

100            S100        P100    C100

 

客戶表:

CustID  name  creditlevel

100         abc  

 

地址表:

CustID  adress

100         bj

100         tj

 

獲取如下信息,準備工作:

employees:

員工總數:107

SQL> select count(*) from employees;

有部門的員工數:106

SQL> select count(*) from employees where department_id is not null;

SQL> select count(department_id) from employees;

沒有部門的員工數:1

SQL> select count(*) from employees where department_id is null;

 

departments

部門總數:27

SQL> select count(*) from departments;

有員工的部門數:11

SQL> select count(distinct department_id) from employees;

沒有員工的部門數:16

SQL> select count(*) from departments where department_id not in (select department_id from employees where department_id is not null);

 

for dept in 1..27

  for emp in 1..107

   dept.deptid不在emp表中出現

 

select count(*)

from employees e, departments d

where e.department_id(+)=d.department_id

and e.employee_id is null;

 

select count(*)

from departments d

where not exists

(select 1 from employees where department_id=d.department_id);

 

select (select count(*) from departments)-(select count(distinct department_id) from employees) from dual;

 

內連接:106(106, 11)

select e.last_name, d.department_name

from employees e, departments d

where e.department_id=d.department_id;

 

select e.last_name, d.department_name

from employees e join departments d on e.department_id=d.department_id;

 

左外連接:107106+1

select e.last_name, d.department_name

from employees e, departments d

where e.department_id=d.department_id(+);

 

select e.last_name, d.department_name

from departments d, employees e

where e.department_id=d.department_id(+);

 

select e.last_name, d.department_name

from employees e left outer join departments d

on e.department_id=d.department_id;

 

右外連接:122106+16

select e.last_name, d.department_name

from employees e, departments d

where e.department_id(+)=d.department_id;

 

select e.last_name, d.department_name

from employees e right outer join departments d

on e.department_id=d.department_id;

 

完全外連接:123106+1+16

select e.last_name, d.department_name

from employees e full outer join departments d

on e.department_id=d.department_id;

 

多表連接的擴展:

n張表連接:

select e.last_name, d.department_name, l.city

from employees e, departments d, locations l

where e.department_id=d.department_id

and d.location_id=l.location_id;

 

select e.last_name, d.department_name, l.city

from employees e join departments d on e.department_id=d.department_id

               join locations l on d.location_id=l.location_id;

 

select e.last_name, d.department_name, l.city

from employees e, departments d, locations l

where e.department_id=d.department_id(+)

and d.location_id=l.location_id(+);

 

select e.last_name, d.department_name, l.city

from employees e left outer join departments d on e.department_id=d.department_id

               left outer join locations l on d.location_id=l.location_id;

 

練習:

查詢所有員工姓名,部門名稱,部門所屬城市(city),國家(country)和區域(region)名稱,對于空值用“無”代替。(N/A)

(使用oraclesql99的語法)

select e.last_name, d.department_name, l.city, c.country_name, r.region_name

from employees e, departments d, locations l, countries c, regions r

where e.department_id=d.department_id(+)

and d.location_id=l.location_id(+)

and l.country_id=c.country_id(+)

and c.region_id=r.region_id(+);

 

select e.last_namee.last_name, d.department_name, l.city, c.country_name, r.region_name

from employees e

left outer join departments d on e.department_id=d.department_id

left outer join locations l on d.location_id=l.location_id

left outer join countries c on l.country_id=c.country_id

left outer join regions r on c.region_id=r.region_id;

 

自連接:

empid       ename      mgrid

100            abc           

101            def             100

102            xyz             100

 

emp:                                                                 mgr:

empid       ename      mgrid                          empid       mgrname

100            abc                                                 100            abc

101            def             100

102            xyz             100

 

 

101            def             100            100            abc

102            xyz             100            100            abc

 

select emp.ename, mgr.mgrname

from emp, mgr

where emp.mgrid=mgr.empid

 

emp:                                                                 mgr:

empid       ename      mgrid                          empid       ename      mgrid

100            abc                                                 100            abc

101            def            100                              101            def             100

102            xyz             100                              102            xyz             100

select e.last_name, m.last_name

from employees e, employees m

where e.manager_id=m.employee_id;

 

有經理的員工數:106

SQL> select count(*) from employees where manager_id is not null;

沒有經理的員工數:1

SQL> select count(*) from employees where manager_id is null;

練習:

顯示所有員工姓名和經理姓名,沒有經理的顯示“無”。

select e.last_name, nvl(m.last_name, 'N/A')

from employees e, employees m

where e.manager_id=m.employee_id(+);

 

不等值連接:

conn scott/tiger

select e.ename, sg.grade

from emp e, salgrade sg

where e.sal between sg.losal and sg.hisal;

 

練習:

找出工資大于所在部門平均工資的員工姓名。

create table avg_sal_dept as select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id;

select e.last_name, e.salary, asd.avg_sal

from employees e, avg_sal_dept asd

where e.department_id=asd.department_id

and e.salary>asd.avg_sal;

 

select e.last_name, e.salary, asd.avg_sal

from employees e, (select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id) asd

where e.department_id=asd.department_id

and e.salary>asd.avg_sal;

子查詢

單行子查詢的思路:

SQL> select salary from employees where last_name='Feeney';

SQL> select last_name from employees where salary>3000;

SQL> select last_name from employees where salary>(select salary from employees where last_name='Feeney');

多行子查詢的思路:

SQL> select distinct department_id from employees where department_id is not null;

SQL> select department_name from departments where department_id in (10, 20,30);

SQL> select department_name from departments where department_id in (select department_id from employees where department_id is not null);

用多表連接改寫:

select distinct d.department_name

from employees e, departments d

where e.department_id=d.department_id

 

for dept in 1..27

  for emp in 1..107

查看emp中是否出現deptid

 

練習:

工資大于全公司平均工資的員工姓名。

SQL> select last_name from employees where salary>(select avg(salary) from employees);

Feeney同年入職的員工姓名

select last_name, hire_date

from employees

where extract(year from hire_date)=

(select extract(year from hire_date) from employees where last_name='Feeney')

and last_name != 'Feeney';

select last_name, hire_date

from employees

where hire_date between

(select to_date(to_char(hire_date, 'yyyy')||'0101', 'yyyymmdd') from employees where last_name='Feeney')

and

(select to_date(to_char(hire_date, 'yyyy')||'1231', 'yyyymmdd') from employees where last_name='Feeney')

Seattle工作的所有員工姓名

select last_name

from employees

where department_id in

(select department_id from departments

where location_id=

(select location_id from locations where city='Seattle'));

查找符合下列條件的員工姓名:和Abel在同一個部門,工資比Olson

select last_name from employees

where department_id=

(select department_id from employees where last_name='Abel')

and salary >

(select salary from employees where last_name='Olson');

 

配對子查詢:

Feeney在同一個部門、做同一職位的員工姓名:

select last_name, department_id, job_id

from employees

where department_id=

(select department_id from employees where last_name='Feeney')

and job_id=

(select job_id from employees where last_name='Feeney')

and last_name != 'Feeney';

select last_name, department_id, job_id

from employees

where (department_id, job_id)=

(select department_id, job_id from employees where last_name='Feeney')

and last_name != 'Feeney';

 

innotinnull值的影響:

所有管理者的姓名:

SQL> select last_name from employees where employee_id in (select manager_id from employees);

所有普通員工的姓名:

SQL> select last_name from employees where employee_id not in (select manager_id from employees where manager_id is not null);

 

關聯子查詢:

工資大于所在部門平均工資的員工姓名。

for i in 1..107所有員工

{

select avg(salary) from employees where department_id=i.department_id

if i.salary > i所在部門的平均工資

保留此記錄

}

select last_namesalary,department_id

from employees outer

where salary >

(select avg(salary) from employees

 where department_id = outer.department_id)

order by department_id;

 

select e.last_name, e.salary, asd.avg_sal

from employees e, (select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id) asd

where e.department_id=asd.department_id

and e.salary>asd.avg_sal;

 

exists/not exists查詢:

for i in 1..27所有部門

{

  forjin1..107所有員工

{

  if i.department_id = j.department_id

保留此記錄

  break

}

}

select department_name

from departments outer

where exists

(select 1 from employees where department_id=outer.department_id);

 

select department_name

from departments outer

where not exists

(select 1 from employees where department_id=outer.department_id);

 

練習:

所有管理者的姓名:

for i in 1..107所有員工

{

  forjin1..107所有員工

{

  if i.employee_id = j.manager_id

保留此記錄

  break

}

}

select last_name

from employees outer

where exists

(select 1 from employees where manager_id=outer.employee_id);

 

select last_name

from employees

where employee_id in

(select manager_id from employees);

 

 

 

select last_name

from employees,(select distinct(manager_id) from employees)asd

where employee_id=asd.manager_id

所有普通員工的姓名:

select last_name

from employees outer

where not exists

(select 1 from employees where manager_id=outer.employee_id);

 

 

select last_name

from employees

where employee_id not in(select manager_id from employees  where manager_id is not null);

 

子查詢和多表連接的轉換:

有員工的部門的名稱

select department_name

from departments

where department_id in

(select department_id from employees);

 

select department_name

from departments outer

where exists

(select 1 from employees where department_id=outer.department_id);

 

select distinct d.department_name

from employees e, departments d

where e.department_id=d.department_id;

 

練習:

Seattle工作的所有員工姓名(使用子查詢和多表連接兩種方式)

select last_name

from employees

where department_id in

(select department_id from departments

where location_id=

(select location_id from locations where city='Seattle'));

 

select e.last_name

from employees e, departments d, locations l

where e.department_id=d.department_id

and d.location_id=l.location_id

and l.city='Seattle';

 

最大值查詢:

SQL> select last_name from employees where salary=(select max(salary) from employees);

 

top-N查詢:

SQL> select last_name, salary from employees where rownum<=3 order by salary desc;

SQL> select * from (select last_name, salary from employees order by salary desc) where rownum<=3;

 

分頁查詢:

SQL> select * from

(select * from

(select * from

(select last_name, salary from employees order by salary desc)

where rownum<=6)

order by salary)

where rownum<=3

order by salary desc;

 

SQL> select last_name, salary

 from (select rownum row_num, v1.*              from

               (select last_name, salary from employees order by salary desc) v1

         ) v2

 where row_num between 4 and 6;

 

select * from

(select rownum num,last_name,salary from

(select last_name,salary from employees order by salary desc))

where num between 4 and 6

 

 select last_name, salary

 from (select rownum row_num, v1.*

             from

               (select last_name, salary from employees order by salary desc) v1

             where rownum<=6

         ) v2

 where row_num >= 4;

集合操作

select employee_id, job_id from employees

union all

select employee_id , job_id from job_history;

 

select employee_id, job_id from employees

union

select employee_id, job_id from job_history;

 

select employee_id, job_id from employees

intersect

select employee_id, job_id from job_history;

 

select employee_id from employees

minus

select employee_id from job_history;

 

select employee_id, job_id, salary from employees

union all

select employee_id, job_id, null from job_history;

 

select employee_id, job_id, to_char(salary) from employees

union all

select employee_id, job_id, 'no salary' from job_history;

 

集合排序:

select employee_id, job_id, salary from employees

union all

select employee_id, job_id, null from job_history

orderbysalary;

 

select employee_id, job_id, null from job_history

union all

select employee_id, job_id, salary from employees

orderby 3;

DML

insert:

SQL> create table t1(x int, y char(1), z date);

SQL> insert into t1(x, y, z) values (1, 'a', sysdate);

SQL> insert into t1(x, z, y) values (2, sysdate+1, 'b');

SQL> insert into t1(x, y, z) values (1, null, sysdate);

SQL> insert into t1(x, z) values (2, sysdate+1);

SQL> insert into t1 values (1, null, sysdate);

 

SQL> create table my_emp as select * from employees;

SQL> create table my_emp as select last_name, salary from employees where department_id=50;

SQL> create table avg_sal as select department_id, avg(salary) avg_sal from employees group by department_id;

SQL> create table my_emp as select * from employees where 1=0;

SQL> insert into my_emp select * from employees;

 

update:

SQL> update my_emp set salary=salary*1.1;

SQL> update my_emp set salary=salary*1.1 where department_id=50;

SQL> update my_emp set salary=salary*1.1, commission_pct=0.5 where employee_id=197;

 

delete:

SQL> delete from my_emp where employee_id=197;

SQL> delete from my_emp where department_id=50;

SQL> delete from my_emp;

 

子查詢:

SQL> create table my_emp as select * from employees;

SQL> alter table my_emp add(department_name varchar2(30));

SQL> update my_emp outer set department_name=(select department_name from departments where department_id=outer.department_id);

 

update (select t1.department_name as aname,t2.department_name bname from my_emp t1 ,departments t2 where t1.department_id=t2.department_id) set aname=bname;

練習:

new_dept表中刪除沒有員工的部門

SQL> create table my_dept as select * from departments;

delete from my_dept outer

where not exists

(select 1 from my_emp

where department_id=outer.department_id);

 

deletetruncate

                                     delete                                   truncate

語句類型                   dml                                        ddl

undo數據                  產生大量undo數據       不產生undo數據

空間管理不釋放                                 釋放

語法                            where                                   刪除全部數據

DDL

字符串:

SQL> create table t1(x char(10), y varchar2(10));

SQL> insert into t1 values('x', 'y');

SQL> select dump(x), dump(y) from t1;

數值:

SQL> create table t1(x number(5,2), y number(5));

SQL> insert into t1 values (123.45, 12345);

SQL> insert into t1 values (12.345, 12345);

SQL> insert into t1 values (12.345, 123.45);

SQL> select * from t1;

SQL> insert into t1 values (12.345, 112345);

日期時間:

SQL> create table t1(a date, b timestamp, c timestamp with time zone, d timestamp with local time zone);

SQL> insert into t1 values (sysdate, systimestamp, systimestamp, systimestamp);

SQL> alter session set time_zone='+9:00';

SQL> select * from t1;

修改表結構:

SQL> alter table t1 add(e char(10));

SQL> alter table t1 drop(e);

SQL> alter table t1 modify(d not null);

 

約束條件:

字段(列):not null, check(salary>0)

行與行:primary key, unique

表與表之間:foreign key

create table dept (

    deptno int constraint dept_deptno_pk primary key,

    dname varchar2(20) constraint dept_dname_nn not null);

 

create table emp (

    empno int constraint emp_empno_pk primary key,

    ename varchar2(20) constraint emp_ename_nn not null,

    email varchar2(50) constraint emp_email_uq unique,

    salary int constraint emp_salary_ck check(salary>0),

    deptno int constraint emp_deptno_fk references dept(deptno))

 

SQL> select constraint_name, constraint_type from user_constraints where table_name in('DEPT', 'EMP');

 

SQL> insert into emp values (100, 'abc', 'abc@123.com', 10000, 10);

insert into emp values (100, 'abc', 'abc@123.com', 10000, 10)

*

ERROR at line 1:

ORA-02291: integrity constraint (HR.EMP_DEPTNO_FK) violated - parent key not

found

 

 

SQL> insert into dept values (10, 'sales');

 

1 row created.

 

SQL> insert into dept values (10, 'market');

insert into dept values (10, 'market')

*

ERROR at line 1:

ORA-00001: unique constraint (HR.DEPT_DEPTNO_PK) violated

 

 

SQL> insert into dept values (20, 'market');

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL> insert into emp values (101, 'def', 'def@123.com', 10000, 20);

 

create table emp (

    empno int constraint emp_empno_pk primary key,

    ename varchar2(20) constraint emp_ename_nn not null,

    email varchar2(50) constraint emp_email_uq unique,

    salary int constraint emp_salary_ck check(salary>0),

    deptno int constraint emp_deptno_fk references dept(deptno) on delete set null)或者on delete cascade

 

instead of trigger視圖觸發器

 

序列:

SQL> create sequence test_seq increment by 1 start with 1 maxvalue 1000 nocycle cache 20;

SQL> create table t1(x int primary key, y int);

SQL> insert into t1 values (test_seq.nextval, 11);             反復執行

SQL> select * from t1;

 

索引:

主鍵和唯一性約束自動創建索引:

SQL> select constraint_name, constraint_type from user_constraints where table_name='EMPLOYEES';

SQL> select index_name, index_type from user_indexes where table_name='EMPLOYEES';

SQL> set autot on

SQL> select last_name from employees where employee_id=100;         走索引

SQL> select email from employees;                                                                  走索引

SQL> select last_name from employees where salary=2100;          全表掃描

SQL> create index emp_salary_ix on employees(salary);

SQL> select last_name from employees where salary=2100;          走索引

SQL> set autot off

 

 

PL/SQL

$ vi $ORACLE_HOME/sqlplus/admin/glogin.sql

set serveroutput on

 

 

游標

普通顯式游標練習:

指定員工的工號

如果高于或等于所在部門的平均工資,輸出first_name() last_name(列)’s salary: (顯示員工的工資) higherorequal than avgrage salary of department department_name(列): (顯示部門工資).

如果低于所在部門的平均工資,輸出first_name last_name’s salary lowerer than avgrage salary of department department_name.

如果員工不屬于任何部門,輸出first_name last_name nodepartment

DECLARE

v_empno employees.employee_id%type := 100;

  v_emp_rec employees%rowtype;

  v_avg_sal employees.salary%type;

  v_department_name departments.department_name%type;

BEGIN

select *

  into v_emp_rec

  from employees

  where employee_id=v_empno;

 

  select avg(salary)

  into v_avg_sal

  from employees

  where department_id=v_emp_rec.department_id;

 

  select department_name

  into v_department_name

  from departments

  where department_id=v_emp_rec.department_id;

 

  if v_emp_rec.salary >= v_avg_sal

  then

    dbms_output.put_line(v_emp_rec.first_name||', '||v_emp_rec.last_name);

  end if;

 

END;

/

對所有員工檢查工資,輸出和上面練習相同的內容。

BEGIN

  for v_emp_rec in (select * from employees)

  loop

   if v_emp_rec.department_id is null then

     dbms_output…

   else

 

 

    select avg(salary)

    into v_avg_sal

from employees

    where department_id=v_emp_rec.department_id;

 

    select department_name

    into v_department_name

    from departments

where department_id=v_emp_rec.department_id;

 

if …

  end loop;

END;

 

DECLARE

  cursor emp_cur is

   select e.last_name, e.salary, asd.avg_sal

from employees e, (select department_id, avg(salary) avg_sal from employees where department_id is not null group by department_id) asd

where e.department_id=asd.department_id;

BEGIN

  for v_emp_rec in emp_cur

  loop

if v_emp_rec.salary >= v_emp_rec.avg_sal then

elsif

  end loop;

 

參數游標練習:

指定部門編號,顯示部門中工資最高的前3名(不足3名的全部顯示)。輸出:部門編號姓名工資。

DECLARE

  cursor emp_sal_cur(p_department_id number) is

select department_id, last_name, salary

from employees

where department_id=p_department_id

order by salary desc;

BEGIN

for v_emp_rec in emp_sal_cur(10)

  loop

exit with emp_sal_cur%rowcount>3;

dbms_output…

  end loop;

 

END;

 

DECLARE

  cursor emp_sal_cur(p_department_id number) is

select * from (select department_id, last_name, salary

from employees

where department_id=p_department_id

order by salary desc) where rownum<=3;

BEGIN

for v_emp_rec in emp_sal_cur(10)

  loop

dbms_output…

  end loop;

 

END;

 

對所有部門,做同樣的工作。

DECLARE

  cursor emp_sal_cur(p_department_id number) is

select department_id, last_name, salary

from employees

where department_id=p_department_id

order by salary desc;

BEGIN

for v_dept_rec in (select distinct department_id from employees where department_id is not null)

loop

for v_emp_rec in emp_sal_cur(v_dept_rec.department_id)

  loop

exit with emp_sal_cur%rowcount>3;

dbms_output…

  end loop;

end loop;

END;

 

DECLARE

  cursor emp_sal_cur(p_department_id number) is

select * from (select department_id, last_name, salary

from employees

where department_id=p_department_id

order by salary desc) where rownum<=3;

BEGIN

for v_dept_rec in (select distinct department_id from employees where department_id is not null)

loop

for v_emp_rec in emp_sal_cur(v_dept_rec.department_id)

  loop

dbms_output…

  end loop;

end loop;

END;

 

練習

指定員工工號,修改員工的email地址,如果是新員工,將員工信息插入到new_emp表中。

SQL> create table new_emp as select * from employees;

DECLARE

  v_employee_id …

  v_email …

BEGIN

  update new_emp set email=v_email

  where first_name=v_first_name and last_name=…;

  if SQL%notfound then

    insert into new_emp values ();

  end if;

END;

異常

預定義異常練習:

輸入員工的工號,返回員工姓名和工資。對于不準確的工號,給出提示信息“該工號不存在”。

BEGIN

  select first_name, last_name, salary

  into v_first_name, v_last_name, v_salary

  from employees

  where employee_id=&emp_id;

 

  dbms_output.put_line(…);

EXCEPTION

  WHEN no_data_found THEN

    dbms_output…

  WHENothers THEN

    dbms_output…

END;

非預定義異常練習:

new_emp中添加新員工信息,針對工號重復、姓名缺失、工資<0,都要給出錯誤提示信息。

SQL> create table new_emp as select * from employees;

SQL> alter table new_emp modify(employee_id primary key);

SQL> alter table new_emp modify(check(salary>0));

SQL> alter table new_emp modify(email null);

SQL> alter table new_emp modify(hire_date null);

SQL> alter table new_emp modify(job_id null);

 

insert into new_emp…

declare

  e_name exception;

  e_salary exception;

pragma exception_init(e_name,-2292);

begin

insert into new_emp values ();

exception

  when DUP_VAL_ON_INDEX then

    dbms_output…

  when e_name then

    dbms_output…

  when e_salary then

    dbms_output…

  when others then

    ….

end;

自定義異常練習:

new_emp表中的員工修改,指定工號,修改員工的工資。對于工號不存在、修改后的工資<0,都要給出錯誤信息。

過程

練習:

輸入員工的工號,返回員工姓名和工資。對于不準確的工號,給出提示信息“該工號不存在”。

(在過程中用dbms_output輸出結果。使用out類型參數,在過程外輸出結果)

create procedure get_emp_info(1,2,3,4) is

begin

 

end;

 

declare

id, name, sal

begin

  get_emp_info(1,2,3,4)

  dbms_output.234

end;

函數

練習:

輸入工號,顯示員工姓名的全稱。

select full_name(employee_id) from employees;

abc, def

將員工管理相關的過程和函數,放入包emp_pack中。

過程包括:查詢、添加、修改員工。函數包括:顯示員工全名。

oracle管理

體系結構

                                              oracle學習筆記

SGA:

$ sqlplus / as sysdba

SQL> show sga

SQL> show parameter sga_max_size

SQL> select * from V$SGAINFO;

oem:瀏覽器中服務器-->內存指導(https://192.168.0.1:1158/em

sharedpool:

SQL> show parameter shared_pool_size

SQL> select component, current_size from V$SGA_DYNAMIC_COMPONENTS where component='shared pool';

SQL> select * from v$SGAINFO;

db buffer cache:

SQL> show parameter db_block_size

SQL> show parameter db_cache_size

SQL> select * from v$SGAINFO;

SQL> select component, current_size from V$SGA_DYNAMIC_COMPONENTS where component='DEFAULT buffer cache';

redo log buffer:

SQL> show parameter log_buffer

SQL> select * from v$sgainfo;

PGA:

SQL> show parameter pga_aggregate_target

SQL> select * from V$PGASTAT where NAME='total PGA allocated';

后臺進程:

SQL> select name from v$bgprocess where paddr<>'00';

SQL> ! ps -ef | grep ora_

SQL> show parameter db_writer_processes

數據文件:

$ ll /u01/app/oracle/oradata/orcl/*.dbf

SQL> select name from v$datafile;

SQL> select name from v$tempfile;

控制文件:

$ find /u01 -name 'control0[12].ctl'

SQL> select name from v$controlfile;

SQL> select TYPE, RECORD_SIZE, RECORDS_TOTAL, RECORDS_USED from v$controlfile_record_section;

重做日志:

$ ll /u01/app/oracle/oradata/orcl/*.log

SQL> select group#, member from v$logfile;

參數文件:

$ ll $ORACLE_HOME/dbs/spfile*.ora

$ strings $ORACLE_HOME/dbs/spfileorcl.ora

SQL> show parameter spfile;

SQL> show parameter

密碼文件:

$ ll $ORACLE_HOME/dbs/orapw*

歸檔日志:

SQL> select name from v$archived_log;

警告日志:

$ find /u01 -name 'alert_*.log'

實例管理

監聽

啟動監聽:

$ netstat -tlnp | grep 1521

$ lsnrctl

LSNRCTL> help

 

$ lsnrctl status

$ lsnrctl stop

$ netstat -tln | grep 1521

 

快速動態注冊:(可選)

$ sqlplus / as sysdba

SQL> alter system register;

 

$ lsnrctl status

em

啟動EM

$ netstat -tlnp | grep 1158

$ echo $ORACLE_SID

orcl

$ echo $ORACLE_UNQNAME

orcl

如果沒有設置ORACLE_UNQNAME

$ export ORACLE_UNQNAME=orcl

$ vi .bash_profile

export ORACLE_UNQNAME=orcl

$ . .bash_profile

 

確保主機名正常解析:

$ cat /etc/hosts

 

$ emctl status dbconsole

$ emctl stop dbconsole

$ emctl start dbconsole

 

查看oem的端口:

$ find /u01 -name portlist.ini

 

重新配置em

$ emca

$ emca -deconfig dbcontrol db

$ emca -config dbcontrol db

數據庫

oracle學習筆記

啟動實例:

$ ls $ORACLE_HOME/dbs/spfileorcl.ora

SQL> shutdown immediate

SQL>startup nomount

SQL> select status from v$instance;

SQL> select * from v$sgainfo;

SQL>select * from hr.employees;

SQL> conn hr/hr

 

SQL>startup mountalter database mount;

SQL> show parameter control_files

SQL> select status from v$instance;

SQL> select * from v$controlfile;

SQL> select name from v$datafile;

SQL>select * from hr.employees;

SQL> conn hr/hr

 

SQL>startupalter database open;

SQL> select status from v$instance;

SQL>select * from hr.employees;

SQL> conn hr/hr

oracle學習筆記

關閉數據庫:

SQL> shutdown normal

SQL> shutdown transactional

SQL> shutdown immediate

SQL> shutdown abort

控制腳本:

$ vi /etc/oratab

$ vi $ORACLE_HOME/bin/dbstart

$ vi $ORACLE_HOME/bin/dbshut

重啟數據庫:

SQL> startup force

startup force = shutdown abort + startup

startup force mount = shutdown abort + startup mount

 

練習:

熟悉3個服務的啟動和關閉

參數管理

參數文件:

$ ls $ORACLE_HOME/dbs/spfileorcl.ora

預先備份:

$ cp spfileorcl.ora spfileorcl.ora.bak

不可以通過vi直接修改!

查看參數:

SQL> show parameter

SQL> select NAME, VALUE from v$parameter;

修改參數:

動態參數:

$ strings $ORACLE_HOME/dbs/spfileorcl.ora|grep reource_limit

SQL> show parameter RESOURCE_LIMIT

SQL> alter system set RESOURCE_LIMIT=true;

SQL> show parameter RESOURCE_LIMIT

$ strings $ORACLE_HOME/dbs/spfileorcl.ora|grep reource_limit

 

靜態參數:

$ strings $ORACLE_HOME/dbs/spfileorcl.ora|grep processes

*.processes=150

SQL> show parameter processes      值為150

SQL> alter system set processes=300 scope=spfile;

SQL> show parameter processes      值為150

$ cat $ORACLE_HOME/dbs/spfileorcl.ora

*.processes=300

 

重啟數據庫,靜態參數修改生效:

SQL> shutdown immediate

SQL> startup

SQL> show parameter processes      值為300

 

session級別修改參數:

SQL> select sysdate from dual;

SQL> alter session set nls_date_format='dd-mon rr';

SQL>select sysdate from dual;                   只影響當前會話,不影響系統

SQL> conn / as sysdba

SQL>select sysdate from dual;                   恢復默認設置

 

pfile/spfile格式轉換:

SQL> create pfile='/home/oracle/initorcl.ora' from spfile;

$ cat /home/oracle/initorcl.ora

$ mv $ORACLE_HOME/dbs/spfileorcl.ora $ORACLE_HOME/dbs/spfileorcl.ora.bak

SQL> shutdown immediate

SQL> create spfile from pfile='/home/oracle/initorcl.ora';

$ strings $ORACLE_HOME/dbs/spfileorcl.ora

 

指定參數文件啟動數據庫:

SQL> startup pfile='/home/oracle/initorcl.ora'

 

練習:

修改resource_limitprocesses參數。并在alertlog中找到對應的信息。

警告日志和后臺進程的轉儲文件

$ find /u01 -name alert_*.log

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log

SQL> show parameter dump

練習:

查看alertlog中最近一次啟動/關閉實例的詳細信息。

查看alertlog中記錄的用戶對參數所做的修改。

數據字典/動態性能視圖

SQL> conn hr/hr

SQL> desc user_tables

SQL> select TABLE_NAME from user_tables;

SQL> desc user_views

SQL> select VIEW_NAME from user_views;

SQL> desc user_indexes

SQL> select INDEX_NAME, TABLE_NAME from user_indexes;

 

SQL> conn scott/tiger

SQL> select TABLE_NAME from user_tables;

SQL> select VIEW_NAME from user_views;

SQL> select INDEX_NAME, TABLE_NAME from user_indexes;

 

SQL> conn hr/hr

SQL> select count(*) from all_tables;

 

SQL> conn scott/tiger

SQL> select count(*) from all_tables;

 

SQL> conn hr/hr

SQL> select count(*) from dba_tables;

 

SQL> conn scott/tiger

SQL> select count(*) from dba_tables;

 

SQL> desc v$instance

SQL> desc v$database

存儲管理

oracle學習筆記

查詢預定義表空間:

SQL> select TABLESPACE_NAME,CONTENTS from dba_tablespaces;

SQL> select FILE_NAME, TABLESPACE_NAME from dba_data_files;

創建新表空間:

SQL> create tablespace tbs01 datafile '/u01/app/oracle/oradata/orcl/tbs01.dbf'SIZE 10MAUTOEXTEND ON NEXT 10M MAXSIZE 100M;

在指定的表空間中創建表:

SQL> create table t1 tablespace tbs01 as select * from dba_objects where 1=0;

SQL> select bytes, blocks, extents, tablespace_name from dba_segments where segment_name='T1';

SQL> insert into t1 select * from dba_objects;

SQL> select bytes, blocks, extents, tablespace_name from dba_segments where segment_name='T1';

SQL> select extent_id, bytes, blocks from dba_extents where segment_name='T1';

SQL> insert into t1 select * from t1;

SQL> insert into t1 select * from t1;

SQL> insert into t1 select * from t1;

SQL> select bytes, blocks, extents, tablespace_name from dba_segments where segment_name='T1';

SQL>select extent_id, bytes, blocks from dba_extents where segment_name='T1';

SQL> insert into t1 select * from t1;                  空間不足,報錯

SQL> rollback;

SQL> select bytes, blocks, extents, tablespace_name from dba_segments where segment_name='T1';               空間不釋放

SQL> alter table t1 move;        釋放空間

只讀表空間:

SQL> alter tablespace tbs01 read only;

SQL> delete t1;                  禁止dml

SQL> insert into t1 select * from t1;         禁止dml

SQL> create table t2 (x int) tablespace tbs01;         失敗

SQL> alter table t1 add (x int);         成功

SQL> update t1 set x=1;            失敗

SQL> drop table t1;           成功

dmlddl的區別

改變表空間大小:

resizeautoextendadddatafile

刪除表空間:

SQL> drop tablespace tbs01 including contents and datafile;

Oracle NET

oracle學習筆記

1.客戶端通過@ora10g的名字去tnsname.ora文件獲取服務器的具體連接信息

2.客戶端通過tnsname.ora中的描述向服務器發出鏈接請求服務器端

3.服務器的監聽器接收到連接請求后,驗證請求的服務的有效性

4.服務器端產生一個服務進程和客戶端進程建立連接

 

查看會話建立過程:

$ netstat -tlnp | grep 1521

$ sqlplus sys/password@orcl as sysdba

$ netstat -tnp | grep sqlplus

$ kill -9 1234              殺死維護sqlplus的進程

監聽的配置

配置文件:

$vi$ORACLE_HOME/network/admin/listener.ora

通過netca添加新的監聽服務Listener15210,端口使用15210

$ vi listener.ora

$ netstat -tln|grep 1521

$ lsnrctl status listener15210

 

通過netmgr配置高級選項

 

通過lsnrctl命令來啟動/停止/查看/重載監聽器/服務

lsnrctl start|stop|status|reload|service

指定監聽的名稱:

$ lsnrctl status listener15210

 

網絡環境變化,需要檢查listener.ora/etc/hosts文件

 

netca刪除Listener15210

實例的配置

靜態注冊和動態注冊

         什么是靜態注冊

                   就是監聽器的配置文件中寫明了監聽哪個實例需要配置SID_DESC字段

                   定位實例的方式可以使用SID_NAME或者SERVICE_NAME來定位

         什么是動態注冊

                   就是監聽器的配置文件中沒寫明監聽哪個實例

                   要通過PMON告知監聽器要監聽的具體實例

                   PMON是將SERVER_NAME告訴給監聽器這個過程就是注冊

                   默認一分鐘PMON注冊一次也就是說啟動監聽還沒注冊時是無法連接的

                   添加3種方式,后面的刪掉,用文檔改寫

         區分靜態注冊和動態注冊

                   lsnrctl status

                   ready 就是動態

                   unknow 就是靜態

                  

靜態注冊listener.ora文件信息:

$ vi listener.ora

SID_LIST_LISTENER =

  (SID_LIST =

        (SID_DESC =

                (ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)

                (SID_NAME =ora11g)

        )

  )

$ lsnrctl reload

.....

Services Summary...

Service "ora11g" has 1 instance(s).

  Instance "ora11g", status UNKNOWN, has 1 handler(s) for this service...

狀態總是顯示未知的,當有請求時,監聽器才去確認數據是否存在

 

動態注冊

         Oracle9i起實例使用動態服務注冊來通知監聽程序有關其數據庫服務的信息。

         服務注冊依賴PMON 進程向監聽程序注冊實例信息注冊間隔為1分鐘左右

         手動注冊命令 alter system register;

         無需在listener.ora 文件中設置任何信息此文件可以不存在

 

3種注冊方式:

本地默認端口監聽

本地非默認端口監聽

遠程監聽

 

本地非默認端口:

netca創建listener15210,使用15210端口

$ netstat -tlnp | grep 15210

 

寫入監聽的別名:

$ cd $ORACLE_HOME/network/admin

$ vi tnsnames.ora

listener15210 =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node1.test.com)(PORT = 15210))

  )

 

修改參數:

SQL> ALTER SYSTEM SET LOCAL_LISTENER=listener15210;

SQL> ALTER SYSTEM register;     立即注冊(可選)

 

服務信息已添加到新的監聽中:

$ lsnrctl status listener15210

客戶端指定新端口連接:

$ sqlplus sys/password@192.168.0.1:1521/orcl as sysdba               報錯

$ sqlplus sys/password@192.168.0.1:15210/orclas sysdba

 

刪除配置:

SQL> ALTER SYSTEM SET LOCAL_LISTENER='';

SQL> ALTER SYSTEM register;

$ vi tnsnames.ora              刪除listener15210別名

netca刪除15210端口的監聽

客戶端配置

oracle學習筆記

輕松連接:

$ sqlplus sys/password@192.168.0.1:1521/orcl as sysdba

適用于臨時性的連接

 

本地命名:

查看現有的主機連接字符串

$ cd $ORACLE_HOME/network/admin

$ vi tnsnames.ora

 

$ sqlplus sys/password@orcl as sysdba

 

使用netca添加新的主機連接字符串orcl192

$ sqlplus sys/password@orcl192 as sysdba

SQL> select name from v$database;

 

tnsping測試,不需要用戶名和口令:

$ tnsping 192.168.0.1:1521/orcl

$ tnsping orcl192

 

解析方法的順序:

$ vi sqlnet.ora

netca可以修改

 

恢復默認設置:

SQL> alter system set local_listener='';

SQL> alter sytem register;

 

netca刪除不需要的監聽和連接配置

共享服務器模式

專有服務和共享服務模式

         專有模式

                  

                   每個用戶進程和服務進程間通過監聽器建立連接

                   進程信息存放于PGA,也就是說有多少個用戶進程就有多少個PGA產生

                   單單只有進程連接還不足以操作數據庫,還需要產生的會話信息

                   會話信息存儲在UGA,UGA在專有模式中存在于PGA

                   因為進程和進程間是相互隔離的,所以會話信息也相對獨立

                   這就導致了服務進程只能獲知當前用戶進程的會話請求信息只能為當前用戶進程服務

                  

         共享模式

                   用戶進程的請求被監聽器接收,監聽器不委派服務器進程,而是將調度器信息返回給客戶端

                   調度器將用戶進程的請求放入請求隊列

                   多個服務進程中的一個服務進程從隊列中獲取用戶進程的請求,并處理這個用戶進程的請求

                   服務進程處理完后將處理結果放入響應隊列,每個調度器都有自己的響應隊列

                   響應隊列的信息反饋給對應的調度器

                   調度器再把服務進程處理的結果返回給用戶進程

                  

                   共享模式中的用戶進程的會話信息對每一個服務器進程來說都是可見的.

                   因為共享模式的UGA信息存在于SGA,所以此時一個用戶進程的請求可以由多個服務進程來完成.

oracle學習筆記

共享服務器的配置通過初始化參數dispatchers來配置

可以通過DBCA來修改

$ lsnrctl service

SQL> show parameter disp

SQL> show parameter shared_server

 

專有模式和共享模式是可以兼容在一起使用的

此時看用戶如何選擇

 

tnsnames.ora

ORA10G =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = dba.up.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = DEDICATED) # 不寫這個值就是按服務器的模式來匹配

                               # shared 指定使用共享方式連接

                               # DEDICATED 指定使用專有模式連接

      (SERVICE_NAME = raw10g)

    )

  )

 

測試三種模式

 

ORCL_default =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node1.test.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVICE_NAME = orcl)

    )

  )

 

ORCL_dedicated =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node1.test.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orcl)

    )

  )

 

ORCL_shared =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node1.test.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = SHARED)

      (SERVICE_NAME = orcl)

    )

  )

 

測試:

$ sqlplus sys/password@orcl_default as sysdba

$ sqlplus sys/password@orcl_dedicated as sysdba

$ sqlplus sys/password@orcl_shared as sysdba

 

SQL> select SID, SERVER,PROGRAM from v$session where USERNAME='SYS';

SQL> select distinct sid from v$mystat;

 

管理維護、大數據量導入、備份恢復等工作不適合用共享方式:

SQL> shutdown immediate               共享連接下不能發布管理命令

 

恢復原有設置:

dbca修改為dedicated方式

dblink

數據庫A訪問遠程數據庫B上面的表:

在數據庫A中,使用netca創建主機描述字符串orcl_dblink指向數據庫B

$ netca

$ tnsping orcl_dblink

在數據庫A中創建數據庫鏈接:

SQL> create database link orcl_dblink_hr connect to hr identified by hr using 'orcl_dblink';

using使用主機描述字符串orcl_dblink

用戶和口令都是數據庫B上的

db link的名字不要求和主機描述字符串一致

 

訪問數據庫B中的表:

SQL> select count(*) from hr.employees@orcl_dblink_hr;

SQL> select count(*) from hr.employees, departments@orcl_dblink_hr;

用戶管理

AAA:

Authentication: 身份驗證

Authorization: 權限管理

Audition: 審計

authentication

預定義的系統用戶:

SQL> select USERNAME, ACCOUNT_STATUS from dba_users;

open狀態的用戶:

SQL> select USERNAME, ACCOUNT_STATUS from dba_users ACCOUNT_STATUS='OPEN';

系統管理賬號:

SYS            SYSTEM             DBSNMP           SYSMAN

3種身份驗證方式:

password驗證:

瀏覽器中創建用戶user01

或者用命令創建:

SQL> create user user01 identified by password;

SQL> grant create session to user01;

 

測試:

$ sqlplus user01/password

 

externalos)驗證:

操作系統中創建用戶:

$ su -

Password:

[root@node1 ~]# useradd osuser

[root@node1 ~]# passwd osuser

$ sqlplus / as sysdba

外部用戶使用固定的前綴:

SQL> show parameter os_auth

SQL> create user ops$osuser identified externally;

SQL> grant create session to ops$osuser;

不要su - osuser,環境變量保留:

$ su osuser

Password:

[osuser@node1 admin]$ sqlplus /

SQL> show user

USER is "OPS$OSUSER"

 

管理員的身份驗證:

本地連接:

本地連接,預先設置ORACLE_SID,操作系統用戶是dba群組的成員

 

$ id

uid=1001(oracle) gid=1000(oinstall) groups=1000(oinstall),1031(dba),1032(oper)

$ sqlplus / as sysdba

SQL> show user

USER is "SYS"

$ su -

# usermod -G oper oracle

#gpasswd -d oracle dba

# exit

$ sqlplus / as sysdba

報錯,權限不夠

 

只要是dba群組中的成員,就可以不需要知道sys的口令,直接以sqlplus / as sysdba登錄

并且身份為sys

 

恢復:

# gpasswd -a oracle dba

 

遠程客戶端連接:

$ sqlplus sys/password@orcl as sysdba

$ ls $ORACLE_HOME/dbs/orapworcl

$ orapwd

authorization

系統權限:

sys執行授權:

預先創建測試表

SQL> create table t1(x int);

SQL> create user user01 identified by password;

SQL> grant create session to user01;

SQL> grant select any table to user01;

user01測試:

$ sqlplus user01/password

SQL> select count(*) from hr.employees(hr.departments scott.emp);

SQL> delete from scott.emp;            失敗!

SQL> select * from sys.t1;                  失敗!

select any table    n-1模式

sys再次授權:

SQL> grant select any dictionary to user01;

user01測試:

SQL> select * from sys.t1;    成功

select any table(n-1)+select any dictionary(1)

sys授權:

SQL> grant create table to user01;

user01測試:

SQL> create table t1(x int);

sys授權:

SQL> grant unlimited tablespace to user01;

user01測試:

SQL> insert into t1 values (1);

 

對象權限:

表的參照權限:

dept

deptno(pk)        dname

10                       sales

20                       market

 

my_emp

empno               deptno(fk)

100                     10

sys授權:

SQL> grant select on hr.employees to user01;

user01測試:

SQL> select count(*) from hr.employees;

SQL> delete from hr.employees;      失敗

SQL> select count(*) from hr.departments;             失敗

sys授權:

SQL> grant index on hr.employees to user01;

SQL> grant unlimited tablespace to user01;

user01測試:

SQL> create index emp_sal_idx on hr.employees(salary);

SQL> select index_name from user_indexes where table_name='EMPLOYEES';

 

create any table                create table

alter any table                   alter table

drop any table                    drop table

 

權限的級聯刪除:

系統權限:

sys準備工作:

SQL> drop user user01 cascade;

SQL> drop user user02 cascade;

SQL> create user user01 identified by password;

SQL> create user user02 identified by password;

SQL> grant create session to user01;

SQL> grant create session to user02;

sys授權:

SQL> grant select any table to user01 with admin option;

user01測試成功并授權給user02:

SQL> select count(*) from hr.employees;

SQL> grant select any table to user02 with admin option;

user02測試成功:

SQL> select count(*) from hr.employees;

sys收回權限:

SQL> revoke select any table from user01;

user01操作失敗:

SQL> select count(*) from hr.employees;

user02測試成功:

SQL> select count(*) from hr.employees;

對象權限:

SQL> grant select on hr.employees to user01 with grant option;

 

 

dba+sysdba=sys

role

角色就是數據庫中的群組!

角色的作用:簡化權限的管理,動態更新用戶的權限。

oracle學習筆記

 

 

預定義的角色:

SQL> select role from dba_roles;

創建角色:

SQL> create role hr_mgr;

SQL> create role hr_clerk;

SQL> grant select any table to hr_mgr;

SQL> grant select on hr.employees to hr_clerk;

SQL> grant hr_mgr to user01;

SQL> grant hr_clerk to user02;

user01/user02測試:

角色生效必須重新登錄

profile

profile主要控制兩個方面:

1 用戶的資源消耗

2 用戶的口令安全

SQL> select * from dba_profiles where profile='DEFAULT';

SQL> select username, profile from dba_users;

SQL> show parameter resource_limit     資源管理的開關參數

查看復雜性函數的腳本:

$ cd $ORACLE_HOME/rdbms/admin

$ vi utlpwdmg.sql

$ cp utlpwdmg.sql /home/oracle/utlpwdmg.sql

$ vi /home/oracle/utlpwdmg.sql      只保留校驗函數部分

$ sqlplus / as sysdba

SQL> @/home/oracle/utlpwdmg.sql

sys創建概要文件:

SQL> CREATE PROFILE HR_PROFILE LIMIT

PASSWORD_LIFE_TIME 30

PASSWORD_GRACE_TIME 7

PASSWORD_REUSE_MAX 3

PASSWORD_REUSE_TIME unlimited

PASSWORD_LOCK_TIME 5/1440

FAILED_LOGIN_ATTEMPTS 3

PASSWORD_VERIFY_FUNCTION verify_function_11G;

和用戶關聯:

SQL> ALTER USER HR PROFILE HR_PROFILE;

測試:

$ sqlplus hr/hr

SQL> alter user hr identified by password123 replace hr;

audit

oracle學習筆記

開啟開關參數:

SQL> show parameter audit_trail

設置審計選項:

每次設置新的審計選項,測試用戶需要重新連接

sys準備工作:

SQL> drop user user01 cascade;

SQL> create user user01 identified by password;

SQL> grant create session, create table, create any table to user01;

審計系統權限:

SQL>AUDIT CREATE ANY TABLE, CREATE TABLE BY USER01 BY ACCESS;

user01測試:

SQL> create table t1(x int);

SQL> create table t1(x int);               失敗

SQL> create table hr.t1(x int);

SQL> create table hr.t1(x int);          失敗

sys查看審計結果:

SQL> desc aud$

SQL> desc dba_audit_trail

瀏覽器中查看

sys添加審計條件:

SQL> AUDIT SELECT ANY TABLE BY user01 BY ACCESS;

SQL> grant select any table to user01;

user01測試:

SQL> select * from t1;

SQL> select * from hr.t1;

sys查看審計結果:

瀏覽器中或者查看dba_audit_trail

刪除審計選項:

SQL> NOAUDIT CREATE ANY TABLE BY USER01;

SQL> NOAUDIT CREATE TABLE BY USER01;

SQL> NOAUDIT SELECT ANY TABLE BY user01;

 

審計對象:

sys設置審計選項:

SQL> AUDIT SELECT ON hr.employees BY ACCESS;

SQL> drop user user01 cascade;

SQL> create user user01 identified by password;

SQL> grant create session to user01;

sys授權,每執行一個語句,user01就測試一次:

SQL> grant select any table to user01;

SQL> revoke select any table from user01;

SQL> grant select on hr.employees to user01;

user01測試(執行4次):

SQL> select count(*) from hr.employees;

默認不記錄sys的行為:

SQL> select count(*) from hr.employees;

刪除審計選項:

SQL> NOAUDIT SELECT ON hr.employees;

 

審計語句:

sys設置審計選項:

SQL> AUDIT TABLE BY user01 BY ACCESS;

user01測試:

SQL> create table t1(x int);      失敗

SQL> create table t1(x int);

SQL> create table t1(y int);      失敗

SQL> drop table t1;

sys查看結果:

瀏覽器中,或DBA_AUDIT_OBJECT表中

刪除審計選項:

SQL>NOAUDIT TABLE BY USER01

 

審計sys的操作:

SQL> show parameter audit

修改兩個參數

并發管理

讀寫沖突通過讀一致性解決:

sys準備工作:

SQL> create user user01 identified by password;

SQL> grant dba to user01;

以下都用user01

SQL> conn user01/password

Connected.

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

session1

SQL> update t1 set x=11 where x=1;

SQL> select * from t1;

session 2:

SQL> select * from t1;

session 1

SQL> commit;

session 2

SQL> select * from t1;

測試serializable

session1

SQL> alter session set isolation_level=serializable;

重復上面的步驟

 

寫與寫的沖突通過鎖機制解決:

session 1:

SQL> update t1 set x=11 where x=1;

瀏覽器中查看鎖信息

session 2:

SQL> update t1 set x=111 where x=1;              被阻塞

瀏覽器中查看鎖信息

session 1:

SQL>rollback;

瀏覽器中查看鎖信息

 

死鎖:

session1:

SQL> select * from t1;

 

         X

----------

         1

         2

SQL> update t1 set x=11 where x=1;

session2:

SQL> update t1 set x=22 where x=2;

session1:

SQL> update t1 set x=222 where x=2;              阻塞

session2:

SQL> update t1 set x=111 where x=1;              死鎖

ERROR at line 1:

ORA-00060: deadlock detected while waiting for resource

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log

 

鎖和外鍵

select … for update

撤銷管理

什么是撤銷數據:

oracle學習筆記

         1.交易的回退:沒有提交的交易可以rollback

         2.交易的恢復:數據庫崩潰時,將磁盤的不正確數據恢復到交易前

         3.讀一致性  :被查詢的記錄有事務占用,轉向回滾段找改前鏡像

         4.閃回數據  :從回滾段中構造歷史數據

事務與撤銷數據:

oracle學習筆記

redoundo

oracle學習筆記

AUM

3個參數,兩個表空間屬性

 

undo_management=AUTO 回滾表空間段的段管理模式,管理員只需要備足夠的表空間容量,oracle會自動管理擴展回滾段的數量。只能使用一個UNDO表空間。

undo_tablespace:只有在自動管理模式下才可以使用。指明使用哪個UNDO表空間

undo_retention900

         提交之后舊的鏡像保持在回滾段中的時間。

         非強制的回退保持時間.(回滾空間不足老的鏡像就會被覆蓋)

 

autoextend:表空間自動擴展

強制保持:但是對空間要求較大,要慎用。(10g開始支持)

alter tablespace UNDOTABS1 RETENTION GUARANTEE;

select  tablespace_name,RETENTION from dba_tablespaces;

 

UNDO_RETENTION specifies (in seconds) how long already committed undo information is to be retained. The only time you must set this parameter is when:

?The undo tablespace has the AUTOEXTEND option enabled

?You want to set undo retention for LOBs

?You want to guarantee retention

 

undo advisor

調度作業

oracle學習筆記

$ ps -ef | grep cjq

SQL> show parameter job_queue_processes

后臺預先設置的自動化管理作業:

 

自定義作業:

SQL> create table session_history(snap_time timestamp with local time zone, num_session number);

em中創建作業:

使用plsql塊:

declare

  session_count  number;

begin

  select count(*) into session_count from v$session;

  insert into session_history values (systimestamp, session_count);

  commit;

end;

全球化支持

$ vi .bash_profile

#export NLS_LANG=american_america.AL32UTF8

#export NLS_DATE_FORMAT='yyyy-mm-dd hh34:mi:ss'

$ unset NLS_LANG

$ unset NLS_DATE_FORMAT

SQL> select sysdate from dual;

備份恢復

配置可恢復性

控制文件

SQL> show parameter control_files

SQL> select * from v$controlfile;

修改路徑:

$ cd $ORACLE_HOME/dbs

$ cp spfileorcl.ora spfileorcl.ora.bak

SQL> alter system set control_files='/u01/app/oracle/oradata/orcl/control01.ctl', '/home/oracle/control02.ctl' scope=spfile;

SQL> shutdown immediate

$ mv /u01/app/oracle/fast_recovery_area/orcl/control02.ctl /home/oracle/control02.ctl

SQL> startup

SQL> show parameter control_files

SQL> select * from v$controlfile;

增加鏡像:

SQL> alter system set control_files='/u01/app/oracle/oradata/orcl/control01.ctl', '/home/oracle/control02.ctl', '/home/oracle/control03.ctl' scope=spfile;

SQL> shutdown immediate

$ cp /home/oracle/control02.ctl /home/oracle/control03.ctl

SQL> startup

SQL> show parameter control_files

SQL> select * from v$controlfile;

 

日志文件:

增加成員和日志組:

SQL> select GROUP#, SEQUENCE#, STATUS, MEMBERS from v$log;

SQL> select GROUP#, MEMBER from v$logfile;

SQL> alter database add logfile member '/home/oracle/redo01b.log' to group 1;

SQL> alter database add logfile member '/home/oracle/redo02b.log' to group 2;

SQL> alter database add logfile member '/home/oracle/redo03b.log' to group 3;

SQL> alter database add logfile group 4 ('/u01/app/oracle/oradata/orcl/redo04.log', '/home/oracle/redo04b.log') size 50M;

 

FRA

SQL> show parameter db_recovery

 

backupset: 10GB,  archived log: 5GB

 

10+5, 10G

 

開啟歸檔模式:

SQL> archive log list          檢查當前設置

SQL> shutdown immediate

SQL> startup mount

SQL> alter database archivelog;

SQL> alter database open;

SQL> archive log list

SQL> show parameter log_archive_dest

SQL> select group#, sequence#, status, archived from v$log;

SQL> alter system switch logfile;

SQL> select group#, sequence#, status, archived from v$log;

SQL> select NAME, SEQUENCE#, STATUS from v$archived_log;

$ ls /u01/app/oracle/fast_recovery_area/ORCL

RMAN配置

oracle學習筆記

$ rman target /        rman target sys/password@orcl

RMAN> show all;

RMAN>CONFIGURE CONTROLFILE AUTOBACKUP On;

RMAN>CONFIGURE CONTROLFILE AUTOBACKUP clear;

RMAN> backup tablespace users;

RMAN> list backup;

SQL> desc v$backup_set          瀏覽器中也可以查看

 

自動通道管理:

RMAN> CONFIGURE DEVICE TYPE DISK PARALLELISM 2;

RMAN> backup tablespace users, example;

$ mkdir /home/oracle/disk1 /home/oracle/disk2

RMAN> configure channel 1 device type disk to destination '/home/oracle/disk1';

RMAN> configure channel 2 device type disk to destination '/home/oracle/disk2';

RMAN> backup tablespace users, example;

恢復默認

RMAN> CONFIGURE DEVICE TYPE DISK clear;

RMAN> CONFIGURE CHANNEL 1 device type disk clear;

RMAN> CONFIGURE CHANNEL 2 device type disk clear;

 

手動通道管理:

RMAN> run {

allocate channel c1 device type disk to destination '/home/oracle/disk1';

allocate channel c2 device type disk to destination '/home/oracle/disk2';

backup tablespace users, example;

backup (tablespace users channel c1)(tablespace example channel c2);

}

 

backup section size 500M datafile 1;

 

指定備份格式:

RMAN> backup tablespace users;

RMAN> backup as compressed backupset tablespace users;

RMAN> backup as copy tablespace users;

RMAN> list backup of tablespace users;

RMAN> list copy of tablespace users;

 

備份的加密:

RMAN備份

                   不歸檔                                          歸檔

         online       offline                          online       offline

完全部分完全部分完全部分完全部分

 

shutdown nomount mount open

 

備份數據文件:

SQL> select file_id, file_name from dba_data_files;

RMAN> backup datafile 4;

RMAN> backup datafile 4,5;

RMAN> backup datafile '/u01/app/oracle/oradata/orcl/users01.dbf';

RMAN> backup tablespace users;

RMAN> backup tablespace users, example;

RMAN> backup database;

RMAN> list backup;

desc v$backup_set,瀏覽器查看備份

 

增量備份:

RMAN> backup incremental level 0 tablespace users;

RMAN> list backup of tablespace users;

SQL> create table t1(x int) tablespace users;

SQL> insert into t1 values (1);

SQL> commit;

RMAN> backup incremental level 1 tablespace users;

RMAN> backup incremental level 1 tablespace users;

SQL> create table t2(x int) tablespace users;

SQL> insert into t2 values (1);

SQL> commit;

RMAN> backup incremental level 1 cumulative tablespace users;

RMAN> list backup of tablespace users;

開啟塊跟蹤:

SQL> alter database enable block change tracking using file '/home/oracle/blk_trk.chg';

需要重新連接會話

SQL> select * from v$block_change_tracking;

SQL> select DATAFILE_BLOCKS, BLOCKS_READ, BLOCKS, USED_CHANGE_TRACKING from v$backup_datafile where INCREMENTAL_LEVEL>0;

SQL> create table t3(x int) tablespace users;

SQL> insert into t3 values (1);

SQL> commit;

RMAN> backup incremental level 1 tablespace users;

SQL> select DATAFILE_BLOCKS, BLOCKS_READ, BLOCKS, USED_CHANGE_TRACKING from v$backup_datafile where INCREMENTAL_LEVEL>0;

SQL> alter database disable block change tracking;                 關閉

 

增量更新:

SQL> create table t1(x int) tablespace users;

SQL> insert into t1 values (1);

SQL> commit;

RMAN> backup incremental level 1 for recover of copy with tag 'update_copy' tablespace users;        第一次創建的是0級備份

RMAN> list copy;               記錄timescn

SQL> insert into t1 values (2);

SQL> commit;

RMAN> backup incremental level 1 for recover of copy with tag 'update_copy' tablespace users;        2次創建的是1級備份

RMAN> list backup;          backupset格式

RMAN> recover copy of tablespace users with tag 'update_copy';

RMAN> list copy;               timescn更新

腳本形式:

RMAN> run {

backup incremental level 1 for recover of copy with tag 'update_copy' tablespace users;

recover copy of tablespace users with tag 'update_copy';

}

 

備份歸檔日志:

RMAN> list archivelog all;

RMAN> backup archivelog all delete all input;

RMAN> list archivelog all;

RMAN> list backup;

 

備份的維護:

查看:

RMAN> list backup;

RMAN> list copy;

RMAN> list backup of tablespace users;

RMAN> list backup of datafile 4;

RMAN> list archivelog all;

檢查備份:

RMAN> delete backup;                      刪除備份

RMAN> delete copy;

RMAN> list backup;          list copy;

RMAN> report need backup;            根據策略檢查

RMAN> backup tablespace users;

RMAN> report need backup;

RMAN> CONFIGURE RETENTION POLICY TO REDUNDANCY 2;

RMAN> report need backup;

RMAN> CONFIGURE RETENTION POLICY clear;

RMAN> report obsolete;

刪除備份:

RMAN> delete backupset of tablespace users;

RMAN> delete backupset 1234;

RMAN> backup tablespace users;

RMAN> backup tablespace users;

RMAN> show all;

RMAN> delete obsolete;

crosscheck:

RMAN> delete backup;

RMAN> backup tablespace users;

RMAN> list backup of tablespace users;

$ mv /u01/app/oracle/fast_recovery_area/ORCL/backupset/…             改名

RMAN> restore datafile 4;                報錯

RMAN> crosscheck backup;

RMAN> list backup of tablespace users;           報廢狀態

RMAN> list expired backup;

$ mv /u01/app/oracle/fast_recovery_area/ORCL/backupset/…              恢復原名

RMAN> crosscheck backup;

RMAN> list backup of tablespace users;           可用狀態

RMAN> delete expired backup;

catalog:

$ cp /u01/app/oracle/fast_recovery_area/ORCL/backupset/…              復制

RMAN> delete backup;

RMAN> list backup;          backupset消失

$ mv /u01/app/oracle/fast_recovery_area/ORCL/backupset/…              恢復原名

RMAN> catalog recovery area noprompt;

RMAN> list backup;          backupset恢復

RMAN恢復

數據文件

oracle學習筆記

 

oracle學習筆記

RPO/RTO

數據文件:

不歸檔方式下丟失一個數據文件:

SQL> archive log list

備份前工作:

SQL> create table t1(x varchar2(50)) tablespace users;

SQL> insert into t1 values ('friday, before backup');

SQL> commit;

備份:

SQL>查詢v$datafile, v$logfile, v$tempfile, v$controlfile

SQL> shutdown immediate

$ cd $ORACLE_BASE/oradata/

$ cp -r orcl orcl.bak

$ cd $ORACLE_BASE/fast_recovery_area/orcl

$ cp control02.ctl control02.ctl.bak

SQL> startup

備份后工作:

SQL> insert into t1 values ('monday, after backup');

SQL> commit;

故障:

SQL> alter system flush buffer_cache;

$ cd $ORACLE_BASE/oradata/orcl

$ >users01.dbf

SQL> select * from t1;                        報錯

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log

$ dbv file=/u01/app/oracle/oradata/orcl/users01.dbf

恢復:

SQL> shutdown abort

$ cd $ORACLE_BASE/oradata

$ rm -rf orcl

$ mv orcl.bak orcl

$ cd $ORACLE_BASE/fast_recovery_area/orcl

$ mv control02.ctl.bak control02.ctl

SQL> startup

SQL> select * from t1;

 

歸檔模式下丟失一個數據文件:

SQL> archive log list

備份前工作:

SQL> create table t1(x varchar2(50)) tablespace users;

SQL> insert into t1 values ('friday, before backup');

SQL> commit;

備份:

RMAN> backup tablespace users tag "tbs_users_weekend_backup";

備份后工作:

SQL> select group#, sequence#, status, archived from v$log;

SQL> insert into t1 values ('after backup, logseq 7, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 8, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 9, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 10, current');

SQL> commit;

SQL> insert into t1 values ('after backup, logseq 10, current, uncommitted');

SQL> select * from t1;

故障:

SQL> shutdown abort

$ rm $ORACLE_BASE/oradata/orcl/users01.dbf

SQL> startup                       報錯

SQL> select open_mode from v$database;

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log

恢復:

RMAN> list backup of tablespace users;

RMAN> list archivelog all;

SQL> alter database datafile 4 offline;              systemundotbs不能offline

SQL> alter database open;

RMAN> restore datafile 4;

RMAN> recover datafile 4;

SQL> alter database datafile 4 online;

SQL> select * from t1;

 

通過不完全恢復解決用戶的誤操作:

SQL> archive log list

備份前工作:

SQL> create table t1(x varchar2(50)) tablespace users;

SQL> insert into t1 values ('before backup');

SQL> commit;

備份:

RMAN> backup database tag 'weekend_DB_full_backup';

備份后:

SQL> insert into t1 values ('after backup, before delete');

SQL> commit;

誤操作:

SQL> select sysdate from dual;

SQL> select dbms_flashback.get_system_change_number from dual;

SQL> delete t1;

SQL> commit;

SQL> create table after_delete (x int);             正確的操作

SQL> insert into after_delete values (1);

SQL> commit;

恢復:

RMAN>run {

startup force mount;

set until scn= 1806683;

restore database;

recover database;

alter database open resetlogs;

}

set until time=’2015-10-26 11:13:23’;     基于時間點恢復

 

SQL> select * from t1;

SQL> select * from after_delete;              丟失

SQL> select group#, sequence#, status, archived from v$log;

 

通過不完全恢復解決歸檔日志不連續:

SQL> archive log list

備份前:

SQL> create table t1(x varchar2(50)) tablespace users;

SQL> insert into t1 values ('before backup');

SQL> commit;

備份:

RMAN> backup database tag 'weekend_DB_full_backup';

備份后:

SQL> select GROUP#, SEQUENCE#, STATUS, archived from v$log;

SQL> insert into t1 values ('after backup, logseq 1, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 2, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 3, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 4, archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, logseq 5, current');

SQL> commit;

SQL> alter system checkpoint;

故障:

SQL> shutdown abort

$ rm /u01/app/oracle/oradata/orcl/users01.dbf

$ rm /u01/app/oracle/fast_recovery_area/ORCL/archivelog/2016_03_01/o1_mf_1_5_cfbcxo84_.arc

恢復:

SQL> startup

先嘗試只恢復一個數據文件失敗。

RMAN>run {

startup force mount;

set until sequence 5;

restore database;

recover database;

alter database open resetlogs;

}

SQL> select * from t1;

控制文件

丟失部分控制文件:

SQL> select * from v$controlfile;

$ >/u01/app/oracle/oradata/orcl/control01.ctl

SQL> select * from v$tablespace;             報錯

SQL> alter system checkpoint;                   報錯

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log

SQL> shutdown abort

SQL> startup nomount

SQL> show parameter control_files

$ cp /u01/app/oracle/fast_recovery_area/orcl/control02.ctl /u01/app/oracle/oradata/orcl/control01.ctl

SQL> alter database mount;

SQL> alter database open;

 

丟失全部控制文件(有自動備份):

RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;

RMAN> backup datafile 4;

$ >/u01/app/oracle/oradata/orcl/control01.ctl

$ >/u01/app/oracle/fast_recovery_area/orcl/control02.ctl

SQL> select * from v$tablespace;             報錯

SQL> alter system checkpoint;                   報錯

SQL> shutdown abort

SQL> startup nomount

RMAN> restore controlfile from autobackup;

RMAN> alter database mount;

RMAN> recover database;

RMAN> alter database open resetlogs;

 

丟失全部控制文件(沒有自動備份):

SQL> alter database backup controlfile to '/home/oracle/control.bak';

SQL> alter database backup controlfile to trace;

SQL> select * from v$diag_info;

spfile

有自動備份:

RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;

RMAN> backup datafile 4;

聯機恢復:

$ mv $ORACLE_HOME/dbs/spfileorcl.ora $ORACLE_HOME/dbs/spfileorcl.ora.bak

SQL> alter system set resource_limit=true;    報錯

SQL> create spfile='/home/oracle/spfile.bak' from memory;

$ mv /home/oracle/spfile.bak $ORACLE_HOME/dbs/spfileorcl.ora

脫機恢復:

SQL> shutdown immediate

$ mv $ORACLE_HOME/dbs/spfileorcl.ora $ORACLE_HOME/dbs/spfileorcl.ora.bak

RMAN> startup

RMAN> restore spfile from '/u01/app/oracle/fast_recovery_area/ORCL/autobackup/2015_10_26/o1_mf_s_894118741_c2vkgo8x_.bkp';

RMAN> startup force

 

沒有備份:

利用alert_orcl.log中的參數值,構造initorcl.ora

SQL> create spfile='/home/oracle/spfile.bak' from pfile;

利用備份init.ora

$ vi /u01/app/oracle/product/11.2.0/db_1/dbs/init.ora          完善參數

SQL>startup pfile='/u01/app/oracle/product/11.2.0/db_1/dbs/init.ora'

SQL> create spfile from pfile;

redo log

丟失一個成員:

SQL> select GROUP#, MEMBERS from v$log;

SQL> select GROUP#, MEMBER from v$logfile;

SQL> alter database add logfile member '/home/oracle/redo01b.log' to group 1;

SQL> alter database add logfile member '/home/oracle/redo02b.log' to group 2;

SQL> alter database add logfile member '/home/oracle/redo03b.log' to group 3;

SQL> alter system switch logfile;

SQL> alter system switch logfile;

SQL> alter system switch logfile;

故障:

SQL> select group#, status from v$log;            確認current

$ rm -f /home/oracle/redo02b.log                     刪除current組成員

SQL>alter system switch logfile;

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/alert_orcl.log

恢復:

SQL> alter database drop logfile member '/home/oracle/redo02b.log';

SQL> alter database add logfile member '/home/oracle/redo02b.log' reuse to group 2;

如果是當前日志組,不能刪除成員,只能先切換再修改

 

丟失inactive日志組:

故障:

SQL> alter system checkpoint;

SQL> select group#, status from v$log;            確認inactive

SQL> shutdown abort

$ rm -f /home/oracle/redo03b.log /u01/app/oracle/oradata/orcl/redo03.log

$ startup           報錯

恢復:

SQL> startup mount

SQL> select group#, status, archived from v$log;

SQL> alter database clear logfile group 3;

SQL> alter database open;

如果日志未歸檔:

SQL> alter database clear unarchived logfile group 3;

做數據庫的全備份

 

丟失current日志組(正常關閉數據庫):

故障:

SQL> select group#, status from v$log;            確認current

SQL> shutdown immediate

$ rm -f /home/oracle/redo02b.log /u01/app/oracle/oradata/orcl/redo02.log

SQL> startup             報錯

恢復:

SQL> startup mount

SQL> select group#, status , archived from v$log;

SQL> alter database clear unarchived logfile group 2;

SQL> alter database open;

做數據庫的全備份

 

丟失current日志組(非正常關閉數據庫):

故障:

RMAN> backup database;

SQL> create table t1(x varchar2(50));

SQL> insert into t1 values ('after backup, before archived');

SQL> commit;

SQL> alter system switch logfile;

SQL> insert into t1 values ('after backup, after archived, current');

SQL> commit;

SQL> insert into t1 values ('after backup, after archived, current, uncommitted');

SQL> alter system checkpoint;

SQL> shutdown abort

$ rm -f /home/oracle/redo03b.log /u01/app/oracle/oradata/orcl/redo03.log

SQL> startup             報錯

SQL> select group#, sequence#, status, archived from v$log;         確認日志序號

恢復:

RMAN>run {

startup force mount;

set until sequence 10;

restore database;

recover database;

alter database open resetlogs;}

SQL> select * from t1;               丟失數據

 

丟失active日志組:

 

恢復數據塊

故障:

SQL> create tablespace tbs01 datafile '/home/oracle/tbs01.dbf' size 5M;

SQL> create table t1 tablespace tbs01 as select * from dba_objects where rownum<=30000;

RMAN> backup tablespace tbs01;

SQL> alter system flush buffer_cache;

$ dd of=/home/oracle/tbs01.dbf bs=8k conv=notrunc seek=300<<EOF

SQL> select count(*) from t1;           報錯

$ dbv file='/home/oracle/tbs01.dbf'

恢復:

SQL> select file#, block# from v$database_block_corruption;

RMAN> recover datafile 6 block 300;

RMAN> recover corruption list;

 

DBMS_REPAIR包隔離數據塊

rman恢復目錄

SQL> show parametercontrol_file_record_keep_time

 

dbca創建數據庫rc(不配置emfra200M內存,字符集unicode

或者:

netca創建主機連接字符串rc指向自身。

 

rc

$ sqlplus sys/password@rc as sysdba

SQL> create tablespace rc_tbs datafile '/home/oracle/rc_tbs.dbf' size 50M;

SQL> create user rcowner identified by password default tablespace rc_tbs quota unlimited on rc_tbs;

SQL> grant recovery_catalog_owner to rcowner;

 

$ rman catalog rcowner/password@rc

RMAN> create catalog;

$ rman target sys/password@orcl catalog rcowner/password@rc

$ rman target / catalog rcowner/password@rc

RMAN> register database;

 

dbca刪除rc

flashback

功能                            依賴組件                   相關參數                            典型錯誤

query                          undo tbs                     undo_retention                 dml

version query            undo tbs                     undo_retention                 dml

flashback table         undo tbs                     undo_retention                 dml

flashback drop          recyclebin                  recyclebin, freespace       drop table

transaction query    supplemental log                                                    dml

fda                               flashback archive                                                    dml

database                    flashback log             db_flashback_retention_target       ddl

 

sys不允許閃回,創建新用戶

SQL> create user user01 identified by password;

SQL> grant dba to user01;

SQL> conn user01/password

flashbackquery

user01:

SQL> create table t1(x int);

SQL> create index t1_x_idx on t1(x);

SQL> insert into t1 values (1);

SQL> commit;

SQL> select sysdate from dual;

SQL> select dbms_flashback.get_system_change_number from dual;

SQL> delete t1;

SQL> commit;

SQL> select * from t1;

SQL> select * from t1 as of scn 1446069;

SQL> select * from t1 as of timestamp to_timestamp('2015-10-28 10:31:54', 'yyyy-mm-dd hh34:mi:ss');

SQL> truncate table t1;alter table t1 move;或收縮數據文件

SQL> select * from t1 as of scn 1446069;                  物理結構變化,閃回失敗

 

logminer

flashback version query

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> update t1 set x=2;

SQL> commit;

SQL> update t1 set x=3;

SQL> commit;

SQL> update t1 set x=4;

SQL> commit;

SQL>select versions_starttime, versions_endtime, versions_xid, versions_operation, x

from t1

versions between scn minvalue and maxvalue

order by versions_starttime;

 

versions between timestamp to_timestamp('2015-10-28 9:00:00', 'yyyy-mm-dd hh34:mi:ss') and to_timestamp('2015-10-28 10:00:00', 'yyyy-mm-dd hh34:mi:ss')

SQL> truncate table t1;            物理結構改變,查詢失敗

flashback table

SQL> conn user01/password

SQL> create table my_dept(deptno int primary key, dname varchar2(20));

SQL> create table my_emp(empno int primary key, deptno int references my_dept);

SQL> insert into my_dept values (10, 'sales');

SQL> insert into my_emp values (100, 10);

SQL> commit;

SQL> select dbms_flashback.get_system_change_number from dual;

SQL> delete my_emp;

SQL> delete my_dept;

SQL> commit;

SQL> alter table my_dept enable row movement;

SQL> alter table my_emp enable row movement;

SQL> flashback table my_emp to scn 1451706;                失敗

SQL> flashback table my_dept to scn 1451706;

SQL> flashback table my_emp to scn 1451706;

SQL> select INDEX_NAME, STATUS from user_indexes where table_name='MY_EMP';自動維護索引

SQL> select INDEX_NAME, STATUS from user_indexes where table_name='MY_DEPT';

SQL> truncate table my_emp;

SQL> flashback table my_emp to scn 1451706;                失敗

flashback drop

SQL> show parameter recyclebin

SQL> purge recyclebin;

SQL> create tablespace tbs01 datafile '/home/oracle/tbs01.dbf' size 5M;

SQL> create table t1 tablespace tbs01 as select * from dba_objects where rownum<=20000;

SQL> create index t1_object_id_idx on t1(object_id) tablespace tbs01;

SQL> select INDEX_NAME from user_indexes where TABLE_NAME='T1';

SQL> drop table t1;

SQL> select table_name from user_tables;

SQL> show recyclebin

SQL> select object_name, original_name, type, droptime from user_recyclebin; 包含index

SQL> select count(*) from "BIN$IyKOcy5jPo7gUwEAqMCBEg==$0";

SQL> flashback table t1 to before drop;

SQL> select INDEX_NAME from user_indexes where TABLE_NAME='T1';

SQL> alter index "BIN$LRyc7hA1JaPgUwEAqMDzWw==$0" rename to T1_OBJECT_ID_IDX;       恢復index名稱

重名的處理:

SQL> flashback table "BIN$IyKOcy5jPo7gUwEAqMCBEg==$0" to before drop;

SQL> flashback table t1 to before drop rename to t2;

SQL> drop table t1;

SQL> show recyclebin                在回收站中

SQL> create table t2 tablespace tbs01 as select * from dba_objects where rownum<=30000;

SQL> show recyclebin                t1被覆蓋

SQL> drop table t2 purge;

SQL> purge recyclebin

flashback transaction query

SQL> alter database add supplemental log data;

SQL> alter database add supplemental log data (primary key) columns;

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> update t1 set x=11 where x=1;                 誤操作的事務

SQL> commit;

SQL> insert into t1 values (2);

SQL> commit;

select versions_starttime, versions_endtime, versions_xid, versions_operation, x

from t1

versions between scn minvalue and maxvalue

order by versions_starttime;            獲取誤操作事務的xid

SQL> select UNDO_SQL, OPERATION from flashback_transaction_query where xid='02000F0059040000';

flashback database

SQL> shutdown immediate

SQL> startup mount

SQL> alter database flashback on;            數據庫在歸檔模式下

SQL> show parameter db_flashback_retention_target

SQL> select OLDEST_FLASHBACK_TIME from v$flashback_database_log;

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> select dbms_flashback.get_system_change_number from dual;

SQL> truncate table t1;

SQL> create table after_truncate(x int);                   其他正確操作

SQL> select OLDEST_FLASHBACK_TIME, OLDEST_FLASHBACK_SCN from v$flashback_database_log; 確認是否在恢復范圍

SQL> shutdown abort

SQL> startup mount

SQL> flashback database to scn 1495195;

SQL> alter database open resetlogs;

SQL> select * from t1;

SQL> select * from after_truncate;                   消失

移動數據

sqlloader

SQL> create table t1(id int constraint t1_id_pk primary key, name varchar2(20), salary int constraint t1_salary_ck check(salary>0));

$ vi ~/loader.dat

100,"abc",1000

100,"def",2000

102,"xyz",-1000

em中常規導入,自動處理違反約束的記錄

 

em中直接導入

SQL> select CONSTRAINT_NAME, STATUS from user_constraints where TABLE_NAME='T1';

SQL> select INDEX_NAME, STATUS from user_indexes where TABLE_NAME='T1';

SQL> alter table t1 enable validate constraint T1_SALARY_CK;               失敗

SQL> @?/rdbms/admin/utlexpt1.sql

處理check約束:

SQL> alter table t1 enable validate constraint T1_SALARY_CK exceptions into exceptions;

SQL> select * from t1 where rowid in(select ROW_ID from exceptions);

SQL> update t1 set salary=abs(salary) where id=102;

SQL> truncate table exceptions;

SQL> alter table t1 enable validate constraint T1_SALARY_CK exceptions into exceptions;

處理pk約束:

SQL> alter table t1 disable novalidate constraint T1_ID_PK;

SQL> alter table t1 enable validate constraint T1_ID_PK exceptions into exceptions;

SQL> select * from t1 where rowid in(select ROW_ID from exceptions);

SQL> update t1 set id=101 where name='def';

SQL> truncate table exceptions;

SQL> alter table t1 enable validate constraint T1_ID_PK exceptions into exceptions;

SQL> select INDEX_NAME, STATUS from user_indexes where TABLE_NAME='T1';

外部表

oracle_datapump driver

unloading:

CREATE TABLE oe.inventories_xt

    ORGANIZATION EXTERNAL

    (

      TYPE ORACLE_DATAPUMP

      DEFAULT DIRECTORY DATA_PUMP_DIR

      LOCATION ('inv_xt.dmp')

    )

    AS SELECT * FROM oe.inventories;

SQL> delete oe.inventories_xt;                 失敗

loading:

CREATE TABLE oe.inventories_xt2

    (

      product_id          NUMBER(6),

      warehouse_id        NUMBER(3),

      quantity_on_hand    NUMBER(8)

    )

    ORGANIZATION EXTERNAL

    (

      TYPE ORACLE_DATAPUMP

      DEFAULT DIRECTORY DATA_PUMP_DIR

      LOCATION ('inv_xt.dmp')

    );

SQL> delete oe.inventories_xt2;               失敗

 

 

優化

DB time = CPU time + Wait time

自動化維護

準備工作

字典表:

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> select TABLE_NAME, NUM_ROWS from dba_tables where table_name='T1';     值為空

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select TABLE_NAME, NUM_ROWS from dba_tables where table_name='T1';     更新

SQL> insert into t1 values (2);

SQL> commit;

SQL> select TABLE_NAME, NUM_ROWS from dba_tables where table_name='T1';     過時

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select TABLE_NAME, NUM_ROWS, LAST_ANALYZED from dba_tables where table_name='T1';         更新

v$表:

SQL> select name, value from v$sysstat where name like '%sort%';

SQL> select * from hr.employees order by salary;

SQL> select name, value from v$sysstat where name like '%sort%';       增加

SQL> shutdown immediate

SQL> startup

SQL> select name, value from v$sysstat where name like '%sort%';       歸零

參數:

SQL> show parameterstatistics_level               不能是basic

AWR

em中查看基本設置

em中生成和查看awr報表

$ ll /u01/app/oracle/product/11.2.0/db_1/rdbms/admin/awr*.sql

serveralert

SQL> create tablespace tbs01 datafile '/home/oracle/tbs01.dbf' size 5M;

em中修改警告50%,嚴重80%

SQL> create table t1 tablespace tbs01 as select * from dba_objects where 1=0;

SQL> insert into t1 select * from dba_objects where rownum<=10000;

SQL> commit;           超過50%

SQL> insert into t1 select * from dba_objects where rownum<=20000;

SQL> commit;           超過80%

em中查看警告信息。

ADDM

session1:

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> update t1 set x=11;

session 2:

SQL> update t1 set x=22;

ASH

session1:

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> update t1 set x=11;

session 2:

SQL> update t1 set x=22;

em中尋找問題的根源

em中做ash報表

$ ll /u01/app/oracle/product/11.2.0/db_1/rdbms/admin/ash*.sql

AMM

initorcl.ora

spfileorcl.ora

ASMM

AMM

 

SQL> select bytes/1024/1024 from v$sgainfo where name='Granule Size';

SQL> show parameter memory

SQL> select COMPONENT, CURRENT_SIZE/1024/1024 from v$memory_dynamic_components;

em中的內存指導

$ strings $ORACLE_HOME/dbs/spfileorcl.ora           __開頭的隱含參數保留優化設置

 

javapool的調整:

SQL> select CURRENT_SIZE/1024/1024 from v$memory_dynamic_components where COMPONENT='java pool';

 

DECLARE

i NUMBER;

v_sql VARCHAR2(200);

BEGIN

  FOR i IN 1..200 LOOP

    -- Build up a dynamic statement to create a uniquely named java stored proc.

    -- The "chr(10)" is there to put a CR/LF in the source code.

    v_sql := 'create or replace and compile' || chr(10) ||

             'java source named "SmallJavaProc' || i || '"'  || chr(10) ||

             'as' || chr(10) ||

             'import java.lang.*;' || chr(10) ||

             'public class Util' || i || ' extends Object' || chr(10) ||

             '{ int v1=1;int v2=2;int v3=3;int v4=4;int v5=5;int v6=6;int v7=7; }';

    EXECUTE IMMEDIATE v_sql;

  END LOOP;

END;

/

SQL> select CURRENT_SIZE from v$memory_dynamic_components where COMPONENT='java pool';         java pool改變

java pool擴展、buffercache收縮

SQL> select OPER_TYPE, OPER_MODE, INITIAL_SIZE, TARGET_SIZE, FINAL_SIZE, START_TIME from v$memory_resize_ops where COMPONENT='java pool';

SQL> select OPER_TYPE, OPER_MODE, INITIAL_SIZE, TARGET_SIZE, FINAL_SIZE, START_TIME from v$memory_resize_ops where COMPONENT='DEFAULT buffer cache';

 

largepool的調整:

SQL> select CURRENT_SIZE/1024/1024 from v$memory_dynamic_components where COMPONENT='large pool';

SQL> create table t1 as select rownum x from dual connect by level<=100000;

SQL> alter table t1 parallel 64;        也可以在查詢時指定并行度

SQL> select /*+ parallel(t1 24) */ count(*) from (select /*+ parallel(t1 24)*/ * from t1 group by x);

SQL> select CURRENT_SIZE/1024/1024 from v$memory_dynamic_components where COMPONENT='large pool';    large pool改變

SQL> select OPER_TYPE, OPER_MODE, INITIAL_SIZE, TARGET_SIZE, FINAL_SIZE, START_TIME from v$memory_resize_ops where COMPONENT='large pool';

 

備份spfile

$ cp $ORACLE_HOME/dbs/spfileorcl.ora $ORACLE_HOME/dbs/spfileorcl.ora.bak

AMMàASMM

amm下,sgapga不需要設置

SQL> show parameter sga_max_size

SQL> show parameter sga_target

SQL> show parameter pga_aggregate_target

SQL> alter system set memory_target=0;

SQL> show parameter sga_target                     ammasmm都有一對參數

SQL> show parameter sga_max_size

SQL> show parameter pga_aggregate_target

SQL> alter system set sga_target=300M;        手動修改

 

ASMMàmanual

SQL> show parameter shared_pool_size         值為0

SQL> alter system set sga_target=0;

SQL> show parameter shared_pool_size         固定

 

manualàasmmàamm

修改sga_targetmemory_target,清空所有遺留參數

 

內存大小的建議:

SQL> select SHARED_POOL_SIZE_FOR_ESTIMATE ,SHARED_POOL_SIZE_FACTOR, ESTD_LC_TIME_SAVED from V$SHARED_POOL_ADVICE;

SQL> select SIZE_FOR_ESTIMATE, SIZE_FACTOR, ESTD_PHYSICAL_READS, ESTD_PHYSICAL_READ_FACTOR from V$DB_CACHE_ADVICE;

SQL> select * from V$SGA_TARGET_ADVICE;

SQL> select PGA_TARGET_FOR_ESTIMATE, PGA_TARGET_FACTOR, ESTD_PGA_CACHE_HIT_PERCENTAGE from V$PGA_TARGET_ADVICE;

SQL> select * from V$MEMORY_TARGET_ADVICE;

SAA

SQL> alter system flush shared_pool;

SQL> grant dba to hr;

SQL> conn hr/hr

SQL> set autot on

SQL> select e.last_name, d.department_name

from employees e, departments d

where e.department_id=d.department_id;

em中執行saa,過濾條件為表:hr.employees, hr.departments

STA

SQL> alter system flush shared_pool;

SQL> conn hr/hr

SQL> set autot on

SQL> select /*+ full(employees) */ * from employees where employee_id=100;

em中創建tuningset,調用sta分析

 

oracle學習筆記

SQL優化

優化器

參考:optimizer介紹.ppt

 

查詢改寫:

謂詞傳遞:

SQL> set autot trace exp

SQL>select e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id

and e.department_id=50;

自動添加3 - access("D"."DEPARTMENT_ID"=50)謂詞

 

for i in 1 .. 107(employees)

for j in 1 .. 27(departments)

    i的部門=j的部門而且 i的部門=50

endloop

endloop

 

for i in 1 .. 10 (employeesin deptno 50)

for j in 1 .. 27(departments)

    i的部門=j的部門

endloop

endloop

 

for i in 1 .. 10 (employeesin deptno 50)

  i的部門=50

endloop

 

子查詢解嵌套:

SQL> select last_name

from hr.employees outer

where salary >

(select avg(salary) from hr.employees

 where department_id = outer.department_id);

被改寫為多表連接

 

CBORBO的區別:

SQL> create table t1 as select 1 id, object_name from dba_objects;

SQL> update t1 set id=2 where rownum<=1;

SQL> commit;

SQL> select id, count(*) from t1 group by id;

SQL> create index t1_id_idx on t1(id);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> set autot trace exp

SQL> select * from t1 where id=1;            cbo方式

SQL> select /*+ rule */ * from t1 where id=1;

SQL> select * from t1 where id=2;            錯誤

SQL> select /*+ rule */ * from t1 where id=2;          走索引,正確

SQL> exec dbms_stats.gather_table_stats('sys', 't1');              重復搜集,獲取列值分布

exec dbms_stats.gather_table_stats('sys', 't1', method_opt => 'for columns size auto id');

SQL> select * from t1 where id=1;            cbo方式,正確

SQL> select * from t1 where id=2;            cbo方式,正確

SQL> select /*+ rule */ * from t1 where id=1;          走索引,錯誤

SQL> select /*+ rule */ * from t1 where id=2;

不及時更新統計信息,造成錯誤

SQL> update t1 set id=2;

SQL> commit;

SQL> select * from t1 where id=2;                     走索引,錯誤

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select * from t1 where id=2;                     正確

SQL> exec dbms_stats.delete_table_stats('sys', 't1');

SQL> update t1 set id=1 where rownum<=1;

SQL> commit;

SQL> select * from t1 where id=1;                     動態采樣

SQL> select * from t1 where id=2;                     動態采樣

 

影響cbo的初始化參數:

SQL> show parameter optimizer

all_rowsfirst_rows對執行計劃的影響:

SQL> alter session set optimizer_mode=first_rowsall_rows;

SQL> set autot trace exp

select e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

 

select /*+ all_rows */ e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;             使用sort merge

select /*+ first_rows */ e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;             使用nested loop

執行計劃

explain plan

SQL> desc plan_table

SQL> select * from plan_table;

SQL> explain plan set statement_id='test' for select * from hr.employees;

SQL> select PLAN_ID, OPERATION from plan_table where statement_id='test';            可讀性差

SQL> select plan_table_output from table(dbms_xplan.display);            可讀性比較好

不真正執行語句,對使用綁定變量的語句可能出現誤差

 

autotrace

SQL> set autot on

SQL> select count(*) from hr.employees;

SQL> set autot trace

SQL> select count(*) from hr.employees;

SQL> set autot trace exp

SQL> select count(*) from hr.employees;

SQL> set autot trace stat

SQL> select count(*) from hr.employees;

SQL> set autot off

on選項真正執行語句,但對使用綁定變量的語句可能出現誤差

其他選項不真正執行語句

 

DBMS_XPLAN

參考:PL/SQL Packages and Types ReferenceDBMS_XPLAN

explainplan配合:

參考explain plan示例

display_cursor:

查看上一個sql語句:

SQL>SET PAGESIZE 0

SQL> select count(*) from hr.employees;

SQL> SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR);

SQL> select count(*) from hr.employees;

SQL> SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR(null, null, 'advanced'));

 

SQL> desc v$sql

SQL> desc v$sql_plan

SQL> desc v$sql_plan_statistics

SQL> select count(*) from hr.employees;

SQL> select sql_id, child_number, sql_text from v$sql where sql_text like 'select count(*) from hr.employees';

SQL> select OPERATION, OPTIONS, OBJECT_NAME from v$sql_plan where SQL_ID='3ghpkw4yp4dzm' and CHILD_NUMBER=0;

SQL> SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('3ghpkw4yp4dzm',0, 'advanced'));

 

也可以從awr快照中獲取sql執行計劃,display_awr

 

sql trace:

SQL> show parameter sql_trace

SQL> show parameter statistics_level

SQL> show parameter timed_statistics

輔助參數

SQL> show parameter max_dump_file_size

SQL> show parameter diagnostic_dest

SQL> show parameter tracefile_identifier

SQL> select * from v$diag_info;

SQL> alter session set sql_trace=true;

SQL> select count(*) from hr.employees;

SQL> select count(*) from hr.departments;

SQL> alter session set sql_trace=false;

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_6651.trc

$ tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_6651.trc /home/oracle/output.trc

$ vi /home/oracle/output.trc

 

使用DBMS_MONITOR監控指定session:

SQL> select sid, serial# from v$session where USERNAME='HR';

SQL>EXEC DBMS_MONITOR.SESSION_TRACE_ENABLE(30, 4145, TRUE, TRUE);

hrsession:

SQL> select count(*) from employees;

sys關閉跟蹤:

SQL> EXEC DBMS_MONITOR.SESSION_TRACE_DISABLE(30, 4145);

hr的跟蹤文件:

SQL> select * from v$diag_info;

$ vi /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_10676.trc

 

 

使用trcsess匯總共享服務器連接下的用戶會話信息。

 

執行計劃的讀取:

SQL> set linesize 999

SQL> set autot trace exp

SQL>select e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

sqlplussql developer中查看

 

統計信息:

SQL> alter system flush shared_pool;

SQL> alter system flush buffer_cache;

SQL> set autot on

SQL> select count(*) from hr.employees;

SQL> select count(*) from hr.employees;

優化器操作

full table scan

SQL> select * from hr.employees;

掃描高水標記以下的所有塊

查詢的比例、物理順序、表小、沒有索引、并行

selectivitycardinality參考:optimizer介紹.ppt

物理順序對全表掃描的影響:

SQL> create table t1 as select rownum x, dbms_random.value y from dual connect by level<=10000;

SQL> alter table t1 add constraint t1_x_pk primary key(x);

SQL> create table t2 as select * from t1 order by y;

SQL> alter table t2 add constraint t2_x_pk primary key(x);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> exec dbms_stats.gather_table_stats('sys', 't2');

SQL> select * from t1 where x between 1 and 100;

SQL> select * from t2 where x between 1 and 100;

SQL> select INDEX_NAME, CLUSTERING_FACTOR from dba_indexes where table_name in('T1', 'T2');

查詢語句對全表掃描的影響:

SQL> select * from hr.employees;

SQL> select * from hr.employees order by employee_id;

SQL> select employee_id from hr.employees;

SQL>select department_id from hr.employees;

db_file_multiblock_read_count對全表掃描的影響:

SQL> show parameter db_file_multiblock_read_count

SQL> create table t1 as select * from dba_objects;

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> set autot on

SQL> alter system set db_file_multiblock_read_count=16;

SQL> select count(*) from t1;

SQL> alter system set db_file_multiblock_read_count=64;

SQL> select count(*) from t1;

高水標記對全表掃描的影響:

SQL> delete t1;

SQL> commit;

SQL> set autot on

SQL> select count(*) from t1;           刪除數據后,hwm不下降,導致cr讀過多

SQL> alter table t1 move;

SQL> select count(*) from t1;

 

INDEX的使用方式

INDEX UNIQUE SCAN:

SQL> select * from hr.employees where employee_id=100;

INDEX RANGE SCAN:

SQL> select * from hr.employees where employee_id between 100 and 110;

SQL> select * from hr.employees where department_id=10;

SQL> select * from hr.employees where last_name='King';

SQL> select INDEX_NAME, UNIQUENESS from dba_indexes where TABLE_NAME='EMPLOYEES';

INDEX FULL SCAN:   單塊,有序

SQL> select * from hr.employees order by employee_id;

SQL> select /*+ full(employees) */ * from hr.employees order by employee_id;

SQL> select * from hr.employees order by department_id;    全表掃描,因為有null

INDEX FAST FULL SCAN: 多塊,無序

SQL> create table t1 as select rownum id, object_name from dba_objects;

SQL> alter table t1 add constraint t1_id_pk primary key(id);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select count(*) from t1;

SQL> select /*+ index(t1 t1_id_pk) */ count(*) from t1; full scan的開銷大

SQL> select /*+ full(t1) */ count(*) from t1;

SQL> select /*+ index_ffs(employees emp_emp_id_pk) */ employee_id from hr.employees;

INDEX SKIP SCAN:

SQL> create table t1 as select * from dba_objects;

SQL> select count(distinct owner), count(distinct object_type), count(distinct object_name) from t1;

SQL> create index t1_idx on t1(owner, object_type, object_name);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select * from t1 where owner='SYS' and object_type='TABLE' and object_name='AUD$';

SQL> select * from t1 where owner='SYS' and object_type='TABLE';

SQL> select * from t1 where object_type='TABLE' and object_name='AUD$';

SQL> select /*+ full(t1) */ * from t1 where object_type='TABLE' and object_name='AUD$';

 

class_no: 5

stud_no: 50(每個班級)

1

1 2 3 … 50

2

1 2 3 … 50

 

5

1 2 3 … 50

 

 

 

 

where stud_no between 5 and 10;

where class_no=1 and stud_nobetween 5 and 10

or    class_no=2 and stud_nobetween 5 and 10

or    class_no=3 and stud_nobetween 5 and 10

 

null對索引的影響:

SQL> create table t1(x int, y char(1));

SQL> insert into t1 values (null, 'a');

SQL> insert into t1 values (1, 'a');

SQL> insert into t1 values (2, 'a');

SQL> create index t1_x_idx on t1(x);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

測試下列語句:

select x from t1;

select count(*) from t1;

select count(*) from t1 where x is not null;

select count(x) from t1;

select max(x) from t1;

select min(x), max(x) from t1;

排除null,再次測試:

SQL> delete t1 where x is null;

SQL> commit;

SQL> alter table t1 modify(x not null);

SQL> select (select min(x) from t1), (select max(x) from t1) from dual;

 

重復值對索引的影響:

SQL> create table t1(x int not null, y int);

SQL> insert into t1 select rownum, 11 from dual connect by level<=10;

SQL> commit;

SQL> create index t1_x_idx on t1(x);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select * from t1 where x=1;                      full table scan

SQL> select INDEX_NAME, UNIQUENESS from dba_indexes where TABLE_NAME='T1';

SQL> drop index t1_x_idx;

SQL> create unique index t1_x_idx on t1(x);

SQL> select * from t1 where x=1;                      index unique scan

 

外鍵對索引的影響:

SQL> create table dept(deptno int constraint dept_deptno_pk primary key, dname varchar2(10));

SQL> create table emp(empno int, deptno int constraint dept_emp_deptno_fk references dept(deptno));

SQL> insert into dept values (10, 'sales');

SQL> insert into dept values (20, 'market');

SQL> insert into dept values (30, 'it');

SQL> insert into emp values (100, 10);

SQL> commit;

SQL> exec dbms_stats.gather_table_stats('sys', 'dept');

SQL> exec dbms_stats.gather_table_stats('sys', 'emp');

SQL> alter session set sql_trace=true;

SQL> delete dept where deptno=10;                報錯

SQL> delete dept where deptno=20;

SQL> alter session set sql_trace=false;

SQL> select * from v$diag_info;

$ tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_22830.trc /home/oracle/output.trc

$ vi /home/oracle/output.trc

 

SQL> alter table emp modify(deptno not null);

SQL> create index emp_deptno_idx on emp(deptno);

SQL> alter session set sql_trace=true;

SQL> delete dept where deptno=10;                報錯

SQL> alter session set sql_trace=false;

 

類型轉換對索引的影響:

SQL> create table t1(x char(1) primary key, y int);

SQL> insert into t1 values ('1', 11);

SQL> insert into t1 values ('2', 22);

SQL> commit;

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> set autot trace exp

SQL> select * from t1 where x=1;

 

函數索引:

SQL> create table t1 as select * from dba_objects;

SQL> create index t1_object_name_fbi on t1(lower(object_name));

SQL> select * from t1 where lower(object_name)='aud$';

 

create index t1_idx on t1(reverse(x));

where x like reserve(‘%abc%’);

 

bitmap index:

emp

ename      gender     deptno     location    job_id

abc            M               10              BJ               MGR

def             F                 20              SH              EGR

xyz             M               30              GZ             MGR

select ename

from emp

where gender=’M’ and (deptno=10 or location=’GZ’) and job_id=’MGR’;

 

gender     M     F

abc            1       0

def             0       1

xyz             1       0

 

deptno     10     20     30

abc            1       0       0

def             0       1       0

xyz             0       0       1

 

location    BJ     SH    GZ

abc            1       0       0

def             0       1       0

xyz             0       0       1

 

job_id       MGR         EGR

abc            1                0

def             0                1

xyz             1                0

                   gender(M)        and  (deptno(10)or  location(GZ))    and job_id(mgr)

abc            1                                   1                                   0                                   1                                   1

def             0                                   0                                   0                                   0                                   0

xyz             1                                   0                                   1                                   1                                   1

多表連接

nested loop:

for emp in 1..107

  for dept in 1..27

    emp.deptno=dept.deptno

  end;

end;

 

for dept 1-27

  for emp 1-107

 

 

 

 

 

sort merge:

emp 根據deptno排序

dept根據deptno排序

合并empdept

 

hashjoin:

emp 根據hash函數對deptno分割

dept根據hash函數對deptno分割

 

select /*+ first_rows */ e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

或者使用/*+ use_nl(e d) */,但限制了驅動表和被驅動表,不靈活

 

SQL> alter index hr.EMP_DEPARTMENT_IX invisible;               禁用emp上的外鍵索引

執行多表連接時,將dept的主鍵索引作為內部被驅動表,nl會盡量避免對被驅動表的全表掃描。

SQL> alter index hr.EMP_DEPARTMENT_IX visible;                  恢復索引

 

select /*+ use_merge(e d) */ e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

 

select /*+ use_hash(e d) */ e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

 

在缺失索引時,傾向使用hashjoin:

SQL> alter index hr.EMP_DEPARTMENT_IX invisible;

SQL> alter index hr.DEPT_ID_PK invisible;

select e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

SQL> alter index hr.EMP_DEPARTMENT_IX visible;

SQL> alter index hr.DEPT_ID_PKvisible;

統計信息

基本視圖

SQL> desc dba_tab_statistics

SQL> desc dba_tab_col_statistics

SQL> desc dba_ind_statistics

SQL> create table t1 as select * from dba_objects;

SQL> create index t1_object_id_idx on t1(object_id);

SQL> create index t1_owner_idx on t1(owner);

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL>select * from DBA_TAB_STATISTICS where TABLE_NAME='T1';

SQL>select * from DBA_TAB_COL_STATISTICS where TABLE_NAME='T1';

SQL>select * from DBA_IND_STATISTICS where TABLE_NAME='T1';

SQL> select count(*) from t1 where owner='SYS';            沒有直方圖,使用錯誤計劃

直方圖

SQL> create table t1(x int not null, y varchar2(128));

SQL> create index t1_x_idx on t1(x);

SQL> insert into t1 select 1, object_name from dba_objects where rownum<=10000;

SQL> insert into t1 select 2, object_name from dba_objects where rownum<=1;

SQL> commit;

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> select x, count(*) from t1 group by x;

SQL>select * from DBA_TAB_STATISTICS where TABLE_NAME='T1';

SQL>select * from DBA_TAB_COL_STATISTICS where TABLE_NAME='T1';     未搜集直方圖

SQL>select * from DBA_IND_STATISTICS where TABLE_NAME='T1';

SQL> set autot on

SQL> select * from t1 where x=1;             rows不準確

SQL> select * from t1 where x=2;

SQL> exec dbms_stats.gather_table_stats('sys', 't1', method_opt => 'for columns x size skewonly');   搜集列x的直方圖

SQL>select * from DBA_TAB_COL_STATISTICS where TABLE_NAME='T1';

SQL>select * from dba_histograms where table_name='T1' and column_name='X';

SQL> select * from t1 where x=1;             正確

SQL> select * from t1 where x=2;             正確

SQL> select count(distinct y) from t1;      超過254

SQL> select * from t1 where y like 'DBA%';

SQL> exec dbms_stats.gather_table_stats('sys', 't1', method_opt => 'for columns size auto y');

SQL>select * from DBA_TAB_COL_STATISTICS where TABLE_NAME='T1';              創建等高直方圖

select COLUMN_NAME, HISTOGRAM, NUM_BUCKETS from DBA_TAB_COLUMNS where TABLE_NAME='T1';

綁定變量和共享游標

共享游標shared curosr

SQL> conn / as sysdba

SQL> create table t1 (x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL> alter system flush shared_pool;

SQL> select * from t1;

查看父游標、子游標和執行計劃:

select sql_text, sql_id, plan_hash_value, version_count from v$sqlarea where sql_text like 'select * from t1';

select plan_hash_value, child_number from v$sql where sql_id='27uhu2q2xuu7r';

select * from v$sql_plan where plan_hash_value='3617692013';

SQL> conn hr/hr

SQL> create table t1(x int primary key);

SQL> insert into t1 values (1);

SQL> commit;

SQL> select * from t1;

再次查詢父游標、子游標和執行計劃:3個語句

SQL> select * from  t1;           要求字面值完全一致

select sql_text, sql_id, plan_hash_value, version_count from v$sqlarea where sql_text like 'select * from %t1';

 

session cursor:

SQL> show parameter open_cursors

SQL> show parameter session_cached_cursors

SQL> select * from t1;

SQL> select distinct sid from v$mystat;

SQL>select * from v$open_cursor where sid=33;

 

性能差異:

SQL> create table t1(x int not null, y int);

SQL> create index t1_x_idx on t1(x);

SQL> insert into t1 select rownum, 11 from dual connect by level<=100;

SQL> commit;

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

alter session set sql_trace=true;

begin

for i in 1..100 loop

    execute immediate 'select * from t1 where x='||i;

  end loop;

end;

/

begin

for i in 1..100 loop

    execute immediate 'select * from t1 where x=:x' using i;

  end loop;

end;

/

alter session set sql_trace=false;

 

bindingvariablepeekingacs

SQL> create table t1 (x int not null, y int);

SQL> create index t1_x_idx on t1(x);

SQL> insert into t1 select 1, 11 from dual connect by level<=10000;

SQL> insert into t1 values (2, 22);

SQL> commit;

SQL> exec dbms_stats.gather_table_stats('sys', 't1', method_opt=>'for all columns');

SQL>select * from DBA_TAB_COL_STATISTICS where TABLE_NAME='T1';     搜集直方圖

SQL> alter session set optimizer_features_enable='10.2.0.1';

SQL> alter system flush shared_pool;

SQL> var x number;

SQL> exec :x := 1

SQL> select * from t1 where x=:x;

SQL> set pagesize 0

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));

查看父游標、子游標:

select sql_text, sql_id, plan_hash_value, version_count, executions from v$sqlarea where sql_text like 'select * from t1 where x=%';

select plan_hash_value, child_number from v$sql where sql_id='8h3m8wg51m8nm';

select * from v$sql_plan where plan_hash_value='3617692013';

SQL> exec :x := 2

SQL> select * from t1 where x=:x;

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));         錯誤

再次查看游標:3個語句

acs:

SQL> conn / as sysdba      恢復優化器版本

SQL> alter system flush shared_pool;

SQL> var x number;

SQL> exec :x := 1

SQL> select * from t1 where x=:x;

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));

查看游標:3個語句

SQL> exec :x := 2

SQL> select * from t1 where x=:x;

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));         不變

SQL> select * from t1 where x=:x;

SQL> select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));         索引

查看游標:3個語句

sharedpool

latchmutex

shared pool latch數量:

select a.ksppinm, b.ksppstvl, a.ksppdesc

from x$ksppi a, x$ksppsv b

where a.indx=b.indx

and a.ksppinm='_kghdsidx_count';

 

SQL> create table t1 as select rownum x from dual connect by level<=500000;

SQL> exec dbms_stats.gather_table_stats('sys', 't1');

SQL> alter system flush shared_pool;

SQL> exec dbms_workload_repository.create_snapshot()

SQL> select distinct sid from v$mystat;

模擬硬解析:

begin

for i in 1..500000 loop

    execute immediate 'select * from t1 where x='||i;

  end loop;

end;

/

 

另一個session監控:

SQL>select * from v$session_wait where sid=143;

SQL> exec dbms_workload_repository.create_snapshot()

 

emawr的報表和addmash報表和挖掘drilldown

 

mutex等待事件:

SQL> alter system set memory_target=0;

SQL> alter system set sga_target=0;

SQL> alter system flush shared_pool;

SQL> exec dbms_workload_repository.create_snapshot()

在兩個session中同時執行:

begin

loop

  execute immediate 'alter system flush shared_pool';

for i in 1..1000 loop

    execute immediate 'select * from t1 where x='||i;

  end loop;

end loop;

end;

/

 

另一個session監控:

select * from v$session_wait where sid=143;

SQL> exec dbms_workload_repository.create_snapshot()

emawr的報表和addmash報表和挖掘drilldown

buffercache

Latch:cache buffer chains

SQL> create table t1(x int);

SQL> insert into t1 values (1);

SQL> commit;

SQL>select distinct sid from v$mystat;

SQL> exec dbms_workload_repository.create_snapshot()

兩個session同時執行:

declare

  v1 int;

begin

  for i in 1..99999999

  loop

    select count(*) into v1 from t1;

  end loop;

end;

/

 

3session中:

SQL> select * from v$session_wait where sid in (136, 137);

SQL> exec dbms_workload_repository.create_snapshot()

 

Buffer busy waits

兩個session中運行:

declare

  v1 int;

begin

  for i in 1..99999999

  loop

insert into t1 values (i);

  end loop;

end;

/

3session中:

SQL> select * from v$session_wait where sid in (136, 137);

SQL> exec dbms_workload_repository.create_snapshot()

 

 

 

 

 

 

 

 

優化實例

create table t1(x int, y char(1));

insert into t1 values (1, 'a');

insert into t1 values (2, 'a');

create index t1_x_idx on t1(x);

exec dbms_stats.gather_table_stats('sys', 't1');

為什么沒用索引?

select x from t1;

 

 

 

 

 

create table t1 as select 1 id, object_name from dba_objects;

update t1 set id=2 where rownum<=1;

commit;

select id, count(*) from t1 group by id;

create index t1_id_idx on t1(id);

exec dbms_stats.gather_table_stats('sys', 't1', METHOD_OPT => 'FOR ALL COLUMNS size 1');

為什沒用索引?

select * from t1 where x=2;

 

 

 

 

 

alter session set optimizer_mode='first_rows';

客戶抱怨響應時間長

select e.last_name, d.department_name

from hr.employees e, hr.departments d

where e.department_id=d.department_id;

 

 

 

 

 

 

 

 

 

 

create table t1 (x int);

create or replace procedure proc1

as

begin

  for iin 1..100000 loop

execute immediate 'insert into t1 values ('||i||')';

commit;

  end loop;

end;

/

客戶抱怨運行時間長

begin

  proc1;

end;

/

 

 

 

 

 

 

 

 

 

 

1.         原始語句,動態sql,未使用綁定變量:

drop table t1 purge;

create table t1 (x int);

 

create or replace procedure proc1

as

begin

  for iin 1..100000 loop

execute immediate 'insert into t1 values ('||i||')';

commit;

  end loop;

end;

/

 

alter system flush shared_pool;

set timing on

exec proc1;

select count(*) from t1;

44秒完成。

 

select sql_text, sql_id, parse_calls, executions from v$sql where lower(sql_text) like '%insert into t1 values%';

動態sql靈活,處理ddldml的對象預先不存在的時候很方便,但在運行時才解析,性能差。

不使用綁定變量,每個語句都是解析一次,執行一次,效率差。

2.         改寫,使用綁定變量:

drop table t1 purge;

create table t1 (x int);

 

create or replace procedure proc1

as

begin

  for i in 1..100000 loop

    execute immediate 'insert into t1 values (:x)' using i;

commit;

  end loop;

end;

/

 

alter system flush shared_pool;

set timing on

exec proc1;

12秒完成。

 

select sql_text, sql_id, parse_calls, executions from v$sql where lower(sql_text) like '%insert into t1 values%';

使用綁定變量,解析1次,執行10萬次。

3.         改寫,使用靜態sql

drop table t1 purge;

create table t1 (x int);

 

create or replace procedure proc1

as

begin

  for i in 1..100000 loop

insert into t1 values (i);

commit;

  end loop;

end;

/

 

alter system flush shared_pool;

set timing on

exec proc1;

10秒完成。

 

select sql_text, sql_id, parse_calls, executions from v$sql where lower(sql_text) like '%insert into t1 values%';

靜態sql自定使用綁定變量,解析1次,執行10萬次。并且在編譯過程中就解析好了。

4.         改寫,批量提交:

drop table t1 purge;

create table t1 (x int);

 

create or replace procedure proc1

as

begin

  for i in 1..100000 loop

    insert into t1 values (i);

  end loop;

  commit;

end;

/

 

alter system flush shared_pool;

set timing on

exec proc1;

5秒完成。

5.         改寫,使用集合操作:

drop table t1 purge;

create table t1 (x int);

insert into t1 select rownum from dual connect by level<=100000;

或者

create or replace procedure proc1

as

  TYPE dual_typ IS TABLE OF int

      INDEX BY PLS_INTEGER;

  dual_var dual_typ;

begin

   SELECT rownum BULK COLLECT INTO dual_var

   FROMdual connect by level<=100000;

   forall i in dual_var.first .. dual_var.last

     insert into t1 values (dual_var(i));

END;

/

 

alter system flush shared_pool;

set timing on

exec proc1;

0.12秒完成

將一條條插入改為一批寫入buffer的塊里。

6.         改寫,使用直接路徑:

drop table t1 purge;

create table t1 as select rownum x from dual connect by level<=100000;

0.08

insert into先寫內存再刷到磁盤,create table直接刷磁盤。

7.         改寫,使用并行:

drop table t1 purge;

create table t1 nologging parallel 16 as select rownum x from dual connect by level<=100000;

RAC

安裝

1.         創建虛擬機

名稱:node1_RAC_11gR2_rhel6u5_x64node2_RAC_11gR2_rhel6u5_x64

2.5-4g內存,引導:硬盤+cdrom,網卡1hostonly,網卡2內部網絡

主機名:node1.test.comnode2.test.com

網絡:

第一塊網卡改名:eth0,勾選自動連接

手動ip192.168.0.1/24,網關:192.168.0.254dns192.168.0.1,192.168.0.2

手動ip192.168.0.2/24,網關:192.168.0.254dns192.168.0.1,192.168.0.2

第二塊網卡改名:eth2,勾選自動連接

手動ip192.168.1.1/24

手動ip192.168.1.2/24

時區:asia/shanghai

存儲:use all spacereview,刪除/homeswap4096MB,其他都給/

安裝包:desktop

2.         調整系統:

關閉防火墻:

service iptables stop

service ip6tables stop

chkconfig iptables off

chkconfig ip6tables off

管理工具中disabled防火墻

關閉selinux

# vi /etc/selinux/config

SELINUX=disabled

配置yum

# rm -f /etc/yum.repos.d/*

# vi /etc/yum.repos.d/rhel6.repo

[Server]

name=Server

baseurl=file:///media/"RHEL_6.5 x86_64 Disc 1"/Server

enabled=1

gpgcheck=0

安裝vb增強功能:

# yum -y install gcc kernel-devel

# ln -s /usr/src/kernels/2.6.32-431.el6.x86_64/ /usr/src/linux

 

設備-->安裝增強功能

右鍵eject彈出光盤

3.         硬件要求:

內存/swap/tmp/shared momory

# vi /etc/fstab(永久修改)

tmpfs        /dev/shm          tmpfs        defaults,size=4G                0 0

# mount -o remount /dev/shm

臨時修改

# mount -t tmpfs shmfs -o size=4g /dev/shm

 

4.         設置用戶和目錄:

用戶:gridoracle

群組:oinstall, asmadmin, asmdba, asmoper, dba, oper

groupadd -g 1000 oinstall

groupadd -g 1001 dba

groupadd -g 1002 oper

groupadd -g 1003 asmadmin

groupadd -g 1004 asmdba

groupadd -g 1005 asmoper

useradd -u 1000 -g oinstall -G dba,oper,asmdba oracle

useradd -u 1001 -g oinstall -G asmadmin,asmdba,asmoper grid

mkdir -p /u01/app/grid

mkdir -p /u01/app/11.2.0/grid

mkdir -p /u01/app/oracle

chown -R grid:oinstall /u01

chown oracle:oinstall /u01/app/oracle

chmod -R 775 /u01

 

passwd grid

passwd oracle

 

5.         設置userprofile文件:

# vi ~grid/.bash_profile

export ORACLE_SID=+ASM1                      node2上改為+ASM2

export ORACLE_BASE=/u01/app/grid

export ORACLE_HOME=/u01/app/11.2.0/grid

export TNS_ADMIN=$ORACLE_HOME/network/admin

export PATH=$PATH:$ORACLE_HOME/bin

export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib

export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

export EDITOR=vi

export

export NLS_LANG=american_america.AL32UTF8

export NLS_DATE_FORMAT='yyyy-mm-dd hh34:mi:ss'

umask 022

 

#vi ~grid/.bashrc

alias sqlplus='rlwrap sqlplus'

alias asmcmd='rlwrap asmcmd'

 

# vi ~oracle/.bash_profile

export ORACLE_SID=orcl1                          node2上改為orcl2

export ORACLE_BASE=/u01/app/oracle

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1

export TNS_ADMIN=$ORACLE_HOME/network/admin

export ORACLE_HOSTNAME=node1.test.com                  node2上改為node2.host.com

export ORACLE_UNQNAME=orcl

export PATH=$PATH:$ORACLE_HOME/bin

export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib

export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

export NLS_LANG=american_america.AL32UTF8

export NLS_DATE_FORMAT='yyyy-mm-dd hh34:mi:ss'

export EDITOR=vi

export

umask 022

 

#vi ~oracle/.bashrc

alias sqlplus='rlwrap sqlplus'

alias rman='rlwrap rman'

6.         修改資源限制:

# vi /etc/security/limits.conf

grid           soft            nofile        1024

grid           hard          nofile        65536

grid           soft            nproc        2047

grid           hard          nproc        16384

grid           soft            stack         10240

grid           hard    stack                   32768

 

oracle       soft            nofile        1024

oracle       hard          nofile        65536

oracle       soft            nproc        2047

oracle       hard          nproc        16384

oracle       soft            stack         10240

oracle       hard    stack                   32768

7.         修改內核參數:

# vi /etc/sysctl.conf

fs.aio-max-nr = 1048576

fs.file-max = 6815744

kernel.shmall = 2097152

kernel.shmmax = 2076053504

kernel.shmmni = 4096

kernel.sem = 250 32000 100 128

net.ipv4.ip_local_port_range = 9000 65500

net.core.rmem_default = 262144

net.core.rmem_max = 4194304

net.core.wmem_default = 262144

net.core.wmem_max = 1048576

# sysctl -p

8.         安裝軟件包:

# yum -y install …

binutils-2.20.51.0.2-5.11.el6 (x86_64)

compat-libcap1-1.10-1 (x86_64)

compat-libstdc++-33-3.2.3-69.el6 (x86_64)

compat-libstdc++-33-3.2.3-69.el6.i686

gcc-4.4.4-13.el6 (x86_64)

gcc-c++-4.4.4-13.el6 (x86_64)

glibc-2.12-1.7.el6 (i686)

glibc-2.12-1.7.el6 (x86_64)

glibc-devel-2.12-1.7.el6 (x86_64)

glibc-devel-2.12-1.7.el6.i686

ksh

libgcc-4.4.4-13.el6 (i686)

libgcc-4.4.4-13.el6 (x86_64)

libstdc++-4.4.4-13.el6 (x86_64)

libstdc++-4.4.4-13.el6.i686

libstdc++-devel-4.4.4-13.el6 (x86_64)

libstdc++-devel-4.4.4-13.el6.i686

libaio-0.3.107-10.el6 (x86_64)

libaio-0.3.107-10.el6.i686

libaio-devel-0.3.107-10.el6 (x86_64)

libaio-devel-0.3.107-10.el6.i686

make-3.81-19.el6

sysstat-9.0.4-11.el6 (x86_64)

elfutils-libelf-devel

安裝rlwrapbind

/installation/grid/rpm/cvuqdisk-1.0.9-1.rpm(用scp復制到node2

9.         配置網絡:

node1:

public(eth0): 192.168.0.1/24  網關:192.168.0.254

private(eth2): 192.168.1.1/24

node1virutal ip:192.168.0.11

node2:

public(eth0): 192.168.0.2/24  網關:192.168.0.254

private(eth2): 192.168.1.2/24

node2virutal ip:192.168.0.12

 

scanscanvipscan.test.com      192.168.0.101/102/103

 

# vi /etc/hosts

#node1

192.168.0.1              node1.test.com                 node1                #public ip

192.168.1.1               node1-priv.test.com         node1-priv        #private ip

192.168.0.11            node1-vip.test.com          node1-vip          #node1 vip

#node2

192.168.0.2              node2.test.com                 node2                #public ip

192.168.1.2               node2-priv.test.com         node2-priv        #private ip

192.168.0.12            node2-vip.test.com          node2-vip          #node2 vip

 

node1配置主dns

# vi /etc/named.conf

listen-on port 53 { any; };

listen-on-v6 port 53 { any; };

allow-query     { any; };

dnssec-enable no;

dnssec-validation no;

# vi /etc/named.rfc1912.zones

zone "test.com" IN {

        type master;

        file "test.com.hosts";

};

 

zone "0.168.192.in-addr.arpa" IN {

        type master;

        file "192.168.0.rev";

};

# vi /var/named/test.com.hosts

$TTL 1D

@               IN      SOA node1.test.com. root.node1.test.com. (

                          2016031601

                          3h

                          1h

                          1w

                          1h )

                IN      NS      node1.test.com.

                IN      NS      node2.test.com.

node1           IN      A       192.168.0.1

node2           IN      A       192.168.0.2

scan            IN      A       192.168.0.101

scan            IN      A       192.168.0.102

scan            IN      A       192.168.0.103

# vi /var/named/192.168.0.rev

$TTL 1D

@               IN      SOA node1.test.com. root.node1.test.com. (

                          1

                          3h

                          1h

                          1w

                          1h )

                IN      NS      node1.test.com.

                IN      NS      node2.test.com.

1               IN      PTR     node1.test.com.

2               IN      PTR     node2.test.com.

101             IN      PTR     scan.test.com.

102             IN      PTR     scan.test.com.

103             IN      PTR     scan.test.com.

# service named start

# chkconfig --level 35 named on

# nslookup

測試localhost/127.0.0.1/node1/192.168.0.1/node2/192.168.0.2/scan/192.168.0.101(102,103)

 

node2配置輔助dns

# vi /etc/named.conf

listen-on port 53 { any; };

listen-on-v6 port 53 { any; };

allow-query     { any; };

dnssec-enable no;

dnssec-validation no;

# vi /etc/named.rfc1912.zones

zone "test.com" IN {

        type slave;

        file "slaves/test.com.hosts";

                   masters {192.168.0.1;};

};

 

zone "0.168.192.in-addr.arpa" IN {

        type slave;

        file "slaves/192.168.0.rev";

                   masters {192.168.0.1;};

};

# service named start

chkconfig --level 35 named on

# nslookup - 192.168.0.2

測試localhost/127.0.0.1/node1/192.168.0.1/node2/192.168.0.2/scan/192.168.0.101(102,103)

10.     ntp

#service ntpd stop

# chkconfig ntpd off

# mv /etc/ntp.conf /etc/ntp.conf.bak

11.     配置共享存儲

SAN/NAS

ocr/voting disk: 31GB(+CRS)

data: 210GB(+DATA)

fra: 110GB(+FRA)

創建共享磁盤的子目錄:/root/virtualbox vms/shared_disk

關閉node1/node2

node1添加6塊磁盤(固定大小):

/root/virtualbox vms/shared_disk/asmdisk1.vdi

vb6塊硬盤改為可共享

node2添加6塊共享的磁盤

# ll /dev/sd*

執行命令:

#for i in b c d e f g ;

do

echo "KERNEL==\"sd*\", BUS==\"scsi\", PROGRAM==\"/sbin/scsi_id --whitelisted --replace-whitespace --device=/dev/\$name\", RESULT==\"`/sbin/scsi_id --whitelisted --replace-whitespace --device=/dev/sd$i`\", NAME=\"asm-disk$i\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\""      >> /etc/udev/rules.d/99-oracle-asmdevices.rules

done

# start_udev;ls /dev/asm*                 確認生成asmdisk

12.     node1/node2設置臨時共享

# mkdir /oracle; mount -t vboxsf oracle /oracle

# cd /oracle/software/

# yum -y install rlwrap-0.42-1.el6.x86_64.rpm

# cd /oracle/installation/grid/

# yum -y install cvuqdisk-1.0.9-1.rpm

13.     node1安裝gi

# xhost +

# su - grid

$ cd /oracle/installation/grid/

$ ./runInstaller

高級安裝,集群名稱:test-cluster, scan name: scan.test.com,不配置gns,添加node2,配置ssh

asm: 磁盤組名稱:CRSnormal方式,搜索路徑:/dev/asm*,使用bcd三塊硬盤

14.     測試gi

# su - grid

$ crsctl check crs

$ crsctl stat res -t

$ srvctl status asm

15.     node1創建asm磁盤組:

# su - grid

$ asmca

data: 210GBnormal

fra: 110GBexternal

16.     node1上安裝db

# su - oracle

$ cd /oracle/installation/database/

$ ./runInstaller

只安裝軟件,rac方式,選擇全部節點,oracle口令,ssh連接

17.     node1上創建db

dbcarac,數據庫orclnode1/node2,存儲asmdata磁盤組,fra使用+FRA磁盤組,sampleschema,內存800MB,字符集al32utf8

 

 

 

問題:

查看數據庫的字符集:

SQL> select * from v$nls_parameters;

刪除asm磁盤的頭部信息:

#dd if=/dev/zero of=/dev/sdb bs=1M count=1

手動建立ssh信任關系:

node1/node2

# su-grid

$ mkdir ~/.ssh

$ chmod 700 ~/.ssh

 

$ ssh-keygen -t rsa

$ ssh-copy-id 192.168.0.2         node1

$ ssh-copy-id 192.168.0.1         node2

 

ssh node1 date

ssh node2 date

ssh node1-priv date

ssh node2-priv date

關閉自動掛載,避免桌面崩潰:

chmod -x /usr/libexec/gvfs-gdu-volume-monitor

 

體系結構

vi /etc/init/oracle-ohasd.conf           ohasd啟動項

ps -ef | more    has相關的進程

# /u01/app/11.2.0/grid/bin/crsctl stat res -init-t              crsohas的資源

# /u01/app/11.2.0/grid/bin/crsctl stat res -t                     crs所管理的資源

兩個實例連接db(通過scan-vipnode-vip兩種方式),添加數據測試。

node1/node2:

# su - oracle

$ sqlplus / as sysdba

SQL> select instance_name from v$instance;

SQL> select name from v$database;

$ sqlplus sys/password@scan.test.com:1521/orcl as sysdba            多創建連接

$ sqlplus sys/password@192.168.0.11:1521/orcl as sysdba

$ sqlplus sys/password@192.168.0.12:1521/orcl as sysdba

集群管理

啟動/關閉crs和資源,在node1node2上都要執行(root身份):

# /u01/app/11.2.0/grid/bin/crsctlstopcrs[-f]

# /u01/app/11.2.0/grid/bin/crsctl start crs

啟動/關閉資源,在一個節點上執行(root身份):

# /u01/app/11.2.0/grid/bin/crsctlstop cluster -all

# /u01/app/11.2.0/grid/bin/crsctlstart cluster -all

查詢資源(grid用戶就可以):

$ crsctlstatres-t

$ olsnodes -h

 

實例管理

啟動關閉

sqlplusoracle用戶)/oem/srvctlgrid用戶)

實例級別:

# su - oracle

$ sqlplus / as sysdba

SQL> shutdown immediate

# su - grid

$ srvctl status instance -d orcl -i orcl1,orcl2                       查看實例狀態

$ srvctl stop instance -d orcl -i orcl1 -o immediate           關閉任意節點上實例

$ srvctl start instance -d orcl -i orcl1

數據庫級別:

$ srvctl status db -d orcl

$ srvctl stop db -d orcl -o immediate

$ srvctl start db -d orcl -o mount

$ srvctl modify db -d orcl -s open

$ srvctl config db -d orcl -a

$ srvctl modify db -d orcl -y manual

$ srvctl modify db -d orcl -y automatic

asm實例

# su - grid

$ ps -ef | grep asm*

$ sqlplus / as sysasm

SQL> startup|shutdown immediate         每個節點上單獨執行

$ srvctl status asm

$ srvctl stop asm -n node1 -o abort -f

$ srvctl start asm -n node1

 

spfile

查看:

# su - oracle

$ sqlplus / as sysdba

orcl1> show parameter spfile

# su - grid

$ asmcmd

ASMCMD> cd +data/orcl

# su - oracle

$ sqlplus / as sysdba

orcl1> create pfile='/home/oracle/pfile.ora' from spfile;

$ vi /home/oracle/pfile.ora

修改:

orcl1orcl2

# su - oracle

$ sqlplus / as sysdba

orcl1> show parameter open_cursors

orcl1> alter system set open_cursors=600;

SQL> alter system set open_cursors=600 sid='*';             相同

orcl2> show parameter open_cursors

orcl1> alter system set open_cursors=800 sid='orcl2';

orcl2> show parameter open_cursors

恢復:

orcl1> alter system reset open_cursors sid='orcl2';

orcl1> alter system reset open_cursors sid='*';

orcl1> alter system set open_cursors=300 sid='*';

 

存儲:

SQL> show parameter control_files

SQL> show parameter undo_tablespace

SQL> select GROUP#, THREAD#, STATUS, MEMBERS from v$log;

SQL> select GROUP#, MEMBER from v$logfile;

 

SQL>ALTER DATABASE ADD LOGFILE THREAD 1 GROUP 5 SIZE 50M;

SQL>ALTER DATABASE ADD LOGFILE THREAD 2 GROUP 6 SIZE 50M;

ocrvotingdisk

# vi /etc/oracle/ocr.loc              ocr位置

# cd /u01/app/11.2.0/grid/bin

#./ocrcheck

#./ocrconfig -showbackup                 查看主節點上的自動備份

# ./ocrconfig -manualbackup            手動備份,root身份,保存在主節點

# ./ocrconfig-backuploc …                 改備份路徑

# ./ocrdump;vi OCRDUMPFILE

# rm OCRDUMPFILE

# ./ocrdump -h

# ./ocrcheck -config

# ./ocrconfig -add +DATA                   鏡像

# ./ocrcheck -config

# cat /etc/oracle/ocr.loc

# ./ocrconfig -delete +CRS        刪除鏡像

恢復:

# ./ocrconfig -add +CRS

# ./ocrconfig -delete +DATA

 

olr

# ll /u01/app/11.2.0/grid/cdata/node1.olr

# ./ocrcheck -local

# ./ocrdump -local /root/node1.olr

# vi /root/node1.olr

# ./ocrconfig -local -manualbackup

 

votingdisk

# ./crsctl query css votedisk

網絡

publicprivate

#ifconfig或者ip add

#oifcfg getif

node vipscanvip

# ip add

$ sqlplus sys/password@192.168.0.1:1521/orcl as sysdba

$ sqlplus sys/password@192.168.0.11:1521/orcl as sysdba

$ sqlplus sys/password@192.168.0.101:1521/orcl as sysdba 假定101node1

# ifdown eth0                     node1關閉網卡,觀察ip的漂移

# ip add    $ crsctl stat res -t

$ sqlplus sys/password@192.168.0.1:1521/orcl as sysdba

$ sqlplus sys/password@192.168.0.11:1521/orcl as sysdba

$ sqlplus sys/password@192.168.0.101:1521/orcl as sysdba

# ifup eth0                           node1開啟網卡,觀察ip的漂移

再次測試3個連接

listener:

# su - grid

$ lsnrctl status

$ lsnrctl status listener_scan1/2/3

# su - oracle

$ sqlplus / as sysdba

SQL> show parameter listener         查看和監聽相關的參數

$ srvctl relocate vip(scan) -h

$ srvctl relocate scan -i 1 -n node1

private ip的自動管理(haip):

$ crsctl stat res -t -init               確認ohasd維護的haip基礎服務

$ ifconfig

$ oifcfg getif

$ oifcfg iflist -p -n

SQL> select name, ip_address from v$cluster_interconnects;

 

網絡修改:

修改public hostname:重新安裝rac

修改privatehostname11.2.0.2以前重裝rac11.2.0.2以后在/etc/hosts隨意改

修改public/privateip:相同網絡,重啟rac,不同的網絡,修改orc

修改node vip/scan vip:使用srvctl修改

publiceth0: 192.168.0.1/24 à 172.16.0.1/16

private eth2: 192.168.1.1/24 à 10.0.0.0/8

node vip: 192.168.0.11/24 à 172.16.0.11/16

scan vip: 192.168.0.100(1 2) à 172.16.0.100(1 2)/16

修改publicip

# vi /etc/sysconfig/network-scripts/ifcfg-eth0          node1/node2os中修改publicip

node1上:

# su - grid

$ oifcfg getif

$ oifcfg delif -global eth0

$ oifcfg setif -global eth0/172.16.0.0:public

ASM

ASM=RAID+LVM

SAME

 

asm的實例:

$ ps -ef | grep asm

# su - grid

$ sqlplus / as sysasm

+ASM1> show parameter memory

+ASM1> select component, current_size from v$sga_dynamic_components;

+ASM1> show parameter listener

啟動關閉實例:

SQL> startup/shutdown abort          啟動到nomount階段停止

$ srvctl start asm

$ srvctl stop asm -f

SQL> show parameter

 

diskgroup

條帶化RAID 0,鏡像RAID1RAID1+0

vbnode1添加31GB硬盤,共享給node2

# for i in h i j ;

do

echo "KERNEL==\"sd*\", BUS==\"scsi\", PROGRAM==\"/sbin/scsi_id --whitelisted --replace-whitespace --device=/dev/\$name\", RESULT==\"`/sbin/scsi_id --whitelisted --replace-whitespace --device=/dev/sd$i`\", NAME=\"asm-disk$i\", OWNER=\"grid\", GROUP=\"asmadmin\", MODE=\"0660\""      >> /etc/udev/rules.d/99-oracle-asmdevices.rules

done

# start_udev;ls /dev/asm*                 確認生成asmdisk

使用sqlplus/oem/asmca/asmcmd

grid用戶登錄桌面,asmca創建diskgrouptestdgnormal方式。

# su - grid

$ sqlplus / as sysasm

+ASM1> select NAME, STATE, TOTAL_MB, FREE_MB, USABLE_FILE_MB from v$asm_diskgroup;

$ asmcmd

ASMCMD> lsdg

# su - oracle

$ sqlplus / as sysdba

orcl1> create tablespace tbs01 datafile '+testdg' size 600M;

orcl1> select path, failgroup, free_mb from v$asm_disk where group_number=4;

orcl 1> select NAME, STATE, TOTAL_MB, FREE_MB, USABLE_FILE_MB from v$asm_diskgroup;

 

ASMCMD> lsdsk -k

添加/刪除磁盤:

# su - grid

+ASM1> show parameter asm_power_limit

+ASM1> select name, total_mb, free_mb from v$asm_disk;

+ASM1> alter diskgroup testdg add disk '/dev/asm-diskj';

+ASM1> select name, total_mb, free_mb from v$asm_disk;

+ASM1> alter diskgroup testdg drop disk TESTDG_0002;

+ASM1> select name, total_mb, free_mb from v$asm_disk;

 

failgroup:

+ASM1> select path, FAILGROUP from v$asm_disk where group_number=4;

+ASM1> alter diskgroup testdg drop disk TESTDG_0002;

+ASM1> alter diskgroup testdg add failgroup testdg_0000 disk '/dev/asm-diskj';

+ASM1> select name, total_mb, free_mb from v$asm_disk;

oracle用戶刪除表空間,grid用戶asmca刪除testdgroot刪除/etc/udev/rules.d/99-oracle-asmdevices.rules中最后3塊硬盤

SQL> startup mount

SQL> select FILE#, NAME from v$datafile;

SQL> alter database datafile 4 offline;

SQL> alter database open;

SQL> drop tablespace tbs01 force; (including contents and datafiles)

HALB

scanvipHA

nslookup解析scan返回3ip,實現ha

# su - grid

$ srvctl status scan

$ srvctl status scan_listener

# su - oracle

$ tnsping orcl

# su - grid

$ srvctl stop scan_listener -i 1(23)

$ srvctl stop scan -i 1(23)

逐一關閉scanlistenerscanvip,測試客戶端的ha

# su - grid

$ srvctl stop instance -d orcl -i orcl1 -o immediate

# su - oracle

$ sqlplus sys/password@orcl as sysdba

SQL> select instance_name from v$instance;

 

node vipHA

node1node2上修改tnsnames本地解析

# su - oracle

$ vi $ORACLE_HOME/network/admin/tnsnames.ora

TESTHA =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.11)(PORT = 1521))

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.12)(PORT = 1521))

    )

    (CONNECT_DATA =

      (SERVICE_NAME = orcl)

    )

  )

$ sqlplus sys/password@testha as sysdba                           node2上的客戶端測試

testha> select instance_name from v$instance;              始終連接到orcl1

# ifdown eth0            關閉node1的網卡

$ sqlplus sys/password@testha as sysdba                           node2上的客戶端測試

testha> select instance_name from v$instance;              連接到orcl2

node1恢復eth0,客戶端重新連接orcl1

 

scanvipLB

建立多個session,自動分配給orcl1orcl2

$ sqlplus sys/password@orcl as sysdba

SQL> select instance_name from v$instance;

 

nodevipLB

# su - oracle

$ vi $ORACLE_HOME/network/admin/tnsnames.ora

TESTLB =

  (DESCRIPTION =

    (ADDRESS_LIST =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.11)(PORT = 1521))

      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.12)(PORT = 1521))

(LOAD_BALANCE = yes)

    )

    (CONNECT_DATA =

      (SERVICE_NAME = orcl)

    )

  )

建立多個session,自動分配給orcl1orcl2

$ sqlplus sys/password@testlb as sysdba

SQL> select instance_name from v$instance;

service

db name, instance name, global name, sid, service name, db_unique_name

orcl    db name

orcl   global name(service name)

查詢現有服務:

SQL> select name from v$database;

SQL> select instance_name from v$instance;

SQL> select name from v$services;

$ vi tnsnames.ora; lsnrctl status

# su - grid

$ srvctl status service -d orcl

創建服務:

# su - oracle

$ srvctl add service -d orcl -s testsvc -r orcl1 -a orcl2

# su - grid

$ srvctl start service -d orcl -s testsvc

$ crsctl stat res -t

$ lsnrctl status; lsnrctl listener_scan1

# su - oracle

$ sqlplus sys/password@scan.test.com:1521/testsvc as sysdba

SQL> select instance_name from v$instance;

SQL> select name from v$database;

netca添加testsvc的解析

SQL> shutdown immediate               關閉orcl1

$ sqlplus sys/password@scan.test.com:1521/testsvc as sysdba

SQL> select instance_name from v$instance;          連接到orcl2

# su - grid

$ crsctl stat res -t

$ srvctl status service -d orcl -s testsvc

$ srvctl start instance -d orcl -i orcl1

$ crsctl stat res -t              testsvc還在orcl2上,不會自動failback

$ srvctl relocate service -d orcl -s testsvc -i orcl2 -t orcl1

$ crsctl stat res -t

$ srvctl stop service -d orcl -s testsvc

$ srvctl remove service -d orcl -s testsvc

resource manager/scheduler/sql trace

cache fusion

ops

內存>網絡>磁盤

node1

# su - oracle

$ sqlplus / as sysdba

orcl1> create tablespace tbs01;

orcl1> create table t1 (x int, y int) tablespace tbs01;

orcl1> insert into t1 values (1, 1);

orcl1> insert into t1 values (2, 2);

orcl1> commit;

orcl1> select dbms_rowid.rowid_relative_fno(rowid), dbms_rowid.rowid_block_number(rowid) from t1;

orcl1> alter system checkpint;

orcl1> alter system flush buffer_cache;

node1:

begin

  for i in 1..10000 loop

    update t1 set y=i where x=1;

  end loop;

end;

/

node2:

begin

  for i in 1..10000 loop

    update t1 set y=i where x=2;

  end loop;

end;

/

xcuràpiàcr

add/delete node

add:

node3做所有準備工作

node1上驗證:

#su - grid

$ cluvfy stage -pre nodeadd -n node3

$ ./addNode.sh "CLUSTER_NEW_NODES={node3}" "CLUSTER_NEW_VIRTUAL_HOSTNAMES={node3-vip}"

node3root身份執行root.sh

node1上運行dbca添加新實例

crsctl stat res -t

DG

安裝

node1node2安裝osdb軟件,創建監聽,node1上創建orcl數據庫。

或者

vb復制單實例虛擬機,重新初始化網卡,將兩個節點重命名為:

node1_DG_11gR2_RHEL6u5_x64

node2_DG_11gR2_RHEL6u5_x64

 

node1恢復網絡設置:

# vi /etc/udev/rules.d/70-persistent-net.rules         刪除2eth0的信息,將eth2改為eth0

# vi /etc/sysconfig/network-scripts/ifcfg-eth0          替換原有的mac地址

#shutdown -h now

 

node2恢復網絡設置:

# vi /etc/udev/rules.d/70-persistent-net.rules         刪除2eth0的信息,將eth2改為eth0

# vi /etc/sysconfig/network-scripts/ifcfg-eth0          替換原有的mac地址

#reboot

 

oracle登錄桌面,dbca刪除orcl數據庫

 

root身份修改hostnameip

# vi /etc/sysconfig/network-scripts/ifcfg-eth0          ip改為192.168.0.2

# vi /etc/sysconfig/network     改為node2.test.com

# hostname node2.test.com

# vi /etc/hosts

192.168.0.1   node1.test.com          node1

192.168.0.2     node2.test.com          node2

臨時關閉oracle服務(可選):

# chkconfig oracle off

# chkconfig --list oracle

 

oracle身份調整node2的環境:

$ vi $ORACLE_HOME/network/admin/listener.ora          改為node2.test.com

$ lsnrctl stop; lsnrctl start

$ vi ~oracle/.bash_profile

export ORACLE_HOSTNAME=node2.test.com

export ORACLE_SID=orclps

export ORACLE_UNQNAME=orclps

$ . ~oracle/.bash_profile

 

node1(primary)

# vi /etc/hosts

# su - oracle

SQL> shutdown immediate

SQL> startup mount

SQL> alter database archivelog;

SQL> alter database open;

SQL> alter database force logging;

node1(primary)修改主數據庫參數:

SQL> alter system set log_archive_config='dg_config=(orcl,orclps)';

SQL> alter system set log_archive_dest_2='service=orclps async valid_for=(online_logfile,primary_role) db_unique_name=orclps';

添加備用數據庫參數:

SQL> alter system set fal_server=orclps;

SQL> alter system set fal_client=orcl;

SQL> alter system set standby_file_management=auto;

SQL> alter system set db_file_name_convert='/orclps/','/orcl/' scope=spfile;

SQL> alter system set log_file_name_convert='/orclps/','/orcl/' scope=spfile;

$ vi /u01/app/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora

ORCLPS =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node2.test.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orclps)

    )

  )

 

node2(ps):

# su - oracle

$ mkdir -p $ORACLE_BASE/fast_recovery_area/orclps

$ mkdir -p $ORACLE_BASE/admin/orclps/adump

$ mkdir -p $ORACLE_BASE/admin/orclps/dpdump

$ mkdir -p $ORACLE_BASE/oradata/orclps

 

$ vi $ORACLE_HOME/network/admin/listener.ora          添加靜態注冊

SID_LIST_listener=

(SID_LIST=

 (SID_DESC=

  (GLOBAL_DBNAME=orclps)

  (SID_NAME=orclps)

  (ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1)))

$ lsnrctl reload; lsnrctl status

 

$ vi $ORACLE_HOME/network/admin/tnsnames.ora

ORCL =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node1.test.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orcl)

    )

  )

 

ORCLPS =

  (DESCRIPTION =

    (ADDRESS = (PROTOCOL = TCP)(HOST = node2.test.com)(PORT = 1521))

    (CONNECT_DATA =

      (SERVER = DEDICATED)

      (SERVICE_NAME = orclps)

    )

  )

$ tnsping orcl            測試

 

node2上生成口令文件:

$ scp node1:$ORACLE_HOME/dbs/orapworcl $ORACLE_HOME/dbs/orapworclps

node1上生成pfile

SQL> create pfile from spfile;

node2上生成spfile

$ scp node1:$ORACLE_HOME/dbs/initorcl.ora $ORACLE_HOME/dbs/initorclps.ora

node2上刪除orcl.開頭的參數,修改如下參數:

$ vi $ORACLE_HOME/dbs/initorclps.ora

*.audit_file_dest='/u01/app/oracle/admin/orclps/adump'

*.audit_trail='db'

*.compatible='11.2.0.0.0'

*.control_files='/u01/app/oracle/oradata/orclps/control01.ctl','/u01/app/oracle/fast_recovery_area/orclps/control02.ctl'

*.db_block_size=8192

*.db_domain=''

*.db_file_name_convert='/orcl/','/orclps/'

*.db_name='orcl'

*.db_unique_name='orclps'

*.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'

*.db_recovery_file_dest_size=4322230272

*.diagnostic_dest='/u01/app/oracle'

*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclpsXDB)'

*.fal_client='ORCLPS'

*.fal_server='ORCL'

*.log_archive_config='dg_config=(orcl,orclps)'

*.log_archive_dest_2='service=orcl async valid_for=(online_logfile,primary_role) db_unique_name=orcl'

*.log_file_name_convert='/orcl/','/orclps/'

*.memory_target=1073741824

*.open_cursors=300

*.processes=150

*.remote_login_passwordfile='EXCLUSIVE'

*.standby_file_management='AUTO'

*.undo_tablespace='UNDOTBS1'

 

SQL> create spfile from pfile;

SQL> startup nomount

 

$ rman target sys/password@orcl auxiliary sys/password@orclps

RMAN> duplicate target database for standby from active database dorecover;

如果主和備的數據目錄相同,需要加nofilenamecheck

SQL> select status from v$instance;                  mount狀態

如果需要手動啟動備用數據庫:

SQL> startup nomount

SQL> alter database mount standby database;

 

node1(primary)創建srl

SQL> alter database add standby logfile '/u01/app/oracle/oradata/orcl/srl01(234).log' size 50M;

node2(ps)創建srl

SQL> alter database add standby logfile '/u01/app/oracle/oradata/orclps/srl01(234).log' size 50M;

 

node2(ps)開啟redoapply

SQL> alter database recover managed standby database using current logfile disconnect;

SQL> select name from v$datafile;

SQL> select name from v$tempfile;

SQL> select name from v$controlfile;

SQL> select member from v$logfile;

SQL> select protection_mode, protection_level from v$database;

SQL> select sequence#, applied from v$archived_log;

SQL> alter system switch logfile;     node1上切換日志

SQL> select sequence#, applied from v$archived_log;             出現新的歸檔

 

$ vi /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora       刪除靜態注冊

刪除init參數文件(可選)

 

node2(ps)修改啟動腳本:

# vi /etc/init.d/oracle

#!/bin/bash

#chkconfig:35 99 01

case "$1" in

  start)

        su - oracle -c "sqlplus /nolog" <<EOF >/dev/null

        conn / as sysdba

        startup mount

        alter database recover managed standby database using current logfile disconnect;

EOF

        su - oracle -c "lsnrctl start" >/dev/null

        touch /var/lock/subsys/oracle

        ;;

  stop)

        su - oracle -c "lsnrctl stop" >/dev/null

        su - oracle -c "sqlplus /nolog" <<EOF >/dev/null

        conn / as sysdba

        recover managed standby database cancel;

        shutdown immediate

EOF

        rm -f /var/lock/subsys/oracle

        ;;

  *)

        echo "Usage: oracle {start|stop}"

        exit 1

esac

 

# chkconfig --level 35 oracle on

或者

#chkconfig --add oracle

保護模式

node1(primary)準備工作:

SQL> create table t1(x int);

測試代碼:

node1(primary):

SQL> insert into t1 values (1);

SQL> commit;

node2(standby)

SQL> select status, sequence#, block# from v$managed_standby where client_process='LGWR';

或者在adg下檢查

SQL> recover managed standby database cancel;

SQL> alter database open;

SQL> alter database recover managed standby database using current logfile disconnect;

SQL> select * from t1;

 

最大性能:

nod1(primary)

SQL> alter system set log_archive_dest_2='service=orclps async valid_for=(online_logfile,primary_role) db_unique_name=orclps';

SQL> ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE;

SQL> select protection_mode, protection_level from v$database;

測試

 

最大可用性:

node1(primary)

SQL> alter system set log_archive_dest_2='service=orclps sync affirm net_timeout=30 valid_for=(online_logfile,primary_role) db_unique_name=orclps';

SQL> ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE AVAILABILITY;

SQL> select protection_mode, protection_level from v$database;

測試

 

最大保護:

node1(primary)

SQL> alter system set log_archive_dest_2='service=orclps sync affirm valid_for=(online_logfile,primary_role) db_unique_name=orclps';

SQL> ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PROTECTION;

SQL> select protection_mode, protection_level from v$database;

測試

 

逐級修改保護模式,不需要重啟dbperformanceàavailablity要等待resync完成,再àprotection

 

恢復為最大性能:

SQL> ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE;

SQL> alter system set log_archive_dest_2='service=orclps async valid_for=(online_logfile,primary_role) db_unique_name=orclps';

active data guard

只讀模式打開

node1(primary)

SQL> create table t1(x int);      insert into t1 values (1);   commit;

node2(standby)

SQL> select open_mode from v$database;               確認是mount

SQL> recover managed standby database cancel;

SQL> alter database open;

SQL> select open_mode from v$database;               read only

SQL> select * from t1;

SQL> insert into t1 values (2);           commit;            node1上做

SQL> select * from t1;               node1不同步

SQL> delete t1;                  報錯

SQL> alter system switch logfile;                        node1切換日志

SQL> select sequence#, applied from v$archived_log;             傳輸但不應用

SQL> shutdown immediate

SQL> startup mount

SQL> alter database recover managed standby database using current logfile disconnect;

SQL> select sequence#, applied from v$archived_log;             應用node1的日志

 

快照備用

node1(primary)

SQL> create table t1(x int);      insert into t1 values (1);   commit;

node2(standby)

SQL> show parameter db_recovery_file_dest

SQL> recover managed standby database cancel;

SQL> shutdown immediate

SQL> startup mount

SQL> alter database convert to snapshot standby;

SQL> alter database open;

SQL> select open_mode from v$database;               read write

$ ls /u01/app/oracle/fast_recovery_area/ORCLPS/flashback

SQL> select * from t1;

SQL> insert into t1 values (1);           commit;            node1修改

SQL> select * from t1;insert into t1 values (2);commit;  無法看到node1修改,但自己可以修改

SQL> alter system switch logfile;                        node1切換日志

SQL> select sequence#, applied from v$archived_log;             傳輸但不應用

 

SQL> shutdown immediate

SQL> startup mount

SQL> alter database convert to physical standby;            node2丟失更改

SQL> shutdown immediate

SQL> startup mount

SQL> alter database recover managed standby database using current logfile disconnect;

SQL> select sequence#, applied from v$archived_log;             node2應用日志

 

快照備用+flashbackdb

node1(primary)

SQL> create table t1(x int);      insert into t1 values (1);   commit;

node2(standby)

確認數據庫在mount狀態

SQL> show parameter db_recovery_file_dest

SQL> recover managed standby database cancel;

SQL> alter database flashback on;

SQL> alter database convert to snapshot standby;

SQL> alter database open;

SQL> select open_mode from v$database;               read write

SQL> insert into t1 values(2);  commit;          導入測試數據

SQL> create restore point before_test GUARANTEE flashback database;

SQL> delete t1;commit;

SQL> shutdown immediate

SQL> startup mount

SQL> flashback database to restore point before_test;

SQL> alter database open resetlogs;

SQL> select * from t1;

 

SQL> shutdown immediate

SQL> startup mount

SQL> alter database convert to physical standby;            node2丟失更改

SQL> shutdown immediate

SQL> startup mount

SQL> alter database recover managed standby database using current logfile disconnect;

SQL> drop restore point before_test;

 

ADG

node1(primary)

SQL> create table t1(x int);      insert into t1 values (1);   commit;

node2(standby)

SQL> select open_mode from v$database;               確認是mount

SQL> recover managed standby database cancel;

SQL> alter database open;                或者SQL> startup

SQL> alter database recover managed standby database using current logfile disconnect;

SQL> insert into t1 values (2);commit;              node1上修改

SQL> select * from t1;               node2上查看實時數據

角色轉換

switch over

node1(primary)的準備:

fal_server/fal_client/standby_file_management

創建srl

node2(standby)

log_archive_dest_2/log_archive_config

 

node1(primary)確認日志傳輸完整(nogap

SQL>SELECT STATUS, GAP_STATUS FROM V$ARCHIVE_DEST_STATUS WHERE DEST_ID = 2;

node2(standby)確認兩個lag

SQL> SELECT NAME, VALUE, DATUM_TIME FROM V$DATAGUARD_STATS;

 

node1(primary)

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;      應該是TO STANDBY

SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;

SQL> SHUTDOWN ABORT;

 

node2(standbyànew primary)

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;      應該是TO PRIMARY

SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;

SQL> ALTER DATABASE OPEN;

 

node1(primaryànew standby)

SQL> STARTUP MOUNT;

SQL> alter database recover managed standby database using current logfile disconnect;

 

failover

node2(primary)node1(standby)開啟flashback

node2(primary)準備:

SQL>create table t1(x int);       insert into t1 values (1);            commit;

 

node2(primary)模擬故障:

# ifdown eth0            node2(primary)關閉網絡

SQL> insert into t1 values (2);           commit;

SQL> shutdown abort

 

node1(standby)

SQL> recover managed standby database cancel;

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;

SQL>ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;

SQL> ALTER DATABASE OPEN;

 

利用flashback恢復node2(primaryànew standby)

node1(new primary)

SQL> SELECT TO_CHAR(STANDBY_BECAME_PRIMARY_SCN) FROM V$DATABASE;

node2(new standby)

SQL> startup mount

SQL> FLASHBACK DATABASE TO SCN 1275936;

SQL> ALTER DATABASE CONVERT TO PHYSICAL STANDBY;

SQL> SHUTDOWN IMMEDIATE

SQL> STARTUP MOUNT

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;

數據庫設計

基于oracleATM實例

升級

單實例

11.2.0.3.0à 11.2.0.4.0

# mkdir /patch

# chmod 777 /patch

# mount -t vboxsf patch /patch

$ unzip p13390677_112040_Linux-x86-64_1(2)of7.zip

停服務:

$ emctl stop dbconsole

$ lsnrctl stop

$ sqlplus / as sysdba

SQL> shutdown immediate

改環境:

$ vi ~/.bash_profile

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0.4/db_1

$ . .bash_profile       桌面環境需要重新登錄

$ echo $ORACLE_HOME

$ ./runInstaller

選擇upgrade,路徑確認改為/u01/app/oracle/product/11.2.0.4/db_1

# /u01/app/oracle/product/11.2.0.4/db_1/root.sh         提示以root執行腳本

netca:創建新版本listenerservice解析

dbua: 不移動文件

 

SQL> select * from v$version;           db的版本

SQL> select comp_name, version from dba_server_registry;          組件的版本

$ rm -rf /u01/app/oracle/product/11.2.0        確定成功,刪除老版本

 

11.2.0.4.0à 11.2.0.4.8

$ $ORACLE_HOME/OPatch/opatch version

$ unzip p6880880_112000_Linux-x86-64.zip -d $ORACLE_HOME  必須用oracle用戶身份

$ $ORACLE_HOME/OPatch/opatch version

 

$ cd /patch

$ unzip p21352635_112040_Linux-x86-64\(11.2.0.4.8_db\).zip              必須用oracle用戶解壓縮

$ cd 21352635

$ emctl stop dbconsole; dbshut $ORACLE_HOME            關閉db所有組件

$ $ORACLE_HOME/OPatch/opatch apply

不輸入email,確認繼續

 

$ dbstart $ORACLE_HOME; emctl start dbconsole

SQL> @?/rdbms/admin/catbundle.sql psu apply

檢查:

$ $ORACLE_HOME/OPatch/opatch lspatches

SQL> select action, comments from registry$history;

DG

node2上的/etc/oratab中添加數據庫

$ vi /etc/oratab

orclps:/u01/app/oracle/product/11.2.0/db_1:Y

node2上不配置em

node1上選擇“只安裝軟件”

復制老版本路徑下的listener.ora, sqlnet.ora, tnsnames.ora spfileorcl.ora orapworcl至新版本對應目錄

安裝軟件失敗:

$ vi /u01/app/oraInventory/ContentsXML/inventory.xml

 

RAC

升級gi

node1node2

# chown grid /u01/app

$ su - grid

$ vi .bash_profile

export ORACLE_HOME=/u01/app/11.2.0.4/grid

$ . .bash_profile

node1

桌面root登錄

#xhost +

$ su - grid

$ /patch/grid/runInstaller

upgrade gi & asm,測試ssh連接(不用配置),路徑改為/u01/app/11.2.0.4/grid

node1node2上運行rootupgrade.sh

$ crsctl query crs activeversion        確認新版本

 

升級dbsoftware

node1node2

# su - oracle

$ vi .bash_profile

export ORACLE_HOME=$ORACLE_BASE/product/11.2.0.4/db_1

$ . .bash_profile

node1

$ ./runInstaller

選擇upgrade existing database,選中node1/node2ssh輸入口令,路徑改為/u01/app/oracle/product/11.2.0.4/db_1node1/node2執行root腳本,dbua升級數據庫。

 

升級psu

node1node2

su - grid

unzip p6880880_112000_linux-x86-64.zip -d $ORACLE_HOME

$ORACLE_HOME/OPatch/opatch version

su - oracle

unzip p6880880_112000_linux-x86-64.zip -d $ORACLE_HOME

$ORACLE_HOME/OPatch/opatch version

 

node1

su - grid

$ unzip p21523375_112040_Linux-x86-64(11.2.0.4.8_gi&db).zip

 

node1node2

su - oracle

emctl stop dbconsole

 

node1node2上,root生成ocm響應文件,應用psu

# cd /patch/21523375/

#/u01/app/11.2.0.4/grid/OPatch/ocm/bin/emocmrsp -no_banner

#/u01/app/11.2.0.4/grid/OPatch/opatch auto /patch/21523375/ -ocmrf /patch/21523375/ocm.rsp

 

node1上:

su - oracle

sqlplus / as sysdba

SQL> @?/rdbms/admin/catbundle.sql psu apply

 

檢查:

$ORACLE_HOME/OPatch/opatch lspatches

sqlplus / as sysdba

select * from v$version;

select action,comments from registry$history;

 


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大厂| 绥芬河市| 鄢陵县| 晋城| 永宁县| 长沙县| 珲春市| 伊金霍洛旗| 武川县| 通江县| 西丰县| 宜昌市| 乌鲁木齐市| 盐边县| 包头市| 四平市| 寻乌县| 三门峡市| 静海县| 集安市| 齐齐哈尔市| 郓城县| 深圳市| 平昌县| 荥阳市| 抚顺市| 敖汉旗| 竹北市| 宜兰县| 新野县| 中阳县| 天柱县| 宝丰县| 广河县| 余干县| 建瓯市| 施甸县| 扬中市| 巫山县| 丰原市| 襄汾县|