У меня есть процесс ETL, который постепенно наращивает таблицы размеров в RedShift. Он выполняет действия в следующем порядке:Почему неблокированная блокировка таблицы освобождается до завершения транзакции в RedShift?
- начинается транзакция
- Создает таблицу staging_foo как обув
- копирует данные из внешнего источника в staging_foo
- выполняет массовая вставка/обновление/удаление на обув так, что Совпадает staging_foo
- падение staging_foo
- фиксации транзакции
Индивидуально этот процесс работает, но для обеспечения непрерывного потокового обновления до foo
и избыточности в случае сбоя у меня есть несколько экземпляров процесса, выполняемого одновременно. И когда это случается, я иногда получаю параллельные ошибки сериализации. Это связано с тем, что оба процесса воспроизводят одни и те же изменения в foo
от foo_staging
в перекрывающихся транзакциях.
Что происходит, так это то, что первый процесс создает таблицу staging_foo
, а второй процесс блокируется при попытке создать таблицу с тем же именем (это то, что я хочу). Когда первый процесс совершает транзакцию (которая может занять несколько секунд), я обнаруживаю, что второй процесс разблокируется до завершения коммита. Таким образом, похоже, что получение моментального снимка таблицы foo
до фиксации происходит, что приводит к сбою вставки/обновления/удаления (некоторые из которых могут быть избыточными).
Я теоретизировать на основе документации http://docs.aws.amazon.com/redshift/latest/dg/c_serial_isolation.html, где он говорит:
Одновременные операции невидимы друг к другу; они не могут обнаружить изменения друг друга. Каждая параллельная транзакция будет создавать моментальный снимок базы данных в начале транзакции. Снимки базы данных создаются в транзакции при первом вхождении большинства операторов SELECT, таких как команды DML, такие как COPY, DELETE, INSERT, UPDATE и TRUNCATE, а также следующие команды DDL:
ALTER TABLE (для добавления или удаления столбцов)
CREATE TABLE
DROP TABLE
TRUNCATE ТАБЛИЦА
документация цитированной выше несколько сбивает с толку для меня, потому что вначале говорится, что моментальный снимок будет создан в начале транзакции, но впоследствии будет сказано, что моментальный снимок будет создан только при первом появлении некоторых конкретных операций DML/DDL.
Я не хочу делать глубокую копию, где я заменяю foo
вместо поэтапного обновления. У меня есть другие процессы, которые постоянно запрашивают эту таблицу, поэтому никогда не бывает времени, когда я могу ее заменить без перерыва. Другой вопрос задает аналогичный вопрос для глубокой копии, но он не будет работать для меня: How can I ensure synchronous DDL operations on a table that is being replaced?
Есть ли способ для выполнения моих операций таким образом, чтобы я мог избежать параллельных ошибок сериализации?Мне нужно убедиться, что доступ для чтения доступен для foo
, поэтому я не могу LOCK
этой таблицы.