alter table move与shrink space

都知道alter table move 或shrink space可以收缩段,用来消除部分行迁移,消除空间碎片,使数据更紧密,但move跟shrink space还是有区别的。
Move会移动高水位,但不会释放申请的空间,是在高水位以下(below HWM)的操作。
而shrink space 同样会移动高水位,但也会释放申请的空间,是在高水位上下(below and above HWM)都有的操作。
Move解决问题:
a. 我们可以使用move将一个table从当前的tablespace上移动到另一个tablespace上:
alter table t move tablespace tablespace_name;
b. 我们还可以用move来改变table已有的block的存储参数,如:
alter table t move storage (initial 30k next 50k);
c.另外,move操作也可以用来解决table中的行迁移的问题。
使用move的一些注意事项:
a. table上的index需要rebuild:
在前面我们讨论过,move操作后,数据的rowid发生了改变,我们知道,index是通过rowid来fetch数据行的,所以,table上的index是必须要rebuild的。
alter index index_name rebuild online;
b.move时对table的锁定
当我们对table进行move操作时,查询v$locked_objects视图可以发现,table上加了exclusive lock
c.关于move时空间使用的问题:
当我们使用alter table move来降低table的HWM时,有一点是需要注意的,这时,当前的tablespace中需要有1倍于table的空闲空间以供使用
Shrink space语法:
alter table shrink space [ | compact | cascade ];
alter table shrink space compcat;
收缩表,但会保持 high water mark;
alter table shrink space;
收缩表,降低 high water mark;
alter table shrink space cascade;
收缩表,降低 high water mark,并且相关索引也要收缩
用shrink有两个前提条件:
1、表必须启用row movement,如:
alter table nonsrt.TAB_EZG_BIZ_UNCONTRACTED enable row movement;
alter table nonsrt.TAB_EZG_BIZ_UNCONTRACTED shrink space;
2、表段所在表空间的段空间管理(segment space management)必须为auto
segment shrink分为两个阶段:
1、数据重组(compact):通过一系列insert、delete操作,将数据尽量排列在段的前面。在这个过程中需要在表上加RX锁,即只在需要移动的行上加锁。由于涉及到rowid的改变,需要enable row movement.同时要disable基于rowid的trigger.这一过程对业务影响比较小。
2、HWM调整:第二阶段是调整HWM位置,释放空闲数据块。此过程需要在表上加X锁,会造成表上的所有DML语句阻塞。在业务特别繁忙的系统上可能造成比较大的影响。
注意:shrink space语句两个阶段都执行。
shrink space compact只执行第一个阶段。
如果系统业务比较繁忙,可以先执行shrink space compact重组数据,然后在业务不忙的时候再执行shrink space降低HWM释放空闲数据块。

linux查看内存使用情况

使用free命令查看内存使用情况
[oracle@report ~]$ free -m
total   used  free shared buffers  cached
Mem: 7958   7926   3          0          19     6942
物理已用内存 = 实际已用内存 – 缓冲 – 缓存
物理已用内存为:7926-19-6942
物理空闲内存 = 总物理内存 – 实际已用内存 + 缓冲 + 缓存
物理空闲内存:7958-7926+19+6942
应用程序可用空闲内存 = 总物理内存 – 实际已用内存
应用程序可用空闲内存:7958-7926
应用程序已用内存 = 实际已用内存 – 缓冲 – 缓存
应用程序已用内存:7926-19-6942

Goldengate常见错误

ERROR OGG-01031 There is a problem in network communication, a remote file problem, encryption keys for target and source do not match (if using ENCRYPT) or an unknown error. (Reply received is Unable to open file “/opt/OGG/dirdat/AIR/EXTTRAIL/U9000005” (error 11, Resource temporarily unavailable)).
重新启动一次
WARNING OGG-00769 mysql_refresh() failed, falling back to default key. SQL error (1227). Access denied; you need the RELOAD privilege for this operation.
mysql用户权限问题
ERROR OGG-01033 There is a problem in network communication, a remote file problem, encryption keys for target and source do not match (if using ENCRYPT) or an unknown error. (Remote file used is /opt/OGG/dirdat/rl000003, reply received is Unable to lock file “/opt/OGG/dirdat/rl000003” (error 13, Permission denied). Lock currently held by process id (PID) 14409)
原因:网络或者目标段路径不正常,访问到目标端目录失败导致
在目标端kill -9 14409
或者等待2小时,自动系统自动重启目标端进程
ERROR OGG-01033 Oracle GoldenGate Capture for Oracle, p-xz.prm: There is a problem in network communication, a remote file problem, encryption keys for target and source do not match (if using ENCRYPT) or an unknown error. (Remote file used is /opt/OGG/dirdat/XunZhi/EXTFILE/U1000000, reply received is Could not create /opt/OGG/dirdat/XunZhi/EXTFILE/U1000000).
检查远程的目录是否和datapump中的远程目录是否一致

