# Спортивно, на лету, пересобираем АСМ группу

Иногда возникает необходимость изменить структуру *failgroup* в уже существующей ASM disk group. Например, чтобы перераспределить диски между группами отказоустойчивости и привести конфигурацию к новой схеме.

На первый взгляд задача выглядит просто: удалить диск из одной *failgroup* и добавить его в другую. Однако на практике Oracle ASM контролирует баланс дисков между *failgroup* и не позволяет выполнять такие изменения без соблюдения внутренних ограничений.

Разберем этот сценарий на конкретном примере.

#### Исходная конфигурация

Допустим, у нас есть ASM disk group `DATA` со следующей конфигурацией:

```sql
select group_number, operation, state, power, actual, sofar, est_work, est_rate, est_minutes, error_code
from v$asm_operation
order by group_number, operation;

GROUP_NUMBER DISK_NUMBER NAME           PATH           FAILGROUP  HEADER_STA MODE_STA MOUNT_ST STATE
------------ ----------- --------- ------------------ ---------- ---------- -------- -------- ------
           1           0 DISK1     /dev/ASM_DISK1_P1   FG1        MEMBER     ONLINE   CACHED   NORMAL
           1           1 DISK2     /dev/ASM_DISK2_P1   FG1        MEMBER     ONLINE   CACHED   NORMAL
           1           2 DISK3     /dev/ASM_DISK3_P1   FG1        MEMBER     ONLINE   CACHED   NORMAL
           1           3 DISK4     /dev/ASM_DISK4_P1   FG2        MEMBER     ONLINE   CACHED   NORMAL
           1           4 DISK5     /dev/ASM_DISK5_P1   FG2        MEMBER     ONLINE   CACHED   NORMAL
           1           5 DISK6     /dev/ASM_DISK6_P1   FG2        MEMBER     ONLINE   CACHED   NORMAL
```

Текущая схема выглядит так:

- `FG1`: `DISK1`, `DISK2`, `DISK3`
- `FG2`: `DISK4`, `DISK5`, `DISK`

#### Целевая конфигурация

Необходимо получить следующую схему:

```sql
GROUP_NUMBER DISK_NUMBER NAME  PATH               FAILGROUP HEADER_STA MODE_STA MOUNT_ST STATE
------------ ----------- ----- ------------------ --------- ---------- -------- -------- ------
           1           0 DISK1 /dev/ASM_DISK1_P1  FG1       MEMBER     ONLINE   CACHED   NORMAL
           1           1 DISK2 /dev/ASM_DISK2_P1  FG1       MEMBER     ONLINE   CACHED   NORMAL
           1           2 DISK4 /dev/ASM_DISK4_P1  FG2       MEMBER     ONLINE   CACHED   NORMAL
           1           3 DISK5 /dev/ASM_DISK5_P1  FG2       MEMBER     ONLINE   CACHED   NORMAL
           1           4 DISK3 /dev/ASM_DISK3_P1  FG3       MEMBER     ONLINE   CACHED   NORMAL
           1           5 DISK6 /dev/ASM_DISK6_P1  FG3       MEMBER     ONLINE   CACHED   NORMAL
```

То есть итоговая структура должна быть такой:

- `FG1`: `DISK1`, `DISK2`
- `FG2`: `DISK4`, `DISK5`
- `FG3`: `DISK3`, `DISK6`

#### Почему это не получится сделать напрямую

Если просто начать по одному удалять диски из `+DATA`, Oracle ASM не позволит это сделать.

*Предположим, в данном сценарии нельзя сразу вывести по одному диску из `FG1` и `FG2`, чтобы сразу собрать `FG3`, поскольку для такого ребаланса недостаточно свободного места.*

В этом случае Oracle выдаст ошибку:

```sql
ERROR at line 1:
ORA-15032: not all alertations performed
ORA-15411: Failure groups in disk group DATA have different number of disks.
```

ASM проверяет симметрию распределения дисков между *failgroup* и блокирует изменения, которые временно нарушают эту структуру.

#### Временный обход ограничения

В подобных случаях можно временно отключить часть внутренних проверок ASM с помощью скрытых параметров.

> \[!WARNING\] Использование hidden parameters — потенциально рискованная и официально не рекомендуемая практика. Применяйте этот подход только при полном понимании последствий, желательно после проверки на тестовом стенде и при наличии актуальной резервной копии.

Включаем параметры:

```sql
alter system set "_asm_disable_failgroup_size_checking"=true;
alter system set "_asm_disable_dangerous_failgroup_checking"=true;
```

