Ответы пользователя по тегу PostgreSQL
  • Как перенести большую базу с одного сервера на другой?

    Melkij
    @Melkij
    PostgreSQL DBA
    Настраиваете потоковую репликацию, через pg_basebackup снимаете копию, запускаете как реплику. Когда догонит ведующую базу выключаете мастер и повышаете реплику до нового мастера.
    Даунтайм минута вне зависимости от объёма данных. Ну может ещё минута если понадобится рестарт мастера из-за смены wal_level, listen_addresses или max_wal_senders

    https://wiki.postgresql.org/wiki/Streaming_Replication
    Ответ написан
    Комментировать
  • Почему на ставиться ltree?

    Melkij
    @Melkij
    PostgreSQL DBA
    Вы что-то делаете странное. У вас какая версия postgresql?
    Если 9.1 и выше - то единственный верный способ ставить extension - это сказать create extension в нужной базе. Обычно нужны привилегии суперпользователя базы (обычно postgres на linux или pgsql на freebsd)

    Ругать на локаль - ошибка настройки самой ОС, к базе отношения не имеет.
    Ответ написан
  • Из-за чего ошибка POSTGRESQL процедуры?

    Melkij
    @Melkij
    PostgreSQL DBA
    Причина ошибки хранимки полностью и достоверно указана в подробностях текста ошибки:
    It could refer to either a PL/pgSQL variable or a table column.

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

    Melkij
    @Melkij
    PostgreSQL DBA
    А зачем вообще отправлять ошибку запроса на клиент?
    Ошибке запроса самое место в логе и только там. Клиенту - HTTP 500 и "извините, не шмогла" написанное любым вариантом какой вам понравится.
    Если требуется другое сообщение (или действие) для конкретной ошибки - ловите этот конкретный код ошибки. На допустимость логина обычно проверяют предварительным запросом, в апдейт on conflict пока не завезли. Плюс можно хапнуть advisory lock для устранения race condition и закатать всё в одну хранимку чтобы сэкономить на планировщике и сети.
    Ответ написан
    2 комментария
  • Добавление и обновление записей через Insert Into?

    Melkij
    @Melkij
    PostgreSQL DBA
    С insert или update по результату select (к слову, совершенно ненужному запросу) вы вляпываетесь в race condition
    on conflict специально сделан для нормальной сериализации происходящего и использоваться и должен. Другие способы сериализации race condition из времён до on conflict производительность просаживают по вполне очевидным причинам.
    Ответ написан
    2 комментария
  • В чем ошибка при установки ноты?

    Melkij
    @Melkij
    PostgreSQL DBA
    could not find driver

    Скорей всего ошибка от PDO о том, что у вас не установлен модуль PHP с поддержкой запрошенной СУБД. Соответственно проверьте конфигурацию приложения, правильно ли указан DSN и конфигурацию PHP - установлен ли модуль для нужной СУБД.
    Ответ написан
    3 комментария
  • Postgresql запрос, сравнение полученных данных и перевод в секунды, как сделать?

    Melkij
    @Melkij
    PostgreSQL DBA
    select extract(epoch from now() - MAX(DATE_OP)) seconds_ago from tablename;
    Ответ написан
    Комментировать
  • Насколько правильно использовать json для хранения данных в базе данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    json нужно использовать если у вам надо хранить json и сохранять полностью его форматирование. Форматирование именно самого json с пробелами, табами и переносами строк - т.е. как текст, но с валидацией что здесь именно json.
    если вам нужно хранить json - лучше использовать jsonb
    А для описанной задачи и просто массива достаточно, bigint[] или text[]. Контактные данные для заказа уместны именно в заказе, а по jsonb и массивам возможно вполне внятно и искать в том числе
    Ответ написан
    Комментировать
  • Текст в первичном ключе и его переиндексация?

    Melkij
    @Melkij
    PostgreSQL DBA
    Для uuid в принципе не нужен текст, есть нативный одноимённый тип данных.

    При этому line иногда плавает.

    Проверьте память. Физическую на сервере. Подозрение что косячит.
    И диски тоже проверьте.
    Потому что есть всего одно место, где можно поймать "compressed data is corrupted" и связано оно с распаковкой сжатых данных из toast. reindex тоже говорит, что прочитано что-то совсем не то, что предполагалось.
    Ответ написан
  • В какой папке находятся созданные таблицы PostgreSQL?

    Melkij
    @Melkij
    PostgreSQL DBA
    поэтому проще будет найти файлы и все попереносить.

    И так делать нельзя и ничего кроме бесполезного файлика с бинарным мусором вы в резуультате не получите.
    Прочитать данные из raw файлика, а уж тем более подсунуть его в другую базу - очень сильно замучается даже опытный DBA, способный читать и понимать исходный код postgresql (это кстати минимальное требование к тому чтобы что-то достать из сырого файлика таблицы).

    Потому что директория базы PostgreSQL - это один неделимый объект (плюс tablespace, которые отделять тоже нельзя от данных кластера). Для чтения данных из файлов таблицы (их много может быть) нужен системный каталог, нужен toast (если был создан), нужны clog и xlog чтобы понять, а что мы собственно в этом файлике видеть должны, а что просто ещё не вычистил вакуум.

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

    Melkij
    @Melkij
    PostgreSQL DBA
    Так сравниваются массивы - поэлементно по количеству элементов в меньшем из массивов.
    Если элементы идентичны - сравниваем длины массивов. Поэтому массивы в таком виде вам подходят слабо.

    Может лучше ваш список смежности вовсе заменить на штатное материализованное представление ltree?
    Ну или во всяком случае на него можно заменить ваши массивы.
    Ответ написан
    1 комментарий
  • Как правильно сделать фильтрацию по числу JSONB в PostgreSQL используя индекс?

    Melkij
    @Melkij
    PostgreSQL DBA
    Индекс возможно повесить функциональный:
    create index on tablename using btree(((features ->> 'capacity'::text)::integer));

    Соответственно предикат по этому же самому выражению получит возможность использовать этот индекс.

    Больше возможностей внятно индексировать jsonb для запросов на числовые диапазоны мне как-то не вспоминается. Сортировку по полю-то только btree и умеет из всех актуальных access method.

    Т.е. индекс используется, хотя в данном случае index срабатывает на price столбце? Тогда почему запрос отрабатывает быстро?

    Да, индекс используется - индекс по price. Потому что вы по нему сортируете. И планировщик опираясь на свою статистику надеется, что сможет быстро найти 25 строк читая строки в порядке требуемой сортировки по индексу и по пути проверять выкидывать неподходящие.
    Ответ написан
    2 комментария
  • Как правильно составить запрос для взятия первого значения из группы?

    Melkij
    @Melkij
    PostgreSQL DBA
    Ну а когда станет скучно перебирать всю таблицу - обращайтесь :-)

    Postgresql 9.4 и выше, выбор по известному диапазону дат через index scan по timestamp полю:
    select day, data 
    from generate_series('2017-12-10', '2017-12-12', interval '1 day') as day, 
    lateral (
        select data from tablename 
        where "timestamp" between day and day + interval '1 day' 
        order by "timestamp" desc limit 1
    ) ljd;


    Все дни из таблицы по индексу:
    with recursive t as (
    (select "timestamp"::date as day, data from tablename order by "timestamp" desc limit 1)
    union all
    select bpt.* from t, lateral (
    select "timestamp"::date as day, data from tablename where "timestamp" < t.day order by "timestamp" desc limit 1
    ) as bpt
    )
    select * from t;

    Используя loose index scan
    Ответ написан
    7 комментариев
  • Как в PostgreSQL выбрать значения значения которые есть в массиве, но нет в БД?

    Melkij
    @Melkij
    PostgreSQL DBA
    Всё просто: надо развернуть массив в набор строк и проверить на not exists
    select i from unnest(array[1,2,3,4]) as i 
    where not exists (select 1 from tablename where id = i);
    Ответ написан
    9 комментариев
  • Как подсчитать кол-во вставленных записей в БД?

    Melkij
    @Melkij
    PostgreSQL DBA
    Мне неизвестны штатные средства для этого.

    В качестве обходных фокусов можно поизвращаться вот так:
    with 
    data (new_user_id, new_name) as (values(%(user_id)s, %(name)s)),
    wr as (
        INSERT INTO users(user_id, name)
                    select new_user_id, new_name from data
                    ON CONFLICT (user_id) DO NOTHING returning user_id
    ), upd as (
        update users set name = new_name from data where users.user_id = data.new_user_id and data.new_user_id not in (
        select user_id from wr
        )
    )
    select count(*) from wr;


    Что работает согласно задаче из-за того, что do nothing не осуществляет insert и потому строка не появляется в returning.
    Ответ написан
    Комментировать
  • Стоит ли хранить файлы транзакций отдельно от баз?

    Melkij
    @Melkij
    PostgreSQL DBA
    Имеются в виду pg_xlog (pg_wal в 10) или pg_clog (pg_xact)? Файлы (метаданных) транзакций - это вторые и пишутся они не очень интенсивно. Первый - write ahead log - журнал записи, где отражается вся пишущая активность базы и обычно синхронной записью.

    Производительность дисков для записи WAL - это ключевой фактор для времени commit. Но WAL пишется последовательно и за счёт этого можно держать вполне хорошую нагрузку размещая их монопольно на отдельных HDD, а не SSD. Сэкономив соответственно немного денег на требуемой под базу ёмкости SSD.
    Ну или если у вас записи достаточно много при нормально настроенных checkpointer и bgwriter, чтобы была необходимость выделить отдельные несколько SSD под WAL. Впрочем, у вас в тегах NTFS упомянут. На таком нормальный production всё равно не делают, значит не ваш случай.

    Массивы - RAID10 или RAID1 смотря сколько дисков есть. Для тестовых машин смотрите сами.
    Ответ написан
  • Вставка записи в главную таблицу и подчиненные?

    Melkij
    @Melkij
    PostgreSQL DBA
    Добавить ещё один CTE.
    WITH new_tbl_main( id ) AS (
              INSERT INTO tbl_main ( institution_id ) VALUES ( 38)
                RETURNING id 
    ), chi2 as (
    INSERT INTO tbl_child1 ( tbl_main_id ) 
                SELECT new_tbl_main.id  FROM new_tbl_main
    )
    INSERT INTO tbl_child1 ( tbl_main_id ) 
                SELECT new_tbl_main.id  FROM new_tbl_main
                RETURNING tbl_main_id

    Если нужен returning от всех - то добавить ещё cte и в финале склеить запросы через union all или join или как понравится.
    Ответ написан
    Комментировать
  • Как правильно создать функцию возвращающую булевый результат выполнения селекта?

    Melkij
    @Melkij
    PostgreSQL DBA
    Вероятно при упрощении примера вы выкинули собственно саму причину синтаксической ошибки.
    Потому что приведённая в вопросе хранимка синтаксически корректна, что, впрочем, не изменяет некорректности семантической.
    ERROR: cannot use RETURN QUERY in a non-SETOF function

    Вы не можете использовать return query для возврата одного значений. return query только для функций возвращающих множество. Булево выражение можно посчитать непосредственно в return, как в большинстве других языков:
    CREATE OR REPLACE FUNCTION checkPermission(text, text) RETURNS BOOLEAN AS
    $$
    BEGIN
      RETURN $1 && $2;
    END;
    $$ LANGUAGE plpgsql


    Ну и мелочь лучше записывать на language sql, что позволяет оптимизаторы делать интересные фокусы в целях повышения производительности запросов.
    CREATE OR REPLACE FUNCTION checkPermission(text, text) RETURNS BOOLEAN AS
    $$
      SELECT $1 && $2;
    $$ LANGUAGE sql


    Разумеется, это будет работать только если у вас определён оператор && для пары операндов типа text.
    Ответ написан
    Комментировать
  • Как правильно найти пересечение двух jsonb массивов в postgres?

    Melkij
    @Melkij
    PostgreSQL DBA
    Есть у постгреса оператор &&

    "есть оператор" - это сказано немного сильно преждевременно. Например, на моей тестовой 9.6 таких операторов 8 штук.
    Потому что нет отдельно операторов. Операторы определены только неразрывно с типами данных своих операндов (двух или одного для префиксных и постфиксных операторов)

    select oprkind, l.typname, oprname, r.typname from pg_operator join pg_type l on oprleft = l.oid join pg_type r on oprright = r.oid where oprname = '&&';
     oprkind |  typname  | oprname |  typname  
    ---------+-----------+---------+-----------
     b       | box       | &&      | box
     b       | polygon   | &&      | polygon
     b       | tinterval | &&      | tinterval
     b       | circle    | &&      | circle
     b       | inet      | &&      | inet
     b       | tsquery   | &&      | tsquery
     b       | anyarray  | &&      | anyarray
     b       | anyrange  | &&      | anyrange

    И jsonb здесь явно отсутствует.

    Значит берём CREATE OPERATOR в руки, пара хранимок - и вот у вас новый оператор готов. Это PostgreSQL, он так умеет и позволяет делать.

    Плюс посмотреть в релевантный jsonb раздел документации: https://www.postgresql.org/docs/current/static/fun...
    Но с операциями на массивами в json там немного печально и неудобно.
    Ответ написан
    Комментировать
  • Как использовать huge pages для Postgres запущенного в docker контейнере?

    Melkij
    @Melkij
    PostgreSQL DBA
    Не извращаться и вытащить production базу из докера на нативное железо. Что базе в этом докере делать, если и диск и сеть надо использовать хоста?

    Насколько я помню, ни cgroups ни namespaces не мешают выделенным huge pages. Попробуйте вкрутить vm.nr_hugepages на хост системе и стартовать базу с huge_pages=on
    Ответ написан
    Комментировать