Итак, у нас есть производственная база данных объемом 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