- Короткие соединения: Ваше приложение открывает соединение, выполняет быстрый запрос и тут же его закрывает. В MySQL процесс (thread) исчезает сразу, но на уровне операционной системы соединение переходит в статус
TIME_WAIT. - Механизм TCP: После закрытия сессии ОС обязана удерживать соединение в
TIME_WAIT(обычно 60–120 секунд), чтобы убедиться, что все «заблудившиеся» пакеты данных дошли и не перемешались с новым соединением на тех же портах. - Отсутствие Connection Pooling: Если приложение не использует «пул соединений», оно создает новый TCP-хендшейк для каждого чиха. При высоком трафике эти «хвосты» копятся быстрее, чем ОС успевает их вычищать.
- На стороне приложения: Включите Persistent Connections (постоянные соединения) или настройте Connection Pool. Это позволит переиспользовать уже открытые каналы.
- На стороне ОС (Linux): Можно ускорить переиспользование портов, подправив параметры ядра в
/etc/sysctl.conf:net.ipv4.tcp_tw_reuse = 1— разрешает использоватьTIME_WAITсокеты повторно.
- Проверьте код: Убедитесь, что вы не закрываете соединение с базой внутри циклов.
TIME_WAIT 240 секунд (4 минуты). Это можно сократить до 30 секунд.- Путь в реестре:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters - Параметр (DWORD):
TcpTimedWaitDelay - Значение:
30(десятичное) - Требуется перезагрузка для вступления в силу.
- Через реестр:
- В том же разделе создайте/измените параметр MaxUserPort (DWORD).
- Установите значение до
65534(десятичное).
- Через командную строку (без перезагрузки):Это расширит диапазон динамических портов, позволяя ОС «переварить» большее количество одновременныхcmd
netsh int ipv4 set dynamicport tcp start=1025 num=60000Используйте код с осторожностью.TIME_WAITсоединений.
- В файле
my.ini(обычно вC:\ProgramData\MySQL\...) установите:wait_timeout = 300(5 минут вместо стандартных 8 часов).
Windows по умолчанию настроена на консервативную работу с сетью. Приложение на PHP/Python/.NET открывает TCP-порт к MySQL (порт 3306), делает запрос и закрывает сокет. Для MySQL работа окончена, процесс убит. Но стек TCP/IP в Windows обязан ждать
2MSL (максимальное время жизни сегмента), чтобы не возникло путаницы с данными, если новый клиент сразу займет тот же порт.TcpTimedWaitDelay начинает отсчет времени только после того, как соединение уже было закрыто обеими сторонами (приложением и базой данных).- Active: Выполняется запрос (процесс виден в MySQL).
- Closing: Приложение или сервер говорит «все, закончили» (процесс в MySQL исчезает).
- TIME_WAIT: Соединение фактически мертво, но ОС «бронирует» этот номер порта на всякий случай (защита от дубликатов пакетов из старой сессии).
Единственный риск — если сеть крайне медленная или нестабильная, и какой-то пакет данных «заблудился» в интернете/маршрутизаторах более чем на 30 секунд. Но в рамках локальной сети или одного сервера Windows это абсолютно безопасно.
За время жизни живого соединения отвечает параметр в MySQL:
wait_timeout(для спящих соединений);max_execution_time(для слишком долгих запросов).
- Нарушение целостности (крайне редко): Если сеть катастрофически тормозит, старый дубликат пакета может попасть в новую сессию. Современные протоколы (Sequence Numbers в TCP) это отсекают, так что приложение просто получит ошибку и переподключится.
- Ошибки подключения (Address already in use): Если вы ставите слишком маленькое время (например, 5-10 секунд) и при этом у вас бешеный поток запросов, порты могут не успевать очищаться. Но 30 секунд — это «золотой стандарт» для высоконагруженных систем.
- Ложные срабатывания фаерволов: Некоторые старые или параноидальные железные фаерволы могут решить, что вы пытаетесь манипулировать сессиями, если видите быстрое переиспользование портов.
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpTimedWaitDelay" -ErrorAction SilentlyContinue
- Если пусто (ошибка или пустая строка) — значит, параметр не задан и действует стандарт (240 сек).
- Если число есть — это ваше текущее значение в секундах.
- Нажмите
Win + R, введитеregedit. - Перейдите по пути:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters - Ищите в списке справа TcpTimedWaitDelay.
- Если его нет — у вас 240 секунд.
netstat -no | findstr TIME_WAIT
Если вы решили его добавить, выполните эту команду в PowerShell (от админа):
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "TcpTimedWaitDelay" -Value 30 -PropertyType DWORD -Force
192.168.0.10 открывает новый порт (53553, 53554, 53555...) для каждого мелкого чиха к базе на 192.168.0.9. Поскольку порты идут подряд, это происходит очень быстро — буквально десятки или сотни раз в секунду.- Нагрузка на CPU: Windows тратит ресурсы на постоянное создание и закрытие TCP-сокетов.
- Риск отказа: Если порты закончатся (дойдут до 65535), приложение получит ошибку «Не удалось открыть сокет» (Socket Error), хотя база MySQL будет абсолютно свободна.
- Лишний трафик: Каждое соединение — это «тройное рукопожатие» TCP (SYN, SYN-ACK, ACK), что добавляет задержку к каждому запросу.
Изменение
TcpTimedWaitDelay до 30 секунд поможет серверу быстрее «выбрасывать мусор», но не решит причину.- В коде приложения включить Persistent Connections (постоянные соединения).
- Вместо
mysql_connectиспользовать аналоги с поддержкой пула (например, в PHP этоp:localhost, в .NET/Java/Python это встроенные объектыPool).
- Кто «забивает» порты? Статус
TIME_WAITпоявляется на той стороне, которая первой инициировала закрытие TCP-сессии. Обычно это делает приложение после получения данных от базы. - Где дефицит портов? В вашем логе видно:
192.168.0.10:53553стучится на192.168.0.9:3306. Порт базы (3306) всегда один, а вот «исходящие» порты на машине приложения (53553, 53554...) уникальны. Именно они закончатся первыми, и приложение не сможет открыть новое соединение.
- На сервере приложения (
192.168.0.10):- Обязательно установите
TcpTimedWaitDelay = 30иMaxUserPort = 65534. Это позволит приложению быстрее переиспользовать свои исходящие порты. - Настройте Connection Pool в коде. Это сделает так, что вместо 8000 кратковременных соединений у вас будет, например, 50 «вечно живых».
TIME_WAITисчезнет сам собой.
- Обязательно установите
- На сервере MySQL (
192.168.0.9):- Здесь тоже полезно поставить
TcpTimedWaitDelay = 30, чтобы стек TCP/IP сервера базы не «раздувался» от тысяч записей о закрытых сессиях в оперативной памяти. - Проверьте в
my.iniпараметрmax_connections. Если приложение начнет использовать пул, это значение должно быть чуть выше, чем размер пула.
- Здесь тоже полезно поставить
Turn on your Visual Search History?
Google uses its visual recognition technologies to process the images you use to search, like when you search with Google Lens. If you turn on your Visual Search History, Google will save these images from eligible Google services to your Web & App Activity when you’re signed in to your Google Account. You can learn more about this setting and which Google services save images to it at g.co/Search/VisualSearchHistory.
How visual search history is used
Your Visual Search History may be used to improve your experience on Google services, like letting you revisit your past visual searches. It may be used to develop and improve Google’s visual recognition and search technologies, as well as the Google services that use them.
When visual search history is off
If you turn this setting off, any previous Visual Search History may still be kept and used to improve Google’s visual recognition and search technologies, unless you delete it from your Web & App Activity.
Visual Search History doesn’t affect images saved by other settings, like Gemini Apps Activity.
How to manage your Visual Search History
You can view, delete, or manage your Visual Search History at activity.google.com. To download your Visual Search History, visit takeout.google.com. Images will be deleted in accordance with your Web & App Activity auto-delete settings, although some types of images may be deleted sooner.
Google uses and saves data in accordance with Google Privacy Policy.