Эти параметры временно позволяют ASM не блокировать изменения, связанные с неравномерным количеством дисков в *failgroup*.

#### Шаг 1. Удаление диска из текущей failgroup

```sql
ALTER DISKGROUP DATA DROP DISK DISK3 REBALANCE POWER 0;
ALTER DISKGROUP DATA REBALANCE POWER 24;
```

Здесь используется следующая логика:

- команда `DROP DISK` инициирует удаление диска из группы;
- `REBALANCE POWER 0` позволяет не запускать активный ребаланс немедленно;
- затем отдельной командой задается нужная мощность ребаланса.

#### Контроль состояния ребаланса

После каждого удаления или добавления диска необходимо дождаться завершения ребаланса.

Проверить статус можно так:

```sql
select group_number, operation, state, power, actual, sofar, est_work, est_rate, est_minutes, error_code
from v$asm_operation
order by group_number, operation;
```

Переходить к следующему шагу следует только после того, как в `v$asm_operation` не останется активных операций.

#### Шаг 2. Добавление диска в новую failgroup

После завершения ребаланса добавляем тот же диск обратно, но уже в новую *failgroup* `FG3`:

```sql
ALTER DISKGROUP DATA ADD FAILGROUP FG3 DISK '/dev/ASM_DISK3_P1' NAME DISK3 REBALANCE POWER 0;
ALTER DISKGROUP DATA REBALANCE POWER 24;
```

После этого снова необходимо дождаться завершения ребаланса.

#### Шаг 3. Повторение операции для второго диска

Далее аналогичным образом переносим диск `/dev/ASM_DISK6_P1` в `FG3`.

Последовательность та же:

1. удалить диск из текущей *failgroup*;
2. дождаться завершения ребаланса;
3. добавить диск обратно в `FG3`;
4. снова дождаться завершения ребаланса.

#### Возврат скрытых параметров в исходное состояние

После завершения всех операций параметры необходимо вернуть в исходное состояние:

```sql
alter system set "_asm_disable_failgroup_size_checking"=false;
alter system set "_asm_disable_dangerous_failgroup_checking"=false;
```

#### На что стоит обратить внимание

#### 1. Операция связана с риском

Фактически на время работ отключаются встроенные защитные механизмы ASM. Если в этот момент произойдет дополнительный сбой диска или failgroup, последствия могут быть критичными.

#### 2. Нужен запас свободного места

Даже при поэтапном переносе ASM должен иметь достаточно свободного пространства для перемещения экстентов во время ребаланса.

#### 3. Ребаланс нужно завершать на каждом этапе

Не стоит выполнять несколько операций подряд без контроля. Каждое удаление и каждое добавление диска должно завершаться полным ребалансом.

#### 4. Значение `POWER` нужно подбирать осознанно

В примере используется `REBALANCE POWER 24`, но реальное значение зависит от:

- нагрузки на систему;
- требований по времени выполнения работ;
- допустимого влияния на производительность.

#### 5. Важно не ошибиться при повторном добавлении диска

Перед выполнением команды необходимо внимательно проверить:

- путь к устройству;
- имя диска;
- имя целевой *failgroup*.

---

#### Итог

Если нужно перераспределить диски между *failgroup* в Oracle ASM, стандартные проверки ASM могут не позволить выполнить это напрямую. В частности, Oracle блокирует сценарии, в которых *failgroup* временно получают разное количество дисков.

В такой ситуации задачу можно решить поэтапно:

1. временно отключить внутренние проверки;
2. удалить диск из текущей *failgroup*;
3. дождаться завершения ребаланса;
4. добавить диск в новую *failgroup*;
5. повторить процедуру для остальных дисков;
6. вернуть параметры в исходное состояние.

Подход рабочий, но требует аккуратности, понимания рисков и обязательного контроля состояния ASM на каждом шаге.

#### Полезные запросы для контроля

#### Проверка активных операций ASM

```sql
select group_number, operation, state, power, actual, sofar, est_work, est_rate, est_minutes, error_code
from v$asm_operation
order by group_number, operation;
```

#### Просмотр текущего состава дисков в disk group

```sql
select group_number,
       disk_number,
       name,
       path,
       failgroup,
       header_status,
       mode_status,
       mount_status,
       state
from v$asm_disk
where group_number is not null
order by group_number, disk_number;
```

#### Дисклеймер

> \[!CAUTION\] Описанный подход использует скрытые параметры Oracle ASM. Перед применением в production-среде рекомендуется:
> 
> - проверить сценарий на тестовом стенде;
> - убедиться в наличии актуальной резервной копии;
> - оценить объем свободного места в disk group;
> - заранее продумать план отката.