Обсуждение: pg_dump\pg_restore large objects

Поиск
Список
Период
Сортировка

pg_dump\pg_restore large objects

От
Sergej Kandyla
Дата:
Всем привет.

Слегка запутался с дампами и к своему позору обнаружил,
что при обычном дампе (plain text)  large objects не экспортируются!!!
(Хоршо еще, что нюанс всплыл при простой миграции энвайромента...)


В связи с этим сопутствующие вопросы.


1)
делая бекапы, с указанием custom format, и --blob
pg_dump -Fc -b -f ${file} ${db}

можно ли быть уверенным что все нужные данные попадают в бекап?
Подойдет ли подобный вариант на роль универсального решения,
или лучше базы без блобов экспортировать в plain-text ?


2)  Не понимаю, почему такие расхождения по размеру бекапов:

Сама база:
# du -sh /srv/pgsql/data/base/
1.1G    /srv/pgsql/data/base/

Бекап, сделанный при помощи custom format:
pg_dump -Fc -b -f ${file} ${db}
759M    database.dump

Бекап, сделанный при помощи tar format:
pg_dump -Ft -b -f ${file} ${db}
870M    database.dump.tar

И наконец, plain-text бекап:
pg_dump -c  -f ${file} ${db}
2.8G   database.sql (plain text)  - откуда???
даже если потом сжать этот бекап (tar.gz), то получается 1.1G...


3) Восстановление:
даже указывая опцию
-c, --clean,   если база уже содержит данные, то импорт заканчивается
ошибками.

pg_restore -c -d  mydatabase    db.dump
....
pg_restore: [archiver] could not create large object 16887

Если же базу данных предварительно грохнуть, и потом создать заново, то
все ок.
Это что, фича такая?


4) права доступа.
Если в бекапе встречались различные предоставления  привилегий, в духе:
ALTER TABLE mydbtable OWNER TO myuser_role

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


Спасибо!


Re: pg_dump\pg_restore large objects

От
eshkinkot@gmail.com (Сергей Бурладян)
Дата:
Sergej Kandyla <sk@hlsrv.com> writes:

> Слегка запутался с дампами и к своему позору обнаружил,
> что при обычном дампе (plain text)  large objects не экспортируются!!!

Это не так. LO экспортируются по умолчанию, и в этом легко убедиться
запустив pg_dump без параметров, например:
$ pg_dump | grep lo_open
SELECT pg_catalog.lo_open('16651', 131072);

вообще, это зависит от параметров pg_dump. Например если Вы сохраняете
только одну таблицу, то LO экспортироваться не будут.

подробнее можно прочитать здесь: http://www.postgresql.org/docs/current/static/app-pgdump.html

> 1)
> делая бекапы, с указанием custom format, и --blob
> pg_dump -Fc -b -f ${file} ${db}
>
> можно ли быть уверенным что все нужные данные попадают в бекап?

Смотря что Вы имеете ввиду под «нужные», например, можно быть уверенным
что определения пространств таблиц (TABLESPACE) и роли туда точно НЕ попадут.

> 2)  Не понимаю, почему такие расхождения по размеру бекапов:
>
> Сама база:
> # du -sh /srv/pgsql/data/base/
> 1.1G    /srv/pgsql/data/base/

Это бинарные данные, частично возможно сжатые + индексы.

> Бекап, сделанный при помощи custom format:
> pg_dump -Fc -b -f ${file} ${db}
> 759M    database.dump

Это сжатый текст. LO в двоичном виде. Чтобы увидеть сколько оно занимает
без сжатия добавьте параметр -Z0

> Бекап, сделанный при помощи tar format:
> pg_dump -Ft -b -f ${file} ${db}
> 870M    database.dump.tar

Это несжатый текст, LO в двоичном виде + текстовой файл со схемой данных.

> И наконец, plain-text бекап:
> pg_dump -c  -f ${file} ${db}
> 2.8G   database.sql (plain text)  - откуда???
> даже если потом сжать этот бекап (tar.gz), то получается 1.1G...
>

Это несжатый текст, почти такой же как в tar формате, только ещё и LO
тут в текстовом виде (а это значит что один двоичный байт LO в худшем
случае в текстовом виде занимает пять байт «\\000»).

> 3) Восстановление:
> даже указывая опцию
> -c, --clean,   если база уже содержит данные, то импорт заканчивается ошибками.
>
> pg_restore -c -d  mydatabase    db.dump
> ....
> pg_restore: [archiver] could not create large object 16887
>
> Если же базу данных предварительно грохнуть, и потом создать заново, то все ок.
> Это что, фича такая?

Возможно, Вы предоставили мало информации об ошибке. Вообще, ключ -c
подразумевает что очищаемая база соответствует той, что в резервной
копии. Если они различаются — то часть объектов не будет удалена так как
удаляются только те объекты, которые есть в резервной копии.

