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;

в данном случае не помогают.

Как вариант решения предлагаю:

  1. Останавливаем slave: “SLAVE STOP;”
  2. “Выуживаем” из текста ошибки имя бинлога и позицию, на которой произошла ошибка.
    В данном случае это bin-us1.000022 и позиция 17007149
  3. На мастере выполняем запрос “FLUSH LOGS;”
  4. Делаем дамп бинлога начиная с найденной позиции:
    mysqlbinlog --start-position=17007149 bin-us1.000022  >  bin-us1-from17007149.sql
  5. Загружаем полученный дамп на слейве с ключем “–force”
    mysql --force -uuser -ppassword database < bin-us1-from17007149.sql
  6. Выполняем на слейве “FLUSH LOGS;”
  7. В data-директории находим relay-log с максимальным номером и размером около 100 байт (в моем случае это mysqld-relay-bin.000037)
  8. В той же директории в файле relay-log.info
    первую строку заменяем на имя только что найденного relay-log-а, во вторую вписываем 0, в третью – следующий после “испорченного” бинлог, в четвертую – 0
    Получится что-то вроде:
    /var/lib/mysql/mysqld-relay-bin.000037
    0
    bin-us1.000023
    0
  9. Дальше на слейве выполняем:
    CHANGE MASTER TO MASTER_LOG_FILE='bin-us1.000023', MASTER_LOG_POS=0;
    SLAVE START;
  10. Ну и потом чтоб удостоверится что все “завелось”
    SHOW SLAVE STATUS\G

Должно работать.
Подозреваю что пункты 4 и 5 можно обьеденить в один, более простой и элегантный.
Но как это сделать – не гуглил.

Code WTF: JavaScript HTML entities

Рубрика: JavaScript/Ajax, Юмор | 2 July 2009, 10:49 | Vadim Voituk

Извините за “неформат” для данного блога, но не смог удержаться.
Вот так вот мой “юннат” реализует замену html-entities на JavaScript:


function properHtmlFromText(text){
	while (text.search(/\</) != -1)
		text = text.replace(/\</, '&lt;');
	while (text.search(/\&/) != -1)
		text = text.replace(/\&/, '&amp;');
	while (text.search(/\r/) != -1)
		text = text.replace(/\r/, '');
	while (text.search(/\n/) != -1)
		text = text.replace(/\n/, '<br />');
	return text;
}

Как увидел – плакал…
Наверное все-таки будем возобновлять ежедневные code-review…

P.S. В комментариях предлагаю поделиться “правильным” решением :)

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

Mac OS X: Few Usefull Max OS hints

Рубрика: Mac OS X | 11 June 2009, 09:54 | Vadim Voituk

За почти 2 месяца иcпользования MacBook и Mac OS X скопилось несколько полезных советиков, коими и спешу поделиться. Все tips&tricks были честно найдены в глобальной сети и опробованы на себе.

  1. Nokia E50 Не хочет коннектиться по Bluetooth (точнее коннектится, но быстро отваливается).
    Удаляем файл, в котором хранятся bluetooth-профайлы устройств
    rm /Library/Preferences/com.apple.Bluetooth.plist и перенастраиваем коннект с мобильным гаджетом заново.
    Лично у меня 2-ждый такой трюк провернуть не удалось – проблема первый раз решилаcь, а повторно -уже не помогло.

  2. Когда-то я жаловался на отсутствие hotkey-я для максимизации/оптимизации текущего окна. Так вот действие для “зеленой кнопки максимизации”  в большинстве Mac OS приложениях называется “Zoom” и находится в меню View.
    Чтоб назначить горячую клавишу на это действие открываем:
    System Preferences → Keyboard and Mouse → Keyboard Shortcuts Далее в разделе "Application Keyboard Shortcuts → All Applications" добавляем такую запись:
    Zoom
    (в данном случае, я выбрал shortcut Command+Shift+M )

  3. В Finder в “Column mode” по дефолту колонки очень узкие, а после изменения и закрытия окна – их размеры не сохраняются.
    Решается просто: Если изменить ширину колонки при этом зажав “Option” – новый размер станет стандартным.
    Как сделать ширину auto-adjustable – я так и не нашел.
  4. Для того чтоб в заголовке окон Finder показывать полный путь к открытой директории (например “/home/vadim/Desktop” вместо простого “Desktop”), нужно в терминале выполнить:
    defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES; killall Finder
    ну и соответственно заменить YES на NO чтоб показывать “короткий” путь.
    Выглядит это так:
  5. При коннекте по SSH на Ubuntu/Debian линуксы, в оболочке screen не работает BackSpace (и мапинг Ctrl+H не спасает)
    Решение: Необходимо перед запуском установить переменную окружения TERM=screeen.
    В приниципе можно в .bashrc назначить alias:
    alias screen='TERM=screen screen'

  6. И еще несколько мелких советов, которые я почерпнул с твиттера @okertanov

    1. Shift-Minimize button – нууууу очень медленнноооое сворачивание окна в док
    2. Смена дефолтного браузера на Маке происходит через Safari → Preferences → Default Web Browser
    3. Alt-Shift-K = “символ яблочко” 
  7. Чтоб сменить unix-имя пользователя Max OS X (ну и заодно имя home-директории) нужно
    1. Включить root-пользователя, залогиниться под ним
    2. Переименовать home-директорию (For ex:  $ mv /Users/admin /Users/vadim)
    3. Через System Preferences → Accounts создать пользователя с желаемым именем, совпадающим с новым именем home-директории
    4. Согласиться с предупреждением, что существующая home-директория будет назначена новому пользователю.
    5. Залогиниться под новым пользователем, проверить все ли ок, удалить старого пользователя
    6. Отключить root-а

