暂无图片
暂无图片
5
暂无图片
暂无图片
暂无图片

MYSQL-PTONLINE 改分区表

912

上次用ONLINE DDL 来改分区,结果是锁表比较严重,对24小时必须运行的系统来说,有点不能接受! 那些有停机维护的窗口的业务还是不错的选择,毕竟能用SQL解决的问题,相对其它办法来说更简单容易.

下面用PT ONLINE 工具来改造, 该工具大约28MB. 在CENTOS7上面测试

下载地址:https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html

#
#01 CENTOS 7需要安装两个预先包
tar -zxvf  percona-toolkit3.3.1.tar.gz
yum -y install perl-CPAN
yum -y  install perl-Time-HiRes

#
#该工具可能还需要一些依赖包,直接执行不成功时一般会有提示,这里可以提前yum安装
yum install perl-DBI
yum install perl-DBD-MySQL
yum install perl-Time-HiRes
yum install perl-IO-Socket-SSL

编译安装


perl Makefile.PL
make
make install


看得出该脚本基本上用PERL语言搞的.


先用ONLINE DDL 来做分区主键和唯一索引


## 02 SQL

## 0201    
ALTER TABLE `dba_test_big_table_source`.`dba_unique_test` DROP INDEX flow_no_idx;

## 0202 创建为普通索引
CREATE INDEX `flow_no_idx` USING BTREE ON `dba_test_big_table_source`.`dba_unique_test` (`flow_no`);

## 0203 修改表主键把分区字段添加到主键列表中
ALTER TABLE `dba_test_big_table_source`.`dba_unique_test`  DROP PRIMARY KEYADD PRIMARY KEY(`id`,`create_time`) ;


接下来就是我们工具的使用了


##03 VIM pt_online.sh 注意时间的双引号
clear
pt-online-schema-change --print --statistics \
    --progress time,30 --preserve-triggers \
    --max-load=threads_running=100,threads_connected=200 \
    --critical-load=threads_running=1000  \
    --chunk-size=1000 --charset=utf8 --no-version-check \
    --alter-foreign-keys-method auto \
    --user=root  --password=123456  h=192.168.2.220,P=3306,D=dba_test_big_table_source,t=dba_unique_test \
   --alter '
partition by range(to_days(`create_time`))
(
 PARTITION create_time_20210902 VALUES LESS THAN (to_days("2021-09-02")),
 PARTITION create_time_DEFAULTE VALUES LESS THAN MAXVALUE 
);'
\
  --dry-run
 ##--execute


其实前面一大堆参数基本上都可以保留,通用性比较强. 我们看下各个参数的解释

###MEMO
--print:打印工具执行的SQL语句。
--statistics:打印统计信息。
--pause-file:当指定的文件存在时,终止执行。
--max-load:超过指定负载时,暂定执行   默认为Threads_running=25
--critical-load:超过指定负载时,终止执行
--chunck-size:指定每次复制的行数
--alter-foreign-keys-method:指定外键更新方式
--progress:copy进度打印的频率
--charset=utf8 使用utf8编码,避免中文乱码
--no-version-check 不检查版本,在阿里云服务器中一般加入此参数,否则会报错
--dry-run 不真实运行,只是检查语法
--execute 真实执行

##涉及从库的参数
--max-lag    默认1s。每个chunk拷贝完成后,会查看所有复制Slave的延迟情况。要是延迟大于该值,则暂停复制数据,直到所有从的滞后小于这个值,使用Seconds_Behind_Master。如果有任何从滞后超过此选项的值,则该工具将睡眠--check-interval指定的时间,再检查。如果从被停止,将会永远等待,直到从开始同步,并且延迟小于该值。如果指定--check-slave-lag,该工具只检查该服务器的延迟,而不是所有服务器。
--check-slave-lag 指定一个从库的DSN连接地址,如果从库超过--max-lag参数设置的值,就会暂停操作。  
--recursion-method    默认是show processlist,发现从的方法,也可以是host,但需要在从上指定report_host,通过show slave hosts来找到,可以指定none来不检查Slave。 
--check-interval   默认是1。--max-lag检查的睡眠时间。 
--[no]check-replication-filters    默认yes。如果工具检测到服务器选项中有任何复制相关的筛选,如指定binlog_ignore_db和replicate_do_db此类。发现有这样的筛选,工具会报错且退出。因为如果更新的表Master上存在,而Slave上不存在,会导致复制的失败。使用–no-check-replication-filters选项来禁用该检查


