Ответы пользователя по тегу MySQL
  • Как правильно хранить массивы в mysql?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Можно хранить массив в типе колонки JSON (доступно с MySQL 5.7 / MariaDB 10.2.3).
    Можно хранить массив бинарно в типе BLOB, десериализуя данные в приложении.
    Ответ написан
    2 комментария
  • Как снизить нагрузку на БД или какую БД использовать?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Миллионы записей - это совершенно обычный и, я бы сказал, крайне небольшой кейс для MySQL.

    Самое быстрое: отпрофилировать запросы (например, performance_schema=1 и подключить sys-таблицы, они наполнятся данными по прошествии времени), найти неоптимизированные индексами и добавить недостающие индексы на этих таблицах.
    Ответ написан
    8 комментариев
  • Можно ли как-нибудь узнать, какие запросы к какой таблице производились на протяжении работы веб-приложения? И сколько времени они занимали?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    1. В my.cnf:
      performance_schema=1
    2. Перезапустить MySQL.
    3. Импортировать sys_xx.sql из проекта mysql-sys: https://github.com/mysql/mysql-sys
    4. Подождать немного времени, пока наберётся статистика с последнего старта БД.
    5. Анализировать запросы в таблице `sys`.`statement_analysis`.
    Ответ написан
    Комментировать
  • Хранение аватарок в БД, что скажете?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Хочу таким образом уменьшить количество запросов на сервер

    Это не уменьшит количество клиентских запросов на веб-сервер. Запросов останется такое же количество, просто источником данных для выдачи станет не диск, а СУБД.
    В большинстве случаев, обращение к диску дешевле, чем обращение к СУБД.

    Для уменьшения количества клиентских запросов на веб-сервер, можно:
    • Перенести изображения на внешний CDN/облачное хранилище: Amazon S3 или Openstack Swift у большинства облачных провайдеров.
    • Перенести изображения на ещё один веб-хостинг, используя его исключительно для публикации изображений.
    Ответ написан
    Комментировать
  • Селекты из таблицы на 5 млн строк. Если разбить её на 100 таблиц - будет выигрыш в производительности?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Прироста не будет.
    Но давайте посмотрим на проблему под другим углом:

    5кк строк - это ничтожное кол-во. Если у вас происходят селекты по 30 секунд, значит либо у вас не выставлены правильные индексы на те колонки, которые вы селектите, либо вы совершаете LIKE, начинающиеся с %. Индексы не используются при запросах LIKE %...%. Только при LIKE ...%

    Ещё одна возможная причина - это хранилище. Посмотрите, не упирается ли всё в этот момент в диски. Если окажется, что в момент тяжёлых запросов у вас высокий iowait, попробуйте мигрировать на площадку с SSD.
    Ответ написан
    Комментировать
  • Tmp_table_size и tmpdir = /dev/shm?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Представьте, что tmp_table_size - это ваш RAM, а tmpdir - это ваш swap.
    Если в вашей операции участвует tmp-таблица, и её размер начинает выходить за пределы tmp_table_size, она переносится на диск, чтобы продолжать работать.

    Если у вас много неиспользуемой RAM, вы можете значительно увеличить tmp_table_size, причём не прибегая к /dev/shm, поскольку в нём не окажется никакого смысла.
    Только не забудьте пропорционально увеличить и max_heap_table_size, поскольку он распространяется и на tmp-таблицы, ведь до перехода на диск они работают на движке MEMORY.

    Если у вас в таблицах используются поля TEXT/BLOB, то tmp-таблицы, связанные с ними, всегда будут размещаться на диске. Если ваше приложение зависит от полей TEXT/BLOB и вам очень часто приходится сталкиваться с tmp-таблицами, то размещение на /dev/shm оправдано. В этом случае tmp_table_size можно оставить низким.
    Ответ написан
  • Как объединить 2 столбца в MySQL с помощью PhpMyAdmin в один?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Посмотреть:
    SELECT concat(customers_firstname, ' ', customers_lastname) as customers_fullname FROM `customers`;


    Поменять:
    UPDATE `customers` SET customers_fullname = CONCAT(customers_firstname, " ", customers_lastname);
    Ответ написан
    2 комментария
  • Почему не получается подключиться к MySQL через сокет?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    $mysqli = new mysqli('localhost', 'root', 'password', '', 0, '/var/run/mysqld/mysqld.sock');

    php.net/manual/ru/mysqli.construct.php
    Ответ написан
  • Как вынести большую таблицу из базы и сделать её общей?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Если самоцель такого выноса - прекратить влияние дампов на доступность чтения с БД, то, при условии, что ваши таблицы в InnoDB и у вас включён binlog, вы можете снимать копии БД с помощью xtrabackup (innobackupex), не останавливая службу и не прерывая доступ к таблицам.
    Изменения, произошедшие с момента старта бекапа, "доедут" из бинлога на завершении процесса.
    Снимать копии можно как на тот же сервер, так и стримить их (без использования локального диска) на другой.

    Если таблицы в MyISAM, можно настроить SLAVE-сервер и снимать дампы с него, не влияя на доступность основного.

    Это практика.

    Правда из контекста не совсем ясно - это некие регулярные дампы данных для резервирования, или это ручные дампы для разработчиков, которые они могут спонтанно снять в любое время через phpmyadmin?
    Если второе, то это не исправить изменением архитектуры. Для чего dev'ы дампят базу с логами? Почему они не могут задампить только нужные мелковесящие таблицы, или даже ограничиться их структурой, чтобы не задевать другие таблицы?
    Если для разработки необходим весь снэпшот базы, я бы сделал его снятие регулярным с xtrabackup и публиковал разработчикам для скачивания по сети из одного конкретного места, чтобы никто больше не подключался к продакшену и не делал никаких дампов с продакшена.
    Ответ написан
    Комментировать
  • Как установить mariadb поверх mysql?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Касательно миграции:

    В общей ситуации, может быть достаточно следующего:
    1. Выделить внерабочее время, когда можно будет провести профилактику.
    2. Сделать резервную копию БД (как приложения, так и information_scheme)
    3. Остановить MySQL
    4. Сделать резервную копию файлов данных (/var/lib/mysql)
    5. Сделать резервную копию конфигов из /etc/mysql
    6. Удалить пакет: 'sudo apt-get remove mysql-server'
    7. Подключить репозиторий MariaDB:
      https://downloads.mariadb.org/mariadb/repositories/
    8. Выполнить sudo apt-get update
    9. Установить пакет: sudo apt-get install mariadb-server
    10. Убедиться, что приложение работает, как ожидается.

    Всё.

    Что может пойти не так:
    - Слишком существенная разница в конфигах гипотетически может привести к проблеме чтения имеющихся файлов данных новым сервером, препятствуя запуску службы. Причину при этом скорее всего напишет в /var/log/mysql.log или /var/log/mysql.err.
    Я с таким прежде не сталкивался, но если это случится, то будет быстрее: удалить MariaDB, затем отключить репозиторий (удалив соответствующую строку/файл из /etc/apt/sources.list или /etc/apt/sources.list.d/), затем sudo apt-get update, затем установить пакет mysql-server обратно. Перед этим, хорошей идеей будет откатить бэкапы /etc/mysql и /var/lib/mysql на прежние места, чтобы исключить последствия изменения файлов данных/конфигов обновлением на MariaDB. Затем проанализировать, что пошло не так и более лучше подготовиться к следующей попытке миграции.

    Материалы по теме с советами по миграции:
    https://mariadb.com/kb/en/mariadb/upgrading-from-m...
    https://mariadb.com/kb/en/mariadb/moving-to-mariadb/
    https://mariadb.com/blog/how-migrate-mysql-mariadb...
    https://www.digitalocean.com/community/tutorials/s...

    Касательно оптимизации:

    Часто производительность упирается в архитектуру приложения, а не в использование конкретной технологии.

    Например, хорошей идеей будет освоить индексы для тяжёлых запросов.
    Примеры, по какому принципу выбирать колонки для индексирования:
    ruhighload.com/post/%D0%9A%D0%B0%D0%BA+%D0%BF%D1%8...
    ruhighload.com/index.php/2009/06/09/%D0%BA%D0%B0%D...
    ruhighload.com/post/%D0%A0%D0%B0%D0%B1%D0%BE%D1%82...
    Ответ написан
    Комментировать
  • Как скрыть с сайта некоторые id объектов из SQL-запроса?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Обновите эту часть запроса:
    WHERE janr='$janr_search' AND `id` NOT IN ('1','2','3')


    Добавьте вместо 1, 2, 3, 4 - те id фильмов, которые Вы не хотите показывать.
    Ответ написан
    4 комментария
  • Что быстрее одна БД на много сайтов или отдельная БД под каждый сайт?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Работа каждой отдельной базы данных - определённый накладной расход, который сокращается при содержании всех баз в одном месте. Содержание на одном сервере 10 виртуалок с маленькими базами внутри - по ресурсам дороже, чем их содержание на одном сервере БД.

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

    Если все базы находятся на независимом оборудовании, то конечно же разделение будет производительнее.
    Ответ написан
    Комментировать
  • MySQL в оперативке. Как правильно делать бекап?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Останавливать MySQL совершенно не нужно.

    Варианты бэкапа без остановки сервера:
    • mysqdump - снимает логический дамп данных, но см. подводные камни про блокировку таблиц и консистенц...
    • xtrabackup (использующий innobackupex) - снимает физическую копию InnoDB-баз без остановки приложения/сервера БД. Делает что-то похожее, что и Ваш скрипт, но более продвинуто и без остановки службы.
    Ответ написан
    Комментировать
  • Ubuntu Server: Возможен ли автобэкап каталога и MySQL бд с добавлением в архив и загрузкой на облако?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Готовых средств для такой совмещённой задачи ни в одном дистрибутиве нет.

    Можно написать bash-скрипт, делающий следующее:
    1. Дамп либо через mysqldump (см. подводные камни с блокировкой таблиц), либо с xtrabackup (только для InnoDB), именующий его по дате.
    2. Другим инструментом (rclone, duplicity) синхронизировать его в нужное облако или на удалённый сервер (rsync, scp).
    Ответ написан
    Комментировать
  • Стоит ли выносить БД на другой сервер?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Просто так это делать нет необходимости. Тем более в истории про "пару сайтов".
    Этот процесс, в общем случае, вообще никак не влияет на безопасность.

    Физическое отделение БД от приложения обычно нужно по каким-то конкретным функциональным причинам.
    Ответ написан
    Комментировать
  • Как подрубиться к mySql, имея sftp доступ к серверу?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Обычно наличие SFTP доступа = наличие SSH доступа, поскольку SFTP работает поверх SSH.

    Попробуйте подключиться с учёткой от SFTP к серверу через SSH-клиент, например Putty или его форк Kitty. Открыв соединение и войдя под учётной записью, в параметрах подключения:
    Connection->SSH->Tunnels
    Add new forwarded port:
    Source port: 3307 (или любой другой)
    Destination: 127.0.0.1:3306
    Local, Auto
    Add

    После этого у себя клиентом нужно подключаться к 127.0.0.1:3307 (или другому указанному)
    Ответ написан
    6 комментариев
  • Как залить большой дамп в базу?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    в чем может быть проблема?

    В том, что, на самом деле, Вы не сняли дамп.

    Это нужно делать программой mysqldump, а не mysql:
    mysqldump -uuser -p dbname > dump.sql

    А запуск mysql с -u и указанием имени базы не выгружает данные. Утилита вернёт Вас в интерактивный режим для дальнейших ручных операций с выбранной базой.

    На то, что Вы не сняли дамп, указывает и мгновенный возврат консоли после заливки.
    Ответ написан
    2 комментария
  • Как исправить ошибку MySQL Error: Duplicate entry при импорте базы?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    В ваш дамп попало две строки с одинаковым значением `node_name_unique`.

    Варианта два:
    1. Удалить из дампа дубль записи с `node_name_unique` = 'Forum'
    2. Убрать в структуре таблицы у колонки `node_name_unique` UNIQUE KEY

    Можно убрать у колонки UNIQUE KEY, залить дамп, удалить дублирующую строку с 'Forum' и добавить UNIQUE KEY обратно.
    Ответ написан
    5 комментариев
  • Почему не запускается MySQL?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    Прежде всего, сделайте сейчас копию файлов баз данных куда-нибудь.
    Выключите приложение, подключающееся к вашей базе.

    Попробуйте (имея копию файлов) запустить MySQL в режиме innodb_force_recovery, чтобы он всё-таки аварийно (ничего не проверяя) запустился, и вы могли снять дамп данных.
    Добавьте в my.cnf в секцию [mysqld]:
    innodb_force_recovery = 1
    и запустите MySQL.

    Если не помогло - читайте, что делает следующая цифра и ставьте её. Почитать про каждый уровень можно здесь:
    dev.mysql.com/doc/refman/5.7/en/forcing-innodb-rec...
    Имейте ввиду, что поднимать уровень нужно только при наличии файловой копии баз данных, поскольку они почти наверняка могут повредить данные.

    На всякий случай, добавьте в ту же секцию:
    innodb_purge_threads=0

    Если MySQL запустился, снимайте дамп всех критичных таблиц.
    Чтобы узнать, какая именно таблица стопила весь процесс, запустите mysqlcheck --all-databases. Те таблицы, что напишут "Corrupted", надо дампнуть и после всей этой канители переразвернуть с дампа заново.

    Не оставляйте этот режим на продакшене.
    Ответ написан
    3 комментария
  • Длинные запросы MySQL, (CentOS, nginx, 1C-Bitrix)?

    landergate
    @landergate
    IT-шный jack-of-all-trades
    База данных препятствует добавлению новых данных на период снятия бекапа для того, чтобы Ваш бекап был консистентен по всем таблицам. Это стандартное поведение.

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

    Если Вы хотите делать бекап без блокировки таблиц, но Вам важна консистентность данных, Вы можете:
    1. Настроить репликацию MASTER-SLAVE и снимать резервные копии со SLAVE. С ним можно будет сколько угодно блокировать таблицы бекапами, поскольку SLAVE-сервер не будет использоваться сайтом. Все новые данные с MASTER доедут на него после завершения бекапа.
    2. Если таблицы в InnoDB, то можно освоить XtraBackup, делающий резервную копию прямо на ходу.


    Если Вы хотите делать бекап без блокировки таблиц, но Вам не нужна консистентность данных:
    Для MyISAM:
    mysqldump --lock-tables=false ...
    Для InnoDB:
    mysqldump --single-transaction ...
    Ответ написан
    Комментировать