Ця стаття є дзеркальною статтею машинного перекладу, будь ласка, натисніть тут, щоб перейти до оригінальної статті.

Вид: 11917|Відповідь: 0

[Зв'язок] Параметр MySQL max_connect_errors аналіз і уточнення сумнівів

[Копіювати посилання]
Опубліковано 08.04.2019 11:01:48 | | | |
Нещодавно через деякі особливі причини виник MySQL серверПОМИЛКА 1129 (00000): Хост 'xxx' заблоковано через численні помилки з'єднання. Розблокуйте за допомогою 'mysqladmin flush-hosts'Після вирішення проблеми, у процесі вивчення параметрів max_connect_errors, деякі суперечливі описи різних мережевих даних трохи збили мене з пантелику (щодо цієї помилки, головна причина в тому, що одна й та сама IP генерувала надто багато перерваних з'єднань з базою даних (що перевищує максимальне значення max_connect_errors) за короткий проміжок часу, і нижче наведено процес дослідження моїх проблем, аналізу проблем і роз'яснення сумнівів.
По-перше, я шукав інформацію в Інтернеті, багато з яких стверджують, що якщо кількість спроб введення пароля перевищує max_connect_errors змінних, MySQL блокує цей клієнтський логін, а потім знайшов офіційну інформацію про впровадження max_connect_errors, як показано нижче, MySQL 5.6/5.7 те саме
Якщо більше ніж стільки послідовних запитів на підключення від хоста перериваються без успішного з'єднання, сервер блокує цей хост від подальших з'єднань. Ви можете розблокувати заблоковані хости, очистивши кеш хостів. Для цього виведіть оператор FLUSH HOSTS або виконайте команду mysqladmin flush-hosts. Якщо з'єднання успішно встановлено менш ніж за max_connect_errors спроби після переривання попереднього з'єднання, кількість помилок для хоста знищується до нуля. Однак, коли хост заблоковано, очищення кешу є єдиним способом його розблокувати. За замовчуванням — 100.
Як показано вище, трансляція приблизно так: якщо сервер MySQL отримує послідовні запити від одного й того ж хоста, і всі ці послідовні запити перериваються без успішного встановлення з'єднання, коли сукупне значення цих послідовних запитів перевищує встановлене значення max_connect_errors, сервер MySQL блокує всі наступні запити від цього хоста. Я вірю, що коли ви побачите цю інформацію на початку, вас також атакуватимутьбагато послідовних запитів на підключення від хоста перериваються без успішного з'єднанняЗбентежено, насправді це тому, що підключення до бази даних перервано через аномалії в мережі. Я шукав таку інформацію в Інтернеті:
Здається, навколо цієї змінної існує плутанина. Він насправді не блокує хости через повторні неправильні паролі, а лише через перервані з'єднання через помилки мережі.
Тоді ми зможемо експериментувати і перевірити це самостійно, щоб з'ясувати, яка з них правильна. Створимо тестовий обліковий запис у базі MySQL, а потім встановлюємо змінну max_connect_errors на3.
Потім ми використовуємо іншу тестову машину для підключення до бази MySQL з неправильним паролем, як показано нижче, навіть якщо введені три попередні неправильні паролі, четвертий вхід не виявляє помилки.Тоді можна виключити, що ця змінна пов'язана з неправильним введенням пароля.
[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p
Введіть пароль:
ПОМИЛКА 1045 (28000): Доступ заборонено для користувача 'test'@'mytestlnx02' (використання пароля: ТАК)
[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p
Введіть пароль:
ПОМИЛКА 1045 (28000): Доступ заборонено для користувача 'test'@'mytestlnx02' (використання пароля: ТАК)
[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p
Введіть пароль:
ПОМИЛКА 1045 (28000): Доступ заборонено для користувача 'test'@'mytestlnx02' (використання пароля: ТАК)
[root@mytestlnx02 tmp]# mysql -h10.20.57.24 -utest -p
Введіть пароль:
ПОМИЛКА 1045 (28000): Доступ заборонено для користувача 'test'@'mytestlnx02' (використання пароля: ТАК)
[root@mytestlnx02 tmp] #
Насправді, якщо IP вводить неправильний пароль, MySQL записує його у таблиці host_cache під базою даних performance_schema. Він сукупно зафіксований у COUNT_AUTHENTICATION_ERRORS полях наступним чином:



Згідно з офіційною інформацією, галузь host_cache статистично вважається так:Засміченняпомилок з'єднання (оцінюваних на основі max_connect_errors системних змінних). Враховуються лише помилки при рукостисканні протоколу і використовуються лише для автентифікованих хостів (HOST_VALIDATED = ТАК).
SUM_CONNECT_ERRORS
Кількість помилок з'єднання, які вважаються «блокуючими» (оцінюються заmax_connect_errorsсистемна змінна). Враховуються лише помилки при рукостисканні протоколу, і лише для хостів, які пройшли валідацію (HOST_VALIDATED = ТАК).
MySQLКлієнту потрібно ініціювати триразовий протокол handshake для встановлення з'єднання з базою даних; зазвичай цей час дуже короткий, але коли з'являються аномалії мережі, тайм-аут та інші фактори, протокол handshake не може завершитися, MySQL має параметр connect_timeout — це час, коли сервер MySQL обробляє mysqld, чекаючи на встановлення з'єднання за секунди. Якщо протокольне рукостискання все ще не завершено після connect_timeout часу, клієнт MySQL отримає виключення з повідомленням про виключення, подібне на: Втрата з'єднання з MySQL сервером на 'XXX', системна помилка: ерно, змінна за замовчуванням встановлюється на 10 секунд:

Давайте побудуємо випадок, коли підключення до бази даних переривається через тайм-аут мережі, ми використовуємо команди netem і tc у Linux для моделювання затримки передачі мережі в складному середовищі, після наступних налаштувань, у цей момент від тестового сервера для доступу до сервера MySQL буде затримка 11 секунд:
[root@gettestlnx02 ~]# пінг 10.20.57.24
PING 10.20.57.24 (10.20.57.24) 56(84) байтів даних.
64 байти від 10.20.57.24: icmp_seq=1 ttl=62 час=0.251 мс
64 байти від 10.20.57.24: icmp_seq=2 ttl=62 часу=0.330 мс
64 байти від 10.20.57.24: icmp_seq=3 ttl=62 час=0.362 мс
64 байти від 10.20.57.24: icmp_seq=4 ttl=62 час=0.316 мс
64 байти від 10.20.57.24: icmp_seq=5 ttl=62 час=0.281 мс
64 байти від 10.20.57.24: icmp_seq=6 ttl=62 час=0.377 мс
^C
--- 10.20.57.24 ping статистика ---
6 переданих пакетів, 6 отриманих, 0% втрати пакетів, час 5716мс
RTT min/AVG/max/mdev = 0,251/0,319/0,377/0,047 мс
[root@gettestlnx02 ~]# tc qdisc add dev eth0 root netem delay 11000ms
[root@gettestlnx02 ~]# пінг 10.20.57.24
PING 10.20.57.24 (10.20.57.24) 56(84) байтів даних.
64 байти з 10.20.57.24: icmp_seq=1 ttl=62 час=11000 мс
64 байти від 10.20.57.24: icmp_seq=2 ttl=62 час=11000 мс
64 байти від 10.20.57.24: icmp_seq=3 ttl=62 час=11000 мс
64 байти від 10.20.57.24: icmp_seq=4 ttl=62 час=11000 мс
64 байти з 10.20.57.24: icmp_seq=5 ttl=62 час=11000 мс
64 байти з 10.20.57.24: icmp_seq=6 ttl=62 час=11000 мс
64 байти від 10.20.57.24: icmp_seq=7 ttl=62 час=11000 мс


Ми підключаємося до бази даних MySQL на тестовому сервері gettestlnx02, як показано нижче (зверніть увагу, що якщо ви підключаєтеся до цього сервера через ssh, наразі роботу на gettestlnx02 буде досить повільно). Звісно, можна також імітувати затримку мережі на MySQL сервері або зменшити і connect_timeout, і мережеву затримку)
[root@gettestlnx02 ~]# mysql -h10.20.57.24 -utest -p
Введіть пароль:
ПОМИЛКА 2013 (HY000): Втрата з'єднання з MySQL сервером на 'reading authorization packet', системна помилка: 0
[root@gettestlnx02 ~] #
Як показано вище, через затримку мережі понад 10 секунд з'єднання з MySQL не впало, і в цей момент, коли ви запитуєте таблицю host_cache на сервері MySQL, ви побачите, що SUM_CONNECT_ERRORS став 1, і COUNT_HANDSHAKE_ERRORS також змінився1.


Потім ми кидаємо так три рази і знову, і ви побачите, що SUM_CONNECT_ERRORS стає 3, а COUNT_HANDSHAKE_ERRORS — 3.
Потім ми використовуємо команди netem і tc, щоб скасувати симуляцію затримки мережі на тестовому сервері, а потім переходимо до тестового з'єднання з базою даних MySQL, як показано у наступному тесті:
[root@gettestlnx02 ~]# tc qdisc del dev eth0 root netem delay 11000ms
[root@gettestlnx02 ~]# mysql -h10.20.57.24 -utest -p
Введіть пароль:
ПОМИЛКА 1129 (HY000): Хост '192.168.27.180' заблоковано через численні помилки з'єднання; Розблокуйте за допомогою 'mysqladmin flush-hosts'
[root@gettestlnx02 ~] #


На даний момент його можна побудуватиПОМИЛКА 1129 (HY000): Хост '192.168.27.180' заблоковано через численні помилки з'єднання; Розблокуйте за допомогою 'mysqladmin flush-hosts'Ні.
рішення
Вирішено ПОМИЛКУ 1129 (00000): Хост 'xxx' заблоковано через численні помилки з'єднання. Існує багато способів отримати помилку Unblock за допомогою 'mysqladmin flush-hosts', але деякі з них тимчасові. Тимчасовий план полягає в тому, що індикатори не вирішують корінну причину. Ключ — усунути мережеві помилки (які часто потребують консультації з мережевими адміністраторами або системними адміністраторами)
Обхідний шлях:
1, встановіть значення змінної max_connection_errors на більше значення

Це тимчасове рішення є лише умовою затримки, що забороняє IP, і у складних випадках або з високою паралелізацією необхідно встановити велике значення, інакше воно легко буде активовано знову. Крім того, змінні діють лише на поточне середовище і втрачають чинність, якщо їх перезапустити.
2: використанняФлеш-хости
MySQL> Flush-хости;
Запит OK, 0 рядків торкнуто (0,00 сек)
mysql> вибрати * з performance_schema.host_cache;
Порожній набір (0,00 сек)
mysql>
Звісно, ви також можете скористатися командою mysqladmin flush-hosts для очищення інформації кешу хостів
[root@DB-Server ~]# mysqladmin --port=3306 -uroot -p flush-host
Введіть пароль:
То що таке кеш хостів? Офіційний вступ виглядає так:
Сервер MySQL зберігає кеш хоста в пам'яті, який містить інформацію про клієнтів: IP-адресу, ім'я хоста та інформацію про помилки. Сервер використовує цей кеш для нелокальних TCP-з'єднань. Кеш не використовується для TCP-з'єднань, встановлених за допомогою адреси інтерфейсу loopback (127.0.0.1 або ::1), або для з'єднань, встановлених за допомогою файлу Unix socket, іменованої труби або спільного пам'ять.
Простими словами, MySQL сервер зберігає кеш у пам'яті, що містить інформацію про клієнта: IP-адресу, ім'я хоста, повідомлення про помилку тощо. Сервер кешує інформацію про нелокальне TCP-з'єднання. Він не кешує TCP-з'єднання, створені за допомогою адрес інтерфейсу loopback (127.0.0.1 або ::1), або з'єднання, здійснені за допомогою файлів сокетів Unix, іменованих конвеєрів або спільної пам'яті. Інформацію кешу хоста можна запитувати через таблицю host_cache у базі даних performance_schema.
3: Встановіть змінну host_cache_size як0
Насправді, я б сказав, що це найменш надійне рішення — щоб MySQL сервер не реєстрував інформацію про кеш хоста. Цей метод можна повністю ігнорувати.








Попередній:Яка причина блокування акаунта при вході на цій сторінці?
Наступний:@MappedSuperclass використання анотувань
Застереження:
Усе програмне забезпечення, програмні матеріали або статті, опубліковані Code Farmer Network, призначені лише для навчання та досліджень; Вищезазначений контент не повинен використовуватися в комерційних чи незаконних цілях, інакше користувачі несуть усі наслідки. Інформація на цьому сайті надходить з Інтернету, і спори щодо авторських прав не мають до цього сайту. Ви повинні повністю видалити вищезазначений контент зі свого комп'ютера протягом 24 годин після завантаження. Якщо вам подобається програма, будь ласка, підтримуйте справжнє програмне забезпечення, купуйте реєстрацію та отримайте кращі справжні послуги. Якщо є будь-яке порушення, будь ласка, зв'яжіться з нами електронною поштою.

Mail To:help@itsvse.com