Thread: pg_dump\pg_restore large objects
Всем привет. Слегка запутался с дампами и к своему позору обнаружил, что при обычном дампе (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 А на новой базе такой роли нету (или я умышленно хочу сделать для импортируемой базы другого владельца), как будет правильно поступать..? Я, конечно, понимаю, что при создании базы я указываю и владельца для нее, и весь импорт будет присвоен указанному владельцу, но все же. Спасибо!
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 > > А на новой базе такой роли нету (или я умышленно хочу сделать для импортируемой > базы другого владельца), > как будет правильно поступать..? Создать нужную роль, а потом её переименовать. Если такая роль уже есть и Вы хотите её изменить - то тут сложнее :) > Я, конечно, понимаю, что при создании базы я указываю и владельца для нее, и > весь импорт будет присвоен указанному владельцу, > но все же. -- С уважением, Сергей Бурладян
Сергей Бурладян 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 -С я знаю, но считаю не очень портабельным, поэтому не использую). Спасибо!
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»).
Указывая эту опцию: -c, --clean clean (drop) database objects before recreating3) Восстановление:
даже указывая опцию
-c, --clean, если база уже содержит данные, то импорт заканчивается ошибками.
pg_restore -c -d mydatabase db.dump
....
pg_restore: [archiver] could not create large object 16887
Если же базу данных предварительно грохнуть, и потом создать заново, то все ок.
Это что, фича такая?
Возможно, Вы предоставили мало информации об ошибке. Вообще, ключ -c
подразумевает что очищаемая база соответствует той, что в резервной
копии. Если они различаются — то часть объектов не будет удалена так как
удаляются только те объекты, которые есть в резервной копии.
я ожидал что будет нечто подобное как в мускиле, и вроде бы оно так и есть...
DROP TABLE...
CREATE TABLE...
Однако, если база уже была создана и содержала данные,
то ни дамп, сделанный посредством, pg_dump --clean ни pg_restore -c ... binary.dump
не отрабатывают корректно (проверял на разных PG серверах.).
Мне такое поведение не ясно.
Для консистентного импорта бекапа, нужно сначала базу грохнуть, потом создать заново
и тогда уже импортить. В этом случае порядок.
Хотя может такое поведение и вполне оправдано.
И это правильно, т.к. БД - по определению - каталог, содержимое
которого - суть объекты БД, которые не зависят от её имени.
Во время разработки бывает очень удобно импортировать дамп
в разные БД (например, чтобы выявить изменения с помощью
того или иного ПО, которые требуют 2 БД в разврёрнутом виде).
которого - суть объекты БД, которые не зависят от её имени.
Во время разработки бывает очень удобно импортировать дамп
в разные БД (например, чтобы выявить изменения с помощью
того или иного ПО, которые требуют 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 ...;
-- Команды создания объектов...
перед накатом новой версии:
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.
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. -- С уважением, Сергей Бурладян
On 08.04.2011 22:17, Dmitriy Igrishin wrote:
....
Согласен, сам так просматриваю. Однако, когда речь идет о блобах и многомегабайтных дампах,
полезность diff сравнения пропадает.
Вообщем, зависит от задачи.
Да, удобно.
Исходя из практики девелопмента, лучше сделать отдельную базу с отдельным логином и паролем,
чтобы никто из прогеров ничего не перепутал "случайно" ;)
Так сказать, повышенная дурако-устойчивость ;)
Спасибо за ответы!
....
Субьективные выводы:
1. Не нашел почти никаких преимуществ в plain-text бекапах (кроме как цели руками его посмотреть)
binary dump в сумме получается заметно быстрее и портабельнее, занимает меньше места.
Перенастроил систему бекапов на этот формат.Часто бывает полезным сравить два дампа вручную (например, git-diff(1)).
Согласен, сам так просматриваю. Однако, когда речь идет о блобах и многомегабайтных дампах,
полезность diff сравнения пропадает.
Вообщем, зависит от задачи.
2. Импорт бекапов нужно делать, только предварительно удалив и заново создав базу данных.
(про pg_dump -С я знаю, но считаю не очень портабельным, поэтому не использую).Ещё бывает удобно переименовывать текущую (старую) версию БД
перед накатом новой версии:
ALTER DATABASE mydb RENAME TO mydb_old;
CREATE DATABASE mydb ...;
-- Команды создания объектов...
Да, удобно.
Исходя из практики девелопмента, лучше сделать отдельную базу с отдельным логином и паролем,
чтобы никто из прогеров ничего не перепутал "случайно" ;)
Так сказать, повышенная дурако-устойчивость ;)
Спасибо за ответы!