shell /bin/bash^M: bad interpreter报错的解决

可能是你的脚本文件是DOS格式的, 即每一行的行尾以\r\n来标识, 其ASCII码分别是0x0D, 0x0A.
可以有很多种办法看这个文件是DOS格式的还是UNIX格式的, 还是MAC格式的
vi filename
然后用命令
:set ff?
可以看到dos或unix的字样. 如果的确是dos格式的, 那么你可以用 set fileformat=unix 把它强制为unix格式的, 然后存盘退出.

使用rman备份做Data Guard

前两天公司的一套oracle dg因为维护人员的疏忽到值出现gap,无法恢复,只能重做,因为该库每天都有rman的增量备份,所以选择最近的一次全部进行重做dg
1、主库
ALTER DATABASE CREATE STANDBY CONTROLFILE AS ‘/tmp/control01.ctl’;
alter system archive log current;
2、修改pfile文件(因为我是重做,所以不需要做)
11g data guard(PHYSICAL STANDBY)配置
3、拷贝控制文件/rman文件到备库的相同位置
备份全备的内容(/opt/ORBS/data /tmp/control01.ctl)
4、复制数据库做dg
启动到nomount状态
rman target sys/srtsysdb@zjch_Action auxiliary /
duplicate target database for standby dorecover nofilenamecheck;
出现以下错误
RMAN-06025: no backup of log thread 1 seq 675 lowscn 1096519 found to restore
RMAN-06025: no backup of log thread 1 seq 674 lowscn 1095666 found to restore
RMAN-06025: no backup of log thread 1 seq 673 lowscn 1095663 found to restore
RMAN-06025: no backup of log thread 1 seq 672 lowscn 1095656 found to restore
RMAN-06025: no backup of log thread 1 seq 671 lowscn 1095081 found to restore
RMAN-06025: no backup of log thread 1 seq 670 lowscn 1092545 found to restore
RMAN-06025: no backup of log thread 1 seq 669 lowscn 1090351 found to restore
RMAN-06025: no backup of log thread 1 seq 668 lowscn 1088837 found to restore
RMAN-06025: no backup of log thread 1 seq 667 lowscn 1088834 found to restore
RMAN-06025: no backup of log thread 1 seq 666 lowscn 1088721 found to restore
原因:因为控制文件和备份文件中有时间间隔,所以rman要恢复,但是归档日志没有传输过来,所以不能恢复。
–到主库的归档目录查看这些日志是否存在
ls -l(如果存在,下面的操作恢复日志的操作可以忽略)
–查看这些日志是否存在
list backup of archivelog from sequence 666 until sequence 675;
–如果存在rman备份中,使用rman进行恢复
restore archivelog from sequence 666 until sequence 675;
如果存在相关联机日志就不需要添加
–添加redo log
alter database add logfile group 1 (‘/opt/oracle/oradata/zjch/redo01.log’) size 50m;
alter database add logfile group 2 (‘/opt/oracle/oradata/zjch/redo02.log’) size 50m;
alter database add logfile group 3 (‘/opt/oracle/oradata/zjch/redo03.log’) size 50m;
–添加sandby log
ALTER DATABASE ADD STANDBY LOGFILE (‘/opt/oracle/oradata/zjch/std_redo04.log’) SIZE 50M reuse;
ALTER DATABASE ADD STANDBY LOGFILE (‘/opt/oracle/oradata/zjch/std_redo05.log’) SIZE 50M reuse;
ALTER DATABASE ADD STANDBY LOGFILE (‘/opt/oracle/oradata/zjch/std_redo06.log’) SIZE 50M reuse;
ALTER DATABASE ADD STANDBY LOGFILE (‘/opt/oracle/oradata/zjch/std_redo07.log’) SIZE 50M reuse;
5、开启日志应用
–开启实时应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
–开启应用(根据配置和需求)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
到这一步会如果主机端有所需的归档日志,会自动传输过来,并进行恢复,不用人工干预。
–查看alter文件,查询日志传输是否正常
–查看日志是否传输完成
select thread#, low_sequence#, high_sequence# from v$archive_gap;
–主库切换日志
alter system switch logfile;
–查询最大sequence
select max(sequence#) from v$archived_log;
–备库查看alert文件
tail -100 alert.log
Media Recovery Log /opt/oracle/oradata/zjch/archive/stdarch/1_46544_681145105.dbf
Media Recovery Log /opt/oracle/oradata/zjch/archive/stdarch/1_46545_681145105.dbf 有类似内容
–查询最大sequence
select max(sequence#) from v$archived_log;
–主库建立一个测试表
create table SCOTT.t_test(id number,name varchar2(10));
insert into SCOTT.t_test values(1,’aaaa’);
commit;
alter system switch logfile;
–查询最大sequence
select max(sequence#) from v$archived_log;
–备库检查
–查询最大sequence
select max(sequence#) from v$archived_log;
–取消日志应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE cancel;
–只读模式打开数据库
alter database open read only;
–查询刚刚建的表和插入数据是否通报不成功
select * from SCOTT.t_test;
–重启备库,设置为日志应用模式
shutdown immediate;
startup mount;
–开启实时应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
–开启应用(根据配置和需求)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
–主库删除测试表
drop table SCOTT.t_test;

ORACLE中的default role/set role

oracle权限体系中有个default role,比较难以理解。下面用实例说明一下作用。
我们可以给某个用户分配一些角色,比如role r1,r2,r3,r4,而其中可以将某些角色比如r1设置为default role,其他的不设置成default role,这样,当该用户登录时,自动具有default role中所包含的权限,其他的角色所具有的权限要通过set role 角色来获得。
下面我们举个例子:
(1)sys用户作为sysdba登录,创建4个角色:
create role r1;
create role r2 identified by r2;
create role r3 identified by r3;
create role r4 identified by r4;
(2)sys用户赋予这四个角色对应的权限:
grant create session to r1;
grant select on hr.test to r2;(这里hr.test是我新创建的一个表,里面有ID和name两列)
grant update(name) on hr.test to r3;
grant insert on hr.test to r3;
grant delete on hr.test to r4;
(3)sys用户创建一个用户u3
create user u3 identified by u3;
(4)将角色r1,r2,r3,r4赋予用户u3
grant r1,r2,r3,r4 to u3;
在修改用户u3的默认角色前,r1,r2,r3,r4 角色均为u3的 default role,以u3用户登录,查询、增删改hr.test,都没有问题。
(5)现在sys用户修改用户u3的default role,仅将r1作为u3的默认角色:
alter user u3 default role r1; –此时将覆盖原来的设置,u3 的default role =r1,仅仅有登录权限。
(6)用户u3 log off ,然后再log on,进去后发现,
查询、增删改hr.test都不能进行。
(7) 用户自己打开role权限
set role r2 identified by r2;
这时执行 select * from hr.test,发现没有问题。增删改不行。
将对应的角色打开:
set role r3 identified by r3;
此时修改和插入记录没有问题,但是select * from hr.test 确发现不行了。证明此时用户所属的角色仅仅是默认角色r1,和刚刚打开的角色r3,而r2被set role r3 identified by r3;覆盖掉了。
那要同时有r2,r3,r4的权限怎么办呢?
set role r2 identified by r2,r3 identified by r3,r4 identified by r4。此时就同时对hr.test可以进行查询,增删改了。
不过set role 的效果是临时的,只是当前session有效,其他的session无效,当结束当前session后再登录,又只有default role 的权限了。

MySql分区表管理

1、RANGE和LIST分区的管理
1.1)删除分区
ALTER TABLE table_name DROP PARTITION partition_name;
1.2)添加分区
ALTER TABLE table_name ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));
Note:
1)分区的范围或者值不能重复;
2)在范围分区中,不能添加比当前范围最大值小的分区
1.3)重新定义分区
ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO (partition_definitions);
其中,tbl_name 是分区表的名称,partition_list 是通过逗号分开的、一个或多个将要被改变的现有分区的列表。partition_definitions 是一个是通过逗号分开的、新分区定义的列表,它遵循与用在“CREATE TABLE”中的partition_definitions 相同的规则。应当注意到,在把多少个分区合并到一个分区或把一个分区拆分成多少个分区方面,没有限制。例如,可以重新组织成员表的四个分区成两个分区,具体实现如下:
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
PARTITION m0 VALUES LESS THAN (1980),
PARTITION m1 VALUES LESS THAN (2000)
);
2、HASH和KEY分区的管理
2.1)合并HASH或KEY分区
ALTER TABLE … COALESCE PARTITION
Note:对于LINEAR HASH和LINEAR KEY分区同样有效
2.2)添加分区
ALTER TABLE table_name ADD PARTITION PARTITIONS 18;–18比原来值大
3、分区维护
3.1) 重建分区
ALTER TABLE table_name REBUILD PARTITION (p0, p1);
3.2)优化分区
ALTER TABLE table_name OPTIMIZE PARTITION (p0, p1);
3.3)分析分区
ALTER TABLE table_name ANALYZE PARTITION (p0, p1);
3.4)检查分区
ALTER TABLE table_name CHECK PARTITION (p0, p1);

