DECLARE
V_OLD_TABLESPACE VARCHAR2(100):='USERS';
V_NEW_TABLESPACE VARCHAR2(100):='TEMP';
BEGIN
FOR XX IN (
SELECT L.TABLE_NAME, L.COLUMN_NAME, L.INDEX_NAME
FROM USER_LOBS L, USER_SEGMENTS S
WHERE (S.SEGMENT_NAME=L.SEGMENT_NAME) AND (S.TABLESPACE_NAME=V_OLD_TABLESPACE)) LOOP
DBMS_OUTPUT.PUT_LINE('ALTER TABLE '||XX.TABLE_NAME||' MOVE LOB('||XX.COLUMN_NAME||')
STORE AS (TABLESPACE '||V_NEW_TABLESPACE||' INDEX '||XX.INDEX_NAME||'(TABLESPACE '||
V_NEW_TABLESPACE||' STORAGE (MAXEXTENTS UNLIMITED)));');
END LOOP;
END;
Пример результата работы данного скрипта:ALTER TABLE QUERY_TBL MOVE LOB(QUERY_TEXT) STORE ASПосле этого сделать rebuild индексов (в данном случае, в таблицах QUERY_TBL, QUERY_PARM_TBL,
(TABLESPACE TEST INDEX SYS_IL0000049532C00011$(TABLESPACE TEST
STORAGE (MAXEXTENTS UNLIMITED)));
ALTER TABLE QUERY_PARM_TBL MOVE LOB(QUERY_PARMS) STORE AS
(TABLESPACE TEST INDEX SYS_IL0000049553C00003$(TABLESPACE TEST
STORAGE (MAXEXTENTS UNLIMITED)));
ALTER TABLE OFS_ITEMS MOVE LOB(DATA) STORE AS (TABLESPACE TEST
INDEX SYS_IL0000177335C00011$(TABLESPACE TEST
STORAGE (MAXEXTENTS UNLIMITED)));
OFS_ITEMS).
Найдено на просторах www.sql.ru
среда, 31 марта 2010 г.
Перенос LOBSEGMENT и LOBINDEX в другой Tablespace.
Данный скрипт генерирует код, который нужно выполнить для переноса LOBSEGMENT и LOBINDEX в другой Tablespace.
вторник, 30 марта 2010 г.
Уменьшение размера tablespace в Oracle.
После чистки таблиц в базе, а затем выполнения их дефрагментации, высвободилось достаточно много свободного места в табличном пространстве. В итоге 24 datafile's размером по 32Гб каждый получились заняты процентов по 20-25%. Решено было уменьшить размеры самих datafile's, чтобы освободить место на файловой системе.
Размеры tablespace's можно посмотреть так:
select a.tablespace_name ,
round(a.bytes_alloc / 1024 / 1024, 2) m_alloc,
round(nvl(b.bytes_free, 0) / 1024 / 1024, 2) m_free,
round((a.bytes_alloc - nvl(b.bytes_free, 0)) / 1024 / 1024, 2) m_used,
round(maxbytes/1048576,2) Max
from ( select f.tablespace_name,
sum(f.bytes) bytes_alloc,
sum(decode(f.autoextensible, 'YES',f.maxbytes,'NO', f.bytes)) maxbytes
from dba_data_files f
group by tablespace_name) a,
( select f.tablespace_name,
sum(f.bytes) bytes_free
from dba_free_space f
group by tablespace_name) b
where a.tablespace_name = b.tablespace_name (+);
Результат выглядит примерно так:
Здесь видно, что USERS занимает 618Gb, а использует 129Gb. Посмотрим до какого размера можно сжать tablespace.
select dba_data_files.file_name,
dba_data_files.file_id,
dba_data_files.tablespace_name,
ceil((nvl(hwm, 1) * db_block_size) / 1024 / 1024) smallest,
ceil(blocks * db_block_size / 1024 / 1024) currsize,
ceil(blocks * db_block_size / 1024 / 1024) -
ceil((nvl(hwm, 1) * db_block_size) / 1024 / 1024) savings
from dba_data_files,
(select file_id,
max(block_id + blocks - 1) hwm
from dba_extents
group by file_id) b,
(select value db_block_size from v$parameter where name = 'db_block_size') c
where dba_data_files.file_id = b.file_id(+);
Результат:
Там, где есть возможность уменьшить размер datafale's - уменьшаем. Т.е. datafile
E:\ORACLE\DATA\DSAUDIT\USERS19.DBF можно уменьшить до 6200Мб.
E:\ORACLE\DATA\DSAUDIT\USERS19.DBF можно уменьшить до 6200Мб.
Пример:
SQL>alter database datafile 'E:\ORACLE\DATA\DSAUDIT\USERS19.DBF' resize 6200M;
Остальные datafile's уменьшить не получается, т.к. в них данные раскиданы по всему пространству. А это значит, что таблички нужно переносить в другой tablespace. Можно перенести все сразу таблички, уменьшить размер, и вернуть таблички на место. А можно найти объекты, которые раскиданы по tablespace, и переместить только их.
select dba_extents.owner,
dba_extents.segment_name,
dba_extents.segment_type,
dba_extents.tablespace_name,
dba_extents.file_id,
dba_extents.block_id
from dba_extents,
(select file_id,
max(block_id) max_block_id
from dba_extents
group by file_id) b
where dba_extents.file_id = b.file_id and
dba_extents.block_id = b.max_block_id;
Результат:
Для переноса таблицы в другой tablespace:
SQL>alter table PINECONE.QUERY_TABLE_TBL move tablespace TEST;
Затем в перенесённой таблице необходимо сделать rebuild индексов.
Посмотрим какие индексы есть в таблице
SQL>SELECT STATUS, INDEX_NAME FROM USER_INDEXES WHERE TABLE_NAME = 'QUERY_TABLE_TBL';
STATUS INDEX_NAME
-------- ------------------------------
UNUSABLE QTT_OWNER_NAME
И делаем непосредственно ребилд
SQL> ALTER INDEX SYS_C005185 REBUILD;
Проверяем
SQL>SELECT STATUS, INDEX_NAME FROM USER_INDEXES WHERE TABLE_NAME = 'QUERY_TABLE_TBL';
STATUS INDEX_NAME
-------- ------------------------------
VALID QTT_OWNER_NAME
Для переноса индексов в другой tablespace:
SQL>alter index PINECONE.SYS_C005180 rebuild tablespace TEST;
Также определяем и переносим другие таблички или индексы,и пробуем снова уменьшить tablespace.
Определяем объекты, находящиеся в корзине:
SQL>purge table PINECONE."BIN$0IlaH5/6SyGv+h8B8BzJzQ==$0";
Определяем объекты, находящиеся в корзине:
И удаляем их, например так:select decode(partition_name, null,
segment_name,
segment_name || ':' || partition_name) objectname,
segment_type object_type,
owner,
tablespace_name,
header_block
from dba_segments
where tablespace_name = 'PINECONE' and
segment_name like 'BIN$%';
SQL>purge table PINECONE."BIN$0IlaH5/6SyGv+h8B8BzJzQ==$0";
Уменьшаем tablespace.
SQL>alter database datafile 'F:\ORACLE\DATA\DSAUDIT\USERS23.DBF' resize 10M;
...
...
...
В итоге получилось так:
Теперь переносим таблицы и индексы обратно.
Составлено на основе материалов http://all-oracle.ru, http://ora-20000.blogspot.com/2009/04/tablespace.html
понедельник, 22 марта 2010 г.
Как обрезать errorlog не останавливая сервер Sybase ASE.
Способы выполнения этой задачи зависят от версии ASE и платформы, на которой он работает.
Unix-подобные системы.
Здесь стандартный способ обрезать открытый другим процессом - это скопировать в него файл /dev/null. Т.е. :
cat /dev/null > /opt/sybase/YOUSERVERLOG.log
В вашей системе путь к файлу лога может быть другим.
Для выполнения этой команды из ASE можно воспользоваться системной процедурой xp_cmdshell.
Надо также заметить что в силу особенностей работы файловой подсистемы этих ОС, удаление файла лога или переименование пустого файла в файл лога не поможет - ASE будет все так же писать в свой старый файл.
Win32 (все Windows-ы)
Лог может быть обрезан открытием файла лога в редакторе Notepad, удалением всех строк и сохранением его. На самом деле конечно это может быть любой редактор, который не открывает файл в монопольном режиме для чтения и записи.
Кроме того, нужно отметить, что все особенности файловой системы Unix-подобных систем присущи и файловой системе NTFS, так что трюк с cat /dev/null > yourlog
также работает. Утилиту cat можно взять например в пакете CygWin.
Начиная с ASE 12.5 лог можно привязать к прокси-таблице ( в 12.5 появилась возможность делать прокси-таблицы на файлы ОС ) и тогда лог очищается коммандой
SQL>truncate table MYERRORLOG
где MYERRORLOG - прокси-таблица, привязанная к файлу лога ASE.
Этот способ работает на всех платформах, где работает ASE.
Unix-подобные системы.
Здесь стандартный способ обрезать открытый другим процессом - это скопировать в него файл /dev/null. Т.е. :
cat /dev/null > /opt/sybase/YOUSERVERLOG.log
В вашей системе путь к файлу лога может быть другим.
Для выполнения этой команды из ASE можно воспользоваться системной процедурой xp_cmdshell.
Надо также заметить что в силу особенностей работы файловой подсистемы этих ОС, удаление файла лога или переименование пустого файла в файл лога не поможет - ASE будет все так же писать в свой старый файл.
Win32 (все Windows-ы)
Лог может быть обрезан открытием файла лога в редакторе Notepad, удалением всех строк и сохранением его. На самом деле конечно это может быть любой редактор, который не открывает файл в монопольном режиме для чтения и записи.
Кроме того, нужно отметить, что все особенности файловой системы Unix-подобных систем присущи и файловой системе NTFS, так что трюк с cat /dev/null > yourlog
также работает. Утилиту cat можно взять например в пакете CygWin.
Начиная с ASE 12.5 лог можно привязать к прокси-таблице ( в 12.5 появилась возможность делать прокси-таблицы на файлы ОС ) и тогда лог очищается коммандой
SQL>truncate table MYERRORLOG
где MYERRORLOG - прокси-таблица, привязанная к файлу лога ASE.
Этот способ работает на всех платформах, где работает ASE.
Создание копии MBR.
Создание копии MBR
dd if=/dev/sda of=mbr.img bs=446 count=1
Создание копии MBR+таблица разделов
dd if=/dev/sda of=mbr.img bs=512 count=1
Для восстановления параметры if и of поменять местами.
dd if=/dev/sda of=mbr.img bs=446 count=1
Создание копии MBR+таблица разделов
dd if=/dev/sda of=mbr.img bs=512 count=1
Для восстановления параметры if и of поменять местами.
Ярлыки:
дисковые разделы,
Linux
пятница, 19 марта 2010 г.
Пропадает место на разделе (Linux&unix).
Если команда df -h показывает заполненный раздел (например /var), а du -s /var выдаёт гораздо меньший размер, значит какие-то процессы "держат" удалённые файлы.
Получить список удалённых файлов и "держащих" их процессов можно командой
lsof | grep deleted
К сожалению lsof далеко не всегда показывает правильно статус (deleted), в таком случае можно проверить на существование все выданные им пути к файлам. Топорный способ:
lsof | grep REG| awk '{print $9}' | xargs ls -l >/dev/null
lsof в первую очередь вам выдал процессы, которые эти файлы держат, а также размеры файлов. Дальше виновнику посылка сигнала HUP или действие стартового скрипта reload. Ну а если не поможет, то stop/start. Перезагружать всю машину нет никакого смысла.
Получить список удалённых файлов и "держащих" их процессов можно командой
lsof | grep deleted
К сожалению lsof далеко не всегда показывает правильно статус (deleted), в таком случае можно проверить на существование все выданные им пути к файлам. Топорный способ:
lsof | grep REG| awk '{print $9}' | xargs ls -l >/dev/null
lsof в первую очередь вам выдал процессы, которые эти файлы держат, а также размеры файлов. Дальше виновнику посылка сигнала HUP или действие стартового скрипта reload. Ну а если не поможет, то stop/start. Перезагружать всю машину нет никакого смысла.
Ярлыки:
дисковые разделы,
системное,
Linux,
solaris,
unix
Фрагментация таблиц в Oracle.
1. Для начала посмотрим размер таблицы(с фрагментацией)
SQL> SELECT TABLE_NAME, ROUND((BLOCKS*8),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 7497760KB
2. Определим реальный размер данных
SQL> SELECT TABLE_NAME, ROUND((NUM_ROWS*AVG_ROW_LEN/1024),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 4032361,52KB
В итоге 7497760KB - 4032361KB = 3465399 KB используется без толку.
В процентном соотношении 46% занятого пространства не используется.
3. Для удаления фрагментации потребуется реорганизовать таблицу.
Есть несколько опций для реорганизации фрагментированных таблиц.
Рассмотрим один вариант - перенос таблицы и пересоздание индексов.
4. Посмотрим какие индексы имеются в данной таблице
SQL> SELECT STATUS, INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'SESSION_TBL';
STATUS INDEX_NAME
-------- ------------------------------
VALID SYS_C005180
VALID ST_LCL_SES_STRT_TS
5. Начинаем. Необходимо, чтобы в tablespaces имелось свободное место.
SQL> ALTER TABLE SESSION_TBL MOVE;
Table altered.
6. Проверим индексы.
SQL> SELECT STATUS, INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'SESSION_TBL';
STATUS INDEX_NAME
-------- ------------------------------
UNUSABLE SYS_C005180
UNUSABLE ST_LCL_SES_STRT_TS
7. Пересоздаём индексы.
SQL> ALTER INDEX SYS_C005180 REBUILD;
Index altered.
SQL> ALTER INDEX ST_LCL_SES_STRT_TS REBUILD;
Index altered.
8. Проверяем.
SQL> SELECT STATUS, INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'SESSION_TBL';
STATUS INDEX_NAME
-------- ------------------------------
VALID SYS_C005180
VALID ST_LCL_SES_STRT_TS
8. Собираем статистику.
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('workusers','SESSION_TBL');
PL/SQL procedure successfully completed.
9. Проверяем размеры данных в даблице и размер самой таблицы.
SQL> SELECT TABLE_NAME, ROUND((BLOCKS*8),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 4780632KB
SQL> SELECT TABLE_NAME, ROUND((NUM_ROWS*AVG_ROW_LEN/1024),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 4032361,52KB
В итоге 4780632KB - 4032361KB = 748271KB
Т.е. освободилось 36% от ранее занятого таблицей пространства.
Составлено на основе материалов http://all-oracle.ru
SQL> SELECT TABLE_NAME, ROUND((BLOCKS*8),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 7497760KB
2. Определим реальный размер данных
SQL> SELECT TABLE_NAME, ROUND((NUM_ROWS*AVG_ROW_LEN/1024),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 4032361,52KB
В итоге 7497760KB - 4032361KB = 3465399 KB используется без толку.
В процентном соотношении 46% занятого пространства не используется.
3. Для удаления фрагментации потребуется реорганизовать таблицу.
Есть несколько опций для реорганизации фрагментированных таблиц.
Рассмотрим один вариант - перенос таблицы и пересоздание индексов.
4. Посмотрим какие индексы имеются в данной таблице
SQL> SELECT STATUS, INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'SESSION_TBL';
STATUS INDEX_NAME
-------- ------------------------------
VALID SYS_C005180
VALID ST_LCL_SES_STRT_TS
5. Начинаем. Необходимо, чтобы в tablespaces имелось свободное место.
SQL> ALTER TABLE SESSION_TBL MOVE;
Table altered.
6. Проверим индексы.
SQL> SELECT STATUS, INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'SESSION_TBL';
STATUS INDEX_NAME
-------- ------------------------------
UNUSABLE SYS_C005180
UNUSABLE ST_LCL_SES_STRT_TS
7. Пересоздаём индексы.
SQL> ALTER INDEX SYS_C005180 REBUILD;
Index altered.
SQL> ALTER INDEX ST_LCL_SES_STRT_TS REBUILD;
Index altered.
8. Проверяем.
SQL> SELECT STATUS, INDEX_NAME FROM USER_INDEXES
WHERE TABLE_NAME = 'SESSION_TBL';
STATUS INDEX_NAME
-------- ------------------------------
VALID SYS_C005180
VALID ST_LCL_SES_STRT_TS
8. Собираем статистику.
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS('workusers','SESSION_TBL');
PL/SQL procedure successfully completed.
9. Проверяем размеры данных в даблице и размер самой таблицы.
SQL> SELECT TABLE_NAME, ROUND((BLOCKS*8),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 4780632KB
SQL> SELECT TABLE_NAME, ROUND((NUM_ROWS*AVG_ROW_LEN/1024),2)||'KB' "SIZE"
FROM USER_TABLES
WHERE TABLE_NAME = 'SESSION_TBL';
TABLE_NAME SIZE
------------------------------ ------------------------------------------
SESSION_TBL 4032361,52KB
В итоге 4780632KB - 4032361KB = 748271KB
Т.е. освободилось 36% от ранее занятого таблицей пространства.
Составлено на основе материалов http://all-oracle.ru
Подписаться на:
Сообщения (Atom)