> 4) права доступа.
> Если в бекапе встречались различные предоставления  привилегий, в духе:
> ALTER TABLE mydbtable OWNER TO myuser_role
>
> А на новой базе  такой роли нету (или я умышленно хочу сделать для импортируемой
> базы другого владельца),
> как будет правильно поступать..?

Создать нужную роль, а потом её переименовать. Если такая роль уже есть
и Вы хотите её изменить - то тут сложнее :)

> Я, конечно, понимаю, что при создании базы я указываю и владельца для нее, и
> весь импорт будет присвоен указанному владельцу,
> но все же.

-- 
С уважением, Сергей Бурладян

Re: pg_dump\pg_restore large objects

От
Sergej Kandyla
Дата:
Сергей Бурладян wrote:
> Sergej Kandyla <sk@hlsrv.com> writes:
>
>
>> Слегка запутался с дампами и к своему позору обнаружил,
>> что при обычном дампе (plain text)  large objects не экспортируются!!!
>>
>
> Это не так. LO экспортируются по умолчанию, и в этом легко убедиться
> запустив pg_dump без параметров, например:
> $ pg_dump | grep lo_open
> SELECT pg_catalog.lo_open('16651', 131072);
>
> вообще, это зависит от параметров pg_dump. Например если Вы сохраняете
> только одну таблицу, то LO экспортироваться не будут.
>
> подробнее можно прочитать здесь: http://www.postgresql.org/docs/current/static/app-pgdump.html
>

Спасибо за ответ.


Я, видимо, начитался старых манов из гугла:

http://www.postgresql.org/docs/8.0/static/backup.html
22.1.4. Caveats
For reasons of backward compatibility, pg_dump does not dump large
objects by default. To dump large objects you must use either the custom
or the tar output format, and use the -b option in pg_dump. See the
pg_dump reference page for details. The directory contrib/pg_dumplo of
the PostgreSQL source tree also contains a program that can dump large
objects.

и отсюда сделал такие выводы.

Однако, факт остается.
Отгреб кучу проблем на ровном месте используя бекап в текстовый файл.  В
импорте множество самых разных ошибок...

Все вылечилось после перехода на бинарный формат. Ни одной ошибки.


>> Бекап, сделанный при помощи custom format:
>> pg_dump -Fc -b -f ${file} ${db}
>> 759M    database.dump
>>
>
> Это сжатый текст. LO в двоичном виде. Чтобы увидеть сколько оно занимает
> без сжатия добавьте параметр -Z0
>
>
>> Бекап, сделанный при помощи tar format:
>> pg_dump -Ft -b -f ${file} ${db}
>> 870M    database.dump.tar
>>
>
> Это несжатый текст, LO в двоичном виде + текстовой файл со схемой данных.
>

Не понял,  момента.
Для переноса базы достаточно  одного из таких дампов.
Из ваших слов выходит   что  -Ft -b  содержит дополнительые схемы
данных, которые отсутствуют в бекапе  "-Fc -b"..


>> И наконец, plain-text бекап:
>> pg_dump -c  -f ${file} ${db}
>> 2.8G   database.sql (plain text)  - откуда???
>> даже если потом сжать этот бекап (tar.gz), то получается 1.1G...
>>
>>
>
> Это несжатый текст, почти такой же как в tar формате, только ещё и LO
> тут в текстовом виде (а это значит что один двоичный байт LO в худшем
> случае в текстовом виде занимает пять байт «\\000»).
>
ясно!

>> 3) Восстановление:
>> даже указывая опцию
>> -c, --clean,   если база уже содержит данные, то импорт заканчивается ошибками.
>>
>> pg_restore -c -d  mydatabase    db.dump
>> ....
>> pg_restore: [archiver] could not create large object 16887
>>
>> Если же базу данных предварительно грохнуть, и потом создать заново, то все ок.
>> Это что, фича такая?
>>
>
> Возможно, Вы предоставили мало информации об ошибке. Вообще, ключ -c
> подразумевает что очищаемая база соответствует той, что в резервной
> копии. Если они различаются — то часть объектов не будет удалена так как
> удаляются только те объекты, которые есть в резервной копии.
>

Указывая эту опцию:     -c, --clean                 clean (drop)
database objects before recreating
я ожидал что будет нечто подобное как в мускиле, и вроде бы оно так и
есть...

DROP TABLE...
CREATE TABLE...

Однако, если база уже была создана и содержала данные,

то ни дамп, сделанный посредством,   pg_dump  --clean
ни  pg_restore -c  ... binary.dump

не отрабатывают корректно (проверял на разных PG серверах.).

Мне такое поведение не ясно.
Для консистентного импорта бекапа, нужно сначала базу грохнуть, потом
создать заново
и тогда уже импортить. В этом случае порядок.

Хотя может такое поведение и вполне оправдано.




