我们专注服务于当下互联网基础设施建设与云计算、大数据时代的各种需求!

【转】在线热切换innodb表空间

InnoDB 是一个非常不错的 MySQL 的存储引擎,目前使用非常广泛基本所有的网站和项目,我想都会优先选择这个,这个也有很好的诊断和微调的工具.我发现其中一个缺点,就是磁盘空间管理时设计非常低效.这个设计成给所有数据都存到 ibdata1 文件,所以这个文件的存储空间会不断的扩展.InnoDB 并不会收缩这些空间,就算你删除表和数据库.

所以我们需要注意我们的配置.最好一开始就使用 innodb_file_per_table 的选项.这样可以使得更加灵活性的给数据存到每个单表的数据库. 我非常不幸地, 最开始我的数据并没有考虑这个所以没有打开这个参数.后来我测试过,在之后打开这个参数根本不能生效.所以只能 dump 整个数据库,然后在启动这个参数后重新恢复数据库才行.这时我们在想有没有法子,不用关掉数据库的服务时就能完成这个工作.

目前看来只能使用 mysqldump 输出,然后才能恢复.所以我们只能使用 MySQL 的主从模式来切换,才能最大限度地减少停机时间.

所以,我使用的基本步骤是:

配置为当前的原始数据库为 Master 数据库.
使用 Xtrabackup 来备份你的原始数据库.
恢复你的备份和到第二个 MySQL 的实例上.
恢复,但不同步,然后运行 mysqldump 在第二个做为 Slave 的数据库上然后导出.
停止第二个数据库实例,并删除数据库.
创建一个新的数据库,使用前面导出的数据来恢复 MySQL 的实例,记得先要打开 innodb_file_per_table 的选项恢复.
配置这个数据库为 slave 然后运行复制.
当复制完成时,给这个 slave 切换成主,然后重新配置你的客户端使用这个实例
现在可以停止主数据库和删除它.

下面是详细的步骤
准备,配置数据库主从

这个看以前的 Blog 有讲怎么在线做 MySQL 的主从.接下来在 Slave 上做转换的操作

Dump 出 Slave 上的数据

假设你根据我以前的文章都做好了.现在配置好 slave 了.记得使用 innobackupex-1.5.1 –apply-log 恢复后,然后复制到数据库的目录.并修改权限.

这时记得先不要设置同步.直接启动数据后.直接使用 MySQL 的 mysqldump 来导出整个数据库.

service mysqld start
mysqldump -uroot -p –quick –default-character-set=utf8 bbsee >dump_data.sql
service mysqld stop

创建新的数据库

在新的机器上.安装新的数据库文件.只保留 dump_data.sql.然后使用 mysql_install_db 来建权限数据,MySQL 的数据库

mysql_install_db –user=mysql

创建新的配置文件

vim /etc/mysql/my.cnf

添加以下行到新的文件:

innodb_file_per_table = 1
server-id = 2
bin-log = 1

我在次声明,这是成功的关键,innodb_file_per_table 会让过一会导入的数据按表来存, binlog 是为了以后切主的时候使用.

启动 MySQL的并配置 Slave 的同步

先要启动数据库

server mysqld start

恢复导出的数据库

mysql -uroot -p –default-character-set=utf8 < dump_data.sql

配置复制
因为刚导入数据库,所以要从现在开始复制,需要在主数据库上根据我以前的文章,给这个设置好权限,然后我们在 Slave 配置一下 slave 的设置

change master to master_host=’127.0.0.1′,
master_user=’repl’,
master_password=’passwd’,
master_port=3306,
master_log_file=’mysql-bin.000001′,
master_log_pos=3874;
start slave;

这个中的 master_log_file 和 master_log_pos 是根据我以前文章刚开始使用 innobackupex 做主数据备份时 xtrabackup_binlog_info 中的信息

mysql -uroot -p -e “show slave status\G”|grep Seconds

当MySQL显示 Seconds_Behind_Master: 0 时,这就 Slave 就同步的和主数据库一样了.

主从切换

现在备份完 Salve 也同步成和主一样,这时因为使用了 innodb_file_per_table 的参数,所以可以切成主了.直接在主数据库中锁一下数据库

SET global read_only=1;

然后查看主数据库的状态,写 binlog 到那个文件,什么位置了.

SHOW master STATUS;

接着到 Slavle 的数据库上看看是不同步到一样的状态了.

SHOW slave STATUS \G;

确保主从同步的一样后,先到 Slave 上停止 Slave 的复制变成新的 master,这时才方便切成主,所以要在新的 master上执行

stop slave
change master to master_host=”
reset slave
reset maters

之所以要在新的master上执行change master to master_host=”及reset slave,主要是为了断开与老的master之间连接信息.

现在切完了,可以根据以前设置 msater 的经验来给原来的主数据库设置成这个的 slave .也可以给这个重新备份一个出来,在恢复了.

其实可以在凌晨的时候,直接alter table sk engine=innodb; 就更换为独立表空间了。用不着原文这样复杂,不过这篇文章我们可以看到如何做数据的热迁移和其他的一些工作步骤。