Databases
Редактировать на GitHubticket_id=56412. Записей с ticket_id > 60000 нет, никаких символов перед 56412 нет. Как могла появиться разница в количестве? Опишите ваши действия.Какой из вопросов MySQL самый тяжелый? Расскажите как вы его выявили?Теоретические вопросы
Как настроить master-slave репликацию в mysql (кратко)?
Необходимы 2 сервера: master и slave.
- На обеих сервера устанавливаем сервер MySQL одинаковой версии.
- Включаем сервер базы данных на обеих серверах.
- Настраиваем master - в
/etc/my.cnfустанавливаем слеюущие значения:
# выбираем ID сервера, произвольное число, лучше начинать с 1
server-id = 1
# путь к бинарному логу
log_bin = /var/log/mysql/mysql-bin.log
# название Вашей базы данных, которая будет реплицироваться
binlog_do_db = newdatabaseПерезапускаем сервер базы данных. 4. Подключаемся к master серверу, создаем пользователя и назначаем ему права для выполнения репликации.
mysql -u root -p <пароль root сервера БД>
GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;- На master сервере делаем дамп базы данных c блокировкой таблиц.
mysqldump -u root -p --lock-all-tables newdatabase > newdatabase.sql- Переносим дамп базы на slave сервер, создаем базу данных с таким же именем и импортируем базу.
CREATE DATABASE newdatabase;
mysql -u root -p newdatabase < newdatabase.sql- Настраиваем slave в
/etc/my.cnf:
# ID Слейва, удобно выбирать следующим числом после Мастера
server-id = 2
# Путь к relay логу
relay-log = /var/log/mysql/mysql-relay-bin.log
# Путь к bin логу на Мастере
log_bin = /var/log/mysql/mysql-bin.log
# База данных для репликации
binlog_do_db = newdatabaseПерезапускаем сервер базы данных. 8. Запускаем репликацию на slave сервере.
CHANGE MASTER TO MASTER_HOST='10.10.0.1', MASTER_USER='slave_user', MASTER_PASSWORD='password',
MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 107;
##Указанные значения мы берем из настроек Мастера
После этого запускаем репликацию на Слейве:
START SLAVE;- Проверяем статус репликации:
SHOW SLAVE STATUSGКакой тип базы данных использует Prometheus?
Prometheus использует TSDB (time series database).
Что такое VACUUM в PostgreSQL?
VACUUM высвобождает пространство, занимаемое «мёртвыми» кортежами. При обычных операциях PostgreSQL кортежи, удалённые или устаревшие в результате обновления, физически не удаляются из таблицы; они сохраняются в ней, пока не будет выполнена команда VACUUM. Таким образом, периодически необходимо выполнять VACUUM, особенно для часто изменяемых таблиц.
Без параметра команда VACUUM обрабатывает все таблицы в текущей базе данных, которые может очистить текущий пользователь. Если в параметре передаётся имя таблицы, VACUUM обрабатывает только эту таблицу.
Простая команда VACUUM (без FULL) только высвобождает пространство и делает его доступным для повторного использования. Эта форма команды может работать параллельно с обычными операциями чтения и записи таблицы, так она не требует исключительной блокировки. Однако освобождённое место не возвращается операционной системе (в большинстве случаев); оно просто остаётся доступным для размещения данных этой же таблицы. VACUUM FULL переписывает всё содержимое таблицы в новый файл на диске, не содержащий ничего лишнего, что позволяет возвратить неиспользованное пространство операционной системе. Эта форма работает намного медленнее и запрашивает исключительную блокировку для каждой обрабатываемой таблицы.
Практические вопросы
Мы знаем, что есть всего 7 записей с ticket_id=56412. Записей с ticket_id > 60000 нет, никаких символов перед 56412 нет. Как могла появиться разница в количестве? Опишите ваши действия.
По условию задачи:
SELECT count(*) FROM tickets_messages WHERE ticket_id=56412;возвращает 5 записейSELECT count(*) FROM tickets_messages WHERE ticket_id LIKE '%56412';возвращает 7 записей
Разница возникает из-за того, что в колонке ticket_id могут храниться данные разных типов (например, строка VARCHAR вместо INT).
- В случае строгого сравнения
ticket_id=56412выбираются только записи, где значение строго равно числу 56412. - В случае
LIKE '%56412'выбираются записи, где значение заканчивается на "56412", включая строки вроде:'56412'(строка, совпадающая с числом),'abc56412','0056412'.
📌 Итог: 2 «лишние» записи — это строки, в которых ticket_id содержит 56412 как подстроку, но не равен числу 56412.
Что бы я сделал:
- Проверил тип поля
ticket_id:
\d tickets_messages -- в PostgreSQL
DESC tickets_messages; -- в MySQL- Вывел все записи для проверки:
SELECT ticket_id FROM tickets_messages WHERE ticket_id LIKE '%56412';- Нормализовал поле (привёл к числовому типу, если это действительно ID).
Какой из вопросов MySQL самый тяжелый? Расскажите как вы его выявили?
Данные по запросам:
- Запрос #1
Query_time: 2.18sRows_examined: 324,036- JOIN + сортировка + LIMIT 100.
- Запрос #2
Query_time: 9.25sRows_examined: 948,209DELETE FROM phpbb_post_revisions WHERE post_id = …;- Очень долго для DELETE по одному
post_id. Вероятнее всего нет индекса поpost_id.
- Запрос #3
Query_time: 1.11sRows_examined: 521,597- JOIN + ORDER BY + LIMIT "бесконечный" (
18446744073709551615). То есть фактически без LIMIT, что очень тяжело.
- Запрос #4
Query_time: 4.68sRows_examined: 2,457,916(! много)- Тоже JOIN + ORDER BY + огромный список
IN (…)+ "бесконечный" LIMIT.
Самый тяжёлый:
👉 Запрос #2 (DELETE)
- 9.25s (самое большое время выполнения)
- почти миллион строк просмотрено для удаления всего одной записи.
Это явный индикатор отсутствия индекса по
post_idв таблицеphpbb_post_revisions.
Как выявили:
- Взял slow-log.
- Сравнил
Query_timeиRows_examined. - Запрос #2 выделяется как самый тяжёлый (и по времени, и по неэффективности).
Как исправить:
- Проверить индексы:
SHOW CREATE TABLE phpbb_post_revisions\G - Если по
post_idнет индекса → добавить:CREATE INDEX idx_post_id ON phpbb_post_revisions(post_id); - Перепроверить EXPLAIN:
EXPLAIN DELETE FROM phpbb_post_revisions WHERE post_id = 10472158;
Последнее обновление: 7 окт. 2025 г., 08:07:55