Регулирование ввода / вывода в pg_dump postgres? - PullRequest
5 голосов
/ 05 октября 2010

Итак, у нас есть производственная база данных объемом 32 ГБ на машине с 16 ГБ ОЗУ. Благодаря кешированию это обычно не проблема. Но всякий раз, когда я запускаю pg_dump базы данных, запросы от серверов приложений начинают стоять в очереди, и через несколько минут очередь убегает, и наше приложение останавливается.

Я буду первым, кто признает, что у нас есть проблемы с производительностью запросов, и мы их устраняем. Между тем, я хочу иметь возможность запускать pg_dump по ночам, таким образом, чтобы глотать из базы данных и не закрывать наше приложение. Мне все равно, если это займет несколько часов. Наше приложение не запускает DDL, поэтому меня не беспокоит конфликт блокировки.

Пытаясь решить проблему, я запускаю pg_dump как с nice, так и с ionice. К сожалению, это не решает проблему.

nice ionice -c2 -n7 pg_dump -Fc production_db -f production_db.sql

Даже с ionice я все еще вижу проблему выше. Похоже, что ожидание ввода-вывода и множество попыток вызывают проблему.

vmstat 1 

Показывает, что Айовит колеблется около 20-25% и иногда достигает 40%. Реальный% CPU колеблется между 2-5% и иногда достигает 70%.

Я не верю, что замки - возможный преступник. Когда я запускаю этот запрос:

select pg_class.relname,pg_locks.* from pg_class,pg_locks where pg_class.relfilenode=pg_locks.relation;

Я вижу только те замки, которые отмечены как предоставленные = 't'. Обычно мы не запускаем DDL на производстве, поэтому проблемы с блокировками, похоже, не являются проблемой.

Вот вывод ps с включенным столбцом WCHAN:

PID WIDE               S TTY          TIME COMMAND
3901 sync_page         D ?        00:00:50 postgres: [local] COPY
3916 -                 S ?        00:00:01 postgres:  SELECT
3918 sync_page         D ?        00:00:07 postgres:  INSERT
3919 semtimedop        S ?        00:00:04 postgres:  SELECT
3922 -                 S ?        00:00:01 postgres:  SELECT
3923 -                 S ?        00:00:01 postgres:  SELECT
3924 -                 S ?        00:00:00 postgres:  SELECT
3927 -                 S ?        00:00:06 postgres:  SELECT
3928 -                 S ?        00:00:06 postgres:  SELECT
3929 -                 S ?        00:00:00 postgres:  SELECT
3930 -                 S ?        00:00:00 postgres:  SELECT
3931 -                 S ?        00:00:00 postgres:  SELECT
3933 -                 S ?        00:00:00 postgres:  SELECT
3934 -                 S ?        00:00:02 postgres:  SELECT
3935 semtimedop        S ?        00:00:13 postgres:  UPDATE waiting
3936 -                 R ?        00:00:12 postgres:  SELECT
3937 -                 S ?        00:00:01 postgres:  SELECT
3938 sync_page         D ?        00:00:07 postgres:  SELECT
3940 -                 S ?        00:00:07 postgres:  SELECT
3943 semtimedop        S ?        00:00:04 postgres:  UPDATE waiting
3944 -                 S ?        00:00:05 postgres:  SELECT
3948 sync_page         D ?        00:00:05 postgres:  SELECT
3950 sync_page         D ?        00:00:03 postgres:  SELECT
3952 sync_page         D ?        00:00:15 postgres:  SELECT
3964 log_wait_commit   D ?        00:00:04 postgres:  COMMIT
3965 -                 S ?        00:00:03 postgres:  SELECT
3966 -                 S ?        00:00:02 postgres:  SELECT
3967 sync_page         D ?        00:00:01 postgres:  SELECT
3970 -                 S ?        00:00:00 postgres:  SELECT
3971 -                 S ?        00:00:01 postgres:  SELECT
3974 sync_page         D ?        00:00:00 postgres:  SELECT
3975 -                 S ?        00:00:00 postgres:  UPDATE
3977 -                 S ?        00:00:00 postgres:  INSERT
3978 semtimedop        S ?        00:00:00 postgres:  UPDATE waiting
3981 semtimedop        S ?        00:00:01 postgres:  SELECT
3982 -                 S ?        00:00:00 postgres:  SELECT
3983 semtimedop        S ?        00:00:02 postgres:  UPDATE waiting
3984 -                 S ?        00:00:04 postgres:  SELECT
3986 sync_buffer       D ?        00:00:00 postgres:  SELECT
3988 -                 R ?        00:00:01 postgres:  SELECT
3989 -                 S ?        00:00:00 postgres:  SELECT
3990 -                 R ?        00:00:00 postgres:  SELECT
3992 -                 R ?        00:00:01 postgres:  SELECT
3993 sync_page         D ?        00:00:01 postgres:  SELECT
3994 sync_page         D ?        00:00:00 postgres:  SELECT

Ответы [ 2 ]

0 голосов
/ 06 октября 2010

Ваш вывод PS имеет несколько операторов UPDATE в состоянии «ожидания», которое все еще говорит о блокировках для меня (ваш тестовый запрос на блокировку в стороне).Я уверен, что иначе вы не увидите «ожидание» на выходе PS.Можете ли вы проверить, показывает ли этот запрос что-либо во время проблемы:

SELECT * FROM pg_stat_activity WHERE waiting;

(Вы не сказали, какую версию PostgreSQL вы используете, поэтому я не уверен, будет ли это работать.)

Если там что-то есть (то есть с ожиданием = ИСТИНА), тогда это проблема блокировки / транзакции.

0 голосов
/ 05 октября 2010
  1. Самый простой: вы можете регулировать pg_dump, используя pv .
  2. Сложнее: измените процедуру резервного копирования.Используйте, например:
        psql -c 'pg_start_backup()'
        rsync --checksum --archive /var/lib/pgsql /backups/pgsql
        psql -c 'pg_stop_backup()'
    
    Но позаботьтесь о том, чтобы вам также пришлось настроить непрерывное архивирование , чтобы все это работало, а все файлы WAL, созданные во время резервного копирования, хранились вдоль резервной копии файлов данных.
  3. Еще сложнее: Вы можете настроить реплицированную базу данных (например, доставка журналов ) на дополнительный дешевый диск и вместо резервного копирования производственной базы данных сделать резервную копию реплики.Даже если он будет отставать от некоторых транзакций, он в конечном итоге наверстает упущенное.Но перед началом резервного копирования проверьте, достаточно ли актуальна реплика.
...