1. 程式人生 > >pt-online-schema-change大表結構修改利器

pt-online-schema-change大表結構修改利器

簡介:

pt-online-schema-change是Percona-toolkit一員,通過改進原生ddl的方式,達到不鎖表線上修改表結構。

pt-osc工作過程
1. 建立一個和要執行 alter 操作的表一樣的新的空表結構(是alter之前的結構)
1. 在新表執行alter table 語句(速度應該很快)
1. 在原表中建立觸發器3個觸發器分別對應insert,update,delete操作
1. 以一定塊大小從原表拷貝資料到臨時表,拷貝過程中通過原表上的觸發器在原表進行的寫操作都會更新到新建的臨時表
1. Rename 原表到old表中,在把臨時表Rename為原表
1. 如果有參考該表的外來鍵,根據alter-foreign-keys-method引數的值,檢測外來鍵相關的表,做相應設定的處理
1. 預設最後將舊原表刪除

使用之前,請參考安裝Percona-toolkit教程參考:

Percona Toolkit初識

下面是pt-online-scheme-change示例:

在test庫新建表pt:

CREATE TABLE `pt` (
 `id` int(11) NOT NULL DEFAULT '0',
 `disktype` enum('sas','shannon','memdisk') NOT NULL,
 `blocksize` enum('4K','64K','256K','1M') NOT NULL,
 `testmode` enum('seqwr','seqrewr','seqrd'
,'rndrd','rndwr','rndrw') NOT NULL, `thread` enum('1','2','4','8','16','32') NOT NULL, `bandwidth` float(10,2) unsigned NOT NULL, `resptime` float(10,2) unsigned NOT NULL DEFAULT '0.00', PRIMARY KEY (`id`), UNIQUE KEY `id_UNIQUE` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8

我們來上面欄位resptime改為responsetime

#自己修改ip和賬號和密碼
------------------------------------------------------------
~ # pt-online-schema-change --host=127.0.0.1 --user=root --password=123456 --alter "CHANGE resptime responsetime float(10,2) unsigned not NULL default '0'" D=test,t='pt' --execute --print --statistics --no-check-alter  


#執行整個流程輸出
------------------------------------------------------------
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.
*******************************************************************
 Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
 is deprecated! Please set SSL_verify_mode to SSL_VERIFY_PEER
 together with SSL_ca_file|SSL_ca_path for verification.
 If you really don't want to verify the certificate and keep the
 connection open to Man-In-The-Middle attacks please set
 SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
*******************************************************************
  at /usr/bin/pt-online-schema-change line 6948.
*******************************************************************
 Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
 is deprecated! Please set SSL_verify_mode to SSL_VERIFY_PEER
 together with SSL_ca_file|SSL_ca_path for verification.
 If you really don't want to verify the certificate and keep the
 connection open to Man-In-The-Middle attacks please set
 SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
*******************************************************************
  at /usr/bin/pt-online-schema-change line 6948.

# A software update is available:
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
Altering `test`.`pt`...
Renaming columns:
  resptime to responsetime
Creating new table...
CREATE TABLE `test`.`_pt_new` (
  `id` int(11) NOT NULL DEFAULT '0',
  `disktype` enum('sas','shannon','memdisk') NOT NULL,
  `blocksize` enum('4K','64K','256K','1M') NOT NULL,
  `testmode` enum('seqwr','seqrewr','seqrd','rndrd','rndwr','rndrw') NOT NULL,
  `thread` enum('1','2','4','8','16','32') NOT NULL,
  `bandwidth` float(10,2) unsigned NOT NULL,
  `resptime` float(10,2) unsigned NOT NULL DEFAULT '0.00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Created new table test._pt_new OK.
Altering new table...
ALTER TABLE `test`.`_pt_new` CHANGE resptime responsetime float(10,2) unsigned not NULL default '0'
Altered `test`.`_pt_new` OK.
2018-01-07T16:36:29 Creating triggers...
2018-01-07T16:36:29 Created triggers OK.
2018-01-07T16:36:29 Copying approximately 1 rows...
INSERT LOW_PRIORITY IGNORE INTO `test`.`_pt_new` (`id`, `disktype`, `blocksize`, `testmode`, `thread`, `bandwidth`, `responsetime`) SELECT `id`, `disktype`, `blocksize`, `testmode`, `thread`, `bandwidth`, `resptime` FROM `test`.`pt` LOCK IN SHARE MODE /*pt-online-schema-change 7706 copy table*/
2018-01-07T16:36:29 Copied rows OK.
2018-01-07T16:36:29 Analyzing new table...
2018-01-07T16:36:29 Swapping tables...
RENAME TABLE `test`.`pt` TO `test`.`_pt_old`, `test`.`_pt_new` TO `test`.`pt`
2018-01-07T16:36:29 Swapped original and new tables OK.
2018-01-07T16:36:29 Dropping old table...
DROP TABLE IF EXISTS `test`.`_pt_old`
2018-01-07T16:36:29 Dropped old table `test`.`_pt_old` OK.
2018-01-07T16:36:29 Dropping triggers...
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_pt_del`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_pt_upd`
DROP TRIGGER IF EXISTS `test`.`pt_osc_test_pt_ins`
2018-01-07T16:36:29 Dropped triggers OK.
# Event  Count
# ====== =====
# INSERT     1
Successfully altered `test`.`pt`.

成功看到:

mysql> show create table pt;

| pt    | CREATE TABLE `pt` (
  `id` int(11) NOT NULL DEFAULT '0',
  `disktype` enum('sas','shannon','memdisk') NOT NULL,
  `blocksize` enum('4K','64K','256K','1M') NOT NULL,
  `testmode` enum('seqwr','seqrewr','seqrd','rndrd','rndwr','rndrw') NOT NULL,
  `thread` enum('1','2','4','8','16','32') NOT NULL,
  `bandwidth` float(10,2) unsigned NOT NULL,
  `responsetime` float(10,2) unsigned NOT NULL DEFAULT '0.00',#改變了
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

新增一個欄位p1

------------------------------------------------------------
~ # pt-online-schema-change --host=127.0.0.1 --user=root --password=123456 --alter "add p1 float(10,2) not NULL default '0'" D=test,t='pt' --execute --print --statistics --no-check-alter

成功看到:

----------------------------------------------------------+
| pt    | CREATE TABLE `pt` (
  `id` int(11) NOT NULL DEFAULT '0',
  `disktype` enum('sas','shannon','memdisk') NOT NULL,
  `blocksize` enum('4K','64K','256K','1M') NOT NULL,
  `testmode` enum('seqwr','seqrewr','seqrd','rndrd','rndwr','rndrw') NOT NULL,
  `thread` enum('1','2','4','8','16','32') NOT NULL,
  `bandwidth` float(10,2) unsigned NOT NULL,
  `responsetime` float(10,2) unsigned NOT NULL DEFAULT '0.00',
  `p1` float(10,2) NOT NULL DEFAULT '0.00',  #新增一列
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |