Проблемы с кодировкой в базе данных

Проблемы с кодировкой в базе данных

от Alexandre Scherbyna -
Количество ответов: 16

Всем доброго времени суток!

Есть у меня один сайт, который прошел блольшой и славный путь, начиная от версии Moodle 1.4, а сейчас отлично работает на 1.8.4 ( нигде нет никаких проблем, в том числе и с кодировкой). За 5 лет работы случались аварии сервера, но все успешно восстанавливали и, поскольку сайт работает без замечаний, то и смотреть что там делается в базе данных особой надобности не было.

Однако, когда мы попытались перевести его с 1.8.4 на 1.9.5, то к большому удивлению получили сообщение об ошибке, что, якобы, база данных не в юникоде, и, дескать, нужно сначала установить версию 1.7. Но у нас же 1.8 давно и успешно работает, а на юникод мы переходили еще когда ставили 1.6!

Стал я смотреть базу данных через phpMyAdmin и обнаружил, что действительно, во многих таблицах в графе сравнение значится не utf8_general_ci, а cp1251_general_ci. Но больше удивило даже не это, а количество таблиц. Их там оказалось аж 307! Причем многие таблицы явно Moodle'овские, но не имеют в имени префикса, указанного в config.php. Если бы та же таблица и префикс неправильный имела и сортировка в ней была не та, то было бы понятно, что ее как-то случайно сюда занесло. Но это совсем не так!

Подскажите, пожалуйста, что делать? Как отремонтировать базу данных и убрать из нее лишние таблицы? Дальше оставаться на 1.8 уже нельзя.

В ответ на Alexandre Scherbyna

Re: Проблемы с кодировкой в базе данных

от Alexandre Belousov -
Как вариант - сделать копию базы, сокнвертить таблицы в utf8 при помощи iconv, поискать ссылки на таблицы без префикса (возможно, были нестандартные расширения установлены?), если нет - удалить соответствующие файлы. Внимательно просмотреть базу на предмет времени обновления файлов, удалить неиспользуемые.
Попробовать снова поставить. Должно пройти нормально
В ответ на Alexandre Scherbyna

Re: Проблемы с кодировкой в базе данных

от Alex Djachenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода Изображение пользователя ООО "Открытые Технологии" Изображение пользователя Тестер Moodle Изображение пользователя Эксперт по Moodle
К сожалению, это частая ситуация, когда устанавливать и обслуживать систему поручают непрофильному специалисту, иногда даже вообще просто студенту: легкость установки персональной версии на домашнем компьютере создает впечатление, что и промышленным сервером с сотнями посетителей можно управляться без навыков администрирования Linux, СУБД, веб-серверов, знания php и понимания архитектуры Moodle.

Очевидно, Вам придется теперь разгребать проблемы, накопленные за годы администрирования предыдущими специалистами.

Рекомендую начать с полной резервной копии дампа базы данных, htdocs и moodledata. Проверьте, чтобы в дампе данные были в читаемой кодировке (не важно, будет ли дамп читался при utf-8 или cp1251, но главное чтобы читался хоть в какой-нибудь - иначе он бесполезен).

Используются только те таблицы, имена которых начинаются с префикса, указанного в config.php, остальные можно просто удалить.

Кодировку сравнения всей БД и всех таблиц нужно изменить на utf8 (вообще, при миграции с 1.5 на 1.6 это делал специальный скрипт, но почему он у вас не сработал - уже не разобраться). Можно воспользоваться дампом - скопировать туда нужные таблицы, заменить кодировку, а затем восстановить. Можно, конечно и вручную, через админку.

Что делать дальше, придется разбираться эмперически. По крайней мере у меня не было такого набора одинаковых случаев, чтоб можно было дать четкий рецепт - смотришь, что происходит с системой и по ситуации правишь.
В ответ на Alex Djachenko

Re: Проблемы с кодировкой в базе данных

от Alexandre Scherbyna -
Спасибо всем, кто откликнулся.
Я открыл базу в phpMyAdmin. Во все таблицы, где в графе Сравнение значилось CP1251_general_ ci заходил в Структуру и менял сначала в отдельных полях Сравнение с CP1251_general_ ci на utf8_general_ci, а потом входил на вкладку Операции и устанавливал utf8_general_ci для таблицы в целом (параметр, который отображается в в графе Сравнение общего списка таблиц базы данных).
Если открыть Обзор, то содержимое всех этих и любых других таблиц прекрасно читается, и браузер подтверждает, что кодировка UTF-8.
В результате CP1251 уже не видно нигде, но это не помогло. Выдает ту же ошибку. Пишет, что база данных не в юникоде грущу
В ответ на Alexandre Scherbyna

