前回更新してからかれこれ3週間。もう2月も終わりです。
Cofoチェアを使って仕事をしているわけですが、腰痛とか姿勢についてはとても楽になりました。
やっぱり値段のする椅子ほど快適さは違うんだな、と実感しました。
さて、本題。
今回は仕事でOracleのデータベースを作成する機会がありまして、サーバー構築から行い、Oracleをインストールし、Create Database を行い、表領域を作成し・・・ということをやっていました。
実を言うとこれまでPosばかり作ってきたのでOracleの構築はやったことがなく、調べながら試行錯誤をしていました。
そして、出来上がったものの・・・
表領域のデータファイルがものすごく増えた。(ルール上、自動追加なしにしているんですが1ファイル単位のサイズルールもなかったようで、過去の事例的には作った人たちの感覚だったみたい)
ものすごく気持ち悪かったので、一通り完成後、表領域だけ作り直そうとしました。
ざっくりとした手順
1.新しい表領域(データファイル)を作成
2.既存の表領域からテーブル・インデックスなどを新表領域に移動
3.既存のデータファイルが空になっていることを確認し、削除
4.既存の表領域と同名のデータファイルを再作成(サイズ・ファイル数をここで調整)
5.2の逆パターンでテーブルとインデックスなどを戻す
6.1で作成した表領域を削除する
というもの。
Oracleは基本的にデータファイルにあとから手を加える、ということができないので、
一旦削除する必要があります。
正直フルDumpしたほうが楽なのでは?と思った。
以下、実際やってみた
-- 0.表領域の確認
SELECT
tablespace_name,
TO_CHAR(SUM(bytes) / 1024 / 1024, '99,999,999') || ' MB' AS "Size"
FROM
dba_segments
GROUP BY
tablespace_name;
-- 1.新しい表領域を作成する
CREATE TABLESPACE 表領域名
DATAFILE 'データファイル保存先パス' SIZE 30G;
(,続きで複数のデータファイルを作成可能)
--表領域のデータ確認・移動
--テーブル
SELECT owner,table_name
FROM dba_tables
WHERE tablespace_name = '表領域名';
ALTER TABLE スキーマ名.テーブル名 MOVE TABLESPACE 新しい表領域;
--インデックス
SELECT owner,index_name
FROM dba_indexes
WHERE tablespace_name = '表領域名';
ALTER INDEX スキーマ名.インデックス名 REBUILD TABLESPACE 新しい表領域;
--ロブセグメント
SELECT owner,table_name, column_name
FROM dba_lobs
WHERE tablespace_name = '表領域名';
ALTER TABLE スキーマ名.テーブル名 MOVE LOB (カラム名) STORE AS (TABLESPACE 新しい表領域);
で、データファイルから新しいデータファイルへ移動できると思います。
あとは表領域を
DROP TABLESPACE 表領域名 INCLUDING CONTENTS AND DATAFILES;
でばっと削除し、AND DATAFAILES でデータファイルごと削除。
その後は先の逆パターンで戻して終了。
という作業。
データ量が多ければ時間はかかります。あと、テーブルとか多いとスクリプトが面倒くさい。
ので、データベースを複製・作成するときはあらかじめルールとかを決めておいたほうがいいと思いました。