В прицнипе пока все, по мере возможности буду пополнять список.

Mac OS X: Home/End/etc in Terminal.app

Рубрика: Mac OS X | 7 May 2009, 22:59 | Vadim Voituk

Мне кажется, Mac OS X  – является популярной ОС среди разработчиков, в большинстве своем потому, что она внутри все-таки *nix.  Хоть и “облагороженный” до уровня домохозяйки, – но все-таки *nix.
А какой же *nix без терминала, aka-консоли?
Вот и у меня, знакомство с новым MacBook-ом началось именно с терминала. Но к сожалению очень быстро обнаружилось, что в bash, запущенном внутри Terminal.app  не работают клавиши Home / End (в случае MacBook – это Fn+LeftArrow / Fn+RightArrow),  а также Ctrl+LeftArrow / Ctrl+RightArrow для перемещения на слово вперед/назад.

Google выдает огромное количество советов, как это исправляется, но 99% тех, что я перепробовал решали проблему в локальном терминале, и не решали при удаленном подключении из него.

Единственное рабочее решение, которое заработало и локально и remote-но, выглядит так:

  1. Открываем Preferences приложения  Terminall.app
  2. Переходим на закладку Settings => Keyboard
  3. Для Home/End добавляем в список такие записи:
    picture-20 picture-27

    (для вставки \033 нужно в поле ввода нажать Esc)
  4. Аналогичным образом, для реализации переещения вправо-влево с шагом в одно слово используются комбинации \033b и \033f

Вуаля! – и жизнь вне Windows постепенно налаживается :)

На более новых версиях Mac OS X, согласно совету приведенному тут, можно попробовать  комбинации \033OH и \033OF.

Этой заметкой я постараюсь открыть в блоге серию небольших Tips&Tricks, основанных на собственном опыте и относящихся к использованию MacBook и Mac OS X.

Следующей заметкой хочу рассказать, как в Java Swing приложение добавить немного Mac OS X специфичного внешнего вида и поведения. Это кому-то вообще интересно? Или банальщина и не стоит даже напрягаться?

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.

Продам свой Dell XPS 1330 (ПРОДАНО!)

Рубрика: Just a life | 7 April 2009, 23:15 | Vadim Voituk

В связи с переходом на MacBook, неспешно продам свой ноутбук Dell XPS 1330.

Конфигурация:

Intel Core 2 Duo T5550 / 2GB RAM / 160Gb HDD / NVidia GeForce 8400 128MB / 13.3″ (1280×800) / 1.9 кг веса / DVDRW+CardReader+BT+etc
(вроде такой как тут, только красный)

Фото: можно поглядеть тут

Состояние: отличное, проблем и дефектов нет

Комплектация: все включено (коробки, международная гарантия 2.5 года,  сумка, пульт ДУ, и тд)

Из опыта личного пользования:

  • очень неплох в плане производительности
  • достойное качество сборки (нигде даже не поскрипывает)
  • мягкая приятная клавиатура (пересев на хваленую Мак-овскую – разницы не почувствовал)
  • баттарея 3.5 часа при нагрузке чуть выше средней
  • производительность графики не тестировал (в игры не играю), но Vista рисуется быстро и красиво

