2011-01-13 15:22:44

Обновление MySQL 4.1 до 5.5

Про работу MySQL

По опыту обновления 3.23 на 4.1, процесс этот сначала казался вполне простым и безболезненным, но все оказалось не так просто. Ниже предлагаю инструкцию о том, как я обновил MySQL 4.1 до 5.5 на Windows XP x32.

Начальные данные: под виндой установлен MySQL 4.1 с кучей баз разного размера, так называемая developer machine, тип баз только MyISAM, а об InnoDB речь не идет.


Шаг 0. Для начала качаем свежий MySQL с сайта производителя, я брал MySQL Community Server 5.5 MSI Installer, а пока он качается изучаем оригинальную инструкцию Upgrading from MySQL 4.1 to 5.0, в которой описан процесс, но его результат меня не устроил. Поэтому отсюда подчеркиваем только основные моменты.

Шаг 1. Стопорим старый MySQL 4.1 и удаляем службу с именем MySQL. Если служба называется по-другому, то ее можно не удалять (потом будет удобнее).

Шаг 2. Бэкапим старый data folder (обычно путь_к\MySQL4\data, а если такого нет, то смотрим куда указывает datadir в my.ini и берем его). Создаем папку для данных MySQL5 (в моем случае D:\Server\MySQL5\data) и кладем в нее копию данных от MySQL4. Вытираем файлы из корня папки D:\Server\MySQL5\data чтоб потом не мешались (это старые логи и т.п.).

Шаг 3. Ставим MySQL5 в подготовленную папку варианте "Custom", выбираем нужные компоненты и самое главное выбираем путь для данных, который мы уже создали и заполнили старыми базами на предыдущем шаге. Обращу внимание на то, что название папки data указывать не надо, т.е. если указали путь к данным как "D:\Server\MySQL5" то базы будут лежать в "D:\Server\MySQL5\data".

В конце установки нм предлагают запустить instance config wizard, соглашаемся и конфигурим MySQL. Важно! На шаге выбора default charset нужно выбрать ровно тот же что был раньше для того чтобы корректно работали старые базы. Далее все стандартно, install service и т.п., кстати modify security settings можно и не делать тк не пригодится.

Теперь смотрим как мастер выполняет операции, если он заткнулся на start service (долго висит и ничего не делает), то просо убиваем процесс мастера.

Шаг 4. Теперь идем в службы и стопорим службу MySQL5. Копируем с заменой базу mysql (папку MySQL4\data\mysql) в папку данных MySQL5 (MySQL5\data).

Шаг 5. Из командной строки запускам MySQL5 без привилегий, в моем случае как

D:\Server\MySQL5\bin>mysqld --defaults-file="D:\Server\MySQL5\my.ini" --skip-grant-tables

Если не запустилось - смотрим логи и пытаемся исправить ошибки.

Шаг 6. Запускаем mysql_upgrade который проводит анализ/ремонт таблиц, приводит их к новой версии, и самое главное, переделывает старую базу с пользовательскими привилегиями, делает ее работоспособной в новой версии.

D:\Server\MySQL5\bin>mysql_upgrade.exe

Обязательно проверяем что в конце работы оно написало "Running mysql_fix_privilege_tables" и что это произошло успешно. Если этого не было, то гуглим как вручную конвертировать таблицы привилегий. Все предыдущие ошибки таблиц пока игнорируем.

Шаг 7. Стопорим MySQL5 при помощи диспетчера задач (убиваем процесс) и корректно запускаем службу. Если она запустилась - значит все хорошо и можно продолжить, обновлению быть. Если - нет, то все плохо, идем в логи и пытаемся устранить ошибки.

Шаг 8. Запускаем mysqlcheck и, если много баз и таблиц, сохраняем результат в файл для анализа всех ошибок а не только того что уместилось в консоли.

D:\Server\MySQL5\bin>mysqlcheck.exe --all-databases -u root -p > d:\temp\checkrepair.txt

вводим свой старый рутовый пароль и ждем пока оно выполнится. Идем в файл и ищем там все таблицы с проблемами, которые не удалось починить. Если таковые есть их придется переносить через mysqldump со старой версии. Обычно таких таблиц не много и задампить их вполне реально.

Шаг 10. Если есть проблемные таблицы, то останавливаем MySQL5, запускам старый MySQL4 (если удалили службу, то по аналогии с шагом 5). И при помощи mysqldump вытаскиваем нужные таблицы:

D:\Server\MySQL4\bin>mysqldump.exe -u root -p DB_NAME TB_NAME1 TB_NAME2 > d:\temp\dump.NAME.sql

Здесь DB_NAME - имя базы, TB_NAME1 - имя таблицы 1 и т.д. И так для каждой базы в которой есть проблемные таблицы. В полученных файлах дампов добавляем первой строчку "use DB_NAME;" без кавычек, где DB_NAME - имя базы (иначе импорт не произойдет).

Теперь останавливаем MySQL4 (останавливаем службу или убиваем процесс, в зависимости от типа запуска) и запускам службу MySQL5.

Теперь импортируем в MySQL5. Для каждого дампа выполняем:

D:\Server\MySQL5\bin>mysql -u root -p < d:\temp\dump.NAME.sql

Теперь запускаем mysqlcheck и убеждаемся что все таблицы в порядке.

D:\Server\MySQL5\bin>mysqlcheck.exe --all-databases -u root -p > d:\temp\check.txt

На этом процесс обновления можно считать успешно завершенным. Идем в службы и ставим тип запуска у MySQL5 - автомат, а у MySQL4 (если ее не удалили на шаге 1) - вручную, позже службу можно будет совсем удалить вместе со старым MySQL.

Но как всегда, не все так просто. Если у вас был корректно настроен MySQL4 и вам не требовалось использовать SET NAMES в скриптах или приложениях сразу после подключения к БД, то велика вероятность, что вместо русских букв база будет выдавать знаки вопроса. Знакомая проблема? Но решается она теперь новым способом! Идем в my.ini и убеждаемся или добавляем опции в разделы:

[mysql]
default-character-set=cp1251

[mysqld]
skip-character-set-client-handshake
character-set-client=cp1251

Где вместо cp1251 ваш дефолтный charset. Перезапускаем MySQL.

Основное отличие от MySQL4 заключается в опции skip-character-set-client-handshake. После этого проблема знаков вопроса у меня решилась.

И еще одни грабли, которые мне встретились: на вполне рабочие запросы mysql стала отвечать

Incorrect integer value: '' for column 'xxx_xxxx' at row 1

Эта ошибка возникает в результате настройки MySQL для работы в более требовательном к SQL режиме. Для нормальной работы нужно удалить STRICT_TRANS_TABLES из опции sql-mode в my.ini. По-умолчанию у  меня было

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

А стало

sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

И проблема ушла. Для вступления изменений в силу нужно перезапустить MySQL.

Надеюсь эта инструкция будет полезна :)