Re: Проблемы с кодировкой в базе данных

от Alexandre Belousov -
В phpmyadmin что стоит по умолчанию как mysql-кодировка? Убедитесь, пожалуйста, что физически базы в Utf8.

В базе в mdl_config строка locale в какое значение установлена? Должно быть "ru_RU.UTF-8"
В ответ на Alex Djachenko

Re: Проблемы с кодировкой в базе данных

от Alexandre Scherbyna -
Да, и что во всем этом больше всего удивляет, это то, что если вернуться к Moodle 1.8.4, то эта база данных с ним прекрасно работала и до описанных выше исправлений и продолжает работать после них. Выходит то, что для 1.8.4 - юникод, для 1.9.5 - уже не юникод?
В ответ на Alex Djachenko

Не полностью отображается главное навигационное меню

от Alexandre Scherbyna -
Разобраться, почему эта ошибка возникает не смог, но нашел место в файле admin/index.php, где она обнаруживается:

/// If the database is not already Unicode then we do not allow upgrading!
/// Instead, we print an error telling them to upgrade to 1.7 first. MDL-6857
if (empty($CFG->unicodedb)) { print_error('unicodeupgradeerror', 'error', '', $version); }

Поставил после if ( восклицательный знак, и 1.9.5 установилась.
На первый взгляд работает все, кроме главного навигационного меню. В нем почему-то осталась только ссылка для перехода на главную страницу сайта, а ссылки на главную страницу дисциплины и всего, что за ней обычно следует, уже нет. Вместо всего этого – только слово Array без ссылок.

Кто-нибудь с таким сталкивался?
В ответ на Alexandre Scherbyna

Re: Не полностью отображается главное навигационное меню

от Alex Djachenko -
Изображение пользователя Developers Изображение пользователя Майнтейнер перевода Изображение пользователя ООО "Открытые Технологии" Изображение пользователя Тестер Moodle Изображение пользователя Эксперт по Moodle
Без таких грубых хаков вполне можно обойтись (и вообще лучше избегать прямого редактирования кода): добавьте в таблицу mdl_config запись unicodedb со значением 1. Это отключит предупреждение, но не решить проблему с кодировками базы данных. При неправильной кодировке может неправильно выполняться поиск и сортировка, а так же могут возникнуть проблемы с импортом и экспортом дампа базы данных. Если Вы уверены что база данных в кодировке utf-8, для базы данных и всех таблиц установлены правильные параметры сравнения, то просто внесите запись unicodedb в mdl_config и предупреждение исчезнет (то же самое можно сделать через config.php).
В ответ на Alex Djachenko

Re: Не полностью отображается главное навигационное меню

от Alexandre Scherbyna -
Спасибо Алексей, это ценная информация. Записи unicodedb в моей mdl_config действительно нет, хотя в других базах, я вижу, это самая первая запись этой таблицы.
Перед следующим обновлением я ее пропишу. В общем перечне таблиц всюду установлено utf8_general_ci, но есть же еще и сравнение для каждого поля. Будет время позаглядываю еще и внутрь таблиц, какая там сортировка установлена.
А еще я читал, что после изменения сортировки надо делать REPAIR TABLE. С помощью phpMyAdmin это как можно сделать?
В ответ на Alexandre Scherbyna

Re: Не полностью отображается главное навигационное меню

от Dmitry Pupinin -
Александр, лучший способ быть уверенным что в базе все в utf8 сделать следующее:
1. Сделать дамп базы в текстовый файл.
2. С помощью поиска/замены установить всюду сравнение в utf8_general_ci.
3. Переименовать старую базу данных.
4. Создать новую базу установив для нее utf8_general_ci.
5. Востановить данные из дампа в новую базу данных.
В ответ на Dmitry Pupinin

Re: Не полностью отображается главное навигационное меню

от Alexandre Scherbyna -

Есть база данных Moodle, в которой всюду используется сортировка utf8_general_ci. Пытаюсь воспользоваться вашим алгоритмом, чтобы заменить ее на нужную мне utf8_unicode_ci.

Открываю базу в phpMyAdmin и выбираю для всех ее таблиц Экспорт, Texy! текст , Сохранить как файл, ОК.

Получаю текстовый файл, который комбинации символов utf8_general_ci нигде не содержит. Что я не так делаю?

Кусочек из созданного файла присоединяю.

В ответ на Alexandre Scherbyna

Re: Не полностью отображается главное навигационное меню

от Vadim Tabunshchik -
Изображение пользователя Developers
Александр, в phpMyAdmin выбирайте экспорт в SQL и проверьте, отмечен ли бокс Структура.
Получите файл с расширением .sql, который можно открыть блокнотом и увидеть примерно такое:
-- phpMyAdmin SQL Dump
--
-- Структура таблицы `mdl_assignment`
--
CREATE TABLE IF NOT EXISTS `mdl_assignment` (
`id` int(10) unsigned NOT NULL auto_increment,
`course` int(10) unsigned NOT NULL default '0',
`name` varchar(255) collate utf8_unicode_ci NOT NULL default '',
`description` text collate utf8_unicode_ci NOT NULL,
`format` tinyint(4) unsigned NOT NULL default '0',
`assignmenttype` varchar(50) collate utf8_unicode_ci NOT NULL default '',
`resubmit` tinyint(2) unsigned NOT NULL default '0',
`preventlate` tinyint(2) unsigned NOT NULL default '0',
`emailteachers` tinyint(2) unsigned NOT NULL default '0',
`var1` int(10) default '0',
`var2` int(10) default '0',
`var3` int(10) default '0',
`var4` int(10) default '0',
`var5` int(10) default '0',
`maxbytes` int(10) unsigned NOT NULL default '100000',
`timedue` int(10) unsigned NOT NULL default '0',
`timeavailable` int(10) unsigned NOT NULL default '0',
`grade` int(10) NOT NULL default '0',
`timemodified` int(10) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `course` (`course`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Defines assignments' AUTO_INCREMENT=265 ;

--
-- Дамп данных таблицы `mdl_assignment`.....................................

Вот тут вы и можете воспользоваться "Поиск - Замена"
В ответ на Vadim Tabunshchik

Re: Не полностью отображается главное навигационное меню

от Alexandre Scherbyna -

Как я понял, с помощью Поиск/Замена нужно utf8_general_ci всюду заменить на utf8_unicode_ci. Но проблема как раз в том, что utf8_general_ci нигде нет. В файле с расширением sql (экспортированном со структурой) тоже.

В одной из баз я в phpMyAdmin заменил сортировку нескольких полей на utf8_unicode_ci. Так там строчки COLLATE utf8_unicode_ci где-то проскакивали, но utf8_general_ci, увы, нет нигде. Может его нет потому, что оно где-то по умолчанию установлено?

В ответ на Alexandre Scherbyna

Re: Не полностью отображается главное навигационное меню

от Dmitry Pupinin -
Описаный способ использовался при переходе на 1.6, когда возникли проблемы с кодировкой. Так что это не теория...

Если COLLATE отсутствует, то почему его не добавить?.. с помощью той же замены... улыбаюсь
В ответ на Alex Djachenko

Правила сортировки в таблицах базы данных

от Alexandre Scherbyna -

С REPAIR TABLE разобрался.

Позвольте еще один вопрос по поводу сортировки в таблицах. Дело в том, что установленная у меня всюду кодировка utf8_general_ci неправильно сортирует по украинскому алфавиту (буквы і, ї, є оказываются впереди а). Оказалось, что правильно это делает utf8_unicode_ci. Я установил ее пока только в полях lastname, firstname таблицы mdl_user и списки студентов всюду стали сортироваться правильно. Можно ли ограничиться изменением правил сортировки только для тех полей, по которым действительно нужно выводить какие-либо отчеты, или эти правила во всем Moodle должны быть одинаковыми? Если да, то как можно автоматизировать перевод всей базы данных на сортировку utf8_unicode_ci ? И не может ли этот переход вызвать какие-либо нежелательные последствия? Ведь речь идет о достаточно большой базе данных.

В ответ на Alex Djachenko

Re: Проблемы с кодировкой в базе данных

от Alexandre Scherbyna -
Разобрался с навигационным меню. Оказалось, был какой-то глюк в тогдашней 1.9.5+. Скачал более свежую, там меню работает. Спасибо всем.
В ответ на Alexandre Scherbyna

Давайте подведем итоги

от Alexandre Scherbyna -

Дорогие коллеги! Чтобы завершить это обсуждение, прошу специалистов подтвердить или опровергнуть мои выводы:

  1. Moodle не требует, чтобы во всех текстовых полях его базы данных использовалась ОДИНАКОВАЯ кодировка для сравнения и поиска. (Где то может быть utf8_general_ci, где-то utf8_unicode_ci, лишь бы всюду была utf8 и база данных исправно работала).
  2. Кодировка utf8_general_ci используется по умолчанию. Поэтому в дампе базы данных нельзя вывести в явном виде: COLLATE utf8_general_ci. Следовательно, для замены этой кодировки алгоритм, описанный выше Дмитрием, использовать нельзя.
Заранее всем спасибо.