Comments 18
sleep в скрипте — маскируемый race conditions. Так делать не надо. Что произойдёт, если gdb по какой-то причине потратит на чтение 3.1с?
Хорошее замечание. Я так и не нашел способа как делать надо.
Я давал сильную искусственную нагрузку на тестовый баунсер и измерял время. Больше секунды не получалось на моих серверах.
Было бы интересно узнать как делать правильней…
Я давал сильную искусственную нагрузку на тестовый баунсер и измерял время. Больше секунды не получалось на моих серверах.
Было бы интересно узнать как делать правильней…
Видимо, дело в gdb.
Хотя если бы эту задачу решал я, раз уж мы говорим про патчинг кода (а вызов функции в контексте gdb — это такой извращённый метод патчинга реального времени), то бы просто добавил в код postgre обработчик сигнала (любого неиспользуемого). По вызову сигнала дёргается функция, после чего выполнение продолжается.
После этого процесс передёргивания больше не будет ставить pgbounce раком на 3 секунды с шансом огрести race.
Хотя если бы эту задачу решал я, раз уж мы говорим про патчинг кода (а вызов функции в контексте gdb — это такой извращённый метод патчинга реального времени), то бы просто добавил в код postgre обработчик сигнала (любого неиспользуемого). По вызову сигнала дёргается функция, после чего выполнение продолжается.
После этого процесс передёргивания больше не будет ставить pgbounce раком на 3 секунды с шансом огрести race.
Задача была «не перезапускать сервис».
Была идея написать программку, которая коннектится с помощью ptrace() и дёргает эту функцию. Но gdb ведь делает всё красиво: call он вызывает в неком dummy-frame, а не в текущем. Я бы такое не осилил закодить. :)
Была идея написать программку, которая коннектится с помощью ptrace() и дёргает эту функцию. Но gdb ведь делает всё красиво: call он вызывает в неком dummy-frame, а не в текущем. Я бы такое не осилил закодить. :)
вот что отсутствие HUP делает
А вы правы :).
Наверное, правильней делать так:
при подключении gdb'ой нужно смотреть в каком контексте мы остановились (gdb это покажет последней строкой вывода), и если мы остановились на getaddrinfo(), то лучше отключиться от процесса и попытаться заново.
Наверное, правильней делать так:
при подключении gdb'ой нужно смотреть в каком контексте мы остановились (gdb это покажет последней строкой вывода), и если мы остановились на getaddrinfo(), то лучше отключиться от процесса и попытаться заново.
Кстати, забыл написать: вызов res_info() дёргает getaddrinfo() даже если gdb остановился в контексте getaddrinfo() и всё после этого нормально работает. :)
Я так понял, call завершает выполнение текущего контекста, после чего выходит в dummy-frame (контекст) и дёргает вызванную функцию.
В результате, ничего не ломается.
Осталось только понять как gdb останавливает программу при простом подключении, когда мы еще не поставили точку останова. Где он останавливает программу? В начале функции как при brake или где угодно?
Я так понял, call завершает выполнение текущего контекста, после чего выходит в dummy-frame (контекст) и дёргает вызванную функцию.
В результате, ничего не ломается.
Осталось только понять как gdb останавливает программу при простом подключении, когда мы еще не поставили точку останова. Где он останавливает программу? В начале функции как при brake или где угодно?
А не лучше ли будет использовать nscd? Он делает тот же самый res_init(), а getaddrinfo() будет обращаться к nscd. После правки resolv.conf чистим кеш и делаем nscd reload. Правда, установка nscd во FreeBSD требуется отдельно, насколько я понимаю.
Отличный комментарий.
Но мы тут подумали и решили, что в нашем случае прописывать «cache» для hosts в /etc/nsswitch.conf было бы не очень хорошо, так как это может не очень хорошо повлиять на работу некоторых наших сервисов на машине с pgbouncer. Но идея отличная.
Но мы тут подумали и решили, что в нашем случае прописывать «cache» для hosts в /etc/nsswitch.conf было бы не очень хорошо, так как это может не очень хорошо повлиять на работу некоторых наших сервисов на машине с pgbouncer. Но идея отличная.
nscd
работает для gethostbyname
, но не работает для getaddrinfo
.Я проверял на centos x86_64. Точно работает для getaddrinfo. Посмотрите код функции в glibc. Там есть макрос USE_NSCD.
FreeBSD, man nsswitch.conf:
Если в nsswitch.conf прописать 'cache' дял hosts, то будет работать.
hosts getaddrinfo(3), gethostbyaddr(3), gethostbyaddr_r(3),
gethostbyname(3), gethostbyname2(3), gethostbyname_r(3),
getipnodebyaddr(3), getipnodebyname(3)
Если в nsswitch.conf прописать 'cache' дял hosts, то будет работать.
Возможно, я неправильно понял, но этот способ работает только если целевая программа собрана с отладочной информацией, что далеко не всегда так.
Sign up to leave a comment.
Как вынудить процесс использовать новый адрес DNS-сервера из обновлённого resolv.conf без перезапуска самого процесса