>> 4) права доступа.
>> Если в бекапе встречались различные предоставления  привилегий, в духе:
>> ALTER TABLE mydbtable OWNER TO myuser_role
>>
>> А на новой базе  такой роли нету (или я умышленно хочу сделать для импортируемой
>> базы другого владельца),
>> как будет правильно поступать..?
>>
>
> Создать нужную роль, а потом её переименовать. Если такая роль уже есть
> и Вы хотите её изменить - то тут сложнее :)
>
да, все оказалось проще.
аля,
CREATE ROLE newrole
CREATE DATABASE $DBNAME WITH OWNER=newrole

pg_restore -U newrole -O -d  $DBNAME   db.dump



Субьективные выводы:
1.  Не нашел почти никаких преимуществ в plain-text бекапах (кроме как
цели руками его посмотреть)
    binary dump в сумме получается заметно быстрее и портабельнее,
занимает меньше места.
    Перенастроил систему бекапов на этот формат.

2. Импорт бекапов нужно делать, только предварительно удалив и заново
создав базу данных.
       (про pg_dump -С я знаю,  но считаю не очень портабельным, поэтому
не использую).



Спасибо!

Re: pg_dump\pg_restore large objects

От
Dmitriy Igrishin
Дата:


8 апреля 2011 г. 18:17 пользователь Sergej Kandyla <sk@hlsrv.com> написал:
Сергей Бурладян wrote:
Sergej Kandyla <sk@hlsrv.com> writes:

 
Слегка запутался с дампами и к своему позору обнаружил,
что при обычном дампе (plain text)  large objects не экспортируются!!!
   

Это не так. LO экспортируются по умолчанию, и в этом легко убедиться
запустив pg_dump без параметров, например:
$ pg_dump | grep lo_open
SELECT pg_catalog.lo_open('16651', 131072);

вообще, это зависит от параметров pg_dump. Например если Вы сохраняете
только одну таблицу, то LO экспортироваться не будут.

подробнее можно прочитать здесь: http://www.postgresql.org/docs/current/static/app-pgdump.html
 

Спасибо за ответ.


Я, видимо, начитался старых манов из гугла:

http://www.postgresql.org/docs/8.0/static/backup.html
22.1.4. Caveats
For reasons of backward compatibility, pg_dump does not dump large objects by default. To dump large objects you must use either the custom or the tar output format, and use the -b option in pg_dump. See the pg_dump reference page for details. The directory contrib/pg_dumplo of the PostgreSQL source tree also contains a program that can dump large objects.

и отсюда сделал такие выводы.

Однако, факт остается.
Отгреб кучу проблем на ровном месте используя бекап в текстовый файл.  В импорте множество самых разных ошибок...

Все вылечилось после перехода на бинарный формат. Ни одной ошибки.



Бекап, сделанный при помощи custom format:
pg_dump -Fc -b -f ${file} ${db}
759M    database.dump
   

Это сжатый текст. LO в двоичном виде. Чтобы увидеть сколько оно занимает
без сжатия добавьте параметр -Z0

 
Бекап, сделанный при помощи tar format:
pg_dump -Ft -b -f ${file} ${db}
870M    database.dump.tar
   

Это несжатый текст, LO в двоичном виде + текстовой файл со схемой данных.
 

Не понял,  момента.
Для переноса базы достаточно  одного из таких дампов.
Из ваших слов выходит   что  -Ft -b  содержит дополнительые схемы данных, которые отсутствуют в бекапе  "-Fc -b"..



И наконец, plain-text бекап:
pg_dump -c  -f ${file} ${db}
2.8G   database.sql (plain text)  - откуда???
даже если потом сжать этот бекап (tar.gz), то получается 1.1G...

   

Это несжатый текст, почти такой же как в tar формате, только ещё и LO
тут в текстовом виде (а это значит что один двоичный байт LO в худшем
случае в текстовом виде занимает пять байт «\\000»).
 
ясно!


3) Восстановление:
даже указывая опцию
-c, --clean,   если база уже содержит данные, то импорт заканчивается ошибками.

pg_restore -c -d  mydatabase    db.dump
....
pg_restore: [archiver] could not create large object 16887

Если же базу данных предварительно грохнуть, и потом создать заново, то все ок.
Это что, фича такая?
   

Возможно, Вы предоставили мало информации об ошибке. Вообще, ключ -c
подразумевает что очищаемая база соответствует той, что в резервной
копии. Если они различаются — то часть объектов не будет удалена так как
удаляются только те объекты, которые есть в резервной копии.
 

Указывая эту опцию:     -c, --clean                 clean (drop) database objects before recreating
я ожидал что будет нечто подобное как в мускиле, и вроде бы оно так и есть...

DROP TABLE...
CREATE TABLE...

Однако, если база уже была создана и содержала данные,