MySql创建分区表

一、前沿知识
1、分区表类型
RANGE分区、LIST分区、HASH分区、KEY分区、子分区
2、查询是否支持分区表
mysql> SHOW VARIABLES LIKE ‘%partition%’;
+———————–+——-+
| Variable_name | Value |
+———————–+——-+
| have_partition_engine | YES |
+———————–+——-+
1 row in set (0.00 sec)
3、MySQL分区处理NULL值的方式
MySQL中的分区在禁止空值(NULL)上没有进行处理,如果出现NULL,MySQL 把NULL视为0
二、分区表的创建
1、RANGE分区

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

2、 LIST分区

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id)
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

Note:LIST分区没有类似如“VALUES LESS THAN MAXVALUE”这样的包含其他值在内的定义。将要匹配的任何值都必须在值列表中找到。
3、 HASH分区

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH(YEAR(hired))
PARTITIONS 4;

3.1、LINEAR HASH分区

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LINEAR HASH(YEAR(hired))
PARTITIONS 4;

Note:线性哈希功能使用的一个线性的2的幂(powers-of-two)运算法则,而常规哈希使用的是求哈希函数值的模数
4、KEY分区

CREATE TABLE tk (
    col1 INT NOT NULL,
    col2 CHAR(5),
    col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;

Note:
1)按照KEY进行分区类似于按照HASH分区,除了HASH分区使用的用户定义的表达式,而KEY分区的 哈希函数是由MySQL 服务器提供。MySQL 簇(Cluster)使用函数MD5()来实现KEY分区;对于使用其他存储引擎的表,服务器使用其自己内部的哈希函数,这些函数是基于与PASSWORD()一样的运算法则。
2)“CREATE TABLE … PARTITION BY KEY”的语法规则类似于创建一个通过HASH分区的表的规则。它们唯一的区别在于使用的关键字是KEY而不是HASH,并且KEY分区只采用一个或多个列名的一个列表。
5、子分区

