SlideShare une entreprise Scribd logo
1  sur  4
Télécharger pour lire hors ligne
Detecting and Curing Row Migration                                              Administration Tips




Detecting and Curing Row Migration

Row migration occurs when an existing row, happily contained within an Oracle Block, is
updated to contain extra information, and finds that there is insufficient free space within
the block to house the newly-grown record. The primary cause for this is that PCTFREE for
a segment has been set too low (PCTFREE is there to stop new inserts taking place in a
block before the block is actually full -thus leaving some wasted space at the top of the
block, expressly for the purpose of allowing existing rows to slosh around within the block
as they are updated).

Finding no room to expand within its original block, most of the row is moved off into a
completely new block. All that is left behind in the original block is a small row stub (a
row header, if you like), which is used to point to where the real row data is now loacted.

This seriously degrades performance, since the index on the segment still points to the
original block. That means all access to that row via the index is first directed to the
original block -where it discovers the row stub pointing to the new block. That's two
blocks that have to be read before we can access the row data, rather than the original
one. Doubling your I/O for row access is not exactly what one would recommend as a
performance enhancing tip!!

Detecting whether rows have already migrated is therefore important. There are a
number of ways to do it, but the easiest is to issue the following command:

ALTER TABLE BLAH COMPUTE STATISTICS;


That causes a full table scan to take place (so it's not something you'd do in the middle of a
busy day), and each row to be inspected for pointers to other blocks. (It also calculates
other important statistics for the table which the Cost-based Optimizer uses to generate
execution plans whenever a new SQL statement is thrown at the database).

The DBA_TABLES view is then populated with the statistics gathered during the scan, and
for our purposes the killer column is one called CHAIN_CNT. If that contains a non-zero
number, then you have row migration -or, possibly, row chaining -the column doesn't
distinguish between them.

To distinguish row migration (which can be fixed) from row chaining (which can't), you
need to know your table column definitions. If the definition included things like 'CLOB' or
"BLOB' or 'VARCHAR2(3000)', then the number probably reflects row chaining (which is
where a single row is simply too long to fit into a single Oracle Block, and has to be broken
up and distributed amongst several). If the definition is full of "normal" stuff, like
'VARCHAR2(30)', 'NUMBER(8,2) and so on, then it is extremely unlikely that the row simply
can't be fitted into a block -in which case, the CHAIN_CNT must represent migrated rows.


Copyright © Howard Rogers 2001            10/18/2001                                     Page 1 of 4
Detecting and Curing Row Migration                                              Administration Tips


If you determine that row migration has taken place, what can you do to fix it up? Firstly,
of course, you probably want to adjust PCTFREE for the segment:

ALTER TABLE BLAH         PCTFREE 30;

(or some other percentage that is appropriate).

That helps prevent future migration, but it doesn't cure any that's already taken place.
For that, you have to recall that the migration happened because rows got updated.
Migration does not happen when rows are freshly inserted. So what we need is something
that will get all the rows of a table freshly inserted -and that will fix the problem.

The easiest way to achieve that (in 8i only, alas) is to issue the following command:

ALTER TABLE BLAH MOVE TABLESPACE       X;

The 'move tablespace' command does not have to reference a completely new tablespace -
you can type in the name of the same tablespace in which the table is already housed. But
it does cause every record to be read, and freshly inserted into new blocks, and the fresh
insertion means that the row migration is cured. There's only one slight drawback with this
approach: you need to rebuild all indexes on the table, since they are left pointing at the
blocks where the table used to be.

In earlier versions of Oracle (7.x and 8.0) the move command is not available to you, so
the only real option you have is to perform an export of the table, truncate it, and then
run import for it. Import needs to be run with the 'IGNORE=Y' parameter (otherwise, the
fact that the table still exists will cause it to abort with an error). The import will then
proceed to insert all the rows back into the table -and, since these are fresh inserts, row
migration will be cured. The main drawback to this approach is that until the import is
finished, your Users can have no access to the table data (whereas a 'move tablespace' still
allows query access to the original data whilst the move is taking place). On the plus side,
import re-creates all indexes automatically, so they don't need to be rebuilt manually.

