
Stas
16.07.2017
08:06:35
приветствую всех. Господа, есть вопрос.
Пишу проект, решил сменить БД с MySQL на PostgreSQL. Пока все хорошо, кроме одного момента.
В функциональных тестах на каждый сценарий делаю TRUNCATE с cascade=true. И вот, что-то на постгресе транкейт отнимает прилично времени - 25сек. для каждого сценария.
Есть какие-то лайфхаки, что подтюнить, чтобы сократить это время?
Мб заменить на
DELETE FROM table;
VACCUUM (FULL, ANALYZE) table;
Что посоветуете?

Dmitry
16.07.2017
08:19:42
но чтобы это выполнить ему необходимо взять локи

Stas
16.07.2017
08:20:18
Ну замеры говорят об обратном.

Google

Stas
16.07.2017
08:21:06
Таблиц не много. Около 20

Dmitry
16.07.2017
08:21:09
у вас просто активное использование данной таблицы, truncate стоит в очереди и ожидает какой-нибудь залипшей транзакции на update/delete конкретно этой таблицы

Stas
16.07.2017
08:23:13
Хм. Транзакцию только открываю. И транкейт это впринципе первая операция с бд.
Но на всякий случай в логах проверю.
Спасибо за инфу.
глянул. транкейт это действительно одна из первых операций с БД. До этого толтько чтение из постгресовских таблиц типа pg_attribute, pg_index, pg_class и т.п.
Т.е. на вставку ничего нет. Далее открываю транзакцию и начинаю truncate а за ним ALTER SEQUENCE .. RESTART где необходимо

Darafei
16.07.2017
08:38:32
мы в тестах выкрутили synchronuous_commit=off
транкейты стали отпускать быстрее

Stas
16.07.2017
08:50:28
что-то легче не стало. от слова совсем.
я все верно прописал?
$conn->exec('SET synchronous_commit = off;');

Darafei
16.07.2017
08:55:13
а у вас foreign keys, или к чему cascade=true?
подозреваю, может помочь транкейтить в другом порядке, или встречных индексов по foreign key, чтобы проверки были шустрее
или снимать fk перед транкейтами и потом возвращать на место

Stas
16.07.2017
09:00:05
а в постгресе естб аналог set FOREIGN_KEY_CHECKS = 0;
?

Pavel
16.07.2017
09:10:12

Google

Stas
16.07.2017
09:11:22
во время выполнения сценария может произойти несколько транзакций
перед запуском след. нужно все вычистить

Pavel
16.07.2017
09:11:52
Ну там же вложенные работают. Точнее savepoints.
А, ну хотя функциональные тесты наверно используют отдельное соединение? Тогда посмотреть что в другой транзакции действительно не получится

Andrey
16.07.2017
09:48:33
Скорее всего, у вас есть внешние ключи на поля, по которым нет индексов. Тогда при truncate проверка может занимать много времени. Тоже может иметь место даже при удалении одной записи.

Stas
16.07.2017
09:50:20
такая ситуация исключена. ORM вешает индексы на все FK

Andrey
16.07.2017
09:52:32
Ох уж эти ORM. Не доверяю я им ).

Darafei
16.07.2017
09:59:30

Stas
16.07.2017
10:00:21
не может быть FK без индекса по этому полю)

Darafei
16.07.2017
10:00:43
но может быть fk без индекса по колонке, которая fk

Andrey
16.07.2017
10:00:56

Stas
16.07.2017
10:02:27
индекс в обеих таблицах создается

Darafei
16.07.2017
10:05:43
покажь :)

Stas
16.07.2017
10:07:38
:)
вот ddl одной из таблиц
create table streets
(
id uuid not null
constraint streets_pkey
primary key,
town_id uuid not null
constraint fk_93f67b3e75e23604
references towns,
district_id uuid not null
constraint fk_93f67b3eb08fa272
references districts,
name varchar(64) not null
)
;
create index idx_93f67b3e75e23604
on streets (town_id)
;
create index idx_93f67b3eb08fa272
on streets (district_id)
;

Dmitry
16.07.2017
10:08:50
А причем тут вообще индексы?

Darafei
16.07.2017
10:09:40
ну, можно ещё спросить explain (analyze, verbose, buffers) от тормозящего транкейта

Dmitry
16.07.2017
10:09:45
какая версия пг?

Stas
16.07.2017
10:09:56
9.5.x

Google

Stas
16.07.2017
10:10:08
стандартный из коробки ubuntu 16.04

Dmitry
16.07.2017
10:12:08
а транкейт просто медленный, т.е. руками тоже, или только из под тестов? и точно паралелльных процессов нет, кто может лочить что-то?

Stas
16.07.2017
10:13:22
лочить никто не должен и не может. все в лоб. последовательно.
руками сейчас проверю.
руками выглядит, что все также.

Darafei
16.07.2017
10:18:16
explain (analyze, verbose, buffers)

Dmitry
16.07.2017
10:18:18
а fsync в каком сотоянии?

Darafei
16.07.2017
10:18:38
fsync тридцать секунд не накинет