具体执行过程.. 中间搞个新表,然后新建3个触发器,接着COPY数据,然后RENAME


[root@CENTOS7GUI ~]# sh pt_online.sh 
No slaves found.  See --recursion-method if host localhost.localdomain has slaves.
Not checking slave lag because no slaves were found and --check-slave-lag was not specified.
Operation, tries, wait:
  analyze_table, 10, 1
  copy_rows, 10, 0.25
  create_triggers, 10, 1
  drop_triggers, 10, 1
  swap_tables, 10, 1
  update_foreign_keys, 10, 1
No foreign keys reference `dba_test_big_table_source`.`dba_unique_test`; ignoring --alter-foreign-keys-method.
Altering `dba_test_big_table_source`.`dba_unique_test`...


Creating new table...
CREATE TABLE `dba_test_big_table_source`.`_dba_unique_test_new` (
  `Id` bigint(20NOT NULL AUTO_INCREMENT,
  `amount` decimal(20,2NOT NULL,
  `status` smallint(3NOT NULL,
  `flow_no` varchar(33NOT NULL COMMENT '流水号',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`Id`,`create_time`),
  UNIQUE KEY `idx_id_time` (`Id`,`create_time`USING BTREE,
  UNIQUE KEY `idx_flow_time` (`flow_no`,`create_time`USING BTREE,
  KEY `idx_btree_flow` (`flow_no`USING BTREE
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='用户流水表'
Created new table dba_test_big_table_source._dba_unique_test_new OK.

Altering new table...
ALTER TABLE `dba_test_big_table_source`.`_dba_unique_test_new` 
partition by range(to_days(`create_time`))
(
 PARTITION create_time_20210902 VALUES LESS THAN (to_days("2021-09-02")),
 PARTITION create_time_DEFAULTE VALUES LESS THAN MAXVALUE 
);
Altered `dba_test_big_table_source`.`_dba_unique_test_new` OK.


3个触发器

2021-09-06T15:47:19 Creating triggers...
-----------------------------------------------------------
Event : DELETE 
Name  : pt_osc_dba_test_big_table_source_dba_unique_test_del 
SQL   : CREATE TRIGGER `pt_osc_dba_test_big_table_source_dba_unique_test_del` AFTER DELETE ON `dba_test_big_table_source`.`dba_unique_test` 
FOR EACH ROW BEGIN DECLARE CONTINUE HANDLER FOR 1146 begin end;
 DELETE IGNORE 
 FROM `dba_test_big_table_source`.`_dba_unique_test_new` 
 WHERE `dba_test_big_table_source`.`_dba_unique_test_new`.`id` <=> OLD.`id` 
 AND `dba_test_big_table_source`.`_dba_unique_test_new`.`create_time` <=> OLD.`create_time`;
 END  
Suffix: del 
Time  : AFTER 
-----------------------------------------------------------
-----------------------------------------------------------
Event : UPDATE 
Name  : pt_osc_dba_test_big_table_source_dba_unique_test_upd 
SQL   : CREATE TRIGGER `pt_osc_dba_test_big_table_source_dba_unique_test_upd` AFTER UPDATE ON `dba_test_big_table_source`.`dba_unique_test` 
FOR EACH ROW BEGIN DECLARE CONTINUE HANDLER FOR 1146 begin end;
 DELETE IGNORE 
 FROM `dba_test_big_table_source`.`_dba_unique_test_new` 
 WHERE !(OLD.`id` <=> NEW.`id` 
 AND OLD.`create_time` <=> NEW.`create_time`
 AND `dba_test_big_table_source`.`_dba_unique_test_new`.`id` <=> OLD.`id` 
 AND `dba_test_big_table_source`.`_dba_unique_test_new`.`create_time` <=> OLD.`create_time`
 REPLACE INTO `dba_test_big_table_source`.`_dba_unique_test_new` (....) VALUES (NEW.*); 
 END  
Suffix: upd 
Time  : AFTER 
-----------------------------------------------------------
-----------------------------------------------------------
Event : INSERT 
Name  : pt_osc_dba_test_big_table_source_dba_unique_test_ins 
SQL   : CREATE TRIGGER `pt_osc_dba_test_big_table_source_dba_unique_test_ins` AFTER INSERT ON `dba_test_big_table_source`.`dba_unique_test` 
FOR EACH ROW BEGIN DECLARE CONTINUE HANDLER FOR 1146 begin end;
 REPLACE INTO `dba_test_big_table_source`.`_dba_unique_test_new` (*) VALUES (NEW.*);
 END  
Suffix: ins 
Time  : AFTER 
-----------------------------------------------------------
2021-09-06T15:47:19 Created triggers OK.


重要的拷贝数据

2021-09-06T15:47:19 Copying approximately 997472 rows...
INSERT LOW_PRIORITY IGNORE INTO `dba_test_big_table_source`.`_dba_unique_test_new` (...) 
SELECT * FROM `dba_test_big_table_source`.`dba_unique_test` FORCE INDEX(`PRIMARY`
WHERE ((`id` > ?) OR (`id` = ? AND `create_time` >= ?)) 
AND ((`id` < ?) OR (`id` = ? AND `create_time` <= ?)) 
LOCK IN SHARE MODE /*pt-online-schema-change 21612 copy nibble*/

SELECT /*!40001 SQL_NO_CACHE */ `id``id``create_time` FROM `dba_test_big_table_source`.`dba_unique_test` FORCE INDEX(`PRIMARY`
WHERE ((`id` > ?) OR (`id` = ? AND `create_time` >= ?)) 
ORDER BY `id``create_time` LIMIT ?, 2 /*next chunk boundary*/

Copying `dba_test_big_table_source`.`dba_unique_test`:  7300:10 remain
2021-09-06T15:48:00 Copied rows OK.


改名 删触发器


Copying `dba_test_big_table_source`.`dba_unique_test`:  73% 00:10 remain
2021-09-06T15:48:00 Copied rows OK.

2021-09-06T15:48:00 Adding original triggers to new table.
2021-09-06T15:48:00 Analyzing new table...

2021-09-06T15:48:00 Swapping tables...
RENAME TABLE `dba_test_big_table_source`.`dba_unique_test` TO `dba_test_big_table_source`.`_dba_unique_test_old``dba_test_big_table_source`.`_dba_unique_test_new` TO `dba_test_big_table_source`.`dba_unique_test`
2021-09-06T15:48:00 Swapped original and new tables OK.

2021-09-06T15:48:00 Dropping old table...
DROP TABLE IF EXISTS `dba_test_big_table_source`.`_dba_unique_test_old`
2021-09-06T15:48:00 Dropped old table `dba_test_big_table_source`.`_dba_unique_test_old` OK.

2021-09-06T15:48:00 Dropping triggers...
DROP TRIGGER IF EXISTS `dba_test_big_table_source`.`pt_osc_dba_test_big_table_source_dba_unique_test_del`
DROP TRIGGER IF EXISTS `dba_test_big_table_source`.`pt_osc_dba_test_big_table_source_dba_unique_test_upd`
DROP TRIGGER IF EXISTS `dba_test_big_table_source`.`pt_osc_dba_test_big_table_source_dba_unique_test_ins`
2021-09-06T15:48:00 Dropped triggers OK.
# Event  Count
# ====== =====
# INSERT  1002
Successfully altered `dba_test_big_table_source`.`dba_unique_test`.


文章转载自海鲨数据库架构师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论