したがって、前述したように、私はSQL ServerのDBA /コンサルタントであり、Oracleデータベースで顧客を支援しています。ほとんどの場合、ドキュメントとGoogleの助けを借りて何をする必要があるのかを理解し、問題を解決することができましたが、現在、不可解なことに対処しようとしています。
データベースの1つは、少なくとも10年間(おそらく20年)使用され、アップグレードされたOracle 10g LIMSデータベースです。これは重要なアプリですが、過去数年にわたり、信頼性の問題が数多く発生しています。実際に何が問題であり、何ができるかを把握するために、ホスティング/ MSプロバイダーに別の(同一の)サーバーに物理コピーを作成してもらいました。 (プロバイダーがそれを「RMANのバックアップと復元」の意味として解釈したと確信しています)。
その後、分析に影響を与えたり、調査、修復を試みたり、生産に影響を与えたりすることなく、必要なツールを使用できるという考えです。ここまでは順調ですね。すべてのデータファイルに対してDBVerify(dbv
)を実行しましたが、問題はありませんでした。
それから私は走ったANALYZE TABLE .. VALIDATE STRUCTURE CASCADE ONLINE;
データベース内のすべてのテーブル。これらのテーブルのうち2つについては、コマンドが他の2500テーブル(結合された)よりもはるかに時間がかかったため、それらをキャンセルして、他のテーブルを終了させました。問題はなく、エラーも報告されませんでした。
結局のところ、これらの2つのテーブルは、最大のアプリケーションデータテーブルでもあります。そこで、最大のテーブル(23GB、3600万行)から始めて、(CASCADEを使用せずに)パーツごとに分析することにします。最初にテーブル自体、次にインデックスです。テーブルは30〜60分で終了します(正確には覚えていません)が、ANALYZE INDEX .. VALIDATE STRUCTURE ONLINE;
firstのインデックスは終了しません。
しばらく実行して、進行状況を監視する方法を見つけることができるかどうかを確認することにしました。これをグーグルで調べると、ANALYZE TABLEをv$session_longops
しかし、それを見てもコマンドから何も表示されず、これは統計収集機能でのみ機能し、検証機能では機能しないという結論に達しました。たくさんのことを試した後、私は最終的にv$session
行を実行するコマンドの場合、P1 *およびP2 *列を使用して、読み取られているファイルとブロックを追跡できます。
これは、期待されたデータファイルから実際に読み取っており、それらから異なるブロックを読み取っていたことを示しています。これと、コマンドの実行中(および他に何もない)のサーバーのディスク使用率が100%であるという事実は、実際に何かが実行されており、ブロック/ロック/ハングしていないことを確信しました。だから私はそれを実行させます。
3日(+72時間)を超えており、終了の兆候はなく、ここで私は途方に暮れています。
追加情報:
テーブルのDDL:
-- Unable to render TABLE DDL for object O$LIMS.N__RESULTS with DBMS_METADATA attempting internal generator.
CREATE TABLE O$LIMS.N__RESULTS
(
SAMPLE_ID NUMBER(10, 0) NOT NULL
, SUBMISSION_ID NUMBER(10, 0) NOT NULL
, RESULT_ID NUMBER(10, 0) NOT NULL
, RESULT_VERSION NUMBER(3, 0) NOT NULL
, TASK_ID NUMBER(10, 0) NOT NULL
, TASK_REPETITION NUMBER(3, 0) NOT NULL
, TASK_VERSION NUMBER(3, 0) NOT NULL
, REQUIRED VARCHAR2(1 BYTE) NOT NULL
, METHOD_DATAGROUP VARCHAR2(40 BYTE) NOT NULL
, COMPONENT VARCHAR2(40 BYTE) NOT NULL
, MEASURE VARCHAR2(40 BYTE) NOT NULL
, UNITS VARCHAR2(40 BYTE) NOT NULL
, STATUS VARCHAR2(20 BYTE) NOT NULL
, PLANNED_RESULT VARCHAR2(3 BYTE) NOT NULL
, RESULT_Origin VARCHAR2(1 BYTE) NOT NULL
, CONDITION VARCHAR2(20 BYTE) NOT NULL
, CONDITION_LEVEL VARCHAR2(20 BYTE)
, VALUE_TYPE VARCHAR2(20 BYTE) NOT NULL
, NUMBER_VALUE NUMBER
, TEXT_VALUE VARCHAR2(80 BYTE)
, TIME_VALUE DATE
, REASON VARCHAR2(40 BYTE)
, INLIMIT VARCHAR2(3 BYTE)
, INDETECTION VARCHAR2(3 BYTE)
, INSPEC VARCHAR2(3 BYTE)
, ENTRY_USERID VARCHAR2(20 BYTE)
, ENTRY_DATE DATE
, SPEC_ID NUMBER(10, 0)
, SPEC_VERSION NUMBER(3, 0)
, DETECTION_ID NUMBER(10, 0)
, DETECTION_VERSION NUMBER(3, 0)
, LIMIT_ID NUMBER(10, 0)
, LIMIT_VERSION NUMBER(3, 0)
, CUSTOMER_DATAGROUP VARCHAR2(40 BYTE)
, ANALYST VARCHAR2(20 BYTE)
, REPORT VARCHAR2(3 BYTE)
, TIMESTAMP DATE
, USERSTAMP VARCHAR2(20 BYTE)
, MEASURE_LINK O$LIMS.N_UT_MEASURE
, RESULT_PLAN_LIST_LINK O$LIMS.N_UT_RESULT_PLAN_LIST
, TEXT O$LIMS.N_TT_TEXT
, ATTRIBUTES O$LIMS.N_TT_ATTRIBUTES
, SEQUENCE NUMBER(4, 0)
, CONSTRAINT N_C_RESULTS_1 PRIMARY KEY
(
RESULT_ID
, RESULT_VERSION
)
USING INDEX
(
CREATE UNIQUE INDEX O$LIMS.N_C_RESULTS_1 ON O$LIMS.N__RESULTS (RESULT_ID ASC, RESULT_VERSION ASC)
LOGGING
TABLESPACE "SQLLIMS_INDEX"
PCTFREE 10
INITRANS 2
STORAGE
(
INITIAL 311296
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS UNLIMITED
BUFFER_POOL DEFAULT
)
NOPARALLEL
)
ENABLE
)
LOGGING
TABLESPACE "SQLLIMS_RESULTS"
PCTFREE 25
INITRANS 1
STORAGE
(
INITIAL 566231040
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS UNLIMITED
BUFFER_POOL DEFAULT
)
NOCOMPRESS
NOPARALLEL
NESTED TABLE TEXT STORE AS RESULT_TEXT RETURN AS VALUE
NESTED TABLE ATTRIBUTES STORE AS RESULT_ATTRIBUTES RETURN AS VALUE
現在分析されているインデックスのDDL:
-- Unable to render INDEX DDL for object O$LIMS.SYS_C0010496 with DBMS_METADATA attempting internal generator.
CREATE UNIQUE INDEX O$LIMS.SYS_C0010496 ON O$LIMS.N__RESULTS (ATTRIBUTES ASC)
LOGGING
TABLESPACE "SQLLIMS_RESULTS"
PCTFREE 10
INITRANS 2
STORAGE
(
INITIAL 65536
NEXT 1048576
MINEXTENTS 1
MAXEXTENTS UNLIMITED
BUFFER_POOL DEFAULT
)
NOPARALLEL
私の質問:
ANALYZE TABLEが最大で1時間しかかからなかったときに、ANALYZE INDEXが長くかかるのは妥当ですか?
この時点での私の選択肢は何ですか?私がこれを殺したと仮定すると、どうすれば(論理的な)破損などのチェックを続行できますか?このコマンドを妥当な時間で完了するために私ができることはありますか、または代わりに使用できる他のツールまたはアプローチはありますか?
バージョンなどの情報:
関連するSGAパラメータは次のとおりです(私はそう思います)。
Rajが引用した記事( https://www.pythian.com/blog/analyze-index-validate-structure-dark-side/ )はこれをかなりよく説明していると思います。 「クラスタリング係数」も、問題の説明を読んでいるときの最初の推測でした。また、RMANを使用して破損をチェックすることも好みます。
RMAN> backup check logical validate database;
その後、V$DATABASE_BLOCK_CORRUPTION
破損したブロックの詳細。
通常、巨大なクラスタリングには理由があります。次の詳細を確認できます。
これは、clustering_factorが高いかどうかを判断するのに役立ちます。 dba_extents
clustering_factorを決定します。
クラスタリングがパフォーマンスに悪いのはなぜですか? Oracleがディスクまたはキャッシュからデータを読み取るときは、常にブロックで読み取ります。ブロックが半分空の場合、読み取りパフォーマンスの50%が失われます。全表スキャンまたは全索引スキャンを実行する場合、Oracleはセグメント(索引または表)に属するすべてのブロックをスキャンします。ブロックが空であるかどうかはチェックしません。 Oracleは最初のブロックから最後のブロック(HWM)までを読み取ります。インデックスに10milのブロックがあり、1milのブロックしか必要ない場合、Oracleは9milのゴミブロックを読み取ります。
ASSM(自動セグメントスペース管理)は、クラスタリングの削減/防止に大きく役立ちます。可能であれば、手動セグメント領域管理TbsをASSM Tbsに移行する必要があります。
なぜ破損をチェックするのですか? ASMやstatspackのレポートを運用データベース(test/dev dbではなく)から収集することで、常にデータベースの分析を開始します。これは誰にも害を与えるものではなく、データベースに関する多くの詳細を提供しますが、それは小さな秘密です。データベースはそれを修復しようとしないため、通常、破損はパフォーマンスに影響しません。現在のクエリがクラッシュするだけです。
更新:うまくいきました...
@Rajからリンクを読み、@ ora-600の回答を読んだ後、RMANコマンドbackup check logical validate database;
を使用してデータベースを検証しようとしました。これは正常に機能しましたが、ANALYZE INDEX
コマンドが実行するすべてのことを確認していないことも明らかでした。
多くの異なるバリエーションを試した後、私はこのコマンドが機能することを最終的に発見しました:
ANALYZE TABLE .. VALIDATE STRUCTURE CASCADE offline;
ええ、OFFLINEに切り替えるだけで解決するようです。そして、thatは最終的にこのページのバグ#5752105に私を導きました: http://www.eygle.com/case/10204_buglist.htm 。私は今それを証明する立場にはありませんが(当面はパッチを適用できません)、これが私が遭遇していたことだと強く疑っています。
そのため、質問には完全には回答していませんが、@ ora-600の非常に役立つ回答を正しいものとしてマークし、ポールホワイトの非常に寛大な報奨金を収集できるようにします。