Stas
16.07.2017
10:18:40
но вот момент. похоже что тут в логике косяк.
я перебираю все таблицы.
и выходит что я одни и те же таблицы транкейчу по N раз
cascade это делает
и я сам(

Darafei
16.07.2017
10:19:14
так cascade не транкейтит, он по одной записи убивает

Dmitry
16.07.2017
10:19:25
накинет, если много мелочи, там же дофига дисковых операций на truncate происходит

Stas
16.07.2017
10:20:22

Stas
16.07.2017
10:20:28
развернул - звпустил

Darafei
16.07.2017
10:20:49
предлагаю банить за предложения fsync=off ;)

Dmitry
16.07.2017
10:21:23
на стейдж среде для прогона тестов? предлагаю думать начать

Darafei
16.07.2017
10:22:58
деградация в 30 секунд на операцию при переходе с mysql подразумевает, что проблема не в fsync

Stas
16.07.2017
10:26:50
сейчас свичнул БД. транкейт всех таблиц с каскадом на мускуле 4.98
поэтому, если у кого-то появятся мысли - буду благодарен.

Dmitry
16.07.2017
10:29:50
Весьма голословное утверждение не зная схемы и среды окружения. Хотя в 9.2 на этот счет были патчи,
но ничего не мешает взять и проверить, чем рассуждать

Google

Dmitry
16.07.2017
10:30:44
Стас, попробуй fsync=off и посмотрим

Stas
16.07.2017
10:30:46
fsync=off;
верно?
оке

Pavel
16.07.2017
10:31:00

Fike
16.07.2017
10:31:01
сейчас в меня полетят ссаные тряпки, но вариант с докером не рассматривался?

Pavel
16.07.2017
10:31:22
(если не секретно)

Darafei
16.07.2017
10:33:05
а что будет, если всё затранкейтить в одном выражении,
truncate table table1, table2, table3... restart identity cascade
?

Stas
16.07.2017
10:34:53
fsync=off;
Truncate all - 0.60193705558777

Admin
ERROR: S client not available

Stas
16.07.2017
10:35:37
я же могу на сделать что-то подобное
set fsync = off;
затранкейтить, а потом
set fsync = on;
или из-под юзера это не меняется

Dmitry
16.07.2017
10:36:34
а зачем? у тебя же тестовая среда...

Darafei
16.07.2017
10:36:56
fsync can only be set in the postgresql.conf file or on the server command line. If you turn this parameter off, also consider turning off full_page_writes.

Stas
16.07.2017
10:36:58
ну да,

Dmitry
16.07.2017
10:37:21
ну помрет у тебя база, ну и фиг с ней, пересоздашь с нуля

Darafei
16.07.2017
10:37:53
а перформанс в том же окружении стейджится?

Stas
16.07.2017
10:38:18
In many situations, turning off synchronous_commit for noncritical transactions can provide much of the potential performance benefit of turning off fsync, without the attendant risks of data corruption.
но вот мне что-то synchronous_commit не помог (
я все на локальной машине гоняю.

Darafei
16.07.2017
10:39:54
fsync=off может сделать так, что тест пройдёт за 0.00001, но в продакшене без fsync=off окажется 10000.1

Google

Stas
16.07.2017
10:40:43
ну в проде я транкейтить ничего не буду.

Dmitry
16.07.2017
10:40:48
а тесты и не делаются для замеров производительности

Stas
16.07.2017
10:41:35
перед релизом, я прогоню нагрузочное, уже на реальном окружении. там уже буду смотреть что и где просело
задача была не ждать по 25сек на сценарий, пока я фиксанул что-то и хочу проверить что ничего не отвалилось

Dmitry
16.07.2017
10:42:41
можно еще попробовать delete стратегию, на самом деле в некоторых случаях она быстрее в pg
но, конечно, лучше всего если получается в транзакцию все паковать

Stas
16.07.2017
10:46:46
на данном этапе, я думаю этого хватит с головой.
Большое всем спасибо за участие, интерес и ваше время.
?

Anton [Mgn, az09@osm]
16.07.2017
11:23:35
[Из песочницы] Создание справочника адресной информации с блекджеком и API
https://habrahabr.ru/post/333424/
Tags: PostgreSQL, PHP, Laravel, php, postgresql
Author il_kow on #habrahabr
>Импорт данных осуществляется простым способом. Открываем файлы в Excel и сохраняем их как csv.
слабаки

Yura
16.07.2017
12:11:51
truncate, как и drop table, сканирует весь shared_buffers и удаляет из него страницы таблицы. Не знаю, основная ли это причина, но свой вклад она точно вносит. Причем это время зависит не от размера таблицы, а от размера shared_buffers.

Stas
16.07.2017
12:18:46
пробовал уменьшить shared buffers до минимального, выйгрыша во времени это не дало

Сергей
16.07.2017
13:16:33
Я до сих пор не понимаю людей, которые пишут тесты и вычищают базу сами. Почему нельзя тест кейс обернуть в транзакцию и откатить?
Какие кейсы не работают с этим?

Fike
16.07.2017
13:20:38
Включающие несколько транзакций

Mike Chuguniy
16.07.2017
13:22:44

Anatoliy
16.07.2017
13:23:28
Тесты не меняют данные, нафига им коммит?

Fike
16.07.2017
13:24:46
Как ты еще черную коробку протестируешь?
Как делать е2е без изменения данных?

Mike Chuguniy
16.07.2017
13:25:07
Я тестирую конкурентный доступ к данным в приложении. Как я без коммита увижу изменения в другой сессии?!