Доброго времени суток. Нужен совет. Есть сайт, бд которого валиться в аут от зажатия ctrl+f5 примерно за две минуты. На хостинге защиты от подобного флуда нет, хотя и стоит freebsd админы говорят, что iptables на сервере нет. в логах долгих запросов нет - проверял, время обработки всех запросов 0 секунд, иногда проскакивает 1 сек. вот это самый долгий: [sql]# Query_time: 1 Lock_time: 0 Rows_sent: 6 Rows_examined: 112 SELECT a.* FROM `advertisment` a LEFT JOIN `adv_cats` ac ON a.id = ac.adv_id WHERE ac.cat_id IN (0, 1) AND type = '5' ORDER BY RAND();[/sql] Собственно нужен совет - что делать, писать / использовать готовые решения по скриптовой блокировке такого спама (т.е. количество запросов к сайту в секунду, больше какого то - блокировать по ip) или еще какие то варианты. И сколько запросов в секунду с ip считается нормой? Пока просто нагуглил совет блочить, если запросов больше 10, но вдруг кто нить знает где находится более менее подробное руководство. Параллельно попробую еще кэширование некоторых запросов сделать.
Мысли в слух: то же самое на своем компе с локальным сервером пробовал сделать - никой ктрл+ф5 сайт (локальную версию) не укладывает....
просто я вообще хз в какую сторону копать.... на локальном сервере у меня не падает бд, на хостинге Dedicated server: (lw) Athlon 64 3000+ / 1GB / 160GB / 100mbs / 5000GB / FreeBSD 8.x 32bit / Webmin+Virtualmin бд валиться, хотя судя по параметрам не должна. Запросы из логов с долгим временем выполнения при ручном вводе через phpmyadmin выполняются максимум за 0.0150 с. - это самые большие, а так 0,009 - 0,020 с.
вот кусок переписки заказчиков (я код взялся поправить) и админов сервера: заказчик: Сейчас и вовсе не открывается сайт, сначало выдало ошибку Warning: mysql_connect() [function.mysql-connect]: User mdova already has more than 'max_user_connections' active connections in /usr/home/mdova/public_html/classes/DataBase/Class.php on line 24 MySQL Error! Name: NoConnection. MySQL answer: User mdova already has more than 'max_user_connections' active connections. а затем и вовсе все исчезло Данные не получены Невозможно загрузить веб-страницу, так как не поступили данные от сервера. Вот несколько советов и рекомендаций: Обновите эту страницу позже. Ошибка 324 (net::ERR_EMPTY_RESPONSE): Сервер разорвал соединение, не отправив данные. в чем проблема??? Что там случилось с сайтом? админ: Сервер упирается в диск. В mysql зависают запросы mysql> show processlist; +------+-------+-----------+-------+---------+------+----------------+----------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +------+-------+-----------+-------+---------+------+----------------+----------------------------------------------------------------------+ | 6080 | mdova | localhost | mdova | Query | 43 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6081 | mdova | localhost | mdova | Query | 43 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6087 | mdova | localhost | mdova | Sleep | 29 | | NULL | | 6092 | root | localhost | NULL | Query | 0 | NULL | show processlist | | 6094 | mdova | localhost | mdova | Sleep | 25 | | NULL | | 6096 | mdova | localhost | mdova | Sleep | 25 | | NULL | | 6097 | mdova | localhost | mdova | Sleep | 25 | | NULL | | 6099 | mdova | localhost | mdova | Query | 31 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6100 | mdova | localhost | mdova | Sleep | 24 | | NULL | | 6102 | mdova | localhost | mdova | Query | 27 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6103 | mdova | localhost | mdova | Sleep | 24 | | NULL | | 6105 | mdova | localhost | mdova | Query | 27 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6109 | mdova | localhost | NULL | Sleep | 24 | | NULL | | 6110 | mdova | localhost | mdova | Query | 24 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6113 | mdova | localhost | mdova | Query | 22 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6114 | mdova | localhost | mdova | Query | 22 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6115 | mdova | localhost | mdova | Query | 22 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6116 | mdova | localhost | mdova | Query | 22 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6117 | mdova | localhost | mdova | Query | 22 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6118 | mdova | localhost | mdova | Sleep | 22 | | NULL | | 6119 | mdova | localhost | mdova | Query | 22 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6120 | mdova | localhost | mdova | Query | 20 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6121 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6122 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6123 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6124 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6125 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6126 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 6127 | mdova | localhost | mdova | Query | 21 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 7577 | mdova | localhost | mdova | Query | 1 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | | 7593 | mdova | localhost | mdova | Query | 1 | Writing to net | Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") | +------+-------+-----------+-------+---------+------+----------------+----- Что является причиной ошибки User mdova already has more than 'max_user_connections' active connections in этот запрос я переделал немного, хотя он и так не сильно грузил при проверочном запросе, виснуть бд стала на другом (который в первом посте), хотя опять же сами по себе запросы вроде как не сильно грузящие должны быть, и на локальном сервере работают без проблем. Если с запросом Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") сайт выдавал ошибку что максимум подключений к бд, до тех пор пока через myadmin не убьешь лишние запросы (он как ни странно работает), то сейчас где то минуту - две - три подвисает т.е. не выдает сайт пользователю, просто идет загрузка, так же как и идет загрузка пхпмайадмина, а затем начинает нормально работать. т.е. прорабатывает запросы. ОС - FreeBSD 8.1-RELEASE (GENERIC) #0: Mon Jul 19 02:55:53 UTC 2010 могу выложить настройки mysql, полные или только если какие то отдельные пункты нужны
теперь еще интереснее... 404 Not Found nginx/1.0.5 через ssh mysql> show processlist; +-------+-------+-----------+-------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-------+-------+-----------+-------+---------+------+-------+------------------+ | 64578 | root | localhost | NULL | Query | 0 | NULL | show processlist | | 64591 | mdova | localhost | mdova | Sleep | 0 | | NULL | +-------+-------+-----------+-------+---------+------+-------+------------------+ 2 rows in set (0.00 sec)
mysql> show processlist; +-------+-------+-----------+-------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-------+-------+-----------+-------+---------+------+-------+------------------+ | 64960 | root | localhost | NULL | Query | 0 | NULL | show processlist | | 65293 | mdova | localhost | mdova | Sleep | 0 | | NULL | | 65294 | mdova | localhost | mdova | Sleep | 0 | | NULL | +-------+-------+-----------+-------+---------+------+-------+------------------+ 3 rows in set (0.00 sec) mysql> show processlist; +-------+-------+-----------+-------+---------+------+----------------+-------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +-------+-------+-----------+-------+---------+------+----------------+-------------------------------------+ | 64960 | root | localhost | NULL | Query | 0 | NULL | show processlist | | 65294 | mdova | localhost | mdova | Query | 0 | Writing to net | Select * FROM category WHERE id='1' | | 65295 | mdova | localhost | mdova | Sleep | 1 | | NULL | +-------+-------+-----------+-------+---------+------+----------------+-------------------------------------+ 3 rows in set (0.00 sec) mysql> show processlist; +-------+-------+-----------+-------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-------+-------+-----------+-------+---------+------+-------+------------------+ | 64960 | root | localhost | NULL | Query | 0 | NULL | show processlist | | 65296 | mdova | localhost | mdova | Sleep | 0 | | NULL | +-------+-------+-----------+-------+---------+------+-------+------------------+ 2 rows in set (0.00 sec) В браузере 404, в консоли такая вот картина, т.е. какие то запросы обрабатываются, только вот откуда они хз. или в очередь ставится или что.
индексы есть на таблицах? тип таблиц? на myisam на битых индексах тормозить будет жутко. и 20 коннектов для mysql ниочем.
индексы есть, насчет битых проверю. в настройках скуля стояло wait_timeout 28800, поменяли на 30 - соединений висящих в бд нет, но сайт валится все равно, что теперь непонятно. хотя поднимается быстрее. max_connections стоит равным 100 таблицы сейчас попробую прогнать.
CHECK TABLE для всех таблиц выдал ОК в логан никса error.log только то, что не хватает нескольких изображений.
Select * FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d") этот запрос я на count() уже переделал, он только получал количество объявлений за сегодня. в лог мскуля выводятся все запросы, дальше уже по времени ищу, медленных сейчас нет. Точнее вчера не было, сегодня не проверял. На сервере с каждым днем интереснее, то сам хостинг лежит, то апач падает из - за зависших запросов. Вчера кто то всю базу объявлений, как раз таблицу advert грохнул. Конкретно по таблице адверт - большая, будет еще большая, планируемая нагрузка 15 - 30к новых объявлений в день. CREATE TABLE `adverts` ( `id` int(11) NOT NULL auto_increment, `id_category` int(11) NOT NULL, `title` text NOT NULL, `text` text NOT NULL, `date` varchar(20) NOT NULL, `price` varchar(100) default NULL, `curency` char(10) default NULL, `id_city` int(11) NOT NULL, `id_user` int(11) NOT NULL, `check` int(11) default NULL, `on_off` int(11) NOT NULL, `vip` int(11) NOT NULL, `color` int(11) NOT NULL, `look` varchar(255) default '0', `data_click` text NOT NULL, `video` text NOT NULL, `left` varchar(255) NOT NULL, `right` int(11) NOT NULL, `vip_date` char(10) NOT NULL, `foto` int(11) NOT NULL, `parse` int(1) NOT NULL default '0', `old_num` char(20) NOT NULL, `upkol` int(5) NOT NULL, `original_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `original_id` (`original_id`), KEY `date` (`date`), KEY `vip` (`vip`), KEY `on_off` (`on_off`), KEY `id_category` (`id_category`), KEY `check` (`check`) ) ENGINE=MyISAM AUTO_INCREMENT=29823 DEFAULT CHARSET=cp1251 PACK_KEYS=0;
она у тебя при поиске ВСЮ таблицу лопатит. Чем больше будет объявлений тем хуже будет. ТЫ подумай над изменнием структуры. это 100% жопа. почему у тебя unixtime как varchar(20) сдается мне, что при таком подходе НЕ МУДРЕНО, что у тебя там все раком встает. как индексы не строй по текстовым полям =) с преобразованием из текста в int и обратно в текст... ваще ипануться... в общем в таком состоянии БД - стоять раком - ее нормальное состояние.
горе от ума. не надо в условии where использовать функции на поля. Так действительно будет всегда полный перебор. что мешает хотя бы вычислить текущую дату и писать where date='2011-11-11' ?
Ну во первых это все таки не совсем у меня. Меня взяли поправить запросы к бд в фильтрах объявлений, т.к. там на первом же фильтре падала бд. Ну а дальше пошло поехало. Проверять структуру бд как то в голову не приходило, да и заказчик на это внимания не обращал. в данный момент запрос вот так выглядит: Select count(*) as count FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d"). У меня была мысль что надо бы поменять поля, в частности `check` int(11) default NULL, имеет всего три значения 0,1,2 и таких большинство, но решил что фиг с ним, точнее руки просто не дошли. Займусь тогда изменением структуры, только как бы весь сайт тогда не грохнулся.
Кто админит я хз. Хостинг заказчики брали до меня. Сейчас кстати админы сказали что обновили днс и вместо сайта красуется Warning: mysql_connect() [function.mysql-connect]: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (61) Всего навсего на сервер хостера идет ддос атака. Это админы отписали. Кстати заказчик интересуется где можно взять нормальный хостинг с каналом в 1 гб и сколько это будет стоить, никто не в курсе?
При правке типов полей перестает работать выборка по объявлениям... Вопрос: в чем разница между [sql]Select count(*) as count FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d"). [/sql] и PHP: <?php $stTime = mktime(0, 0, 0, date("m") , date("d"), date("Y")); $endTime = mktime(23, 59, 59, date("m") , date("d"), date("Y")); $f = mysql_query('Select count(*) as count FROM adverts WHERE `date` between '.$stTime.' and '.$endTime.''); ?>
поменять тип date на int(11). он же строковый сейчас и between не покатит. date >= $st and date <= $en
мы арендуем 3 сервера на 1Г в разных конторах. 1Г честный. Проверяли. в пн. спрошу у админов конторы и стоимость.
Уже не требуется. Во всяком случае пока. 1. Убрал обращение к сайту погоды при каждом открытии сайта. 2. Заказчик на 5 минут заказал ддос сайта конкурентов и предупредил что если не угомонятся то будет не 5 минут. Второй день полет нормальный. Остается вопрос: Вопрос: в чем разница между [sql]Select count(*) as count FROM adverts WHERE CURDATE()=FROM_UNIXTIME(date,"%Y-%m-%d"). [/sql] и PHP: <?php $stTime = mktime(0, 0, 0, date("m") , date("d"), date("Y")); $endTime = mktime(23, 59, 59, date("m") , date("d"), date("Y")); $f = mysql_query('Select count(*) as count FROM adverts WHERE `date` between '.$stTime.' and '.$endTime.''); ?> *не заметил ответ вверху*