Ответы пользователя по тегу PostgreSQL
  • Как применить ON CONFLICT для отслеживания изменений при INSERT?

    Melkij
    @Melkij
    PostgreSQL DBA
    Возможно ли не встравлять в таблицу записи, которые уже присутствуют в таблице?

    Возможно. Если вы этим знанием свой предметной области поделитесь с СУБД и создадите уникальное ограничение. А скорей всего это вовсе натуральный первичный ключ.

    on conflict работает как ни удивительно при конфликте уникальности. Поэтому пока у вас никто не гарантирует уникальность данных - on conflict ничего не сделает.
    Ответ написан
    Комментировать
  • Можно ли как-то оптимизировать этот SQL запрос?

    Melkij
    @Melkij
    PostgreSQL DBA
    Попробуйте так:
    SELECT Prop.*, coalesce("counters".countAllUnits, 0) AS "countAllUnits", coalesce("counters".countVacantUnits, 0) AS "countVacantUnits"
                        FROM "Property" AS Prop
                        INNER JOIN LATERAL
                        (
                         SELECT COUNT(*) AS countAllUnits,
    count(*) filter(where "Unit".status = 'Vacant') as countVacantUnits
                         FROM "Unit"
                         WHERE Prop."id" = "Unit"."propertyId"
                        ) AS "counters" ON true
                        WHERE  Prop."userId" IN (
                              SELECT id FROM "User" WHERE  "companyId" = 200001
                        )
                        ORDER BY Prop."userId" ASC LIMIT 10 OFFSET 0

    Ожидание: раннее отсечение limit 10 и nested loop именно от них.
    Ответ написан
    3 комментария
  • Как создать триггер для ограничения операторов CREATE в ночное время?

    Melkij
    @Melkij
    PostgreSQL DBA
    Вы с какой-то очень не той стороны хотите подойти к задаче. Вопрос на который надо искать ответ - зачем вы это хотите?

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

    Впрочем, event triggers могут быть ddl_command_start для ряда create команд.
    Ответ написан
    1 комментарий
  • Что будет с первичным ключом если создать таблицу без указания PRIMARY KEY?

    Melkij
    @Melkij
    PostgreSQL DBA
    Но первичный ключ является обязательным для каждой таблицы

    С точки зрения реляционной теории и нормальных форм в частности.

    С точки зрения SQL - не обязателен. Таблица может не объявлять первичный либо даже какой-то уникальный ключ. Дальше - детали реализации.

    В PostgreSQL никакой даже суррогатный первичный ключ в этом случае создаваться не будет. Адресация строк в PostgreSQL выполняется по TID (tuple ID) - физическому адресу строки в датафайле (и потому TID уникален в таблице), в том числе при поиске по первичному ключу. Но TID - не индекс, никак не связан с хранимыми данными и не накладывает каких-либо ограничений на данные.
    Ответ написан
    3 комментария
  • Как импортировать базу данных Postresql в пустую базу данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    Peer authentication failed for user "MyUser"

    То есть первым подходящим правилом pg_hba.conf была peer проверка, требующая чтобы имя пользователя ОС совпадало с запрошенным именем пользователя базы. Что судя по ошибке не выполнено.

    Что делать? Править hba или скорей всего у вас и так настроен вход по паролю при подключении по tcp/ip. То есть psql -h 127.0.0.1 ... вероятнее всего пароль спросит.
    Ответ написан
    Комментировать
  • Как перенести одну базу данных postgres в другой кластер?

    Melkij
    @Melkij
    PostgreSQL DBA
    pg_dump + pg_restore - это как раз самый быстрый, если под "быстрый" подразумевать общие затраты времени на задачу и минимальные проблемы, а не минимальное окно потерянной записи.

    В остальных случаях для переноса базы вам нужна какая-то логическая репликация. Триггерная или что-то на основе logical decoding (например логическая репликация в pg10+). Грабли с любыми изменениями схемы данных в комплекте

    Граничный случай: если одну или несколько баз необходимо выселить в новый кластер. Тогда делаете потоковую реплику, когда догонит рестартуете в мастер и удаляете с неё ненужные базы.
    Ответ написан
    Комментировать
  • Как безопасно применить Vacuum на террабайтую БД Postgress?

    Melkij
    @Melkij
    PostgreSQL DBA
    vacuum - запустить vacuum. В нём нет ничего страшного, если вы не отстрелили себе ноги, то база сама его запускает согласно настройкам.

    vacuum full - история очень сильно отдельная, т.к. это ни разу не vacuum.
    Места под vacuum full надо под копию таблицы с индексами и на запись этой копии в WAL. То есть теоретически до двукратного объёма.
    Поскольку для рабочей базы возможность уйти на сколько-то часов штука неинтересная - vacuum full по большим таблицам не делают.
    Есть pg_repack делающий с помощью триггера и чёрной магии копию таблицы (место всё так же нужно свободное), после накатывает изменения в основной таблице и заменяет основную на свежую копию. В целом - то что делает vacuum full, но без тяжёлой блокировки таблицы.
    Есть pgcompacttable, идущий другим путём. postgresql пытается новые строки размещать в начале таблицы, поэтому фиктивные обновления строк в конце таблицы скорей всего переместятся в начало, а пустые страницы в конце может срезать обычный vacuum. Плюс перестроить индексы (правда не все). Обновление inplace, запас места под копию не требуется. Полную блокировку таблицы конечно тоже не берём.
    Ответ написан
    Комментировать
  • Как ускорить создание индекса в PosgGreSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    Какого индекса? Возможно сюрприз, но они сильно разные.

    1) PSQL создает индекс в одно-поточном режиме. Это 10% от всей производительности cpu.

    psql - это клиент, он вообще не создаёт индексы.
    postgresql - начиная с 11 версии умеет многопоточное создание btree. Хотя, наверное, вернее будет сказать сортировку.

    2) Как я понял он считывает базу перерабатывает и сжимает. (В одно-поточном режиме это происходит оч медленно.)

    Не базу, а таблицу. Один раз полный seqscan для create index (с блокировкой записи) или два seqscan для create index concurrently (без блокировки таблицы).
    Ничего не сжимает.

    3) Из-за того что он медленно перерабатывает данные, он не использует всю скорость ссд на котором расположена база.

    Ну смотря какие диски. Дешёвые SSD вполне можно озадачить временными файлами в большом количестве и одним ядром CPU, видел и такое.

    Для ускорения построения большого индекса нужна память maintenance_work_mem. Сколько не жалко. 10, 20, 30, 100гб.
    На postgresql 11 - плюс настроить число воркеров max_parallel_maintenance_workers, max_worker_processes, max_parallel_workers

    но не нашел как их реализовать

    Если хотите поучаствовать в разработке самого postgresql - welcome в список рассылок pgsql-hackers. Как делали parallel create index можно почитать по ссылкам с коммита.
    Ответ написан
    Комментировать
  • Как найти в базе поля по шаблону "наоборот"?

    Melkij
    @Melkij
    PostgreSQL DBA
    where 'ct_head_short' like template
    seqscan ожидаемо, но для малого числа строк работать будет
    Ответ написан
    Комментировать
  • Почему может не реплицирвоватся База Данных postgresql?

    Melkij
    @Melkij
    PostgreSQL DBA
    выводы \l+ и \dt+ в проблемной базе на мастере и реплике совпадают?

    При потоковой репликации реплика является точной бинарной копией мастера.
    гипотезы:
    повреждена база, но активности в ней нет и потому остаётся незамеченным
    лишние файлы на мастере
    Ответ написан
  • Как выучить PostgreSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    MySQL выучил

    Знаете, даже опытного DBA реально удивить чем-то, что оказывается в базе существовало уже десяток лет.
    Поэтому фраза "MySQL выучил" не воспринимается как-то иначе чем признание в невежестве. Я работал с mysql много лет, оказывается топ3 пользователь по этому тегу на тостере. Знаю я mysql? Ничего подобного. Даже исходник открывал всего 1 раз.

    Какой смысл вы заложили в фразу "MySQL выучил"? Как его можно выучить?

    по курсу от WebForMySelf

    Это тот перепечатник, описывающий функционал, который mysql до сих пор не умеет? mysql_query, когда такого расширения вовсе уже не существует в PHP?
    Надеюсь, 5 лет назад когда вы изучали - было приличнее.

    В качестве обзорной экскурсии по устройству PostgreSQL могу припомнить хорошую лекцию Владимира Бородина, поищите записи Ильи Космодемьянского.
    Мануал хотя бы один раз надо прочесть от начала до конца
    И практика. Без мануала вы не узнаете какие возможности есть, без практики - не поймёте как (и, к слову, зачем) ими пользоваться.
    Ответ написан
    1 комментарий
  • Ошибка синтаксиса (примерное положение: "ON"). Ошибка?

    Melkij
    @Melkij
    PostgreSQL DBA
    А где тут ошибки нет?
    В теге указан postgresql, где синтаксис create database вот такой: https://www.postgresql.org/docs/current/sql-create...

    А ваш запрос как раз начиная со слова on никак не похож и явно от какой-то другой СУБД.
    Ответ написан
    1 комментарий
  • Как правильно использовать модуль multiprocessing с PostgreSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    решил отказаться от SQLite даже для хранения ссылок на файлы

    А зачем?
    sqlite отличная самая распространённая в мире база (см. android, firefox, chrome - sqlite всюду)
    Слабо себе представляю sqlite в масштабе террабайта, а в масштабе пары мегабайт postgresql будет явный overkill.

    Ну а по теме - я не питонщик и по приведённому коду мне совершенно неясно что же вы делаете. Профилируйте своё приложение, ищите где теряете время.
    Ответ написан
  • Как использовать SQL запрос с to_tsquery и include?

    Melkij
    @Melkij
    PostgreSQL DBA
    Что такое include?

    чтобы в найденные объекты Lead добавлялись поля Unit, основываясь на unitId.

    Банальный join.
    Ответ написан
    Комментировать
  • Как создать БД от имени роли, имя которой не соответствует юзеру в Линукс?

    Melkij
    @Melkij
    PostgreSQL DBA
    Аккаунт ОС не имеет никакого отношения к пользователю БД. База может быть настроена проверять подлинность пользователя по соответствию имени пользователя - peer для unix sock. Но это не обязательно и это единственное что может связывать пользователя ОС и базу. (кроме учётки владельца, у того есть доступ напрямую к файлам)

    Но пользователь базы должен уже существовать. А раз вам нужно создать сперва пользователя - то тогда же создайте и базу для него.

    Далее следует сказать, что рядовой пользователь вовсе не может создавать базы данных. Это право должно быть выдано явно.
    Подключиться к postgresql можно только к конкретной уже существующей БД и у вашего пользователя должны быть права как на прохождение аутентификации указанным в hba методом так и права на подключение к нужной базе.
    Ответ написан
    Комментировать
  • Почему wal-g backup-push зависает на Finished writing part 3?

    Melkij
    @Melkij
    PostgreSQL DBA
    archive_command = '/usr/local/bin/backup_wal.sh'

    cat /usr/local/bin/backup_wal.sh
    #!/bin/bash

    . /etc/wal-g.d/server-s3.conf

    wal-g backup-push /var/lib/pgsql/9.6/
    wal-g backup-list

    Аааа?... Это вы сейчас серьёзно?

    Не будет это работать. archive_command вызывается на каждый сегмент WAL - 16мб изменений обычно. То есть легко десятки раз в секунду на нагруженных базах. Пытаться отсюда делать бекап кластера - идея ужасная.

    wal-push в archive_command должен быть. backup-push отдельно, из крона обычно.
    Ответ написан
    Комментировать
  • Возможна ли репликация с 10 postgres серверов на один общий сервер?

    Melkij
    @Melkij
    PostgreSQL DBA
    как более правильно выполнять репликацию

    А что хотите-то?

    Штатной логической репликацией (pg 10 и выше) или через pglogical или даже триггерной репликацией можете реплицировать в одну базу. Корректное внесение DDL за свой счёт.
    Для физической репликации - репликация строго 1:1, потому разные инстансы базы. Всякие докеры абсолютно не нужны для этого. Разворачиваете реплики в разных директориях и на разных listen портах и всё. В ubuntu/debian штатные скрипты pg_ctlcluster даже есть чтобы инстансами удобно рулить.
    Ответ написан
    1 комментарий
  • Как найти записи в Postgres, которые содержат объект с определенным значением?

    Melkij
    @Melkij
    PostgreSQL DBA
    Если у вас это корректный json (или jsonb) а не то что показали:
    where jsonfield->'contacts'->>'email' = 'foo'

    Если там именно какой-то такой странный формат - то пишите его парсер.
    Ответ написан
    Комментировать
  • Как сделать выборку, обновить для нее записи и вернуть курсор с ними?

    Melkij
    @Melkij
    PostgreSQL DBA
    Не надо изобретать кривой велосипед с очередной очередью. Оно не будет работать под нагрузкой. Возьмите pgq.

    Ну а если всё равно хотите пособирать эти грабли:
    update tablename set status = 1
    where status = 0 and id in (
    select id from tablename where ..... order by ... limit ... for update
    )
    returning ...
    Ответ написан
  • Как получить полный размер кластера Postgresql (сумму размера всех БД на сервере)?

    Melkij
    @Melkij
    PostgreSQL DBA
    select sum(pg_catalog.pg_database_size(d.datname)) from pg_catalog.pg_database d;


    Вот только полный размер кластера не то же самое что сумма размера всех БД. Размер кластера считается как du -s от $PGDATA
    Ответ написан
    Комментировать