Yuv*_*uvi 16 mysql innodb myisam
我们有一个相当小的数据库,我们想将它从 MyISAM 转换为 InnoDB。作为数据库新手,我们只是转换(使用alter table),甚至没有关闭站点。
现在转换完成了,很多断断续续的行似乎丢失了。这可能是由于转换期间的操作造成的吗?还是其他地方的问题?
ran*_*omx 20
执行 ALTER 来更改存储引擎不会使行消失。但是,让我提供一些建议,因为您在问题中说您是“数据库菜鸟”。
在修改现有架构或执行任何可能影响数据的操作时,以下是一些基本建议:
我可能还有很多东西可以讨论,但是当出现问题时,上面的内容将为您提供选择。
就您丢失的数据/行而言,无法知道没有“之前/之后”快照进行比较。您可以与最新的备份进行比较,以至少验证这么多。
在没有大量停机的情况下将 MyISAM 转换为 InnoDB 的最佳方法之一只有一个先决条件:使用复制从站。
这是该计划的鸟瞰图
听起来很简单?这背后有很多细节。
创建复制主/从设置
有一种巧妙的方法可以创建一个 Slave 而不会对 Master 造成太多干扰。我写了两个帖子:
请阅读这两篇文章,而不是详细说明如何使用 rsync。
将 slave 上的每个 MyISAM 表转换为 InnoDB
在 DB Slave 上,您可以执行以下 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');
Run Code Online (Sandbox Code Playgroud)
MySQL 5.5 之前的 MySQL 版本
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');
Run Code Online (Sandbox Code Playgroud)
使用查询的输出,您就有了从站的转换脚本。
您必须将这两行放在脚本的顶部:
SET SQL_LOG_BIN = 0;
STOP SLAVE;
Run Code Online (Sandbox Code Playgroud)
该脚本将首先禁用二进制日志(如果您将从属配置为具有二进制日志),停止复制,并将每个 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}
Run Code Online (Sandbox Code Playgroud)
将您的应用指向 Slave
从 Slave 执行 SELECT 查询。如果您对 Slave 上的数据内容感到满意,请随时将您的应用指向 Slave,如下所示:
SHOW SLAVE STATUS\G并确保 Seconds_Behind_Master 为 0service mysql stop(停机时间开始)如果你做到这一点毫发无损,恭喜!
附加奖励:如果你设置主/主复制(又名循环复制)而不是主/从,你可以这样做:
SHOW SLAVE STATUS\G并确保 Seconds_Behind_Master 为 0STOP SLAVE;CHANGE MASTER TO MASTER_HOST='';您现在拥有的是反向的主/从。新的 Master 有 InnoDB 数据,旧的 Master 现在是一个拥有 MyISAM 数据的 slave。如果拆分读取和写入,则可以从 Slave 读取(从 MyISAM 读取比 InnoDB 快),写入到 Master(对 InnoDB 的事务支持)。就像汉娜·蒙塔娜 (Hannah Montana) 唱的那样,您可以两全其美(是的,我有两个喜欢这个节目的女儿)!!!
另一个额外的好处:因为 Master 现在是 InnoDB,你可以从 Master 执行 mysqldump,而不会停机,也不会干扰事务。唯一的缺点是增加了 CPU 和磁盘 I/O。因此,您可以仅在主服务器(InnoDB)上进行表结构的 mysqldump 和仅在从服务器上进行数据的 mysqldump(此类转储将没有对 InnoDB 或 MyISAM 的引用。它只是数据)加上从站的表结构具有 MyISAM 布局。
由于这个新设置,可能性可以继续......
更新 2011-08-27 19:50 EDT
我很抱歉。我没有完全阅读这个问题。您已经执行了转换。
只有当你已经打开了二进制日志,并且你有一个之前的备份,你才可以
service mysql stopservice mysql start --datadir=/var/lib/mysql2这应该捕获记录的所有内容并且应该开始转换。同样,这取决于您在上次备份之前已经打开了二进制日志记录。否则,我的哀悼。