CREATE TABLE ts (id INT, purchased DATE)
    PARTITION BY RANGE(YEAR(purchased))
    SUBPARTITION BY HASH(TO_DAYS(purchased))
    (
        PARTITION p0 VALUES LESS THAN (1990)
        (
            SUBPARTITION s0
                DATA DIRECTORY = '/disk0/data'
                INDEX DIRECTORY = '/disk0/idx',
            SUBPARTITION s1
                DATA DIRECTORY = '/disk1/data'
                INDEX DIRECTORY = '/disk1/idx'
        ),
        PARTITION p1 VALUES LESS THAN (2000)
        (
            SUBPARTITION s0
                DATA DIRECTORY = '/disk2/data'
                INDEX DIRECTORY = '/disk2/idx',
            SUBPARTITION s1
                DATA DIRECTORY = '/disk3/data'
                INDEX DIRECTORY = '/disk3/idx'
        ),
        PARTITION p2 VALUES LESS THAN MAXVALUE
        (
            SUBPARTITION s0
                DATA DIRECTORY = '/disk4/data'
                INDEX DIRECTORY = '/disk4/idx',
            SUBPARTITION s1
                DATA DIRECTORY = '/disk5/data'
                INDEX DIRECTORY = '/disk5/idx'
        )
    );

Note:子分区是分区表中每个分区的再次分割,DATA DIRECTORY/INDEX DIRECTORY确定数据和索引的存储位置

