Строки отсутствуют после онлайн-конвертации из MyISAM в InnoDB

16

У нас достаточно небольшая база данных, которую мы хотели преобразовать из MyISAM в InnoDB. Будучи новичками в базе данных, мы просто конвертировали (используя alter table), даже не закрывая сайт.

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

Yuvi
источник
В каких таблицах отсутствуют строки? Те, которые вы конвертировали или другие таблицы?
longneck

Ответы:

20

Выполнение операции ALTER для изменения механизмов хранения не приведет к исчезновению строк. Однако позвольте мне дать несколько советов, так как вы сказали, что вы «новички в базе данных» в своем вопросе.

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

  1. Сначала сделайте резервную копию.
  2. Есть план изменения.
  3. Проверьте свой план на автономном хосте.
  4. Имейте план тестирования, чтобы сравнить до и после данных.
  5. Расписание и принять время простоя.
  6. Сделайте резервную копию и снимок сразу после того, как ваше время простоя вступит в силу, и вы убедитесь, что трафик остановлен.
  7. Если вы используете MYISAM, используйте «CHECK TABLE», чтобы оценить, с чем вы имеете дело, прежде чем ALTER.
  8. Скопируйте таблицу локально в дополнение к вашей резервной копии, на всякий случай.
  9. Действуйте осторожно, включите «--show warnings» и другие выходные данные, чтобы у вас была полная картина при внесении изменений.
  10. Если данные важны для вас, нанимайте DBA, даже если вы просто проконсультируетесь во время миграции, чтобы на вашей стороне был опытный ветеран.

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

Что касается ваших отсутствующих данных / строк, то нет способа узнать w / oa «до / после» снимок для сравнения. Вы можете сравнить с вашей последней резервной копией, чтобы хотя бы убедиться в этом.

randomx
источник
Я прочитал это. Хороший план DR. Ваш ответ получает +1 за то, что он более чувствителен к вопросу, чем я, в дополнение к плану на будущее.
RolandoMySQLDBA
1
@randy Отметил это как любимый вопрос из-за вашего хорошего ответа
techExplorer
8

Один из лучших способов преобразовать MyISAM в InnoDB без большого количества простоев имеет только одно предварительное условие: использование подчиненного устройства репликации.

Вот с высоты птичьего полета план

  1. Настройка мастера репликации / ведомого
  2. Конвертировать каждую таблицу MyISAM на ведомом устройстве в InnoDB
  3. Направьте ваше приложение на Раба

Звучит просто? За этим стоит много деталей.

Настройка мастера репликации / ведомого

Существует отличный способ создать Раба без особых помех для Мастера. Я написал два поста:

Вместо того, чтобы подробно рассказывать, как использовать rsync, прочтите эти два поста.

Конвертировать каждую таблицу MyISAM на ведомом устройстве в InnoDB

На БД-подчиненном вы можете выполнить следующую инструкцию SQL:

Для MySQL 5.5:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql','performance_schema');

Версия для MySQL до MySQL 5.5

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE engine = 'MyISAM' AND table_schema NOT IN
('information_schema','mysql');

Используя выходные данные из запроса, у вас есть сценарий преобразования для ведомого.

Вы должны поместить эти две строки вверху скрипта:

SET SQL_LOG_BIN = 0;
STOP SLAVE;

Сценарий сначала отключит двоичное ведение журнала (если вы настроили ведомое устройство на наличие двоичных журналов), остановите репликацию и преобразует каждую таблицу MyISAM в InnoDB.

Вот как создать этот скрипт и выполнить его:

SQLSTMT="SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema')"
INNODB_CONV_SCRIPT=MassConvertMyISAMTablesToInnoDB.sql
echo "SET SQL_LOG_BIN = 0;" > ${INNODB_CONV_SCRIPT}
echo "STOP SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Master) -u... -p... --skip-column-names -A -e"${SQL}" >> ${INNODB_CONV_SCRIPT}
echo "START SLAVE;" >> ${INNODB_CONV_SCRIPT}
mysql -h(IP of Slave) -u... -p... --skip-column-names -A < ${INNODB_CONV_SCRIPT}

Направьте ваше приложение на Раба

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

  1. На Slave запустите SHOW SLAVE STATUS\Gи убедитесь, что Seconds_Behind_Master равен 0
  2. На ведомом устройстве mysqldump -h (IP-адрес ведомого) -u ... -p ... --single -action --routines --triggers --all-database> MySQLBackup.sql (эй, резервное копирование было бы правильным правом о сейчас)
  3. На Мастере беги service mysql stop (время простоя начинается)
  4. Повторите шаг 1
  5. Направьте ваше приложение на подчиненное устройство (время простоя заканчивается при первом подключении приложения)

Если вы сделали к этому моменту невредимым, ПОЗДРАВЛЯЕМ !!!

ДОБАВЛЕННЫЙ БОНУС : Если вы настраиваете Master / Master Replication (иначе круговую репликацию) вместо Master / Slave, вы можете сделать это вместо этого:

  1. На Рабе беги SHOW SLAVE STATUS\Gи убедитесь, что Seconds_Behind_Master равен 0
  2. На ведомом устройстве mysqldump -h (IP-адрес ведомого) -u ... -p ... --single -action --routines --triggers --all-database> MySQLBackup.sql (эй, резервное копирование было бы правильным правом о сейчас)
  3. Направьте ваше приложение на подчиненное устройство (время простоя начинается и заканчивается при первом подключении приложения)
  4. На новом Мастере беги STOP SLAVE;
  5. На новом Мастере беги CHANGE MASTER TO MASTER_HOST='';

Теперь у вас есть ведущий / ведомый в обратном порядке. Новый мастер имеет данные InnoDB, а старый мастер теперь является ведомым с данными MyISAM. Если вы разделяете чтение и запись, чтение может идти от ведомого устройства (чтение выполняется быстрее от MyISAM, чем от InnoDB), а запись идет к мастеру (поддержка транзакций для InnoDB). Как поет Ханна Монтана, вы получаете лучшее из обоих миров (Да, у меня есть две дочери, которые любят шоу) !!!

ДРУГОЙ ДОБАВЛЕННЫЙ БОНУС : Поскольку Мастер теперь является InnoDB, вы можете выполнять mysqldump от Мастера без простоев и без вмешательства в транзакции. Единственный недостаток - увеличение загрузки процессора и дискового ввода-вывода. Таким образом, вы можете использовать mysqldump для табличных структур только на ведущем устройстве (InnoDB) и mysqldump данных только на ведомом устройстве (такой дамп не будет иметь ссылок на InnoDB или MyISAM. Это будут только данные) плюс mysqldump из структуры таблиц для ведомого, чтобы иметь расположение MyISAM.

Возможности могут продолжаться из-за этой новой установки ...

ОБНОВЛЕНИЕ 2011-08-27 19:50 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Мои извенения. Я не полностью прочитал вопрос. Вы уже выполнили разговор .

Только если вы уже включили бинарное ведение журнала и у вас есть резервная копия, вы можете

  • восстановить / var / lib / mysql в другое место, например / var / lib / mysql2
  • бегать service mysql stop
  • бегать service mysql start --datadir=/var/lib/mysql2
  • mysqldump база данных из этой резервной копии в /root/olddata.sql
  • Запустите mysqlbinlog для всех двоичных журналов в / var / lib / mysql (не / var / lib / mysql2) с момента времени последнего резервного копирования в /root/changes.sql
  • Загрузите change.sql в mysql (поскольку он все еще указывает на / var / lib / mysql2)

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

RolandoMySQLDBA
источник