Как работает параллельность в Oracle
Что проверяют
Различаете ли вы два смысла вопроса: параллельное выполнение одного тяжёлого запроса несколькими процессами и одновременную работу многих сессий с одними данными. Для Go-разработчика важнее второй, поэтому следом часто спрашивают, что будет, если сто горутин обновят одну строку.
Как отвечать
Уточните, о каком смысле речь, и коротко пройдите оба.
Параллельное выполнение:
- координатор и серверы PX: сессия становится координатором, берёт из пула процессы, делит таблицу на гранулы (диапазоны блоков или секции) и собирает результат. Для сортировок и джойнов серверы работают парами «производитель и потребитель», так что при степени 8 их бывает до 16;
- степень параллелизма (DOP): хинт
/*+ PARALLEL(8) */, атрибут таблицыALTER TABLE ... PARALLEL 4или автоматический выбор приPARALLEL_DEGREE_POLICY = AUTO. Размер пула ограничиваетPARALLEL_MAX_SERVERS; - параллельный DML: по умолчанию выключен, включается
ALTER SESSION ENABLE PARALLEL DML. До коммита изменённую так таблицу в той же транзакции читать нельзя, будет ORA-12838.
Конкурентный доступ:
- многоверсионность: запрос видит согласованный снимок на момент своего старта, старые версии блоков собираются из undo. Читатели не блокируют писателей, и наоборот;
- блокировки строк: хранятся прямо в блоке данных, эскалации до таблицы нет. Вторая сессия ждёт коммита первой, а
SELECT ... FOR UPDATE NOWAITвместо ожидания сразу вернёт ошибку.
Со стороны Go: пул database/sql с драйвером godror или go-ora ограничивайте через SetMaxOpenConns, иначе горутины откроют сотни сессий.
Где спотыкаются
Отвечают только про хинт PARALLEL и молчат про многоверсионность, хотя спрашивали про одновременную работу сессий.
Считают параллельный запрос бесплатным ускорением. В OLTP сотня коротких запросов с DOP 8 выбирает весь пул серверов, и остальные идут с урезанной степенью, последовательно или встают в очередь.
Путают уровни изоляции: по умолчанию READ COMMITTED с согласованностью на уровне оператора, а при SERIALIZABLE конфликт записи даёт ORA-08177, и транзакцию нужно повторять в коде.