Goldengate 配置oracle to mysql

以前oracle to mysql试验总是有乱码问题不能解决,后来和同事交流中,他说oracle使用ogg的11g版本,mysql使用ogg的10g版本可以解决乱码问题,开始我还是怀疑,因为想新的版本都不行,难道老版本就可以解决这个问题吗?抱着试试看的态度,做了个试验,尽然成功了,把试验的相关情况记录下来
mysql参数配置(cat /etc/my.cnf):
[client]
default-character-set = gbk
[mysqld]
lower_case_table_names=1–表名不区分大小写(省的在repl进程中因为大小写的问题导致不能捕获数据)
character-set-server = gbk
表/列编码:均为gbk
Note:
1、因为mysql是target端,所以对于log-bin/binlog_format参数无要求
2、通过以上设置确保mysql的所有相关编码均为gbk
系统编码配置(cat /etc/sysconfig/i18n):
source:
LANG=”zh_CN.GBK”
SUPPORTED=”zh_CN.GBK:zh_CN:zh”
SYSFONT=”latarcyrheb-sun16″
target:
LANG=”zh_CN.GBK”
SYSFONT=”latarcyrheb-sun16″
Note:是的系统编码和mysql编码相同
OGG配置过程:
source端:

add extract ext-all,tranlog,begin now
ADD EXTTRAIL /opt/OGG/dirdat/extract/AL, EXTRACT ext-all
edit params ext-all
extract ext-all
SETENV (NLS_LANG =AMERICAN_AMERICA.ZHS16GBK)
userid is1ogg,password passw0rd
exttrail /opt/OGG/dirdat/extract/AL
discardfile /opt/OGG/discard/ext-all.txt, append, megabytes 100
DDL INCLUDE MAPPED OPTYPE alter OBJNAME ECP.TAB*
TABLE ecp.*;
add EXTRACT p-air, EXTTRAILSOURCE /opt/OGG/dirdat/extract/AL, BEGIN now
add rmttrail /opt/OGG/dirdat/rl extract p-air
edit params p-air
extract p-air
SETENV (NLS_LANG =AMERICAN_AMERICA.ZHS16GBK)
userid is1ogg,password passw0rd
RMTHOST 192.168.1.4,MGRPORT 7809,TCPBUFSIZE 100000,TCPFLUSHBYTES 300000
rmttrail /opt/OGG/dirdat/rl
discardfile /opt/OGG/discard/p-air.txt, append, megabytes 100
TABLE ecp.*;

target端:

add replicat repl, exttrail /opt/OGG/dirdat/rl,nodbcheckpoint
edit params repl
replicat repl
DBOPTIONS HOST 127.0.0.1, CONNECTIONPORT 3306
TARGETDB ecp,userid root,password xifenfei
assumetargetdefs
reperror default,discard
discardfile /tmp/mysql.dsc,append,megabytes 100
MAP ECP.TAB_UUM_DEPT, TARGET ecp.tab_uum_dept;
MAP ECP.TAB_UUM_DEPT_LEADER, TARGET ecp.tab_uum_dept_leader;

mysql中遇到错误

1、ERROR 1042 (HY000): Can’t get hostname for your address
现象:使用ip地址登陆远程服务器出现以上错误提示
原因:因为mysql在默认情况下,会对ip地址也进行解析
解决:添加配置文件
[mysqld]
skip-name-resolve
说明:
#禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接#请求!
#1:去掉mysql启动参数中的skip-name-resolve ,然后jdbc连接串用ip地址和主机名均可。
#2:如果保留启动参数skip-name-resolve 的话,在jdbc连接串中只能使用IP地址的方式连接数据库。
2、The server quit without updating PID file (/var/lib/mysql/localhost.localdomain.pid).[FAILED]
现象:安装好mysql后,使用my.cnf启动报以上错误,不使用可以正常启动
原因:my.cnf文件参数有错误
解决:检查hostname.err文件,发现错误参数,进行修改,然后重启mysql
3、ERROR 1130 (HY000): Host ‘192.168.1.1’ is not allowed to connect to this MySQL server
现象:远程登陆数据库报以上错误
原因:数据库没有该登陆域名或者ip的登陆权限
解决:
mysql>use mysql;
mysql>update user set host = ‘%’ where user = ‘root’; //这个命令执行错误时可略过
mysql>flush privileges;
mysql>select host, user from user;