Wednesday, May 21, 2014

What is difference between Row Chaning and Row Migration and how to resolve it?

Row migration & Row chaining mainly depends on Orale DB Block Size will be 8K, will ranging from 2K to 32K, which will depend on OS. It occurs at a time when table row data is INSERTED or UPDATED. 

Row migration is typically caused by an UPDATE & Row chaining is typically caused by an INSERT.

Row Migration:

When we performing any Update statement on a table row, if the content of new data is not able to fit in one database block. It means in update of a larger content, overall row length increases and free space of database block is already full.

It replaces content of original block to a pointer address - rowid and entire row is moved to the rowid defined in original block.

Row Migration is caused due to lesser value of PCTFREE for the table.There is not enough place in the BLOCK for UPDATES.

To avoid row migration, table should have PCTFREE value to be set in such a way that there is some enough space within the BLOCKS for UPDATES.

select table_name,chain_cnt,pct_free,pct_used from dba_tables where table_name = table_name ;

alter table table_name pctfree 30;

Row Chaining:

When a row data is too large to fit into a single database block. For example, if your database is of 8K db block size, and we need to insert a row of 20K into it. At this time, Oracle will use 3 db blocks and store the row in pieces.

Below are the reasons at a time when row chaining is occurs:
  • Tables having rowsize exceeds the db blocksize.
  • Tables with LONG and LONG RAW or any other LOB columns.
  • Tables with more then 255 columns.
Oracle internally stores the data in multiple blocks, one block stores all forwarding address - rowids and the data on another two or more blocks.

Row Chaining is UNAVOIDABLE but Row Migration can be MANAGED and resolved through reorganization.Whenever a row migration or row chaining will occur, I/O performance will be decrease as Oracle has to scan more than one data block to retrieve data for the row.

We can identify Row Changing and Row Migration by querying table CHAINED_ROWS, USER_TABLES and V$SYSSTAT or in an ADDM/Statspack report and using ANALYZE command.

Run below command on user to create a system table named - CHAINED_ROWS.

@$ORCL_HOME\ADMIN\utlchain.sql

select owner_name,table_name,count(head_rowid) row_count from CHAINED_ROWS where table_name = table_name GROUP BY owner_name,table_name;

SELECT owner, table_name, chain_cnt , initial_extent, num_rows, blocks, empty_blocks, avg_space, avg_row_len 
FROM user_tables WHERE chain_cnt > 0 and table_name = table_name;

SELECT name, value FROM v$sysstat WHERE name = 'table fetch continued row';

analyze table table_name list chained rows;

select count(*) from chained_rows where table_name = table_name ;


To eliminate row migration / row chaining .

alter table table_name MOVE;

This statement does is to move the table to a new segment. Oracle reads the data from current table and rebuilds the table completely. During this reorganization all migrated rows get fixed.

This causes indexes on the table to be marked UNUSABLE, because it changes the rowids of rows in the table. It generates ORA-01502 error, before REBUILDING of a table .

Do remember that you have to REBUILD all your indexes and repopulate table/index statistics in DB before using the table.

We can perform Import/Export activity as an approach to eliminate the migrated rows from a table.