`

Mysql繁忙主从库在线修改表结构与添加索引问题

 
阅读更多
原文地址:http://www.itpub.net/thread-1841034-1-1.html



本帖最后由 jan_1985 于 2014-1-15 13:28 编辑


Mysql繁忙主从库在线修改表结构与添加索引问题
一直以来,生产情况下都有修改索引和修改字段的需求,但是对锁表引起的访问不便是会严重影响到在线业务的。
以前对于索引修改都是在其中一台从库中执行,然后将查询转到相应的服务器上,这种方式不便于服务器变更的情况,也不能满足表结构的修改的情形。
经过测试openark-kit这个套件下oak-online-alter-table这个工具可以实现在线修改表结构,我已经正式在主库使用了4次,目前来说运行良好。
应用环境: Mysql 5.1
工具版本:   openark-kit-180
工具的局限性:
    The table must have at least one UNIQUE KEY (may expand one or more columns)
    The altered table must share a UNIQUE KEY with the original one
    No 'AFTER' triggers may be defined on the table
    Foreign keys currently not supported
    Table name must be at most 57 characters long
工具的说明页面 http://code.google.com/p/openarkkit/wiki/OakOnlineAlterTableSteps


安装工具:
wget http://openarkkit.googlecode.com/files/openark-kit-180.tar.gz
yum install MySQL-python -y
tar -zxvf openark-kit-180.tar.gz
cd openark-kit-180
python setup.py install

运行:
oak-online-alter-table -H localhost -u myuser --ask-pass -S /tmp/mysql.sock \
      -d dbname --table=dbname.tablename -c 3000
      --alter="add column signup_ip int(11) unsigned NOT NULL DEFAULT '' AFTER signup_time;"



工具的实现原理:
oak-online-alter-table 首先新建一个镜像表,将alter应用上去。再将数据从原表同步到镜像表,最后以镜像表替代原表。
一次从原表取出来到镜像表的记录数量 chunk值的设置依据整个表的记录数量和正常读写量不同而设置合适的配置。
当然,做为一个好的DBA,永远都要有两手准备。预案是少不了的。每次修改前我将备份表,并暂停一个备份从库的同步进程,直到执行完没有问题。

工具执行的SQL:
# 建立包含新结构的表
CREATE TABLE dbname.__oak_tablename LIKE dbname.tablename;
ALTER TABLE dbname.__oak_tablename add column signup_ip int(11) unsigned NOT NULL DEFAULT '' AFTER signup_time;
# 建立触发器,使新表与旧表在工具执行期间保持数据同步
CREATE DEFINER=`root`@`%` TRIGGER dbname.tablename_AD_oak AFTER DELETE ON dbname.tablename
        FOR EACH ROW
            DELETE FROM dbname.__oak_tablename WHERE (id) = (OLD.id);
CREATE DEFINER=`root`@`%` TRIGGER dbname.tablename_AU_oak AFTER UPDATE ON dbname.tablename
        FOR EACH ROW
        BEGIN
            DELETE FROM dbname.__oak_tablename WHERE (id) = (OLD.id);
            REPLACE INTO dbname.__oak_tablename (id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom) VALUES (NEW.id, NEW.signup_time, NEW.login_disid, NEW.isolduser, NEW.signup_siteman, NEW.login_time, NEW.signup_mid, NEW.signup_gid, NEW.signup_webads, NEW.signup_disid, NEW.member_id, NEW.login_gid, NEW.signupfrom);
        END;
CREATE DEFINER=`root`@`%` TRIGGER dbname.tablename_AI_oak AFTER INSERT ON dbname.tablename
        FOR EACH ROW
            REPLACE INTO dbname.__oak_tablename (id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom) VALUES (NEW.id, NEW.signup_time, NEW.login_disid, NEW.isolduser, NEW.signup_siteman, NEW.login_time, NEW.signup_mid, NEW.signup_gid, NEW.signup_webads, NEW.signup_disid, NEW.member_id, NEW.login_gid, NEW.signupfrom);

#将数据从旧表插入到新表 chunk模式插入数据.并且随时保持同步。
SET @`unique_key_range_start_0`:=1/*!*/;
SET @`unique_key_range_end_0`:=3000/*!*/;

SET TIMESTAMP=1357542299/*!*/;
INSERT IGNORE INTO dbname.__oak_tablename (id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom)
            (SELECT id, signup_time, login_disid, signup_siteman, login_time, signup_mid, signup_gid, signup_webads, signup_disid, login_gid, signupfrom FROM dbname.tablename
            WHERE
                (((id > @unique_key_range_start_0) OR ((id = @unique_key_range_start_0)))
                AND
                ((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))
            )
/*!*/;
........... 略
#delete 那些在旧表中不存在(执行期间被删除的记录)的数据.
SET @`unique_key_range_start_0`:=1/*!*/;
SET @`unique_key_range_end_0`:=3000/*!*/;
DELETE FROM dbname.__oak_tablename
        WHERE
            (((id > @unique_key_range_start_0) OR ((id = @unique_key_range_start_0)))
            AND
            ((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))
        AND (id) NOT IN
            (SELECT id FROM dbname.tablename
            WHERE
                (((id > @unique_key_range_start_0) OR ((id = @unique_key_range_start_0)))
                AND
                ((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))
            );
SET @`unique_key_range_start_0`:=3000/*!*/;
SET @`unique_key_range_end_0`:=6000/*!*/;
DELETE FROM dbname.__oak_tablename
        WHERE
            (((id > @unique_key_range_start_0))
            AND
            ((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))
        AND (id) NOT IN
            (SELECT id FROM dbname.tablename
            WHERE
                (((id > @unique_key_range_start_0))
                AND
                ((id < @unique_key_range_end_0) OR ((id = @unique_key_range_end_0))))
            );

........... 略
#替换旧表
RENAME TABLE
            dbname.tablename TO dbname.__arc_tablename,
            dbname.__oak_tablename TO dbname.tablename;
DROP TABLE IF EXISTS dbname.__arc_tablename;


Mysql, 主从, 在线, 索引, 生产
分享到:
评论

相关推荐

    mysql主从库配置

    ### MySQL 主从库配置详解 ...通过以上步骤,我们可以成功搭建起 MySQL 的主从库结构,实现了数据的自动同步。这种架构不仅可以提高数据的安全性,还可以通过合理规划负载均衡策略,提升整体系统的性能。

    《深入理解MySQL主从原理32讲》推荐篇

    《深入理解MySQL主从原理32讲》专栏包含GTID部分、Event部分、主库部分、从库部分四大块来详细讲解主从原理。希望能帮助读者朋友们解决关于主从同步中的一些疑问。八怪写作风格很是严谨,几乎每篇都是从源码入手去...

    SpringBoot第 12 讲:SpringBoot+MySQL主从复制、读写分离

    在本讲中,我们将深入探讨如何使用SpringBoot与MySQL实现主从复制以及读写分离的架构设计。这一技术方案在大型分布式系统中尤为常见,它能够有效地提高数据库系统的可用性和性能。 首先,让我们理解主从复制的核心...

    mysql 多主从一 windows

    mysql 多主从一 windows

    Mysql 5.6.26 主从搭建完整版.pdf

    在本篇文章中,我们将详细介绍基于MySQL 5.6.26版本,如何搭建主从复制模式,并解决搭建过程中可能遇到的问题。文章内容涉及环境配置、MySQL安装、配置文件修改、主从同步设置等多个方面,为读者提供一个完整搭建...

    MySQL实现主从复制

    - **监控与调整**:经常检查`SHOW SLAVE STATUS`以确认从库的同步状态,如`Slave_IO_Running`和`Slave_SQL_Running`应为`Yes`,如果有问题,可能需要调整`server-uuid`或解决网络问题。 在实际业务场景中,为了提高...

    MySQL主从安装部署

    ### MySQL主从安装部署知识点详解 #### 一、MySQL主从安装部署概述 MySQL 主从复制是一种常见的数据备份和负载均衡技术,在多个服务器之间同步数据。通过设置一个或多个从服务器来复制主服务器上的数据变更操作,...

    MYSQL数据库主从复制高可用技术改造环境部署方案

    ### MySQL数据库主从复制高可用技术改造环境部署方案 #### 安装部署DRBD DRBD(Distributed Replicated Block Device)是一种分布式复制块设备,主要用于实现数据在两台或多台服务器之间的实时同步,以此来构建高...

    MySQL高级 主从复制——个人总结

    MySQL主从复制是一种数据库同步技术,可以将一台MySQL服务器(称为master)上的数据变动实时复制到一台或多台MySQL服务器(称为slave)上。这种复制技术对于数据备份、读写分离、负载均衡和故障恢复等方面具有重要...

    MySQL数据库主从配置

    MySQL 数据库主从配置 MySQL 数据库主从配置是指在 MySQL 数据库中实现主从复制的配置过程。该配置过程主要涉及到主服务器和从服务器的配置,旨在实现数据库的实时同步。 首先,需要在主服务器上打开二进制日志,...

    Mysql 主从1062问题修复

    在MySQL的主从复制中,主库的更改被记录到二进制日志(binlog),然后从库通过IO线程从主库获取这些日志并应用到自己的中继日志(relay log)。SQL线程则读取中继日志并执行相应的SQL语句,使从库与主库保持同步。 ...

    MySQL 5.7主从复制.pdf

    在这样的背景下,主从复制技术应运而生,它允许将一个MySQL数据库服务器(主服务器)的数据更新操作自动地复制到一个或多个MySQL数据库服务器(从服务器)上。 在MySQL 5.7版本中,主从复制机制得到了优化和增强,...

    MySQL 5.7主从复制

    MySQL 5.7主从复制是数据库高可用性和负载均衡的一种常见实现方式,它通过将主数据库(Master)上的写操作同步到一个或多个从数据库(Slave)来实现数据的冗余备份和读写分离。在Java开发中,MySQL主从复制常常用于...

    mysql集群主从安装总结

    ### MySQL集群主从安装总结 在本篇文章中,我们将详细探讨如何进行MySQL集群的主从复制配置,并通过一系列具体的步骤来实现这一目标。MySQL主从复制是一种常见的数据冗余技术,它能够帮助我们构建高可用性和高可靠...

Global site tag (gtag.js) - Google Analytics