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

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Судя по всему вы делали дамп без --clean и пытаетесь восстановить в уже не пустую базу.
    Ответ написан
  • Какая база луче подойдет на рабочий портал?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Сейчас разработчики пишут портал

    Вот у разработчиков и спрашивайте, какую СУБД они лучше знают. И админов своих спросите, какую СУБД те лучше знают. DBA у вас явно нет, иначе вопрос бы так не стоял.

    Сам headhunter использует postgresql. Но там и своя команда админов классная, и вдобавок опытная команда DBA моих нынешних коллег, специализирующихся именно на postgresql.

    Я достаточно хорошо знаю обе СУБД с точки зрения разработчика, но не умею админить mysql, так что моё мнение будет предвзятым.
    Если делаете коммерческий проект - то используйте ту СУБД, которую лучше знает ваша команда. Если разработчики попрятались за своими ORM'ами и носу не заглядывают в базу - то без разницы, в таких условиях любая СУБД будет работать одинаково плохо. Если же хоть кто-то в команде понимает, что надо делать с базой - доверьте выбор ему и поинтересуйтесь о причинах выбора.
    Ответ написан
    Комментировать
  • Как перенести базу postgresql из нерабочей системы, если в chroot сервис не запускается?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Найдите, где datadir базы. Скорей всего /var/lib/postgresql/(версия базы)/main, но могла была быть перемещена, так же может стоять несколько кластеров базы и разные версии базы - в дебианах и убунтах это делается легко.

    Далее установить на новой системе postgresql идентичной major версии и не ниже minor версии что была там. Какая была major версия - смотрите файлик PG_VERSION в datadir. minor версию ставьте последнюю актуальную.
    Так понимаю, старая система в принципе не работает? Т.е. старая база выключена? Выключите и новую (пока пустую) базу. Проверьте, если не уверены, обе базы должна быть выключена.
    Переименовываете datadir на новом сервере (вообще, можно удалить, но можно и ошибиться консолью и дропнуть не то =) )
    Копируете каталог базы: rsync -a /olddatadir /newdatadir
    Копируете и правите если надо конфиги из /etc/postgresql/версия_базы
    Если каталог pg_tblspc/ в datadir не пуст - скопируйте и симлинки из него и все данные по этим симлинкам в аналогичные места на новой машине.
    Если pg_xlog/ является симлинком - его необходимо скопировать. Можно оставить симлинком, можно содержимое перекопировать.
    Пробуете запустить базу на новом месте. Смотрите в логи. Если на старом месте база не была повреждена (и ничего нужного скопировать не забыли) - то она запустится.
    Ответ написан
    1 комментарий
  • Как мне установить ограничение-проверки на два условия?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Для перечислений можно использовать родной enum
    melkij=> create type gender as enum('M','W');
    CREATE TYPE
    melkij=> create table foo (f gender);
    CREATE TABLE
    melkij=> insert into foo values('M');
    INSERT 0 1
    melkij=> insert into foo values('F');
    ОШИБКА:  неверное значение для перечисления gender: "F"
    СТРОКА 1: insert into foo values('F');
                                     ^
    melkij=> insert into foo values('');
    ОШИБКА:  неверное значение для перечисления gender: ""
    СТРОКА 1: insert into foo values('');

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

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Безопасный подход для больших таблиц:
    create unlogged table list_for_delete (id int);
    insert into list_for_delete values ....
    
    with to_rm as (
        select id from list_for_delete limit 10000
    ), rm as (
        delete from list_for_delete where id in (select id from to_rm)
    )
    delete from tablename  where id in (select id from to_rm);
    
    vacuum analyze tablename;
    drop table list_for_delete ;

    cte с delete повторять пока не будет affeted rows = 0. Смотреть на лаг репликации, добавлять задержки между запросами и увеличивать/уменьшать размер пачки в зависимости от влияния на прод.
    vacuum в конце, можно после половины пройтись дополнительно. С таким-то объёмом можно руками вакуум вообще не делать и оставить автовакууму. А для таблиц побольше при массовом изменении имеет смысл.
    Ответ написан
    Комментировать
  • PostgreSQL 9.4.9. Текстовая колонка: какие-то значения были добавлены как string, другие как integer- может ли это привести к значения NULL?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Как добавляли, так и будет храниться и читаться.
    postgres=# create schema garage;
    CREATE SCHEMA
    postgres=# CREATE TABLE garage.users
    (
    car_id text COLLATE pg_catalog."default"
    )
    WITH (
    OIDS = FALSE
    )
    TABLESPACE pg_default;
    CREATE TABLE
    postgres=# insert into garage.users values ('1'), ($$'1'$$), (null);
    INSERT 0 3
    postgres=# select car_id, car_id is null from garage.users ;
     car_id | ?column? 
    --------+----------
     1      | f
     '1'    | f
            | t
    Ответ написан
    Комментировать
  • Чем бекапить все базы Postgres без прерывания доступа к сервису?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    pg_basebackup
    Сделает консистентную физическую копию базы. Соответственно размер бекапа примерно равен размеру кластера postgresql + накопленные за время копирования WAL.
    Восстанавливаться элементарно запустив postgresql с указанием PGDATA в место где лежит результат pg_basebackup.
    Им обычно реплики поднимают.

    pg_dump или pg_dumpall
    Логический бекап данных. Обычно не очень подходит по критерию быстро восстанавливаться т.к. при восстановлении будут перестраивать индексы, проверять fk и прочие constraint, зато как правило сильно (в пару раз без сжатия легко, со сжатием ещё больше разница) компактнее по размеру бекапа

    Все из штатной поставки Postgresql. И другие способы бекапа Postgresql в основе своей опираются на них же.
    Ответ написан
    1 комментарий
  • Как извлечь данные из JSON?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Если не нужен join со значениями, а только фильтр - то
    where array(select (j->>'category_id')::int from jsonb_array_elements(data->'items') j) && array[1,3,5];

    Можно загнать подзапрос с построением массива в immutable хранимку и повесить по ней gin или gist индекс.
    Ответ написан
    Комментировать
  • Как лучше сделать поиск по json ячейке?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Смотрим операторы: https://www.postgresql.org/docs/current/static/fun...
    Печально, прямого оператора как && overlap у массивов нет.
    ?| text[] Do any of these array strings exist as top-level keys?

    Зато тот вполне подходит. Значит, заменить json на jsonb затем запрос будет
    select * from t where jsonbfield ?| array['0', '5', '7']::text[];

    Если на входе удобен именно json массив, а не pg массив, то относительно просто переписывается одно в другое
    select * from t where jsonbfield ?| (select array_agg(t) from json_array_elements_text('["0","5","7"]') t);


    gin и gist индексы оператор ?| могут обрабатывать.
    Ответ написан
    Комментировать
  • Псевдо-персистентное соединение в PHP, возможно ли?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Используйте pgbouncer.
    Лучше всего в режиме transaction пула. Тогда backend postgresql будет выдаваться соединениям от приложения только на время выполнения транзакции. Что позволяет и очень эффективно утилизировать лишь небольшое число процессов postgresql и сохранить возможность транзакционной работы. В режиме транзакций не работают prepared statements, но PDO их и так эмулирует, так что проблемой это не является.

    pgbouncer легко держит тысячи открытых соединений с приложением, легко их открывает и закрывает, развлечения начинаются при попытке прокачать через баунсер с гигабит трафика (и обходится банально запуском второго баунсера тут же на другом порту). Обычно размещается на машине непосредственно с базой на 6432 порту.
    И вообще-то является фактическим стандартом для инсталляций postgresql.
    Ответ написан
    1 комментарий
  • Автоинкремент в INSERT INTO ... ON CONFLICT?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Никак. Работает как задумано.

    И уже при вставке идет разрыв в id.

    sequence не гарантирует неразрывность. И последовательность значений тоже не гарантирует.
    Гарантирует только уникальность значений.
    Ответ написан
    7 комментариев
  • Как правильно делать бекапы базы Postgresql на продашн сервере?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Зависит от:
    0) какой промежуток времени вам допустимо потерять при восстановлении
    1) сколько места вы можете выделить для хранения бекапов
    2) какой запас времени вы хотите сохранять для возможности восстановить данные когда-то из более далёкого прошлого

    Может, на мыло тоже отправлять на всякий случай?

    Как через почту пропихнуть даже мелкие бекапы в десяток гигабайт?
    Или вы про совсем крошечные базы спрашиваете?

    Шифровать или нет - зависит от требований к безопасности и оценке риска в случае disaster recovery не восстановить ключ шифрования.

    Для хорошего point in time recovery - pg_basebackup + pg_receivexlog (archive_command только если уверены, что можете её сделать нормально). Или что-то, работающее поверх них.
    Отдельный случай pitr с хранением в амазоне - см. вполне внятный wal-e
    Если pitr не обязателен, то pg_dump делать. Да, лучше архивировать, сжимаются дампы весьма неплохо.

    Например, политика бекапа из практики: ежедневный pg_dumpall, хранятся за 1 число каждого месяца на протяжении года плюс 8 дней предыдущих ежедневных.

    Что-то ещё - регулярно пробовать восстановить и запустить базу из бекапа.
    Ответ написан
  • Как при создании нового кластера postgres указать иное расположение хранения баз?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Для начала немного терминологии, чтобы явно говорить на одном языке.
    Кластер postgresql - это один запущенный postgres.
    Один кластер может содержать несколько именованных баз данных, но все они обслуживаются одним запущенным postgres.
    На физической машине кластеров postgres может быть несколько.

    А теперь - что вы хотите сделать?
    * перенести директорию базы в другое место. Остановить базу, скопировать rsync'ом datadir куда надо, на старом месте сделать симлинк (datadir в конфиге в этом случае даже не надо править, если поправить пути в конфиге - то не обязателен симлинк)
    * оставить одни БД в дефолтном месте, а некоторые другие - в другом, но под управлением одного кластера. Вам необходимо сделать tablespace и использовать его. При create database можно указать tablespace, который и будет считаться по-умолчанию для всех объектов этой базы (но переопределить его можно для каждого объекта)
    * запустить отдельный кластер. В одно и то же место вы две базы просто не вставите. Соответствующий, и обычно обязательный, параметр в initdb плюс указать datadir в конфиге или строке запуска базы (зависит от того, как будет запускаться база и где лежать ещё конфиг). А для весьма приятного враппера в debian и ubuntu pg_createcluster параметр --datadir так же есть сразу

    см. также Как правильно изменить месторасположение базы postgresql-9.2.18.rl7?
    Ответ написан
    1 комментарий
  • Как скопировать запросы,которые делает программа к Postgres sql?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Помимо log_statement = 'all' можно выставить настройку log_min_duration_statement в 0 - она тоже может логировать все запросы.

    Если запросов через базу проходит много не только от необходимой программы, то и log_statement и log_min_duration_statement возможно выставить только для пользователя, от имени котрого программа выполняет запросы. Например,
    alter user melkij set log_min_duration_statement = 0;
    Ответ написан
    1 комментарий
  • Какие книги прочитать по лучшим практикам проектирования БД?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Bill Karwin SQL Antipatterns
    В общем-то, в духе рефакторинга как раз: как делают часто неправильно, почему это плохо (но когда и адекватно для задачи) и как сделать лучше.
    Ответ написан
    1 комментарий
  • Как найти вывести список всех не найденных значений из массива?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    select children.code is null as is_not_found, /*another children data is null too*/ 
    from unnest(array[...]) as code 
    left join children using(code)
    Ответ написан
    Комментировать
  • Как сделать временную таблицу с одинаковыми данными?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    небольшая ремарка №3: а нафига вам вообще cross join понадобился?
    SELECT 'Economy' FROM generate_series(1,10);
    Ответ написан
    1 комментарий
  • Как правильно изменить месторасположение базы postgresql-9.2.18.rl7?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    С большим даунтаймом, зато целиком на новый диск:
    Потушить базу, скопировать PGDATA (data_directory в конфиге) в новое место, заменить data_directory в конфиге на новое место, запустить базу.
    Можно, кстати, не менять data_directory, а сделать симлинк. Postgresql не против по симлинкам сходить за своими данными.

    С небольшим даунтаймом, зато с чуть большим числом телодвижений:
    через pg_basebackup сделать копию в новом месте, запустить там второй инстанс постреса с репликой. Когда реплика догонит мастер, потушить мастер (сделав checkpoint), потушить реплику (тоже с чекпоинтом), заменить data_directory в конфиге на новое место, запустить базу.

    Без даунтайма:
    инициализировать второй диск как tablespace, перенести на этот tablespace что мешается на основном (pg_repack попробуйте, емнип умеет без пишущего лока даже переносить). Использоваться будут оба диска, что кстати хорошо с точки зрения io.
    Ответ написан
    2 комментария
  • Как замониторить банусер?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    Нет, сам postgresql о существовании баунсера вообще не знает. pgbouncer является обычным libpq клиентом с точки зрения базы.
    Ответ написан
  • Необходим поменять формат времени в запросе, как?

    Melkij
    @Melkij
    DBA Team для вашего PostgreSQL?
    формат времени с mysql на postgresql

    done by sql design.
    Форматы даты, времени, датывремени эквиваленты. И, емнип, вовсе стандартны для SQL в целом.
    Если вы пихаете данные в неподходящий тип данных вместо штатного для обеих субд timestamp - то вас будут ждать сюрпризы рано или поздно. Это как бы само собой разумеется.

    Если ваш clock, как очевидно по комментарию в другом ответе, int4 является количеством секунд с начала этой эпохи, то привести unixtime к циферке-количеству-секунд-этой-эпохи можно через extract:
    hs.clock > extract(epoch from timestamp 'yesterday')

    Привести циферку количества секунд в этой эпохе к timestamp можно функцией to_timestamp.
    Ответ написан
    2 комментария