728x90

안녕하세요. IBM Community에서 Informix의 rowid를 참조하는 내용이 있어 공유하고자 합니다.

원래 글의 내용은 Informix page 할당 개수의 한계에 관련된 질문이었는데 파티션된 테이블의 rowid에 대한 내용이 중간에 언급되었습니다.

인포믹스의 파티션된 테이블은 rowid 컬럼이 존재하지 않는데, 파티션 테이블에 rowid를 표시되도록 하려면 아래의 명령으로 숨겨진 ROWID 컬럼을 추가할 수 있습니다.

ALTER TABLE frag1 ADD ROWIDS;


그런데 ifx_row_id라는 숨겨진 컬럼이 있다고 합니다. 이리저리 자료들을 찾아보니 11.50 버전부터 지원되었다고 하는데요. IBM에서 공식적으로 문서화되지 않았습니다.

기존 테이블에 rowid 컬럼을 추가하지 않고도 rowid를 대체하여 사용할 수 있습니다.

보여지는 형식은 <partnum>:<rowid> 입니다.

특징으로는 아래와 같이 SEQUENTIAL SCAN이 발생한다는 점입니다.

QUERY: (OPTIMIZATION TIMESTAMP: 01-02-2020 17:27:54)
------
select ifx_row_id from systables where ifx_row_id='1048900:1301'
Estimated Cost: 7
Estimated # of Rows Returned: 1
  1) informix.systables: SEQUENTIAL SCAN
        Filters: informix.systables.ROWID = '1048900:1301'


반면에 ROWID 컬럼은 INDEX SCAN을 합니다.

QUERY: (OPTIMIZATION TIMESTAMP: 01-02-2020 17:51:25)
------
select * from systables where rowid=2058
Estimated Cost: 1
Estimated # of Rows Returned: 1
  1) informix.systables: INDEX PATH
    (1) Index Name: (ROWID)
        Index Keys: ROWID
        Lower Index Filter: informix.systables.ROWID = 2058

ifx_row_id 컬럼은 일반적인 사용자 업무에 사용되기보다는 마이그레이션등의 작업에 이용할 수 있는 옵션이 될 수 있을 것 같습니다.


아래 APAR를 보면 WITH ROWIDS 옵션을 쓰기보다 일반 컬럼을 primary key로 사용할 것을 권고하고 있습니다.

IC94738: IFX_ROW_ID UNDOCUMENTED FEATURE IS DOING SEQUENTIAL SCAN INSTEAD OF READING DIRECTLY IN THE APPROPRIATE PAGE

Using the WITH ROWIDS Option
Nonfragmented tables contain a hidden column called rowid, but
by default, fragmented tables have no rowid column. You can use
the WITH ROWIDS keywords to add the rowid column to a fragmented
table. Each row is automatically assigned a unique rowid value
that remains stable for the life of the row and that the
database server can use to find the physical location of the
row. Each row requires an additional four bytes to store the
rowid.
Important: This is a deprecated feature. Use primary keys as an
access method rather than the rowid column.

https://www-01.ibm.com/support/docview.wss?uid=swg1IC94738

728x90
728x90


Problem(Abstract)

How to unload rows from a table avoiding inaccessible data using the ROWID on data corruption scenarios.

Resolving the problem

INTRODUCTION

This document describes a technique that can help you rebuild a table based on the data that might be still accessible. It uses the concept of the ROWIDs and the UNLOAD command.

    Attention: This technique only saves rows that are still accessible. Damaged rows are lost.

    Note: The technique will not work for fragmented tables, because they do not have rowids.

STEPS

    1. Use the UNLOAD command to extract the accessible rows from the table. This command will fail when the first corrupted row is encountered:
    UNLOAD TO file1 SELECT rowid, * FROM table ;
    file1  
      File name where the data is going to the stored
    table
      Name of the source table
    2. Open file1 and take note of the last ROWID that was unloaded successfully:
    last_rowid = Last ROWID in file1
    3. Add two units to the last_rowid. You will use this value in the next step:
    next_rowid = last_rowid + 2
    4. Run the UNLOAD command again, this time to retrieve the remaining rows of the table using the next_rowid as the filtering argument:
    UNLOAD TO file2
    SELECT rowid, * FROM table where rowid >= next_rowid
    Note: If UNLOAD fails without producing any data, skip another rowid by increasing next_rowid. You might have to repeat steps 2, 3 and 4 many times depending on the quantity of corrupted rows. There are some scenarios where this technique can be very time-consuming.

    5. After unloading all possible rows, repeat steps 1 and 2, this time without selecting the rowid in the column list of the SELECT statement.
    UNLOAD TO file1 SELECT * FROM table ;
    UNLOAD TO file2
    SELECT * FROM table where rowid >= next_rowid
    6. Recreate the table using the data that was just unloaded.
      LOAD FROM file1 INSERT INTO table;
      LOAD FROM file2 INSERT INTO table;

Example:

    1. oncheck reported an error in the table customer. Run the first UNLOAD command until it fails.
      UNLOAD TO file1 SELECT rowid, * FROM customer;
    2. Suppose the last rowid found in the last record on file1 is decimal 1038:
    last_rowid = 1038
    3. Add two units to last_rowid :
    next_rowid = (last_rowid + 2) = 1040
    4. Using this calculation, restart the unload on rowid 1040:
      UNLOAD TO file2
      SELECT rowid, * FROM customer where rowid >= 1040;

    5. Repeat this process until you scan the whole table. Assuming that the second UNLOAD command finished without errors, the next step is to run the same commands again without the rowid.
      UNLOAD TO file1 SELECT * FROM customer;
      UNLOAD TO file2
      SELECT * FROM customer where rowid >=1040;

    6. Recreate the table and load the data using file1 and file2 as input files:
    LOAD from file1 insert into customer;
    LOAD from file2 insert into customer;


http://www-01.ibm.com/support/docview.wss?uid=swg21154363

728x90

+ Recent posts