Thursday, September 14, 2017

Table resize, Index Resize, partition or sub partition table space resize :




Table resize, Index Resize, partition or sub partition table space resize :

Please Note: Take backup of either schema and/or table before doing any changes. No backup means no recovery as simple as that..
Backup is must, backup is must.. Test this in non-prod first - no direct use in prod db.

------------------------- Table Resize --------------

 


execute DBMS_STATS.GATHER_SCHEMA_STATS(user, cascade=>true);



select count(*), sum(bytes) from user_extents where segment_name='T';



alter table t deallocate unused;



select count(*), sum(bytes) from user_extents where segment_name='T';





select table_name, ROW_MOVEMENT from user_tables where table_name='T';



ALTER TABLE t ENABLE ROW MOVEMENT ;

ALTER TABLE T SHRINK SPACE CASCADE;



alter table  t   disable row movement;  -- as per previous table row_movement value



select count(*), sum(bytes) from user_extents where segment_name='T';





------------------- Index Resize -----------------------


 



analyze index i_t validate structure;

select blocks, lf_blks, btree_space, pct_used from index_stats;

alter index i_t rebuild online;

select blocks, lf_blks, btree_space, pct_used from index_stats;

--for partitions
--ANALYZE INDEX   [PARTITION ] [SUBPARTITION ] VALIDATE STRUCTURE

--------------------- Tablespace Level resize by moving to different tableapce.. -------------

In this exmaple : It is considered like

Each partition has its own tablesapce.
No tablesapce being shared between partitions.

 


CREATE TABLE T

(id            NUMBER,

 created_date  DATE)

PARTITION BY RANGE (created_date)

(PARTITION part_2016 VALUES LESS THAN (TO_DATE('01/01/2017', 'DD/MM/YYYY')) TABLESPACE users,

 PARTITION part_2017 VALUES LESS THAN (TO_DATE('01/01/2018', 'DD/MM/YYYY')) TABLESPACE users);





 INSERT INTO t

SELECT level,

         CASE

         WHEN MOD(level,2) = 0 THEN TO_DATE('05/09/2016', 'DD/MM/YYYY')

         ELSE TO_DATE('04/05/2017', 'DD/MM/YYYY')

       END

FROM   dual

CONNECT BY level <= 1000000;

COMMIT;





execute DBMS_STATS.GATHER_SCHEMA_STATS(user, cascade=>true);

EXEC DBMS_STATS.gather_table_stats(USER, 'T',cascade=>true);



col table_name for a30

col partition_name for a30

SELECT table_name,        partition_name,        num_rows FROM   user_tab_partitions where table_name='T' ;



 --- Note down the table space size being altered...




select count(*), sum(bytes) from user_extents where segment_name='T';



SELECT TABLE_NAME,PARTITION_NAME,TABLESPACE_NAME  FROM USER_TAB_PARTITIONS WHERE TABLE_NAME='T';



CREATE TABLESPACE test5



Move partition/subpartition   to new TABLESPACE



ALTER TABLE T MOVE PARTITION part_2016 ONLINE TABLESPACE test5 UPDATE INDEXES PARALLEL;



Rebuild partition/subpartition indexes to new TABLESPACE



ALTER INDEX T_P REBUILD PARTITION part_2016 TABLESPACE test5 PARALLEL ;



drop old tablespace , and rename new tablespace name back to old tablespace

Please note : Ensure no objects exists in the tablesapce before tablespace being dropped, one can check existence of objects using below queries.
To find objects belonging to a tablespace:

select distinct segment_type from dba_segments where tablespace_name='USERS';
OR
select   owner, segment_name, TABLESPACE_NAME from dba_segments where tablespace_name='USERS' 
union
select   owner, table_name, TABLESPACE_NAME from dba_tables where tablespace_name='USERS' 
union
select  owner, index_name, TABLESPACE_NAME from dba_indexes where tablespace_name='USERS';

SELECT UT.TABLESPACE_NAME "TABLESPACE", COUNT (US.SEGMENT_NAME) "NUM SEGMENTS"
   FROM USER_TABLESPACES UT, USER_SEGMENTS US
   WHERE UT.TABLESPACE_NAME = US.TABLESPACE_NAME
   AND ut.tablespace_name='USERS'
   GROUP BY (UT.TABLESPACE_NAME)
   ORDER BY COUNT (US.SEGMENT_NAME) DESC;



DROP TABLESPACE USERS INCLUDING CONTENTS AND DATAFILES;

ALTER TABLE T MODIFY DEFAULT ATTRIBUTES FOR PARTITION part_2016 TABLESPACE test5;

ALTER INDEX  T_P MODIFY DEFAULT ATTRIBUTES FOR PARTITION part_2016 TABLESPACE test5;

