PostgreSQL
coub
express.js
freeware
git
jquery
laravel
links
linux
macos
mysql
node.js
php
powershell
python
ubuntu
vim
virtualbox
анекдот
блог
игры
интересно
стихи
цитаты
MySQL конвертируем cp1251 внутри latin1 в utf8 или "charset hell"
February 28, 2014
Имеем такую ситуацию: есть бд mysql, все таблицы этой бд в кодировке latin1, текст внутри этих таблиц засунут в кодировке cp1251. Цель: конвертировать таблицы и данные в них в utf8.
КОРОТКО И ВНЯТНО
ДЛИННО И ВДУМЧИВО
Понадобится: консоль, screen, iconv, vim(другой ваш любимый редактор) и mysql c mysqldump конечно.
Делаем дамп исходной базы обычным образом (чтобы не корячить боевую)
КОРОТКО И ВНЯТНО
mysqldump -u user -p --default-character-set=latin1 --set-charset db_name > dump_db.sql iconv -f cp1251 -t utf8 dump_db.sql > dump_db_utf.sqlЗатем заменить в конвертированном дампе кодировку latin1 на utf8 вручную.
ДЛИННО И ВДУМЧИВО
Понадобится: консоль, screen, iconv, vim(другой ваш любимый редактор) и mysql c mysqldump конечно.
Делаем дамп исходной базы обычным образом (чтобы не корячить боевую)
mysqldump -u user -p db_name > dump.sqlСоздаем в mysql базу для того чтобы над ней измываться и заливаем туда наш дамп
mysql -u user -p # ввели пароль, зашли CREATE DATABASE db1; # выходим из mysql ^D mysql -u user -p db1 < dump.sql # ввели парольИтого имеем тоже самое в нашей тестовой базе. Теперь чтобы понять суть проблемы сделаем так: переведем кодировку в screen в cp1251 и заглянем в бд чтобы увидеть русский.
# переводим кодировку консоли в screen (или вашим способом) ^a:encoding cp1251 # идем в mysql mysql -u user -p # переключаемся на кодировку нашей бд set names latin1; use db1; # выбираем поле в котором ожидаем русский язык select field from table_name limit 1;Если русский увидели то все ок. Дальше все понятно. mysqldump умеет выгружать данные с установленным чарсетом, делается это вот так
mysqldump -u user -p --default-character-set=latin1 --set-charset db1 > dump_db1.sqlТо есть выводим содержимое в файл так же как мы смотрели выше через mysql, установив кодировку исходной БД. Теперь открываем наш дамп в vim. Учитывая что кодировка консоли у нас сейчас тоже выставлена в cp1251 - должны увидеть в дампе русский текст. Выходим из редактора и конвертируем дамп
iconv -f cp1251 -t utf8 dump_db1.sql > dump_db1_utf.sqlТеперь меняем кодировку консоли обратно в utf8
# для screen ^a:encoding utf8Открываем наш дамп в utf8 и правим кодировки latin1 на utf8
vim dump_db1_utf.sql # замена с подтверждением для vim :%s/CHARSET=latin1/CHARSET=utf8/gcЕщё в начале дампа надо будет изменить строку вида
/*!40101 SET NAMES latin1 */;На вот такую
/*!40101 SET NAMES utf8 */;Все, имеем дамп в utf8. По аналогии немного повращав мозгами можно справляться с другими подобными заморочками.
Node.js + MySQL FOUND_ROWS()
February 10, 2014
Столкнулся с багой оригинального характера. Когда написал свою первую прокладку под mysql сильно радовался тому, что все работает и довольно привычно-удобно. Но оказывается я страшный лошара. В этой самой прокладке есть метод foundRows который должен возвращать (и это иногда работает!) количество рядов в запросе без учета LIMIT (см. FOUND_ROWS()). Загвоздка в том что FOUND_ROWS() сработает только для того запроса который был перед ним в пределах одного коннекта. То есть сначала запрос на select с лимитом и следующим обязательно должен быть select found_rows() примерно так
А теперь внимание вопрос для третьего класса средней школлы..Как поделить три яблока на четверых чтобы каждый получил по яблоку и никто не получил по лицу. Как же это решить? Я не нашел удобного толкового решения. Callback hell забарывает и на код становится жутко глядеть. Решение есть, смотрим тут Pooling connections. То есть если необходимо по каким-то причинам строго последовательно выполнять запросы, то из пула специально берем отдельный коннект и пользуемся им. Выглядеть это будет примерно так:
Стоит обратить внимание на секцию настроек "Pool options" хотя бы чтобы научиться регулировать количество соединений connectionLimit.
Вообще доделать конечно надо ради интереса, но по-хорошему надо переезжать уже на Sequelize или что-то такое.
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10; SELECT FOUND_ROWS();В ситуации с асинхронными запросами, когда используется только один коннект, при приличной паралельной загрузке между этими двумя запросами вполне может проскочить другой запрос и FOUND_ROWS() начнет "врать". По сути очередь будет выглядеть так
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10; # пример "проскочившего" запроса SELECT * FROM tbl_name_2 WHERE id=12; SELECT FOUND_ROWS();И вот уже FOUND_ROWS() возвращает совершенно не то что нужно. Для создания тестовой загрузки проекта можно пользоваться Apache ab например вот так
# 900 раз запросить страницу с 10 конкурентными запросами ab -c 10 -n 900 http://cocainum.info/post/301/В моей ситуации во время такого тестирования мелкие запросы как раз влезали между запросами с лимитом и запросами подсчета рядов. В результате пейджинг думал что страниц у него ровно одна штука и исчезал со всех своих страниц как класс, пока шла нагрузка с конкурентными запросами.
А теперь внимание вопрос для третьего класса средней школлы..
pool.getConnection(function(err, conn) { conn.query( 'SELECT SQL_CALC_FOUND_ROWS * FROM tab1 LIMIT 100,10', function(err, rows) { conn.query('SELECT FOUND_ROWS() as cnt', function(err, rows){ // получаем общее кол-во строк // ... // освобождаем соединение conn.release(); }); }); });В прокладке я это реализовал, но пока что выглядит все это жутко, надо либо свыкнуться с этой мыслью, либо придумать что-то лучше. Пока переделанную версию выкладывать смысла нет по-моему.
Стоит обратить внимание на секцию настроек "Pool options" хотя бы чтобы научиться регулировать количество соединений connectionLimit.
Вообще доделать конечно надо ради интереса, но по-хорошему надо переезжать уже на Sequelize или что-то такое.
MySql: восстановить дамп бд из .gz файла
September 27, 2013
Бывает удобно распаковывать .gz файл прямо в бой вот так
gunzip -c db_dump_file.sql.gz | mysql -u root -p db_name
Mysql: как удалить таблицы по префиксу
April 22, 2013
Как вариант генерим строку запросов
В случае, если целевых таблиц очень много — нужно помнить про вот этот нюанс (group_concat_max_len).
SELECT GROUP_CONCAT('DROP TABLE ', table_name, ';' SEPARATOR '') AS statement FROM information_schema.tables WHERE table_name LIKE 'prefix\_%';В результате получим строку из кучи запросов на дроп таблиц с заданным префиксом. Результат проверяем (на соответствие таблиц целевым) и полученный запрос применяем к базе.
В случае, если целевых таблиц очень много — нужно помнить про вот этот нюанс (group_concat_max_len).
Plink: remote host MySql access via ssh
August 31, 2009
Задача простая. Есть удаленный хост с MySql. Удаленные подключения запрещены. Локальные для нашего пользователя разрешены. Таким образом как нам получить на свою машину доступ к удаленному хосту через какой-нибудь графический MySql клиент, а не только через консоль в шелле (самая надежная безглючная фигня кстати и лучше с боевой БД работать именно через неё, ага). Для этого cуществует утилита plink. Она поможет нам пробросить шелл соединение и забиндить под него локальный порт. Делается это просто. Делаем батничек lala.bat в нем пишем:
REM plink -N -L local_port:remote_localhost:remote_port remote_host_user@remote_host
plink -N -L 4500:localhost:3306 lala@lala-host.ru
Где:
- lala - имя юзера
- lala-host.ru - ваш хост
- -N - не стартовать шелл, коммандная строка не нужна
- -L - [listen-IP:]listen-port:host:port форвард локального порта на удаленный адрес
ssh -N -f -L local_port:remote_localhost:remote_port remote_host_user@remote_host
В примере мы вешаем на свою локальную машину, на порт 4500 коннект к удаленному 3306 порту мускуля через ssh соединение. Потом берем любой клиент для бд и подключаемся к локалхосту на порт 4500. И все дела. Естественно должен быть шелл-доступ к удаленному хосту с мускулем и plink должен оставаться запущенным и авторизованным на время работы с бд.