Ответы пользователя по тегу Администрирование баз данных
  • Как правильно организовать обслуживание и работу с большой БД?

    Vamp
    @Vamp
    Касательно mysql знаю три варианта:

    1. Утилита pt-online-schema-change. Создаёт пустую копию исходной таблицы, делает на ней alter, копирует данные из исходной таблицы и в конце меняет местами старую и новую таблицы.

    Пользовался этой утилитой пару раз. Хорошо работает.

    2. В mysql 5.6 появилась возможность делать alter без блокировок средствами самой субд. Нужно в alter добавить парочку новых параметров:
    ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;
    Этот вариант я сам не пробовал, поэтому прокомментировать не могу.

    3. Самый сложный вариант с использованием двух инстансов mysql, связанных master-master репликацией:

    1. Делаем alter на втором сервере
    2. Ждём, когда второй сервер догонится по репликации
    3. Переключаем сервис на вторую базу
    4. Ждем какое-то время, смотрим, нормально ли приложение работает с новой схемой, нет ли деградации или ошибок
    5. Делаем alter на первой базе
    6. Ждём догона репликации
    7. Возвращаем сервис на первую базу

    С этим вариантом я работаю постоянно. Выглядит просто, но на деле много нюансов.

    Нужно обязательно пропускать alter мимо репликации:
    SET sql_log_bin = 0;
    ALTER TABLE tbl_name ...;
    Важно не забыть про sql_log_bin = 0, иначе alter по репликации переедет на соседний сервер и залочит таблицу уже там. А переключать сервис нельзя, пока репликация не догонится.

    Если меняется структура таблицы - добавляется/удаляется колонка или меняется их порядок, нужно обязательно проследить чтобы тип репликации обязательно был STATEMENT. Иначе репликация приляжет на первом же запросе в формате ROW с примерно такой странной ошибкой:

    Column 25 of table 'mydb.mytable' cannot be converted from type 'varchar(255)' to type 'bigint(20) unsigned'


    А со STATEMENT нужно следить чтобы приложение нигде не понижало уровень изоляции ниже REPEATABLE READ, иначе получит ошибку:

    Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
    Ответ написан
    Комментировать