(Asm Utility(AMDU,KFED,KFOD

همانطور که می دانید، در هر asm disk علاوه بر داده های بانک اطلاعاتی، نوع دیگری از داده هم ذخیره می شود که فراداده مربوط به ان دیسک می باشد و این نوع از داده ها معمولا در قسمت ابتدایی دیسک و به عبارتی در بلاک صفر ذخیره می شوند و کپی ای از ان هم در بلاک 510 برای مسائل امنیتی ذخیره می شود(2088960 bytes / 4096 = 510) البته قسمتی از فراداده داده ذخیره شده در این بلاکها، مربوط به خود دیسک نمی باشد بلکه اطلاعاتی در مورد دیسک گروهی هست که دیسک عضو ان می باشد.

این بلاکها همانند انواع دیگر بلاکها، امکان خرابی دارند و در صورت لزوم باید خرابی ایجاد شده را شناسایی و برطرف کرد و یا در صورتی که این خرابی قابل رفع نباشد، داده های مربوط به بانک اطلاعاتی را از این محیط به محیط بیرون انتقال داد. برای مشاهده اطلاعات دقیق این بلاکها و نیز مدیریت انها در صورتی خرابی، دستوراتی وجود دارد که در این نوشتار به انها خواهیم پرداخت.

دستور AMDU

با کمک این دستور می توان از فایلهای موجود در asm disk دامپ تهیه کرد و یا به عبارتی دیگر، می توان محتویات موجود در دیسک را استخراج نمود. این ابزار از نسخه 11g عرضه شد هر چند برای اوراکل 10g هم می توان ان را بعد از دانلود، نصب نمود. حتی در زمانی که دیسک گروه در حالت dismount قرار دارد می توان از این ابزار استفاده کرد. عمده کاربرد این ابزار به زمانی بر می گردد که به هر دلیلی امکان mount کردن دیسک گروه برای ما وجود ندارد و در عین حال قصد داریم قسمتی از اطلاعات این دیسک گروه را به محیط سیستم عامل منتقل کنیم در این صورت می توانیم با کمک ابزار AMDU، فایلهای مورد نظر را استخراج کنیم. ساختار این دستور برای استخراج فایل، در زیر امده است:

amdu -diskstring ‘<your_path_to_ASM_disks’ -dump ‘<diskgroup>’

زمانی که از این ابزار استفاده می شود، پوشه ای در مسیر جاری با فرمت زیر ساخته می شود:

amdu_YYYY_MM_DD_HH24_MM_SS

در ادامه با چند مثال، تعدادی از کاربردهای ابزار AMDU را نشان خواهیم داد.

مثال 1: استخراج فایل از دیسک گروه به محیط سیستم عامل

در ادامه قصد داریم فایل شماره 257(که یک دیتافایل می باشد) را از دیسک گروه us_group1 که در حالت dismount قرار دارد، استخراج کنیم. برای انجام این تست، ابتدا جدولی را در این دیسک گروه ایجاد کرده و بعد از انجام تست، وجود جدول را مورد بررسی قرار می دهیم.

SQL> create tablespace usef_tbs2 datafile ‘+US_GROUP1’ size 100m;

Tablespace created.

SQL>  create table tbl2 tablespace usef_tbs2 as select * from dba_tables;

Table created.

SQL> select count(*) from tbl2;

  COUNT(*)

———-

      2344

SQL> select name from v$datafile;

NAME

——————————————————————————–

+DATA01/USEFDB/DATAFILE/system.258.958753679

+US_GROUP1/USEFDB/DATAFILE/usef_tbs2.257.958994487

+DATA01/USEFDB/DATAFILE/sysaux.257.958753635

+DATA01/USEFDB/DATAFILE/undotbs1.260.958753737

+US_GROUP1/USEFDB/DATAFILE/usef_tbs1.256.958839057

+DATA01/USEFDB/DATAFILE/users.259.958753735

برای انجام این سناریو، در ادامه دیسک را در حالت dismount قرار می دهیم:

SQL> alter diskgroup us_group1 dismount force;

Diskgroup altered.

با پرس و جو از جدول tbl2، به خطا برخواهیم خورد:

SQL>select count(*) from tbl2;

ORA-01115: IO error reading block from file  (block # )

ORA-01110: data file 2: ‘+US_GROUP1/USEFDB/DATAFILE/usef_tbs2.257.958994487’

ORA-15078: ASM diskgroup was forcibly dismounted

در همین حال، قصد داریم با کمک ابزار amdu، دیتافایل مورد نظر را به محیط سیستم عامل و در مسیر /grid بازیابی کنیم :

[grid@hkm4 ~]$ cd /grid/

[grid@hkm4 grid]$ amdu -diskstring ‘/dev/oracleasm/disks/DATA1’ -extract US_GROUP1.257

amdu_2017_11_02_11_35_30/

[grid@hkm4 grid]$ cd amdu_2017_11_02_11_35_30

[grid@hkm4 amdu_2017_11_02_11_35_30]$ ll

-rw-r–r– 1 grid oinstall      3803 Nov  2 11:35 report.txt

-rw-r–r– 1 grid oinstall 104865792 Nov  2 11:35 US_GROUP1_257.f

 [grid@hkm4 amdu_2017_11_02_11_35_30]$ pwd

/grid/amdu_2017_11_02_11_35_30

همانطور که در خروجی دیدیم، فایل شماره 257 به نام US_GROUP1_257.f در مسیر /grid/amdu_2017_11_02_11_35_30 استخراج شده است.

در نهایت مسیر این دیتافایل را به مسیر جدید تغییر داده و بانک را در حالت open قرار می دهیم:

chown -R oracle.oinstall /grid/amdu_2017_11_02_11_35_30/US_GROUP1_257.f

SQL> alter database rename file ‘+US_GROUP1/USEFDB/DATAFILE/usef_tbs2.257.958994487’ to ‘/grid/amdu_2017_11_02_11_35_30/US_GROUP1_257.f’;

Database altered.

SQL> alter database open;

Database altered.

SQL> select count(*) from tbl2;

  COUNT(*)

———-

      2344

نکته: در صورتی که دیسک گروه بیش از یک دیسک در خود داشته باشد، شکل دستور amdu کمی متفاوت خواهد بود و در این صورت باید همه دیسکها را به دستور معرفی کرد:

amdu -diskstring ‘/dev/oracleasm/disks/DATA1′ -diskstring ‘/dev/oracleasm/disks/DATA2′ -extract US_GROUP1.257

مثال 2: استخراج فایل از دیسک گروه حذف شده

در صورتی که به اشتباه دیسک گروهی را حذف کرده باشیم، با کمک ابزار amdu می توانیم دیتافایلهای ان را بازیابی کنیم:

SQL> alter diskgroup us_group1 dismount force;

Diskgroup altered.

SQL> DROP DISKGROUP us_group1 FORCE INCLUDING CONTENTS ;

Diskgroup dropped.

amdu -diskstring ‘/dev/oracleasm/disks/DATA1’ -diskstring ‘/dev/oracleasm/disks/DATA2’ -former  -extract US_GROUP1.256

با دستور بالا، فایل شماره 256 از یک دیسک گروه حذف شده!!! استخراج و در مسیر جاری قرار می گیرد.

دستور amdu_extract

علاوه بر دستور amdu، می توان از دستورamdu_extract  هم برای استخراج فایل از یک دیسک گروه استفاده کرد که ساختار ان به شکل زیر می باشد:

amdu_extract diskgroup file_name disk_string

مثال: برای اینکه دیتافایل در مسیر /grid استخراج شود، ابتدا مسیر جاری را به /grid تغییر می دهیم:

 [grid@hkm4 ~]$ cd /grid

بعد از ورود به asmcmd، برای دیتاقایل مورد نظر نام مستعاری تعریف می کنیم:

[grid@hkm4 grid]$ asmcmd -p

ASMCMD [+] > cd +JADID/USEFDB/DATAFILE/

ASMCMD [+JADID/USEFDB/DATAFILE] > ls

USEF_TBS4.256.959167027

ASMCMD [+JADID/USEFDB/DATAFILE] > mkalias USEF_TBS4.256.959167027 file256

در نهایت با دستور زیر، این دیتافایل را به زیر پوشه /grid انتقال می دهیم:

ASMCMD [+JADID/USEFDB/DATAFILE] > amdu_extract JADID file256 /dev/oracleasm/disks/*

amdu_2017_11_04_11_20_02/

دیتافایل مورد نظر، به مسیر زیر منتقل شده است:

/grid/amdu_2017_11_04_11_20_02/JADID_256.f

دستور kfed

با کمک این ابزار می توان فراداده asm diskای را خواند و یا اصلاح کرد حتی در زمانی که دیسک در حالت dismount باشد و یا امکان مونت شدن نداشته باشد! پس در زمان خرابی هدر دیسک، این دستور می تواند پرکاربرد باشد.

عملیاتهای مختلفی با کمک ابزار KFED قابل انجام می باشد که در این نوشتار، به پرکاربردترین انها که read، write و repair می باشند، خواهیم پرداخت.

دستور زیر مثالی از نحوه خواندن(read) هدر asm disk می باشد که تنها قسمتی از خروجی در ادامه ان دیده می شود:

kfed read /dev/oracleasm/disks/DATA1

kfdhdb.driver.provstr:    ORCLDISKDATA1 ; 0x000: length=13

kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER

kfdhdb.dskname:          US_GROUP1_0000 ; 0x028: length=14

kfdhdb.grpname:               US_GROUP1 ; 0x048: length=9

kfdhdb.fgname:           US_GROUP1_0000 ; 0x068: length=14

kfdhdb.secsize:                     512 ; 0x0b8: 0x0200

kfdhdb.blksize:                    4096 ; 0x0ba: 0x1000

kfdhdb.ausize:                  1048576 ; 0x0bc: 0x00100000

همانطور که می بینید، خروجی این دستور اطلاعاتی را در مورد وضیعت دیسک(KFDHDR_MEMBER)، نام گروه(US_GROUP1)، اندازه هر بلاک(4096) و … را ارائه می دهد.

در ادامه با چند مثال، نمونه هایی از کاربردهای ابزار KFED را نشان خواهیم داد.

مثال 1: تعمیر هدر asm disk با کمک KFED

همانطور که دستور زیر نشان می دهد، دو دیسک گروه به حالت مونت در بانک جاری وجود دارند:

SQL> select group_number, name, state, type from v$asm_diskgroup;

GROUP_NUMBER NAME                           STATE       TYPE

———— —————————— ———– ——

           1 DATA01                         CONNECTED   EXTERN

           2 US_GROUP1                  MOUNTED     EXTERN

در سناریوی زیر، ابتدا جدولی به دیسک گروه US_GROUP1 اضافه می کنیم و سپس با مخدوش کردن هدر تنها دیسک این دیسک گروه، نشان خواهیم داد که به چه شکلی دستور kfed می تواند این خرابی را اصلاح کند.

SQL> create tablespace usef_tbs1 datafile ‘+US_GROUP1’ size 100m;

Tablespace created.

SQL> create table tbl1 tablespace usef_tbs1 as select * from v$datafile;

Table created.

SQL> select name from v$datafile;

NAME

——————————————————————————–

+DATA01/USEFDB/DATAFILE/system.258.958753679

+DATA01/USEFDB/DATAFILE/sysaux.257.958753635

+DATA01/USEFDB/DATAFILE/undotbs1.260.958753737

+US_GROUP1/USEFDB/DATAFILE/usef_tbs1.256.958839057

+DATA01/USEFDB/DATAFILE/users.259.958753735

دستور زیر، هدر دیسک مربوط به این دیسک گروه را مخدوش می کند:

dd if=/dev/zero of=/dev/oracleasm/disks/DATA1 bs=4096 count=1

1+0 records in

1+0 records out

4096 bytes (4.1 kB) copied, 0.000410305 s, 10.0 MB/s

با اولین راه اندازی مجدد asm instance، خواهیم دید که امکان مونت مجدد این فضا وجود ندارد:

SQL> startup force;

ASM instance started

Total System Global Area 1140850688 bytes

Fixed Size                  2933400 bytes

Variable Size            1112751464 bytes

ASM Cache                  25165824 bytes

ORA-15032: not all alterations performed

ORA-15017: diskgroup “US_GROUP1” cannot be mounted

ORA-15040: diskgroup is incomplete

ORA-15017: diskgroup “DATA01” cannot be mounted

ORA-15013: diskgroup “DATA01” is already mounted

همانطور که می بینید، دیسک گروه US_GROUP1 نمی تواند مونت شود که در این حالت می توان با کمک ابزار kfed، هدر دیسک مورد نظر را اصلاح کرده و دیسک گروه را به حالت مونت دراورد قبل از ان محتویات هدر را بازبینی خواهیم کرد:

[grid@hkm4 ~]$ kfed read /dev/oracleasm/disks/DATA1

kfbh.endian:                          0 ; 0x000: 0x00

kfbh.hard:                            0 ; 0x001: 0x00

kfbh.type:                            0 ; 0x002: KFBTYP_INVALID

kfbh.datfmt:                          0 ; 0x003: 0x00

kfbh.block.blk:                       0 ; 0x004: blk=0

kfbh.block.obj:                       0 ; 0x008: file=0

kfbh.check:                           0 ; 0x00c: 0x00000000

kfbh.fcn.base:                        0 ; 0x010: 0x00000000

kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000

kfbh.spare1:                          0 ; 0x018: 0x00000000

kfbh.spare2:                          0 ; 0x01c: 0x00000000

000000000 00000000 00000000 00000000 00000000  […………….]

  Repeat 255 times

KFED-00322: Invalid content encountered during block traversal: [kfbtTraverseBlock][Invalid OSM block type][][0]

 [grid@hkm4 ~]$ kfed repair  /dev/oracleasm/disks/DATA1

SQL> alter diskgroup US_GROUP1 mount;

Diskgroup altered.

حال با بررسی جدول tbl1، خواهیم یافت که این جدول هم به صورت کامل سالم مانده است:

SQL> select count(*) from tbl1;

  COUNT(*)

———-

         5

نکته 1: اصلاح هدر دیسک با کمک بلاک شماره 510 موجود در دیسک صورت می پذیرد همانطور که قبلا اورده شد، این بلاک، کپی ای از بلاک شماره صفر می باشد. پس در صورت خرابی بلاک شماره 510، این امکان از بین خواهد رفت(امکان اصلاح از طریق repair). برای مقایسه و مشاهده هر دو بلاک، تنها کافیست از دو دستور زیر استفاده شود که خروجی هر دو دستور یکسان می باشد:

kfed read /dev/oracleasm/disks/DATA1 BLKNUM=510

kfed read /dev/oracleasm/disks/DATA1 BLKNUM=0

نکته 2: امکان بکاپ گیری از بلاکهای شماره 510 و 0 وجود دارد که در صورت خرابی هر دو بلاک، با کمک بکاپ، اصلاح قابل انجام می باشد:

kfed read /dev/oracleasm/disks/DATA1 BLKNUM=510  text=/home/grid/backup510

همچنین برای اصلاح می توان با استفاده از عملیات write، از این بکاپ استفاده کرده و عملیات اصلاح را انجام داد:

dd if=/dev/zero of=/dev/oracleasm/disks/DATA1 bs=4096 count=1

kfed write /dev/oracleasm/disks/DATA1 BLKNUM=0 text=/home/grid/backup510

مثال 2: جستجوی spfile با کمک KFED

برای بازیابی spfile از یک دیسک در حالت dismount هم می توانیم از دستور kfed استفاده کنیم. مثال زیر را ببینید.

ابتدا باید تعیین نمود که کدام یک از دیسکها، spfileای در درون خود دارند:

ll /dev/oracleasm/disks/

brw-rw—- 1 grid oinstall 8, 5 Oct 31 15:05 DATA

brw-rw—- 1 grid oinstall 8, 6 Oct 31 12:56 DATA1

kfed read /dev/oracleasm/disks/DATA1 | grep -E ‘spf|ausize’

kfdhdb.ausize:                  1048576 ; 0x0bc: 0x00100000

kfdhdb.spfile:                        0 ; 0x0f4: 0x00000000

kfdhdb.spfflg:                        0 ; 0x0f8: 0x00000000

kfed read /dev/oracleasm/disks/DATA | grep -E ‘spf|ausize’

kfdhdb.ausize:                  1048576 ; 0x0bc: 0x00100000

kfdhdb.spfile:                       59 ; 0x0f4: 0x0000003b

kfdhdb.spfflg:                        1 ; 0x0f8: 0x00000001

همانطور که می بینید، spfile در افست 59 از دیسک /dev/oracleasm/disks/DATA قرار دارد که می توان با یک دامپ، محتوای ان را استخراج نمود:

dd if=/dev/oracleasm/disks/DATA of=spfile.ora skip=59  bs=1M count=1

1+0 records in

1+0 records out

1048576 bytes (1.0 MB) copied, 0.0359577 s, 29.2 MB/s

حال با کمک دستور strings که محتوای فایل باینری را تا حد امکان به صورت خوانا نشان می دهد، پارامترهای موجود در spfile را مشخص خواهیم کرد:

strings -7 spfile.ora

+ASM.__oracle_base=’/grid’#ORACLE_BASE set from in memory value

+ASM.asm_diskgroups=”#Manual Dismount

*.asm_diskstring=’/dev/oracleasm/disks/*’

*.asm_power_limit=1

*.large_pool_size=12M

*.remote_login_passwordfile=’EXCLUSIVE’

نکته: چنین روشی بیشتر در زمانی کاربرد دارد که فضا را از سروری به سرور دیگر منتقل کرده باشیم و یا اینکه سیستم عامل تغییر کرده باشد که در این صورت ممکن است دانستن محل ذخیره سازی vote و یا spfile، مفید باشد.

نکته: دستور زیر ادرس فایل vote را نشان می دهد:

kfed read /dev/oracleasm/disks/DATA1 | grep vf

kfdhdb.vfstart:                      72 ; 0x0ec: 0x00000048

kfdhdb.vfend:                        80 ; 0x0f0: 0x00000050

مثال 3: برگرداندن دیسک گروه حذف شده با کمک KFED

در صورتی که دیسکی از یک دیسک گروه حذف شده باشد و یا این اتفاق در مورد دیسک گروهی رخ داده باشد، می توان با ابزار KFED، این دیسک گروه را مجددا به حالت قبل برگرداند.

مثال:برای انجام این سناریو، ابتدا دیسک گروهی را حذف می کنیم:

SQL> alter diskgroup us_group1 dismount force;

Diskgroup altered.

SQL> DROP DISKGROUP us_group1 FORCE INCLUDING CONTENTS ;

Diskgroup dropped.

سپس با ابزار KFED از هدر دیسک مربوط به این دیسک گروه، دامپی تهیه می کنیم:

[grid@hkm4 ~]$ kfed read /dev/oracleasm/disks/DATA1 aunum=0 blknum=0 text=header.txt

در نهایت کافیست به فایل متنی مربوط به هدر دیسک که از دستور قبلی ایجاد شده، رجوع کرده و عبارت

kfdhdb.hdrsts:                        4 ; 0x027: KFDHDR_FORMER

  را به عبارت

kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER

  تبدیل کرد:

[grid@hkm4 ~]$ vi header.txt

kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER

و برای اعمال این فایل متنی به هدر دیسک، از دستور زیر استفاده می شود:

kfed write /dev/oracleasm/disks/DATA1 aunum=0 blknum=0 text=header.txt

SQL> alter diskgroup us_group1 mount;

Diskgroup altered.

با این روش، دیسک گروه حذف شده، دوباره قابل استفاده می باشد بدون انکه داده ای را از دست داده باشیم.

مثال 4: تغییر نام دیسک گروه

همانطور که می دانید با استفاده از دستورات رایج اوراکل، تغییر نام دیسک گروه به سادگی قابل انجام می باشد برای مثال می توان با کمک دستور renamedg، دیسک گروه us_group1 را به us_ggg تغییر نام داد:

renamedg dgname=us_group1 newdgname=us_ggg asm_diskstring=’/dev/oracleasm/disks/*’   verbose=true

حال در صورتی که بخواهیم همین کار با کمک ابزار KFED صورت پذیرد باید مراحل زیر طی شود.

ابتدا دیسک گروه را در حالت dismount قرار می دهیم:

SQL> alter diskgroup US_GGG dismount force;

Diskgroup altered.

سپس اطلاعات هدر دیسک گروه را در فایل header.txt ثبت می کنیم:

kfed read /dev/oracleasm/disks/DATA1 aunum=0 blknum=0 text=header.txt

در این مرحله باید مقدار جاری grpname را به مقدار جدید تغییر داد:

kfdhdb.grpname:                   JADID ; 0x048: length=5

سپس اطلاعات جدید را در هدر بازنویسی می کنیم:

kfed write /dev/oracleasm/disks/DATA1 aunum=0 blknum=0 text=header.txt

و در نهایت دیسک گروه را مونت می کنیم:

SQL>   alter diskgroup jadid mount;

Diskgroup altered.

همچنین در صورتی که دیتافایلی در این مسیر موجود باشد، باید ان را تغییر نام داد:

SQL> alter database rename file ‘+US_GGG/USEFDB/DATAFILE/usef_tbs3.256.959005031’ to ‘+JADID/USEFDB/DATAFILE/usef_tbs3.256.959005031’;

دستور kfod

برای مشاهده لیست asm diskها در لایه OS، می توان از دستور kfod استفاده کرد. به مثال زیر توجه کنید:

مثال 1: نمایش لیست همه دیسکهای عضو و یا کاندید:

kfod disks=all

——————————————————————————–

 Disk          Size Path                                     User     Group

================================================================================

   1:      10242 Mb /dev/oracleasm/disks/DATA                grid     oinstall

   2:      10244 Mb /dev/oracleasm/disks/DATA1               grid     oinstall

   3:      20489 Mb /dev/oracleasm/disks/DATA2               grid     oinstall

——————————————————————————–

ORACLE_SID ORACLE_HOME

================================================================================

      +ASM /grid/12c

مثال 2:هر کدام از دیسکها عضو چه دیسک گروهی هستند؟

kfod ds=true disks=all

——————————————————————————–

 Disk          Size Path                                     Disk Group   User     Group

================================================================================

   1:      10242 Mb /dev/oracleasm/disks/DATA                DATA01                                  grid     oinstall

   2:      10244 Mb /dev/oracleasm/disks/DATA1               US_GROUP1       grid     oinstall

   3:      20489 Mb /dev/oracleasm/disks/DATA2               #                                          grid     oinstall

——————————————————————————–

ORACLE_SID ORACLE_HOME

================================================================================

      +ASM /grid/12c

مثال 3: نمایش حجم هر کدام از دیسک گروه ها:

kfod op=groups

——————————————————————————–

Group          Size          Free Redundancy Name

================================================================================

   1:      10244 Mb      10082 Mb     EXTERN US_GROUP1

   2:      10242 Mb       8150 Mb     EXTERN DATA01

مثال 4: هر کدام از دیسکها در چه حالتی قرار دارند؟

kfod status=true asm_diskstring=’/dev/oracleasm/disks/*’ disks=all dscvgroup=true

——————————————————————————–

 Disk          Size Header    Path                                     Disk Group   User     Group

================================================================================

   1:      10242 Mb MEMBER    /dev/oracleasm/disks/DATA                DATA01                  grid     oinstall

   2:      10244 Mb MEMBER    /dev/oracleasm/disks/DATA1               US_GROUP1       grid     oinstall

   3:      20489 Mb CANDIDATE /dev/oracleasm/disks/DATA2               #                                                   grid     oinstall

——————————————————————————–

ORACLE_SID ORACLE_HOME

================================================================================

      +ASM /grid/12c

 

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد.