Можно ли создавать / копировать таблицу PostgreSQL, когда в нее вставляются новые данные? - PullRequest
1 голос
/ 20 мая 2019

Я настроил базу данных PostgreSQL (версия 11.2), в которой у меня есть таблица, в которую новые записи вставляются с регулярными интервалами (15-30 минут). Вставка выполняется с помощью скрипта Python с SQLAlchemy и Pandas с командой df.to_sql(). Существующая база данных достаточно велика, и копирование / дампирование, скорее всего, займет более 30 минут.

Будет ли выполнение CREATE TABLE new_table AS TABLE old_table; прерывать процесс вставки данных? Если да, есть ли другой способ сделать это без перерывов?

База данных работает на сервере Red Hat Enterprise версии 7.6. У меня есть права администратора для всей базы данных, и я могу получить к ней доступ с помощью PuTTy + psql -U username -d my_database, а также из pgAdmin, если это имеет значение. Я еще ничего не пробовал, опасаясь прервать процесс сбора.

1 Ответ

1 голос
/ 20 мая 2019

Транзакция в Postgresql - любая операция «все или ничего».Транзакция называется атомарной: с точки зрения других транзакций она либо происходит полностью, либо совсем не происходит.

Обновления, сделанные до сих пор открытой транзакцией, невидимы для других транзакций, пока транзакция не завершится., после чего все обновления становятся видимыми одновременно. Транзакция становится реальной (или видимой для других транзакций) только после ее фиксации с помощью команды COMMIT;.

Ваша первая команда вставки, вероятно, заблокирует только те строки, которыев настоящее время вставляются.Эти строки будут доступны только после завершения транзакции вставки.

Чтобы ответить на ваш вопрос:

1) Запустится ли CREATE TABLE new_table AS TABLE old_table;прервать процесс вставки данных?

Нет.Не за что.

2) Если да, есть ли другой способ сделать это без перерывов?

Ответ на первый вопрос.

Сценарий здесь - создатьКоманда table будет копировать только те данные, которые в данный момент не заблокированы какой-либо транзакцией.Таким образом, для команды вставки это будет (в основном) только в настоящее время вставленные строки.Таблица создания скопирует все данные, которые были до транзакции вставки.

Вы можете проверить блокировки с помощью команды вставки следующим образом:

select * from pg_stat_activity;

Это выведет что-то вроде.

-[ RECORD 2 ]----+--------------------------------
datid            | 73103
datname          | database
procpid          | 28477
sess_id          | 16424
usesysid         | 10
usename          | user
current_query    | insert .....
waiting          | f
query_start      | 2019-05-20 06:10:21.126825+00
backend_start    | 2019-05-20 05:43:51.600017+00
client_addr      | 0.0.0.0
client_port      | 
application_name | 
xact_start       | 

Исходя из этого, мы можем установить блокировки, созданные этим процессом, следующим образом:

select * from pg_locks where pid = 28477;

Вы можете обновлять, удалять, вставлять множество транзакций в одну таблицу без транзакций, блокирующих друг друга - при условии, что каждая транзакцияимеет дело с разными рядами.Две вставки будут блокировать друг друга только в том случае, если вторая попытка вставить те же значения первичного ключа (или уникального ключа), что и первый.Если вы не хотите, чтобы блокировки влияли на ваш запрос, вы можете использовать WITH NOLOCK, но используйте его осторожно.

Дополнительная информация:
https://www.postgresql.org/docs/9.1/explicit-locking.html
https://www.postgresql.org/docs/9.1/transaction-iso.html

...