то ни дамп, сделанный посредством,   pg_dump  --clean ни  pg_restore -c  ... binary.dump

не отрабатывают корректно (проверял на разных PG серверах.).

Мне такое поведение не ясно.
Для консистентного импорта бекапа, нужно сначала базу грохнуть, потом создать заново
и тогда уже импортить. В этом случае порядок.

Хотя может такое поведение и вполне оправдано.
И это правильно, т.к. БД - по определению - каталог, содержимое
которого - суть объекты БД, которые не зависят от её имени.
Во время разработки бывает очень удобно импортировать дамп
в разные БД (например, чтобы выявить изменения с помощью
того или иного ПО, которые требуют 2 БД в разврёрнутом виде).





4) права доступа.
Если в бекапе встречались различные предоставления  привилегий, в духе:
ALTER TABLE mydbtable OWNER TO myuser_role

А на новой базе  такой роли нету (или я умышленно хочу сделать для импортируемой
базы другого владельца),
как будет правильно поступать..?
   

Создать нужную роль, а потом её переименовать. Если такая роль уже есть
и Вы хотите её изменить - то тут сложнее :)
 
да, все оказалось проще.
аля, CREATE ROLE newrole
CREATE DATABASE $DBNAME WITH OWNER=newrole

pg_restore -U newrole -O -d  $DBNAME   db.dump



Субьективные выводы:
1.  Не нашел почти никаких преимуществ в plain-text бекапах (кроме как цели руками его посмотреть)
  binary dump в сумме получается заметно быстрее и портабельнее, занимает меньше места.
  Перенастроил систему бекапов на этот формат.
Часто бывает полезным сравить два дампа вручную (например, git-diff(1)).

2. Импорт бекапов нужно делать, только предварительно удалив и заново создав базу данных.
     (про pg_dump -С я знаю,  но считаю не очень портабельным, поэтому не использую).
Ещё бывает удобно переименовывать текущую (старую) версию БД
перед накатом новой версии:
ALTER DATABASE mydb RENAME TO mydb_old;
CREATE DATABASE mydb ...;
-- Команды создания объектов...



Спасибо!
Удачи!


--
Sent via pgsql-ru-general mailing list (pgsql-ru-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-ru-general



--
// Dmitriy.


Re: pg_dump\pg_restore large objects

От
eshkinkot@gmail.com (Сергей Бурладян)
Дата:
Sergej Kandyla <sk@hlsrv.com> writes:

> Сергей Бурладян wrote:
> > Sergej Kandyla <sk@hlsrv.com> writes:

[вырезано]

> >> Бекап, сделанный при помощи tar format:
> >> pg_dump -Ft -b -f ${file} ${db}
> >> 870M    database.dump.tar
> >>     
> >
> > Это несжатый текст, LO в двоичном виде + текстовой файл со схемой данных.
> >   

> Не понял,  момента.
> Для переноса базы достаточно  одного из таких дампов.
> Из ваших слов выходит   что  -Ft -b  содержит дополнительые схемы данных,
> которые отсутствуют в бекапе  "-Fc -b"..

У custom формата есть таблица объектов (TOC) из которой pg_restore может построить схему данных на
лету. У tar формата она (TOC) тоже есть, плюс помимо неё в tar формате ещё лежит уже построенная
схема данных в текстовом виде, не знаю зачем, судя по всему это для обратной совместимости и чтобы
можно было его восстановить не используя pg_restore.

-- 
С уважением, Сергей Бурладян

Re: pg_dump\pg_restore large objects

От
Sergej Kandyla
Дата:
On 08.04.2011 22:17, Dmitriy Igrishin wrote:
....

Субьективные выводы:
1.  Не нашел почти никаких преимуществ в plain-text бекапах (кроме как цели руками его посмотреть)
  binary dump в сумме получается заметно быстрее и портабельнее, занимает меньше места.
  Перенастроил систему бекапов на этот формат.
Часто бывает полезным сравить два дампа вручную (например, git-diff(1)).

Согласен, сам так просматриваю. Однако, когда речь идет о блобах и многомегабайтных дампах,
полезность diff сравнения пропадает.
Вообщем, зависит от задачи.


2. Импорт бекапов нужно делать, только предварительно удалив и заново создав базу данных.
     (про pg_dump -С я знаю,  но считаю не очень портабельным, поэтому не использую).
Ещё бывает удобно переименовывать текущую (старую) версию БД
перед накатом новой версии:
ALTER DATABASE mydb RENAME TO mydb_old;
CREATE DATABASE mydb ...;
-- Команды создания объектов...


Да, удобно.
Исходя из практики девелопмента,  лучше сделать отдельную базу с отдельным логином и паролем,
чтобы никто из прогеров ничего не перепутал "случайно" ;)
Так сказать, повышенная дурако-устойчивость ;)


Спасибо за ответы!