Ответы пользователя по тегу PostgreSQL
  • Как обеспечить отказоустойчивость БД Postgres?

    Melkij
    @Melkij
    PostgreSQL DBA
    как правильно обеспечить надежность и безотказность ее работы?

    Использовать адекватное железо и не мешать базе работать шаловливыми ручками.

    доступен 24 часа 7 дней в неделю.

    бекап

    Объясните, пожалуйста, как это по вашему мнению между собой связано?
    Бекапы необходимы, но как они связаны с высокой доступностью?

    в случае проблем с доступностью, перезапускать/запускать саму СУБД.

    Простой вопрос: зачем?
    Если база сложилась и даже не смогла подняться самостоятельно - значит проблема капительная и разбираться надо детально. Рестартом по кругу вы можете скорее сделать совсем плохо, чем что-либо починить.
    При том обычно проблемы начинаются от того что разработчики выкатили новую версию приложения и та начинает делать что-то странное. Например, забыли сделать индекс на 50гб табличку и засунули запрос с поиском по ней на главную сайта. Рестартом базы это, разумеется, не исправляется. А делает только больнее.

    Многолетней давности pg_postmaster_start_time() впечатлять не буду - мы периодически ставим минорные апдейты на свои базы. И вам тоже весьма рекомендую обновиться до 10.7 или лучше уже на следующих выходных сразу до 10.8.

    А так, если не трогать - то годами будет работать. Мониторинг и алерты от него, разумеется, нужны. Какая-то автоматика при наступлении алерта - обычно приносит куда больше головной боли, чем помогает.

    какие операции, запросы или их комбинации нежелательны для БД и могут привести к проблемам.

    Большая часть инцидентов с недоступностью сервиса с точки зрения приложения - про уровни блокировок. Кто-нибудь попробует сделать create index вместо create index concurrently и привет ожидание блокировки на всю запись в таблицу. Большинство форм alter table сюда же, но они и чтение заблокируют.
    Ответ написан
    Комментировать
  • В чем причины ошибки "Out of shared memory: You might need to increase max_locks_per_transaction"?

    Melkij
    @Melkij
    PostgreSQL DBA
    https://www.postgresql.org/docs/current/runtime-co...
    This parameter controls the average number of object locks allocated for each transaction; individual transactions can lock more objects as long as the locks of all transactions fit in the lock table. This is not the number of rows that can be locked; that value is unlimited. The default, 64, has historically proven sufficient, but you might need to raise this value if you have queries that touch many different tables in a single transaction, e.g. query of a parent table with many children.


    Не имеет отношения к размерам таблиц. Имеет отношение к размеру внутренней таблицы локов и количеству затронутых объектов (например, таблиц) в транзакции. Строго говоря: максимальное число локов объектов одновременно всеми активными транзакциями.
    Не имеет никакого отношения к shared_buffers (не вычитается из него, а прибавляется сверху. shared_buffers - строго буфер страниц, даже без учёта структур данных по управлению этим буфером. Сегмент разделяемой памяти всегда больше shared_buffers) или work_mem или чему-то ещё (кроме как max_connections + max_prepared_transactions). Тем более не имеет никакого отношения к дедлокам.

    Дефолтного значения обычно более чем достаточно. Может быть злоупотребляете партицированием.
    Ответ написан
    Комментировать
  • Возможно ли делать ALTER на PG10?

    Melkij
    @Melkij
    PostgreSQL DBA
    Ибо эат команда, разумеется, уже не работает.

    Почему "разумеется"?
    pglogical никуда не делся. Как был сторонним модулем, так и остался. Релиз с поддержкой PG11 тоже уже был.

    А логическая репликация которая штатная в pg10 - DDL не обрабатывает. Это опять же обязанность сопровождающего систему админа корректно вносить DDL.
    Ответ написан
  • Как востановить базу из файлов?

    Melkij
    @Melkij
    PostgreSQL DBA
    Если в директории C:\Program Files\PostgreSQL\9.1\data (далее буду называть $PGDATA) лежат директории base, global, pg_xlog и всякое прочее преимущественно с префиксом pg_* - то надежда есть. Если в pg_xlog лежат куча странных файлов, а pg_tblspc пусто либо ссылки из него живые. Сделайте бекап $PGDATA и содержимого pg_tblspc (если там были ссылки).

    Затем ставите сервер версии 9.1.24. Настраиваете data_directory смотреть в ваш $PGDATA. Пробуете запустить СУБД и смотрите в лог базы что происходит.

    pg_upgrade требует заведомо работающих и корректно остановленных кластеров и старой версии и новой. Откажется работать даже если база была выключена аварийно.
    Ответ написан
    Комментировать
  • Как проверять поля на то, чтобы только одно из них было не пусто?

    Melkij
    @Melkij
    PostgreSQL DBA
    Вам нужен check constraint.

    XOR в postgresql вроде нет, так что показывать на пальцах:
    alter table tablename add constraint tablename_p1_xor_p2 check((p1 is null and p2 is not null) or (p2 is null and p1 is not null));
    Ответ написан
    Комментировать
  • О чем говорит эта ошибка?

    Melkij
    @Melkij
    PostgreSQL DBA
    Вас прямым текстом спрашивают и куда смотреть и что делать:
    Is the server running on host "180.20.10.1" and accepting
    TCP/IP connections on port 45433?


    На указанном адресе СУБД запущена? На этом порту?
    Ответ написан
    2 комментария
  • Как правильно прописать конфиг для Hibernate?

    Melkij
    @Melkij
    PostgreSQL DBA
    Java - это такой специальный язык для генерации километровых backtrace...

    Почему получив null value in column violates not-null constraint вы решили, что у вас проблема с подключением к СУБД? Вы пытаетесь вставить NULL в поле отмеченное как NOT NULL. Судя по тексту запроса - у вас не указано default значение для этого поля.
    Ответ написан
    4 комментария
  • Есть ли официальные правила выделения портов Postgresql в зависимости от версии?

    Melkij
    @Melkij
    PostgreSQL DBA
    Нет, гарантии нет. Менять привычный 5432 порт у сообщества причин нет. Теоретически поменять дефолтный порт можем, это не так сложно технически - но зачем? Мы не гарантируем совместимость с последующими версиями и вполне можем решить что-нибудь сломать нужное, если сообщество согласится что оно того стоит. Гарантий не дадим, но вполне можно рассчитывать что будет 5432 ещё очень долго использоваться по умолчанию, нет причин его менять и есть веские причины его не менять.

    Ну и стоит упомянуть, что дефолтный порт может быть указан в конфигах, параметром запуска, и в том числе на этапе компиляции базы:
    --with-pgport=PORTNUM set default port number [5432]


    Пока он как-то сам выбирает порт

    PostgreSQL не занимается таким. Просто откажется стартовать если не удастся открыть сокет. Номер порта не менялся очень давно, если менялся вообще хоть когда-нибудь от самого основания ещё post-ingres в 198х годах.

    Вот сторонние скрипты - те могут иметь какую-нибудь такую логику. Например, пакеты debian/ubuntu при вызове pg_createcluster попробует прописать в конфиге ближайший свободный порт начиная с 5432. Никакой зависимости от версии СУБД нет. Нужен новый кластер? Ок, возьмём ближайший свободный порт и настроим на использование его.
    Ответ написан
    3 комментария
  • Как настроить строку соединения к базе данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    Схемы - дополнительный уровень упорядочивания сущностей.
    Варианты на выбор: указывать схему в именах объектов в запросах (обычно) либо менять search_path на необходимый.

    Именно поэтому имя схемы - это атрибут в аннотации самой таблицы, а не строки подключения.
    https://www.doctrine-project.org/projects/doctrine...
    Ответ написан
  • Почему пользователю БД не назначаются права?

    Melkij
    @Melkij
    PostgreSQL DBA
    postgres=# CREATE DATABASE joba_finder;
    CREATE DATABASE
    postgres=# CREATE USER jf_user WITH PASSWORD 'qwerty';
    CREATE ROLE
    postgres=# \l joba_finder 
                                   Список баз данных
         Имя     | Владелец | Кодировка | LC_COLLATE  |  LC_CTYPE   | Права доступа 
    -------------+----------+-----------+-------------+-------------+---------------
     joba_finder | postgres | UTF8      | ru_RU.UTF-8 | ru_RU.UTF-8 | 
    (1 строка)
    
    postgres=# GRANT ALL PRIVILEGES ON DATABASE joba_finder to jf_user;
    GRANT
    postgres=# \l joba_finder 
                                       Список баз данных
         Имя     | Владелец | Кодировка | LC_COLLATE  |  LC_CTYPE   |     Права доступа     
    -------------+----------+-----------+-------------+-------------+-----------------------
     joba_finder | postgres | UTF8      | ru_RU.UTF-8 | ru_RU.UTF-8 | =Tc/postgres         +
                 |          |           |             |             | postgres=CTc/postgres+
                 |          |           |             |             | jf_user=CTc/postgres
    (1 строка)
    
    postgres=# select version();
                                                    version                                                 
    --------------------------------------------------------------------------------------------------------
     PostgreSQL 11.2 (Debian 11.2-2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-2) 8.3.0, 64-bit
    (1 строка)

    Just works. Настройками это не регулируется, так что проверяйте что вы делаете не так. Может быть не коммитите транзакцию с grant? Не знаю.

    Не заметил:

    joba_finder-# \l

    Внимание на -# так где должен быть =# - метка указывает, что вы начали писать запрос, но не завершили его. psql команды вроде \l при этом всё ещё обрабатываются.
    postgres=# select
    postgres-# \l joba_finder 
                                       Список баз данных
         Имя     | Владелец | Кодировка | LC_COLLATE  |  LC_CTYPE   |     Права доступа     
    -------------+----------+-----------+-------------+-------------+-----------------------
     joba_finder | postgres | UTF8      | ru_RU.UTF-8 | ru_RU.UTF-8 | =Tc/postgres         +
                 |          |           |             |             | postgres=CTc/postgres+
                 |          |           |             |             | jf_user=CTc/postgres
    (1 строка)
    
    postgres-# 1;
     ?column? 
    ----------
            1
    (1 строка)

    Как пример psql команды в середине написания select 1;
    Ответ написан
    3 комментария
  • Не могу вписать условие в базу данных?

    Melkij
    @Melkij
    PostgreSQL DBA
    alter column "id" что? По синтаксису дальше идёт описание действия, а не непонятно откуда взявшееся слово INTEGER

    Если это самодеятельность вашего gui - то это приложение не умеет работать с postgresql, только и всего. Возьмите что-нибудь адекватное. psql например.

    Ну и default должен быть не в кавычках, а именно вызовом функции, set default nextval(...
    Ответ написан
    Комментировать
  • Как применить 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 ожидаемо, но для малого числа строк работать будет
    Ответ написан
    Комментировать