MemcacheDB Quick Benchmarks
Рубрика: Development | 3 March 2010, 18:43 | Vadim Voituk
Эта заметка увидела свет в результате небольшого исследования, проведенного мною в процессе работы на оптимизацией проекта www.savevid.com и призвана поделиться моим скромным опытом миграции на key-value базы дынных (БД) . [Далее...]
MySQL: Slave could not parse relay log event entry
Рубрика: Development, MySQL | 17 September 2009, 10:09 | Vadim Voituk
При использованиии MySQL Master-Slave (или же Master-Master) репликации бывает ситуация что по разным причинам версия слейва ниже чем версия мастера.
Если при этом используется опция binlog_format=MIXED, в результате возможна ситуация когда мастер запишет в свой binlog запись вида:
BINLOG 'XMawShMEAAAARwAAAEp5UwUAAGkAAAAAAAAACHNhblahblahblah'
Которую слейв не сможет выполнить, ибо он ее попросту “еще не умеет”.
Первой ласточкой того, что это произошло станет сообщение “SLAVE DOWN” от мониторинговой системы и запись в MySQL-логе слейва сродни этой:
090917 14:55:51 [ERROR] Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 71, event_type: 19
090917 14:55:51 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O error
090917 14:55:51 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' o
n the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL
code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave. Error_code: 0
090917 14:55:51 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'bin-us1.000022' position 17007149
Попытки пропустить неугодные записи старым добрым методом:
slave stop;
set global sql_slave_skip_counter=1;
slave start;
в данном случае не помогают.
Как вариант решения предлагаю:
- Останавливаем slave: “SLAVE STOP;”
- “Выуживаем” из текста ошибки имя бинлога и позицию, на которой произошла ошибка.
В данном случае это bin-us1.000022 и позиция 17007149 - На мастере выполняем запрос “FLUSH LOGS;”
- Делаем дамп бинлога начиная с найденной позиции:
mysqlbinlog --start-position=17007149 bin-us1.000022 > bin-us1-from17007149.sql - Загружаем полученный дамп на слейве с ключем “–force”
mysql --force -uuser -ppassword database < bin-us1-from17007149.sql - Выполняем на слейве “FLUSH LOGS;”
- В data-директории находим relay-log с максимальным номером и размером около 100 байт (в моем случае это mysqld-relay-bin.000037)
- В той же директории в файле relay-log.info
первую строку заменяем на имя только что найденного relay-log-а, во вторую вписываем 0, в третью – следующий после “испорченного” бинлог, в четвертую – 0
Получится что-то вроде:
/var/lib/mysql/mysqld-relay-bin.000037
0
bin-us1.000023
0 - Дальше на слейве выполняем:
CHANGE MASTER TO MASTER_LOG_FILE='bin-us1.000023', MASTER_LOG_POS=0;
SLAVE START; - Ну и потом чтоб удостоверится что все “завелось”
SHOW SLAVE STATUS\G
Должно работать.
Подозреваю что пункты 4 и 5 можно обьеденить в один, более простой и элегантный.
Но как это сделать – не гуглил.
MySQL: Single row lock implementation
Рубрика: Development, MySQL | 24 June 2009, 16:01 | Vadim Voituk
При разработке приложений с использованием баз данных, часто возникает сценарий “insert if not exists”:
if ( <row exists in table> )
then <insert new record into table>
Из-за того, что данный блок псевдо-кода не выполяняется атомано, может возникнуть ситуация, когда между проверкой <row exists in table> и выполнением действия <insert new record> паралельный поток (клиент) выполнит добавление новой записи и в итоге в БД окажется 2 одинаковых записи (или произойдет ошибка “duplicate key”).
Такой, не самый приятный case, в книгах по паралельному программированию называют race condition и обходят путем создания синхронизирующих блокировок , использованием “выпрямителей” и тд.
[Далее...]
Using iptables to prevent SSH brute force
Рубрика: Development | 21 June 2009, 16:34 | Vadim Voituk
Себе на заметку, дабы потом опять не гуглить.
Эти 2 простых iptables-правила спасают сервер от brute force перебора пароля от SSH:
iptables -I INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsourceiptables -I INPUT -i eth0 -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 180 --hitcount 5 --name DEFAULT --rsource -j DROP
В результате те, кто делает более 5-ти попыток SSH-подключений за последние 3 минуты – блокируются на 3 минуты.
Для того, чтоб эти правила запускались при старте системы делаем dump rules-файла:
iptables-save > /etc/sysconfig/iptables
Apache Tomcat init.d script
Рубрика: Development, Java | 28 April 2009, 15:33 | Vadim Voituk
Продолжая серию заметок “Из программиста в руководители админы” :), опять же себе на заметку пишем init-скрипт для корректного запуска/перезапуска Apache Tomcat под Linux.
Создаем файл /etc/init.d/tomcat такого содержания:
# Tomcat auto-start
#
# chkconfig: - 90 15
# description: Jakarta Tomcat Java Servlets and JSP server
export JAVA_HOME=/usr/java/default
export JRE_HOME=/usr/java/latest
export CATALINA_HOME=/home/vadim/tomcat
case $1 in
start)
sh $CATALINA_HOME/bin/startup.sh
;;
stop)
sh $CATALINA_HOME/bin/shutdown.sh
;;
restart)
sh $CATALINA_HOME/bin/shutdown.sh
sh $CATALINA_HOME/bin/startup.sh
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
exit 0
После этого выполняем:
chmod +x /etc/init.d/tomcat
chkconfig tomcat on
Аналогичный init.d-скрипт для запуска nginx
Java + Groovy on Google App Engine
Рубрика: Development, Google, Groovy, Java | 8 April 2009, 08:30 | Vadim Voituk
Вот и свершилось то, чего так долго ждали и просили большевики прогрессивные ИТ-гики – Google добавляет поддержку Java (а вместе с ней и Groovy) в Google App Engine.
Как сообщает в корпоративном блоге SpringSource Guillaume Laforge (project-manager проекта Groovy), последние несколько недель они работали совместно с командой Google App Engine над “правильным” запуском Groovy на GAE.
Совмесная работа вылилась в набор дополнений в реализацию security-модели Groovy.
Небольшая заметка о том, как запустить Groovy приложение в среде Google App Engine от того же Guillaume Laforge.
P.S. Что-то мне подсказывает что теперь GAE перестанет быть игрушкой для питонистов, а станет упрощенной версией Amazon AWS, тем самым накорню убив остальные Java in Cloud – сервисы а-ля Stax.
MySQL: Archive Storage Engine
Рубрика: Development, MySQL | 13 March 2009, 20:56 | Vadim Voituk
Все очевидно, что любая современная информацонная система занимается хранением и анализом любого рода данных. Аналитики утверждают что в среднем, обьем этих данных для среднестатистичекой компании растет на 42% в год.
В результате проблема хранения этих данных постепенно приобретает бОльшую актуальность.
Из своего опыта работы с достаточно большими массивами данных, хранимых в современных реляционных СУБД (по большей части в MySQL) могу сказать что не менее 50% данных в любой системе – это данные которые представляют собой только “историческую” ценность. [Далее...]
Project closed. Lessons learned.
Рубрика: Development, Just a life, Работа | 11 March 2009, 11:26 | juriy
Вот и подошел к концу очередной абзац моего резюме. Проект, которым я руководил последние полтора года, закончен. Как минимум, закончена его разработка с нашей, аутсорсинговой стороны.
Работая на этом проекте, я вынес для себя несколько важных уроков. Этот опыт я добывал сам: некоторые уроки дались легко, другие вылились в потерянное время и нервы. Чтобы как-то прорезюмировать проект в целом: работа над ним была _нормальной_. Практически не было овертаймов, была хорошо налажена коммуникация с заказчиками и внутри компании все «рабочие моменты» решались на удивление быстро.
[Далее...]
nginx init.d script
Рубрика: Development | 9 February 2009, 19:41 | Vadim Voituk
Как-то так получилось что при установки nginx с исходников, в /etc/init.d/ не установился скрипт для автозапуска web-сервера.
Потому исключительно себе на заметку (знаю точно – пригодится ещё) публикую то, что удалось найти в сети и допилить напильником до рабочего состояния.
JavaScript applet loader.
Рубрика: Ajax, Development, Java | 6 February 2009, 13:50 | juriy
У каждого разработчика есть свои маленькие “заморочки” по поводу того как должно выглядеть приложение. Одна из моих любимых: пользователь должен знать минимум о том, как работает приложение и на каких технологиях оно построено. Взять, к примеру, Flash. Загружается тихонько в окне браузера, крутит пользователю картинки или видео и до тех пор, пока пользователь не начнет по нему кликать правой кнопкой, не признаЕтся кто он такой.
С другой стороны Java. Вот тебе пользователь раз логотип при загрузке апплета, да побольше, побольше, а если ты вдруг забыл про то, что работаешь с великой и могучей Java, мы тебе иконку в трей кинем, чтобы он тебе оттуда напоминал что пора качать новую версию.
Вобщем, вы мою позицию поняли.
Недавно я задался вопросом, как организовать загрузку апплета на странице так, чтобы пользователь не увидел экрана загрузки. Вместо него я бы хотел, к примеру, разместить логотип и progress bar (не настоящий, а просто картинку, которая показывает, что процесс идет). Второе обязательное требование: чтобы приложение отображалось, как только GUI прорисован. Мы не хотим заставлять пользователя ждать лишнее время.
[Далее...]