Both approaches are fairly expensive ways of fixing up row migration: for a large table,
they'd both involve massive reads and writes. If the migrated rows are only a relatively
small proportion of the total number of records (say, 10-20%), there is a more subtle way
of fixing the problem.

In principle, it involves copying the rowid's of the migrated rows out into a holding table,
and using them as a 'hook' by which to delete the rows, and then as a source for re-
inserting them (and, being fresh inserts, they fix up the migration problem).

The steps are as follows:




Copyright © Howard Rogers 2001              10/18/2001                                   Page 2 of 4
Detecting and Curing Row Migration                                            Administration Tips


First, run the Oracle-supplied script utlchain.sql (it's found in the
ORACLE_HOME/rdbms/admin directory). It creates a special table called "chained_rows"
into which the rowid of the rows suffering from migration are copied when you run the
command:

ANALYZE TABLE            ORDER_HIST   LIST CHAINED ROWS;

You can query that table directly, like this:

SELECT * FROM            CHAINED_ROWS;


OWNER_NAME TABLE_NAME ... HEAD_ROWID        TIMESTAMP
---------- ---------- ... ------------------ ---------
SCOTT       EMP       ... AAAALUAAHAAAAA1AAA 04-OCT-01
SCOTT       EMP       ... AAAALUAAHAAAAA1AAB 04-OCT-01
SCOTT       EMP       ... AAAALUAAHAAAAA1AAC 04-OCT-01

However, the more meaningful approach is to create a holding table to hold the entire row
data for these rows, using the rowid stored in the chained_rows table as the hook by which
to select them. You do that by running a command like this:

CREATE TABLE HOLD_EMP
AS SELECT *
FROM EMP
WHERE ROWID IN
(SELECT HEAD_ROWID
FROM CHAINED_ROWS
WHERE TABLE_NAME = 'EMP');

Now you use the same sort of sub-select technique to delete the rows suffering migration
out of the original table, like this:

DELETE FROM EMP
WHERE ROWID IN
(SELECT HEAD_ROWID
FROM CHAINED_ROWS
WHERE TABLE_NAME = 'EMP');

And finally, you insert the same row data back into the original table, drawing on the
holding table contents we created earlier:

INSERT INTO EMP
SELECT *
FROM HOLD_EMP;



Copyright © Howard Rogers 2001                10/18/2001                               Page 3 of 4
Detecting and Curing Row Migration                                               Administration Tips


The freshly inserted rows will now no longer be migrated rows (you could check that by
truncating the chained_rows table, and doing a fresh 'analyze table emp list chained rows'
command -this time, a select * from chained_rows should yield zero records).

To tidy up, drop the holding table:

DROP TABLE          INT_ORDER_HISTORY;