На все вопросы отвечу тут или в skype.

MacBook – my first impressions

Рубрика: Mac OS X | 3 April 2009, 16:26 | Vadim Voituk

… или MacOS for dummies extra dummies.
Где-то недели полторы-две назад твердо решил приобрести модный нынче програмистско-дизайнерский гаджет – MacBook.
Позавчера мой гаджет приехал в Киев и о первых своих впечатлениях в тезисной форме хочу поделиться здесь:
  • У меня на Маке нет русских букв. С одной стороны это хорошо (давно хотел научиться методу ПОЛНОСТЬЮ слепого набора), с другой – как бы не вызвало неудобств (ведь пока же не научился).
    Так что если где-то встретится глупая опечатка – не обезсудьте.
  • Для начала я был очень удивлен размером коробки. Когда-то видел коробку от МакБукПро – ожидал чего-то аналогичного. На самом деле упаковка очень компактная, раза в 4 меньше коробки от моего DELL.
  • Тачпад – просто огромный! Еще и с мультитачем: скролирование двумя пальцами – меня просто покорило.
    Единственное НО – в отличии от большинства ноутбуков, которые мне приходилось видеть, тут нажатие на тачпад должно завершаться  характерным щелчком – “кликом” (как будто на кнопку нажал) – в принципе удобно  (почему еще никто не слямзил?), но со временем щелканье в полной тишине начинает напрягать. Также когда рядом стоит DELL – тут либо начинаешь на нем продавливать тачпад, либо делать легкий “touch” на Маке.
    Спасибо Keith, за то что, пояснил почему тачпад не touch-ается, а-то чувствую, я бы до сих пор сидел и горевал что мне брак попался :)
  • Очень маленькие стрелки навигации (вверх-вниз-вправо-влево) – немного неудобно – часто тыкаю вниз, вместо вправо. Хотя за 2 дня уже вроде как привык
  • Нет буквы “йо” (той Е что с двумя точками сверху) – по крайней мере я ее на клавиатуре на нашел (левее единицы стоит какой-то “]” – нафиг он там нужен?).
  • Одна кнопка для Backspace и для Del – IMHO гениально с точки зрения юзабилити т.к. по сути  они делают одно и тоже. Заметил что “чего-то не хватает” только через часа полтора пользования.
  • Переключение раскладки клавиатуры по Command + Space – очень даже удобно и натурально (куда удобнее чем то что я использовал в Windows: Alt+Shift+1, Alt+Shift+2, Alt+Shift+3)
  • Bluetooth-мышь нашлась с “пол-пинка” (очень в тему, т.к. дожимать тач до клика я еще не привык), WiFi-сеть – тоже.
  • Не всегда ясно когда нужно зажимать Command а когда Ctrl. Например в некоторых программах для замены Home и End нужно нажимать Ctrl+Left/Ctrl+Right а в некоторых Command+Left/Command+Right. А еще есть  Fn – что-то дофига их получается.
  • Не сразу вспомнил что меню активного приложения выносится в верхнюю полосу экрана – с точки зрения юзабилити очень правильно ( читаем того же В. Головача, первую книгу), но взляд как-то автоматом игнорирует верхнюю полоску – надо привыкать
  • Safari (хз какой версии) не разворачивается на весь экран, при нажатии на зеленый “(+)” в title-баре, а принимает какие-то только ему понятные размеры. С Firefox вроде все ОК.
  • Кстати о Firefox –  первый софт какой я самостоятельно установил. Благо Паша предварительно рассказал чем этот процесс отличается от Windows и Linux. Иначе это было бы плачевно :)
  • Батарея заряжается с 47% уже достаточно долго (и заряжена всего на 88%) – сколько же ей надо для полной зарядки?
  • Первую программу, которую я запустил на новом месте, был терминал – сразу почувствовал себя спокойнее и уверенее :)
  • Как оказалось – “закрыть окно” (клик на красную кнопку в title-баре) в Mac-е – это не то же самое то “закрыть приложение” (Control+Q)
  • Если закрыть крышку ноута – он уходит в sleep-mode. После этого мигает белым диодом на передней стенке – выглядит как официально купленный альбом Pink Floyd “Pulse”  (правда там диодик красный)
  • Чего не хватает – так это хоткея для максимизации окна.
  • Что же касается хот-кеев, то их просто дофигище! Понятно почему программеры так любят МакОС.