Про Oracle, ASM, iSCSI и ядро 2.6.39-400
Date January 19th, 2015 Author Vitaly Agapov
Опять заметка про Oracle и опять в стиле "баги атакуют". Может, кому-нибудь пригодится. Итак, есть Oracle 11g, RAC (хоть это и не имеет значения) и группа дисков, получаемых по iSCSI и скормленных в ASM. Пока всё неплохо, но тут переходим к ключевому моменту: всё это работает на RHEL5 с UEK-ядром из ветки 2.6.39-400.
В какой-то момент становится понятно, что, если остановить iSCSI-таргет, с которого мы получаем диски, то, несмотря на normal redundancy и на наличие нескольких failgroups, инстанс ASM умирает, прихватывая с собой весь clusterware. Надёжность летит к чертям, кластер может упасть от любого чиха.
Вот что можно выяснить по горячим следам… После остановки таргета iSCSI-инициатор, который периодически шлёт туда NOP Out'ы (эдакие iSCSI-пинги), обнаруживает, что тот недоступен и стартует таймаут node.session.timeo.replacement_timeout из конфига, по истечении которых на все текущие IO-команды возвращает ошибку. ASM, получая эту ошибку, ругается. Если команда была на чтение, то просто ругается. Если на запись, то инстанс ASM останавливается и пытается перезапуститься.
По умолчанию replacement_timeout равен 120 секундам. Значение влияет только на то, насколько быстро ASM получит обратно ошибку и насколько быстро он упадёт. На время этого таймаута блочный scsi-девайс блокируется – в файле /sys/block/sdX/device/state будет состояние "blocked", то есть все IO-команды будут задерживаться и не возвращать никаких ответов. ASM и все запросы к представлениям v$asm… будут висеть.
Зато когда таймаут истечёт, IO-команды получат коды ошибок, а статус блочного девайса вернётся в "running". Диск в системе при этом видится как живой, хотя на самом деле его нет. Это показалось сначала каким-то стрёмным багом. Уверенность в этом усилилась, когда я проверил, как всё это работает в RHEL6 на 3.8-м ядре. Там как раз после таймаута девайс уходит в transport-offline, asm его тоже метит как оффлайн и все счастливы.
Но оказалось, что это не баг, а так и было задумано. Фича с оффлайном девайса оказалась в ядре только начиная с версии 3.6 (вот эти коммиты: раз и два), а значит во всех старых ядрах висящий в running'е блочный девайс с давно отвалившимся таргетом – это нормальное явление.
Но вернёмся к ASM. Через 120 секунд он получает ошибку, и в alert-логе инстанса ASM мы видим подобные строки:
WARNING: Read Failed. group:1 disk:19 AU:0 offset:0 size:4096 WARNING: Write Failed. group:1 disk:2 AU:1 offset:4096 size:4096 ERROR: unrecoverable error ORA-15188 raised in ASM I/O path; terminating process 28246 ERROR: unrecoverable error ORA-15188 raised in ASM I/O path; terminating process 21487 PMON (ospid: 21449): terminating the instance due to error 493 ORA-1092 : opitsk aborting process License high water mark = 52 Instance terminated by PMON, pid = 21449 USER (ospid: 31407): terminating the instance Instance terminated by USER, pid = 31407 ERROR: -15(asmlib ASM:/opt/oracle/extapi/64/asm/orcl/1/libasm.so op ioerror error Invalid argument) ERROR: -15(asmlib ASM:/opt/oracle/extapi/64/asm/orcl/1/libasm.so op ioerror error Invalid argument)
А в kernel-логе вот такую примечательную строку, из которой мы можем узнать код ошибки SCSI:
kernel: (31,6):asm_end_ioc:1152 ERROR: Invalid error of -67 on request 0xffff880c514a0440!
Поиск по MOS приводит к Bug 18438934 : INCORRECTLY SETTING A ASM_LOCAL_ERROR WHEN UNPLUGGING THE DISK. Из него мы узнаём, что в ядре 2.6.39.400 появились новые коды ошибок SCSI, которые драйвер ASM обрабатывать не умеет и поэтому генерит ASM_LOCAL_ERROR. Баг вроде как пофикшен в 2.6.39-400.215.9, но опыт показывает, что не совсем – падение таргета по-прежнему приводит к падению ASM-инстанса.
Поигравшись с ядром и поизучав код драйвера ASM в UEK-ядре, сделал такой вот патч для ядра 2.6.39-400.215.15.el5uek. На ядре с этим патчем ASM больше не глючит, нормально оффлайнит недоступные диски и не боится падений iSCSI-таргетов. Главной подсказкой был код ошибки 67 из kernel-лога, который в коде заменён макросом ENOLINK.
# cat asm.nolink.patch diff -crBN a/drivers/block/oracleasm/driver.c b/drivers/block/oracleasm/driver.c *** a/drivers/block/oracleasm/driver.c 2015-01-16 08:52:13.000000000 +0300 --- b/drivers/block/oracleasm/driver.c 2015-01-16 08:54:52.000000000 +0300 *************** *** 1165,1170 **** --- 1165,1171 ---- case -EIO: case -ENODATA: case -EREMOTEIO: + case -ENOLINK: r->r_error = ASM_ERR_IO; break; *************** *** 1172,1178 **** r->r_error = asm_integrity_error(r); break; - case -ENOLINK: case -EBADE: case -ENODEV: r->r_error = ASM_ERR_NODEV; --- 1173,1178 ----
Tags: Linux, Oracle
Category:
Linux, Oracle |
No comments »