And finally (if you haven't already done so) clear out the chained_rows table:

DELETE FROM           CHAINED_ROWS;   (or you could truncate it).

This technique is rather more fiddly than the 'move tablespace' or 'export-truncate-import'
ones, but it has the distinct advantage that the bulk of the table remains unaffected by
your repair efforts. On a big table, that's a huge benefit.

Just in case it isn't clear, in all three cases, you need to change PCTFREE first, otherwise
the fix will be purely temporary: unless the underlying cause of row migration is addressed
(i.e., a lack of space in the block to accommodate updates), rows will start migrating
again the first time you do some updates to the table.




Copyright © Howard Rogers 2001                  10/18/2001                                Page 4 of 4

Contenu connexe

Tendances

Lecture02 abap on line
Lecture02 abap on lineLecture02 abap on line
Lecture02 abap on line
Milind Patil
 
Sydney Oracle Meetup - indexes
Sydney Oracle Meetup - indexesSydney Oracle Meetup - indexes
Sydney Oracle Meetup - indexes
paulguerin
 
Sql delete, truncate, drop statements
Sql delete, truncate, drop statementsSql delete, truncate, drop statements
Sql delete, truncate, drop statements
Vivek Singh
 

Tendances (20)

10053 - null is not nothing
10053 - null is not nothing10053 - null is not nothing
10053 - null is not nothing
 
Algo>Stacks
Algo>StacksAlgo>Stacks
Algo>Stacks
 
Technical
TechnicalTechnical
Technical
 
Properly Use Parallel DML for ETL
Properly Use Parallel DML for ETLProperly Use Parallel DML for ETL
Properly Use Parallel DML for ETL
 
Lecture02 abap on line
Lecture02 abap on lineLecture02 abap on line
Lecture02 abap on line
 
IBM Informix Database SQL Set operators and ANSI Hash Join
IBM Informix Database SQL Set operators and ANSI Hash JoinIBM Informix Database SQL Set operators and ANSI Hash Join
IBM Informix Database SQL Set operators and ANSI Hash Join
 
Sas Plots Graphs
Sas Plots GraphsSas Plots Graphs
Sas Plots Graphs
 
Sydney Oracle Meetup - indexes
Sydney Oracle Meetup - indexesSydney Oracle Meetup - indexes
Sydney Oracle Meetup - indexes
 
Discover the power of Recursive SQL and query transformation with Informix da...
Discover the power of Recursive SQL and query transformation with Informix da...Discover the power of Recursive SQL and query transformation with Informix da...
Discover the power of Recursive SQL and query transformation with Informix da...
 
SAS Ron Cody Solutions for even Number problems from Chapter 7 to 15
SAS Ron Cody Solutions for even Number problems from Chapter 7 to 15SAS Ron Cody Solutions for even Number problems from Chapter 7 to 15
SAS Ron Cody Solutions for even Number problems from Chapter 7 to 15
 
Introduction to Oracle Functions--(SQL)--Abhishek Sharma
Introduction to Oracle Functions--(SQL)--Abhishek SharmaIntroduction to Oracle Functions--(SQL)--Abhishek Sharma
Introduction to Oracle Functions--(SQL)--Abhishek Sharma
 
Chap07 scr
Chap07 scrChap07 scr
Chap07 scr
 
Assignment 3
Assignment 3Assignment 3
Assignment 3
 
Sql delete, truncate, drop statements
Sql delete, truncate, drop statementsSql delete, truncate, drop statements
Sql delete, truncate, drop statements
 
What's New in MariaDB Server 10.3
What's New in MariaDB Server 10.3What's New in MariaDB Server 10.3
What's New in MariaDB Server 10.3
 
Understanding sas data step processing.
Understanding sas data step processing.Understanding sas data step processing.
Understanding sas data step processing.
 
Etl2
Etl2Etl2
Etl2
 
Columnrename9i
Columnrename9iColumnrename9i
Columnrename9i
 
SQL Server 2008 Performance Enhancements
SQL Server 2008 Performance EnhancementsSQL Server 2008 Performance Enhancements
SQL Server 2008 Performance Enhancements
 
Advanced functions in PL SQL
Advanced functions in PL SQLAdvanced functions in PL SQL
Advanced functions in PL SQL
 

En vedette (7)

PDP calculator
PDP calculatorPDP calculator
PDP calculator
 
Culinary Portfolio
Culinary PortfolioCulinary Portfolio
Culinary Portfolio
 
AUTM_LTC 2014_When EB1314 Start Our Term
AUTM_LTC 2014_When EB1314 Start Our TermAUTM_LTC 2014_When EB1314 Start Our Term
AUTM_LTC 2014_When EB1314 Start Our Term
 
Pitching
Pitching Pitching
Pitching
 
Presentatie Pim Betist
Presentatie Pim BetistPresentatie Pim Betist
Presentatie Pim Betist
 
PinkSlipParty Elevator Pitch Feb.2012
PinkSlipParty Elevator Pitch Feb.2012PinkSlipParty Elevator Pitch Feb.2012
PinkSlipParty Elevator Pitch Feb.2012
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI Explainer
 

Similaire à Migration

Introduction to MySQL - Part 2
Introduction to MySQL - Part 2Introduction to MySQL - Part 2
Introduction to MySQL - Part 2
webhostingguy
 
Myth busters - performance tuning 102 2008
Myth busters - performance tuning 102 2008Myth busters - performance tuning 102 2008
Myth busters - performance tuning 102 2008
paulguerin
 
Myth busters - performance tuning 103 2008
Myth busters - performance tuning 103 2008Myth busters - performance tuning 103 2008
Myth busters - performance tuning 103 2008
paulguerin
 
Database development coding standards
Database development coding standardsDatabase development coding standards
Database development coding standards
Alessandro Baratella
 

Similaire à Migration (20)

Oracle Join Methods and 12c Adaptive Plans
Oracle Join Methods and 12c Adaptive PlansOracle Join Methods and 12c Adaptive Plans
Oracle Join Methods and 12c Adaptive Plans
 
Oracle NOLOGGING
Oracle NOLOGGINGOracle NOLOGGING
Oracle NOLOGGING
 
Introduction to MySQL - Part 2
Introduction to MySQL - Part 2Introduction to MySQL - Part 2
Introduction to MySQL - Part 2
 
Autonumber
AutonumberAutonumber
Autonumber
 
SQL Database Performance Tuning for Developers
SQL Database Performance Tuning for DevelopersSQL Database Performance Tuning for Developers
SQL Database Performance Tuning for Developers
 
Interview Questions.pdf
Interview Questions.pdfInterview Questions.pdf
Interview Questions.pdf
 
MySQL Essential Training
MySQL Essential TrainingMySQL Essential Training
MySQL Essential Training
 
Hash join
Hash joinHash join
Hash join
 
Application sql issues_and_tuning
Application sql issues_and_tuningApplication sql issues_and_tuning
Application sql issues_and_tuning
 
Group-2.pdf
Group-2.pdfGroup-2.pdf
Group-2.pdf
 
ADVANCE ITT BY PRASAD
ADVANCE ITT BY PRASADADVANCE ITT BY PRASAD
ADVANCE ITT BY PRASAD
 
Access tips access and sql part 3 practical examples
Access tips  access and sql part 3  practical examplesAccess tips  access and sql part 3  practical examples
Access tips access and sql part 3 practical examples
 
Top 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tipsTop 10 Oracle SQL tuning tips
Top 10 Oracle SQL tuning tips
 
Myth busters - performance tuning 102 2008
Myth busters - performance tuning 102 2008Myth busters - performance tuning 102 2008
Myth busters - performance tuning 102 2008
 
Sql DML
Sql DMLSql DML
Sql DML
 
Sql DML
Sql DMLSql DML
Sql DML
 
Myth busters - performance tuning 103 2008
Myth busters - performance tuning 103 2008Myth busters - performance tuning 103 2008
Myth busters - performance tuning 103 2008
 
Database development coding standards
Database development coding standardsDatabase development coding standards
Database development coding standards
 
Data integrity
Data integrityData integrity
Data integrity
 
Sql
SqlSql
Sql
 

Plus de oracle documents

Plus de oracle documents (20)

Applyinga blockcentricapproachtotuning
Applyinga blockcentricapproachtotuningApplyinga blockcentricapproachtotuning
Applyinga blockcentricapproachtotuning
 
Windowsosauthent
WindowsosauthentWindowsosauthent
Windowsosauthent
 
Whatistnsnames
WhatistnsnamesWhatistnsnames
Whatistnsnames
 
Whatisadatabaselink
WhatisadatabaselinkWhatisadatabaselink
Whatisadatabaselink
 
Varraysandnestedtables
VarraysandnestedtablesVarraysandnestedtables
Varraysandnestedtables
 
Usertracing
UsertracingUsertracing
Usertracing
 
Userpasswrd
UserpasswrdUserpasswrd
Userpasswrd
 
Userlimit
UserlimitUserlimit
Userlimit
 
Undo internalspresentation
Undo internalspresentationUndo internalspresentation
Undo internalspresentation
 
Undo internals paper
Undo internals paperUndo internals paper
Undo internals paper
 
Tablespacelmt
TablespacelmtTablespacelmt
Tablespacelmt
 
Tablerename
TablerenameTablerename
Tablerename
 
Sql scripting sorcerypresentation
Sql scripting sorcerypresentationSql scripting sorcerypresentation
Sql scripting sorcerypresentation
 
Sql scripting sorcerypaper
Sql scripting sorcerypaperSql scripting sorcerypaper
Sql scripting sorcerypaper
 
Sql for dbaspresentation
Sql for dbaspresentationSql for dbaspresentation
Sql for dbaspresentation
 
Sequencereset
SequenceresetSequencereset
Sequencereset
 
Rollbacksizes
RollbacksizesRollbacksizes
Rollbacksizes
 
Rollbackshrinks
RollbackshrinksRollbackshrinks
Rollbackshrinks
 
Rollbacklmt
RollbacklmtRollbacklmt
Rollbacklmt
 
Rollbackblocking
RollbackblockingRollbackblocking
Rollbackblocking
 

Migration

  • 1. Detecting and Curing Row Migration Administration Tips Detecting and Curing Row Migration Row migration occurs when an existing row, happily contained within an Oracle Block, is updated to contain extra information, and finds that there is insufficient free space within the block to house the newly-grown record. The primary cause for this is that PCTFREE for a segment has been set too low (PCTFREE is there to stop new inserts taking place in a block before the block is actually full -thus leaving some wasted space at the top of the block, expressly for the purpose of allowing existing rows to slosh around within the block as they are updated). Finding no room to expand within its original block, most of the row is moved off into a completely new block. All that is left behind in the original block is a small row stub (a row header, if you like), which is used to point to where the real row data is now loacted. This seriously degrades performance, since the index on the segment still points to the original block. That means all access to that row via the index is first directed to the original block -where it discovers the row stub pointing to the new block. That's two blocks that have to be read before we can access the row data, rather than the original one. Doubling your I/O for row access is not exactly what one would recommend as a performance enhancing tip!! Detecting whether rows have already migrated is therefore important. There are a number of ways to do it, but the easiest is to issue the following command: ALTER TABLE BLAH COMPUTE STATISTICS; That causes a full table scan to take place (so it's not something you'd do in the middle of a busy day), and each row to be inspected for pointers to other blocks. (It also calculates other important statistics for the table which the Cost-based Optimizer uses to generate execution plans whenever a new SQL statement is thrown at the database). The DBA_TABLES view is then populated with the statistics gathered during the scan, and for our purposes the killer column is one called CHAIN_CNT. If that contains a non-zero number, then you have row migration -or, possibly, row chaining -the column doesn't distinguish between them. To distinguish row migration (which can be fixed) from row chaining (which can't), you need to know your table column definitions. If the definition included things like 'CLOB' or "BLOB' or 'VARCHAR2(3000)', then the number probably reflects row chaining (which is where a single row is simply too long to fit into a single Oracle Block, and has to be broken up and distributed amongst several). If the definition is full of "normal" stuff, like 'VARCHAR2(30)', 'NUMBER(8,2) and so on, then it is extremely unlikely that the row simply can't be fitted into a block -in which case, the CHAIN_CNT must represent migrated rows. Copyright © Howard Rogers 2001 10/18/2001 Page 1 of 4
  • 2. Detecting and Curing Row Migration Administration Tips If you determine that row migration has taken place, what can you do to fix it up? Firstly, of course, you probably want to adjust PCTFREE for the segment: ALTER TABLE BLAH PCTFREE 30; (or some other percentage that is appropriate). That helps prevent future migration, but it doesn't cure any that's already taken place. For that, you have to recall that the migration happened because rows got updated. Migration does not happen when rows are freshly inserted. So what we need is something that will get all the rows of a table freshly inserted -and that will fix the problem. The easiest way to achieve that (in 8i only, alas) is to issue the following command: ALTER TABLE BLAH MOVE TABLESPACE X; The 'move tablespace' command does not have to reference a completely new tablespace - you can type in the name of the same tablespace in which the table is already housed. But it does cause every record to be read, and freshly inserted into new blocks, and the fresh insertion means that the row migration is cured. There's only one slight drawback with this approach: you need to rebuild all indexes on the table, since they are left pointing at the blocks where the table used to be. In earlier versions of Oracle (7.x and 8.0) the move command is not available to you, so the only real option you have is to perform an export of the table, truncate it, and then run import for it. Import needs to be run with the 'IGNORE=Y' parameter (otherwise, the fact that the table still exists will cause it to abort with an error). The import will then proceed to insert all the rows back into the table -and, since these are fresh inserts, row migration will be cured. The main drawback to this approach is that until the import is finished, your Users can have no access to the table data (whereas a 'move tablespace' still allows query access to the original data whilst the move is taking place). On the plus side, import re-creates all indexes automatically, so they don't need to be rebuilt manually. Both approaches are fairly expensive ways of fixing up row migration: for a large table, they'd both involve massive reads and writes. If the migrated rows are only a relatively small proportion of the total number of records (say, 10-20%), there is a more subtle way of fixing the problem. In principle, it involves copying the rowid's of the migrated rows out into a holding table, and using them as a 'hook' by which to delete the rows, and then as a source for re- inserting them (and, being fresh inserts, they fix up the migration problem). The steps are as follows: Copyright © Howard Rogers 2001 10/18/2001 Page 2 of 4
  • 3. Detecting and Curing Row Migration Administration Tips First, run the Oracle-supplied script utlchain.sql (it's found in the ORACLE_HOME/rdbms/admin directory). It creates a special table called "chained_rows" into which the rowid of the rows suffering from migration are copied when you run the command: ANALYZE TABLE ORDER_HIST LIST CHAINED ROWS; You can query that table directly, like this: SELECT * FROM CHAINED_ROWS; OWNER_NAME TABLE_NAME ... HEAD_ROWID TIMESTAMP ---------- ---------- ... ------------------ --------- SCOTT EMP ... AAAALUAAHAAAAA1AAA 04-OCT-01 SCOTT EMP ... AAAALUAAHAAAAA1AAB 04-OCT-01 SCOTT EMP ... AAAALUAAHAAAAA1AAC 04-OCT-01 However, the more meaningful approach is to create a holding table to hold the entire row data for these rows, using the rowid stored in the chained_rows table as the hook by which to select them. You do that by running a command like this: CREATE TABLE HOLD_EMP AS SELECT * FROM EMP WHERE ROWID IN (SELECT HEAD_ROWID FROM CHAINED_ROWS WHERE TABLE_NAME = 'EMP'); Now you use the same sort of sub-select technique to delete the rows suffering migration out of the original table, like this: DELETE FROM EMP WHERE ROWID IN (SELECT HEAD_ROWID FROM CHAINED_ROWS WHERE TABLE_NAME = 'EMP'); And finally, you insert the same row data back into the original table, drawing on the holding table contents we created earlier: INSERT INTO EMP SELECT * FROM HOLD_EMP; Copyright © Howard Rogers 2001 10/18/2001 Page 3 of 4
  • 4. Detecting and Curing Row Migration Administration Tips The freshly inserted rows will now no longer be migrated rows (you could check that by truncating the chained_rows table, and doing a fresh 'analyze table emp list chained rows' command -this time, a select * from chained_rows should yield zero records). To tidy up, drop the holding table: DROP TABLE INT_ORDER_HISTORY; And finally (if you haven't already done so) clear out the chained_rows table: DELETE FROM CHAINED_ROWS; (or you could truncate it). This technique is rather more fiddly than the 'move tablespace' or 'export-truncate-import' ones, but it has the distinct advantage that the bulk of the table remains unaffected by your repair efforts. On a big table, that's a huge benefit. Just in case it isn't clear, in all three cases, you need to change PCTFREE first, otherwise the fix will be purely temporary: unless the underlying cause of row migration is addressed (i.e., a lack of space in the block to accommodate updates), rows will start migrating again the first time you do some updates to the table. Copyright © Howard Rogers 2001 10/18/2001 Page 4 of 4