ALTER TABLESPACE test5 RENAME TO USERS;




-- check index status for all the partitions , table sizes , indexes sizes etc..

The other way of doing is redefinition



--------- Using dbms_redefinition:

--- TABLE LEVEL ------- 12C FEATURE
begin
dbms_redefinition.redef_table (
uname=>USER,
tname=>'PAR_TABLE',
index_tablespace => 'USERS',
table_part_tablespace=>'USERS');
end;
/

------------------------------ TABLE PARTITION LEVEL -------------

Creating   a non partitioned table:


create table  nopar_table( id number,ts timestamp,value varchar2(30)) TABLESPACE TEST5;

--- create all indexes on this non partition table exactly same as the indexes on the partitioned table
create index  nopar_table_ts on  nopar_table(ts) tablespace TEST5;


BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE(
UNAME => USER,
TNAME => 'PAR_TABLE',
PART_NAME => 'P0');
END;
/

BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE(
UNAME => USER,
ORIG_TABLE => 'PAR_TABLE',
INT_TABLE => 'NOPAR_TABLE',
PART_NAME => 'P0' );
END;
/



BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE (
UNAME => USER,
ORIG_TABLE => 'PAR_TABLE',
INT_TABLE => 'NOPAR_TABLE',
PART_NAME => 'P0');
END;
/


-- INCASE IF THERE ARE ERRORS DURING THE REDEFINATION..................
BEGIN
DBMS_REDEFINITION.ABORT_REDEF_TABLE (
UNAME => USER,
ORIG_TABLE => 'PAR_TABLE',
INT_TABLE => 'NOPAR_TABLE',
PART_NAME => 'P0');
END;
/
--- Note: This can be called after the START_REDEF_TABLE Procedure but before the FINISH_REDEF_TABLE Procedure is called.


select TABLE_NAME, PARTITION_NAME, TABLESPACE_NAME,NUM_ROWS from user_tab_partitions where table_name='PAR_TABLE';
select index_name, PARTITION_NAME, TABLESPACE_NAME,status from user_ind_partitions where index_name in (select index_name from user_indexes where table_name='PAR_TABLE');
select index_name, tablespace_name, status from user_indexes where table_name='PAR_TABLE';

------------------

How to find only nfs shares or nfs drives in linux

How to find only nfs shares or nfs drives in linux


 df -Ph -t nfs

Thursday, August 10, 2017

How to restore oracle database with no errors:


Note: please take great care before you do backup and restore as incorrect executions are catastrophic. You are responsible for your own actions and no one else.


We all like to restore database when it is required to restore however at times we found difficult to restore due to non availability of backup files, or missing backups etc.

how can we ensure that the taken backup is perfect for restore  or how can we ensure the database is in correct state to take backup.

In my view, we need to ensure database is in consistent state and has no physical , logical corruptions. It is not for later checks but very next after creation of database.

As soon as we created a database, we need to check if db is free from physical and logical corruptions and we need to put this check in practice all the time.

It is always a good idea to check database before taking backup to see if there any corruptions , if there are any we can restore those corrupted database blocks from valid backups.

How do I check if taken backups are valid and can be restored without actually performing actual restore to be sure restore can be done if needed successfully.

no valid backup no valid restore, it is as simple as that.

Create/upgrade  database -> check db if any corruptions .. if any fix there itself

Assume we have valid database

Take backup
-- as it is first time, there will not be any corruptions
-- from second time on wards
         -- check db for any corruptions, if any fix them from valid backup we took recently
         -- take the backup
         -- validate taken backup

Check if restore can done successfully before actually attempting to restore.

following commands can be used to validate database, backup sets, to see if restore can be done successfully.



--validate the database
BACKUP VALIDATE DATABASE ;
BACKUP VALIDATE DATABASE ARCHIVELOG ALL;

BACKUP VALIDATE CHECK LOGICAL DATABASE ;
BACKUP VALIDATE CHECK LOGICAL DATABASE ARCHIVELOG ALL;

Any block corruptions are visible in the V$DATABASE_BLOCK_CORRUPTION view, as well as in the RMAN output.

-- validate the contents of backup files
RESTORE DATABASE VALIDATE;
RESTORE ARCHIVELOG ALL VALIDATE;

-- Check if restore can be successfull
RESTORE DATABASE PREVIEW;
RESTORE DATABASE PREVIEW SUMMARY;
RESTORE ARCHIVELOG ALL PREVIEW;
-- List backups
LIST BACKUP;       # lists backup sets, image copies, and proxy copies
LIST COPY;         # lists only disk copies

--  To determine which database files need backup under a specific retention policy.
REPORT NEED BACKUP ;



BACKUP VALIDATE  ,   RESTORE VALIDATE command mimics the process of a backup, restore, without actually performing the backup, restore.