{"id":15,"date":"2013-02-26T17:47:00","date_gmt":"2013-02-26T16:47:00","guid":{"rendered":"http:\/\/anjo.pt\/wp\/keyword-oracle\/2013\/02\/26\/find-orphan-asm-files\/"},"modified":"2015-11-17T20:27:23","modified_gmt":"2015-11-17T19:27:23","slug":"find-orphan-asm-files","status":"publish","type":"post","link":"https:\/\/anjo.pt\/keyword-oracle\/2013\/02\/26\/find-orphan-asm-files\/","title":{"rendered":"Find orphan ASM files"},"content":{"rendered":"<p>These days I&#8217;ve been doing the migration of some BI databases into a private cloud, about 7 TB of data in total. We made sure that before starting there was enough disk space.<\/p>\n<p>However, in the middle of the largest &#8220;duplicate from active database&#8221;, it stops. When trying to restart, it complaints that disk group space was exhausted.<\/p>\n<p>After some investigation, I found out that for a previous DB, which made 1.8 TB in datafiles, it was using above 3 TB in ASM. A closer investigation and I could see several copies of some datafiles. I believe it come from the fact that there were network problems, duplicates that were repeated with some interval between, rolling forward with RMAN incremental backup, switch to copy&#8230; a whole mess. \ud83d\ude42<\/p>\n<p>Then come the problem:<\/p>\n<p><b>&#8211; how to make a easy way to detect all orphan files on ASM?<\/b><\/p>\n<p><b>The first solution<\/b> that come to mind was to spool the list of data files and, from asmcmd, output all the files for the problematic DB with the command:<\/p>\n<p><span style=\"font-family: Courier New, Courier, monospace;\">asmcmd ls dgdata\/O01XXXXX\/datafile &gt; \/tmp\/f_asm.txt<\/span><\/p>\n<p>Then put both files as external tables into a database and query them. But there were several steps and was hard work. <\/p>\n<p><b>The second solution<\/b> was to use v$asm_file and v$asm_alias together with queries to v$datafile, v$logfile and v$controlfile. This from the database instance, even if the documentation states that:<br \/>\n&#8220;In a database instance, V$ASM_FILE displays no rows.&#8221;<br \/>\n(<a href=\"http:\/\/docs.oracle.com\/cd\/E11882_01\/server.112\/e25513\/dynviews_1029.htm#REFRN30172\">http:\/\/docs.oracle.com\/cd\/E11882_01\/server.112\/e25513\/dynviews_1029.htm#REFRN30172<\/a>)<\/p>\n<p>For this solution I&#8217;ve based on a query from <a href=\"http:\/\/aychin.wordpress.com\/2011\/07\/26\/dfdg-script-to-display-asm-disk-usage-information-and-files\/\">http:\/\/aychin.wordpress.com\/2011\/07\/26\/dfdg-script-to-display-asm-disk-usage-information-and-files\/<\/a> <\/p>\n<p>And the solution is:<\/p>\n<div>\n<\/div>\n<pre>DEFINE ASMGROUP=\"DGDATA\"\n \nset linesize 200\nset pagesize 50000\ncol reference_index noprint\ncol type format a15\ncol files format a80\n\nWITH v_asmgroup AS (SELECT group_number FROM v$asm_diskgroup WHERE name='&amp;ASMGROUP'),\n     v_parentindex AS (SELECT parent_index \n                    FROM v$asm_alias \n              WHERE group_number = (SELECT group_number FROM v_asmgroup) \n                AND alias_index=0),\n  v_asmfiles AS (SELECT file_number, type \n              FROM v$asm_file \n           WHERE group_number = (SELECT group_number FROM v_asmgroup)),\n v_dbname AS (SELECT '\/'||upper(db_unique_name)||'\/' dbname from v$database)\nSELECT 'rm '|| files files FROM -- this line show the delete command\n(\n  SELECT '+&amp;ASMGROUP'||files files, type \n  FROM (SELECT upper(sys_connect_by_path(aa.name,'\/')) files, aa.reference_index, b.type\n        FROM (SELECT file_number,alias_directory,name, reference_index, parent_index \n        FROM v$asm_alias) aa,\n             (SELECT parent_index FROM v_parentindex) a,\n             (SELECT file_number, type FROM v_asmfiles) b\n  WHERE aa.file_number=b.file_number(+)\n    AND aa.alias_directory='N'\n   -- missing PARAMETERFILE, DATAGUARDCONFIG\n   AND b.type in ('DATAFILE','ONLINELOG','CONTROLFILE','TEMPFILE')\n  START WITH aa.PARENT_INDEX=a.parent_index\n  CONNECT BY PRIOR aa.reference_index=aa.parent_index)\n  WHERE substr(files,instr(files,'\/',1,1),instr(files,'\/',1,2)-instr(files,'\/',1,1)+1) = (select dbname FROM v_dbname)\nMINUS (\n  SELECT upper(name) files, 'DATAFILE' type FROM v$datafile\n    UNION ALL \n  SELECT upper(name) files, 'TEMPFILE' type FROM v$tempfile\n    UNION ALL\n SELECT upper(name) files, 'CONTROLFILE' type FROM v$controlfile WHERE name like '+&amp;ASMGROUP%'\n    UNION ALL\n SELECT upper(member) files, 'ONLINELOG' type FROM v$logfile WHERE member like '+&amp;ASMGROUP%'\n)\n);\n\nFILES\n--------------------------------------------------------------------------------\nrm +DGDATA\/O01XXXXX\/CONTROLFILE\/CURRENT.800.807811333\n<\/pre>\n<p>\nSo then I just need to run from asmcmd:<br \/>\n<span style=\"font-family: Courier New, Courier, monospace;\">ASMCMD&gt; rm +DGDATA\/O01XXXXX\/CONTROLFILE\/CURRENT.800.807811333<\/span><\/p>\n<p><span style=\"font-family: Courier New, Courier, monospace;\"><\/span>Because WITH clause does not work on MOUNTED databases (like a standby) &#8211; SQL Statement Using &#8216;WITH&#8217; Clause Fails with ORA-01219 [ID 1166073.1] <span style=\"background-color: white; font-family: Tahoma, Verdana, Helvetica, sans-serif; font-size: 14.545454025268555px; font-weight: bold; text-align: right;\">&#8211;<\/span>, here the version without the WITH clause:<\/p>\n<pre>DEFINE ASMGROUP=\"DGDATA\"\n \nset linesize 200\nset pagesize 50000\ncol reference_index noprint\ncol type format a15\ncol files format a80\n\nSELECT 'rm '|| files files FROM -- this line show the delete command\n(\n  SELECT '+&amp;ASMGROUP'||files files, type \n  FROM (SELECT upper(sys_connect_by_path(aa.name,'\/')) files, aa.reference_index, b.type\n        FROM (SELECT file_number,alias_directory,name, reference_index, parent_index \n        FROM v$asm_alias) aa,\n             (SELECT parent_index FROM (SELECT parent_index \n                    FROM v$asm_alias \n              WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name='&amp;ASMGROUP') \n                AND alias_index=0)) a,\n             (SELECT file_number, type FROM (SELECT file_number, type \n                                       FROM v$asm_file \n                                    WHERE group_number = (SELECT group_number FROM v$asm_diskgroup WHERE name='&amp;ASMGROUP'))) b\n  WHERE aa.file_number=b.file_number(+)\n    AND aa.alias_directory='N'\n   -- missing PARAMETERFILE, DATAGUARDCONFIG\n   AND b.type in ('DATAFILE','ONLINELOG','CONTROLFILE','TEMPFILE')\n  START WITH aa.PARENT_INDEX=a.parent_index\n  CONNECT BY PRIOR aa.reference_index=aa.parent_index)\n  WHERE substr(files,instr(files,'\/',1,1),instr(files,'\/',1,2)-instr(files,'\/',1,1)+1) = (select dbname FROM (SELECT '\/'||upper(db_unique_name)||'\/' dbname from v$database))\nMINUS (\n  SELECT upper(name) files, 'DATAFILE' type FROM v$datafile\n    UNION ALL \n  SELECT upper(name) files, 'TEMPFILE' type FROM v$tempfile\n    UNION ALL\n SELECT upper(name) files, 'CONTROLFILE' type FROM v$controlfile WHERE name like '+&amp;ASMGROUP%'\n    UNION ALL\n SELECT upper(member) files, 'ONLINELOG' type FROM v$logfile WHERE member like '+&amp;ASMGROUP%'\n)\n);\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>These days I&#8217;ve been doing the migration of some BI databases into a private cloud, about 7 TB of data in total. We made sure that before starting there was enough disk space. However, in the middle of the largest &#8220;duplicate from active database&#8221;, it stops. When trying to restart, it complaints that disk group [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34,6,1],"tags":[],"class_list":{"0":"post-15","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-asm","7":"category-oracle","8":"category-uncategorized","9":"czr-hentry"},"_links":{"self":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts\/15","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/comments?post=15"}],"version-history":[{"count":1,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts\/15\/revisions"}],"predecessor-version":[{"id":80,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/posts\/15\/revisions\/80"}],"wp:attachment":[{"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/media?parent=15"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/categories?post=15"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/anjo.pt\/keyword-oracle\/wp-json\/wp\/v2\/tags?post=15"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}