网站首页 > 博客文章 正文
一 MySQL在线DDL工具pt-osc
1.1 背景介绍
为什么会介绍这个pt-osc呢?因为我们在做DDL的时候为了防止阻塞DML通常会用到这个工具.其实从mysql5.7版本开始.mysql提供了inplace方式的DDL.目前大多数操作都可以使用inplace方式完成.但还是有些场景不能使用到inplace方式.还需要使用原始的copy方式.如果是copy的话.那么就会阻塞DML了.这时候就引入了我们这个工具了.PS:MySQL8.0开始加入了instant的DDL方式.大家有兴趣可以去官网了解
推荐大家看一下我对pt-osc和gh-ost及MySQL原生DDL的压测性能对比文章
1.2 pt-osc工作原理介绍
1. 创建一个与原表结构相同的空表,表名是 _new 后缀;
2. 修改步骤 1 创建的空表的表结构;
3. 在原表上加三个触发器:delete/update/insert,用于 copy 数据过程中,将原表中要执行的语句在新表中执行;
4. 将原表数据以数据块(chunk)的形式 copy 到新表;
5. rename 原表为 old 表,并把新表 rename 为原表名,然后删除旧表;
6. 删除触发器。
1.3 pt-osc限制
1. 原表上要有 primary key 或 unique index,因为当执行该工具时会创建一个 DELETE 触发器来更新新表;
注意:一个例外的情况是 –alter 指定的子句中是在原表中的列上创建 primary key 或 unique index,这种情况下将使用这些列用于 DELETE 触发器。
2. 不能使用 rename 子句来重命名表;
3. 列不能通过删除 + 添加的方式来重命名,这样将不会 copy 原有列的数据到新列;
4. 如果要添加的列是 not null,则必须指定默认值,否则会执行失败;
5. 删除外键约束(DROP FOREIGN KEY constraint_name),外键约束名前面必须添加一个下划线 ‘_’,即需要指定名称 _constraint_name,而不是原始的 constraint_name;
1.4 参数介绍
文末附参数介绍
1.5 使用方法
[root@slowquery ~]# pt-online-schema-change --print --statistics --progress time,30 --preserve-triggers --user=root --password=123 --alter 'add column name varchar(20)' h=localhost,P=3306,D=increment,t=sbtest1 --pause-file=/tmp/ptosc.txt --max-load=threads_running=100,threads_connected=200 --critical-load=threads_running=1000 --chunk-size=1000 --alter-foreign-keys-method auto --execute
No slaves found. See --recursion-method if host slowquery 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 `increment`.`sbtest1`; ignoring --alter-foreign-keys-method.
Altering `increment`.`sbtest1`...
Creating new table...
CREATE TABLE `increment`.`_sbtest1_new` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=5000001 DEFAULT CHARSET=latin1
Created new table increment._sbtest1_new OK.
Altering new table...
ALTER TABLE `increment`.`_sbtest1_new` add column name varchar(20)
Altered `increment`.`_sbtest1_new` OK.
2021-07-26T14:13:22 Creating triggers...
2021-07-26T14:13:22 Created triggers OK.
2021-07-26T14:13:22 Copying approximately 4673705 rows...
INSERT LOW_PRIORITY IGNORE INTO `increment`.`_sbtest1_new` (`id`, `k`, `c`, `pad`) SELECT `id`, `k`, `c`, `pad` FROM `increment`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ?)) AND ((`id` <= ?)) LOCK IN SHARE MODE /*pt-online-schema-change 28750 copy nibble*/
SELECT /*!40001 SQL_NO_CACHE */ `id` FROM `increment`.`sbtest1` FORCE INDEX(`PRIMARY`) WHERE ((`id` >= ?)) ORDER BY `id` LIMIT ?, 2 /*next chunk boundary*/
Copying `increment`.`sbtest1`: 22% 01:43 remain
Copying `increment`.`sbtest1`: 43% 01:17 remain
Copying `increment`.`sbtest1`: 64% 00:50 remain
Copying `increment`.`sbtest1`: 84% 00:22 remain
2021-07-26T14:15:57 Copied rows OK.
2021-07-26T14:15:57 Adding original triggers to new table.
2021-07-26T14:15:57 Analyzing new table...
2021-07-26T14:15:57 Swapping tables...
RENAME TABLE `increment`.`sbtest1` TO `increment`.`_sbtest1_old`, `increment`.`_sbtest1_new` TO `increment`.`sbtest1`
2021-07-26T14:15:57 Swapped original and new tables OK.
2021-07-26T14:15:57 Dropping old table...
DROP TABLE IF EXISTS `increment`.`_sbtest1_old`
2021-07-26T14:15:57 Dropped old table `increment`.`_sbtest1_old` OK.
2021-07-26T14:15:57 Dropping triggers...
DROP TRIGGER IF EXISTS `increment`.`pt_osc_increment_sbtest1_del`
DROP TRIGGER IF EXISTS `increment`.`pt_osc_increment_sbtest1_upd`
DROP TRIGGER IF EXISTS `increment`.`pt_osc_increment_sbtest1_ins`
2021-07-26T14:15:57 Dropped triggers OK.
# Event Count
# ====== =====
# INSERT 5000
Successfully altered `increment`.`sbtest1`.
使用到的参数解释:
- –print:打印工具执行的 SQL 语句。
- –statistics:打印统计信息。
- –pause-file:当指定的文件存在时,终止执行。
- –max-load:超过指定负载时,暂定执行。
- –critical-load:超过指定负载时,终止执行。
- –chunck-size:指定每次复制的行数。
- –alter-foreign-keys-method:指定外键更新方式。
- –progress:copy 进度打印的频率。
查看是否加列成功:
加列之前的sbtest1:
mysql> desc sbtest1;
+-------+-----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| k | int(11) | NO | MUL | 0 | |
| c | char(120) | NO | | | |
| pad | char(60) | NO | | | |
+-------+-----------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
执行完了之后的sbtest1:
mysql> desc sbtest1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| k | int(11) | NO | MUL | 0 | |
| c | char(120) | NO | | | |
| pad | char(60) | NO | | | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
1.6 总结
这篇文章主要分享了pt-osc在线DDL工具的使用.其实无论是什么工具.大家都还是要避开业务高峰期执行.使用pt-osc只是会让DDL的这个过程温柔一点.并不能避免阻塞DML.
参数解释:
① 常用基本
–dry-run
- 相当于真正执行前的测试。不会对原表做更改,只会创建和修改新表(不执行创建触发器、复制数据或替换原始表)
–execute
- 真正执行 DDL
–user, -u
- 用于登录的用户名
–password, -p
- 指定密码,如果密码中包含逗号,必须使用反斜杠转义。
–host, -h
- 指定连接的主机。
–port, -P
- 指定端口号。
–socket
- -S,指定用于连接的 socket 文件
–ask-pass
- 不在命令行中指定密码,连接到 MySQL 时,提示输入密码。
–alter “string”
- 指定表结构变更语句。不需要 ALTER TABLE 关键字,可以指定多个更改,用逗号隔开。
–database, -D
- 指定数据库
② 控制输出形式
- 将工具执行的 SQL 语句打印到 STDOUT,可以和 –dry-run 同时使用。
–progress
- type: array; default: time,30
- 在复制行时,将进度报告打印到 STDERR。该值是一个逗号分隔的列表,由两部分组成。第一部分可以是 percentage, time, iterations(每秒打印次数);第二部分指定对应的数值,表示打印的频率。
–quiet, – q
- 表示不要将信息打印到标准输出(禁用 –progress)。错误和警告仍然打印到 STDERR。
–statistics
- 打印统计信息。
③ 表上行为控制
–alter-foreign-keys-method “string”
- 指定修改外键以使引用新表。
当该工具重命名原始表以让新表取而代之时,外键跟随被重命名的表,因此必须更改外键以引用新表。
支持两种方式:rebuild_constraints 和 drop_swap 。
可选值:
auto:
- 自动决定那种方式是最好的。如果可以使用 rebuild_constraints 则使用,否则使用 drop_swap。
rebuild_constraints
此方法使用 ALTER TABLE 删除并重新添加引用新表的外键约束。这是首选的方式,除非子表(引用 DDL 表中列的表)太大,更改会花费太长时间。
通过比较子表的行数和将行从旧表复制到新表的速度来确定是否使用该方式。
- 如果估计可以在比 –chunk-time 更短的时间内修改子表,那么它将使用这种方式。估计修改子表(引用被修改表)所需的时间方法:行复制率乘以 –chunk-size-limit,因为 MySQL alter table 通常比复制行过程快得多。
说明:
由于 MySQL 中的限制,外键在更改后不能与之前的名称相同。该工具在重新定义外键时必须重命名外键,通常在名称中添加一个前导下划线 ‘_’ 。在某些情况下,MySQL 还会自动重命名外键所需的索引。
drop_swap
禁用外键检查(FOREIGH_KEY_CHECKS=0),先删除原始表,然后将新表重命名到原来的位置。这与交换新旧表的方法不同,后者使用的是客户端应用程序无法检测到的原子 RENAME。
- 这种方式更快,但是有一些风险:在 drop 原表和 rename 临时表之间的一段时间,DDL 的表不存在,查询这个表的语句将会返回报错。如果 rename 执行失败,没有修改成原表名称,但是原表已经被永久删除。
- 这种方式强制使用 –no-swap-tables 和 –no-drop-old-table。
none
这种方式和 drop_swap 类似,但是没有 swap。任何引用原表的外键将会指向一个不存在的表,这样会造成外键违规,在 show engine innodb status 中将会有类似下面的输出:
Trying to add to index `idx_fk_staff_id` tuple:
DATA TUPLE: 2 fields;
0: len 1; hex 05; asc ;;
1: len 4; hex 80000001; asc ;;
But the parent table `sakila`.`staff_old`
or its .ibd file does not currently exist!
这是因为原始表(在本例中为 sakila.staff)被重命名为 sakila.staff_old,然后 drop 掉了。提供了这种处理外键约束的方法,以便数据库管理员可以根据需要禁用该工具的内置功能。
–only-same-schema-fks
- 只在与原始表相同数据库的表上检查外键。这个选项是危险的,因为如果 fks 引用不同数据库中的表,将不会被检测到。
–null-to-not-null
- 允许将允许空值的列修改为不允许空值的列。包含空值的行将被转换为定义的默认值。如果没有给出明确的默认值,MySQL 会根据数据类型指定一个默认值,例如数字数据类型为 0,字符串数据类型为空
–[no]analyze-before-swap
- 默认值:yes
- 在与旧表 swap 之前,在新表上执行 ANALYZE TABLE。在 MySQL 5.6 及更高版本,innodb_stats_persistent 开启的情况下,默认是 yes。
说明:innodb_stats_persistent 为 ON,表示统计信息会持久化存储,OFF 表示统计信息只存储在内存。
–[no]drop-new-table
- 默认值:yes
- 如果复制原始表失败,则删除新表。
- 指定 –no-drop-new-table 和 –no-swap-tables 将保留表的新修改副本,而不修改原始表,见 –new-table-name。
- –no-drop-new-table 不能和 –alter-foreign-keys-method drop_swap 同时使用。
–[no]drop-old-table
- 默认值:yes
- 重命名后删除原始表。在原表被成功重命名以让新表取而代之之后,如果没有错误,该工具将在默认情况下删除原表。如果有任何错误,该工具将保留原始表。如果指定了 –no-swap-tables,则不删除旧表。
–[no]swap-tables
- 默认值:yes
- 交换原始表和修改后的新表。这一步通过使具有新模式的表取代原来的表,从而完成了在线模式更改过程。原始表变成旧表,工具会删除它,除非禁用 –[no]drop-old-table。
使用 –no-swap-tables 会运行整个过程,它会创建新表,复制所有行但最后会删除新表。它的目的是运行一个更现实的演练。
–[no]drop-triggers
- 默认值:yes
- 指定在旧表上删除触发器。–no-drop-old-table 强制 –no-drop-triggers。
–preserve-triggers
- 在指定时保留旧触发器。在 MySQL 5.7.2 中,可以为一个给定的表定义具有相同触发事件和动作时间的多个触发器。这允许我们添加 pt-online-schema-change 所需的触发器,即使表已经有了自己的触发器。如果启用了此选项,那么在开始从原始表复制行之前,pt-online-schema-change 将尝试将所有现有触发器复制到新表,以确保在修改表之后可以应用旧触发器。
例如:
CREATE TABLE test.t1 (
id INT NOT NULL AUTO_INCREMENT,
f1 INT,
f2 VARCHAR(32),
PRIMARY KEY (id)
);
CREATE TABLE test.log (
ts TIMESTAMP,
msg VARCHAR(255)
);
CREATE TRIGGER test.after_update
AFTER
UPDATE ON test.t1
FOR EACH ROW
INSERT INTO test.log \
VALUES (NOW(), CONCAT("updated row row with id ", OLD.id, " old f1:", OLD.f1, " new f1: ", NEW.f1 ));
- 对于这个表和触发器组合,不可能使用 –preserve-triggers 和 –alter “DROP COLUMN f1”,因为触发器引用被删除的列,会导致触发器失败。
- 在测试触发器将在新表上工作之后,触发器将从新表中删除,直到所有行都被复制,然后它们被重新应用。
- –preserve-triggers 不能与 –no-drop-triggers,–no-drop-old-table,–no-swap-tables 这些参数一起使用,因为 –preserve-triggers 意味着旧的触发器应该被删除并在新表中重新创建。由于不可能有多个具有相同名称的触发器,因此必须删除旧的触发器,以便能够在新表中重新创建它们。
- 使用 –preserve-trigger 和 –no-swap-tables 将导致原始表的触发器仍然被定义。如果同时设置了 –no-swap-tables 和 –no-drop-new-table,那么触发器将保留在原始表上,并将复制到新表上(触发器将具有随机后缀,因为没有唯一的触发器名称)。
–new-table-name
- type: string; default: %T_new
- 在交换表之前新建表名。将 %T 替换为原始表名。当使用默认值时,将在名称前添加最多 10 个 ‘_’(下划线),以查找唯一的表名称。如果指定了表名,则不会将其作为前缀,因此该表必须不存在。
–force
- 在使用 –alter-foreign-keys-method = none 的情况下,这个选项会绕过确认。
–tries
- 类型:array
- 遇到错误时,尝试的次数。下面是重试操作,以及它们的默认尝试次数和尝试之间的等待时间(以秒为单位)。
例子:
--tries create_triggers:5:0.5,drop_triggers:5:0.5
格式:
operation:tries:wait[,operation:tries:wait]
- 必须同时指定 3 个值:operation,tries,wait
注意:大多数操作只在 MySQL 5.5 和更新版本中受到 lock_wait_timeout(参见 –set-vars)的影响,因为元数据锁。
对于创建和删除触发器,尝试的次数应用于每个触发器的 create trigger 和 drop trigger 语句。
对于复制行,尝试的次数适用于每个块,不是整个 table。
对于交换表,尝试的次数通常只应用一次,因为通常只有一个 rename table 语句。
对于重新构建外键约束,每个语句都有相应的尝试次数(用于重新构建约束的 alter 语句:–alter-foreign-keys-method;drop_swap 方法的其他语句)
下面这些错误出现时,将会重试,
Lock wait timeout (innodb_lock_wait_timeout and lock_wait_timeout)
Deadlock found
Query is killed (KILL QUERY <thread_id>)
Connection is killed (KILL CONNECTION <thread_id>)
Lost connection to MySQL
错误和重新尝试次数被记录在 –statistics 中。
④ 负载相关
–critical-load
- 类型:Array;默认值:Threads_running=50
- 在复制每个 chunk 之后检查 SHOW GLOBAL STATUS,如果负载太高则终止。该选项接受以逗号分隔的 MySQL 状态变量和阈值列表。格式:variable=MAX_VALUE(或:MAX_VALUE)。如果没有给出,该工具通过在启动时检查默认并将其加倍来确定阈值。
- 参见 –max-load 了解更多细节。不同的是,超过此选项指定的值时终止执行而不是暂停。使用该选项,可以作为一种安全检查,以防当原始表上的触发器给服务器增加过多负载导致停机。
–max-flow-ctl
- 类型:float
- 有点类似于 –max-lag,但是是针对 PXC 集群的。检查用于流控制的集群平均暂停时间,如果超过选项中所示的百分比,则让工具暂停。当检测到任何流控制活动时,0 值将使工具暂停。默认是没有流控制检查。该选项可用于 PXC 版本 5.6 或更高版本。
–max-load
- type: Array; default: Threads_running=25
- 复制每个块后,检查 SHOW GLOBAL STATUS,如果任何状态变量高于其阈值,则暂停执行。格式:variable=MAX 值 ( 或:MAX 值)。如果没有指定,该工具通过检查当前值并将其增加 20% 来确定一个阈值。
–sleep
- 类型:float,默认值:0
- 指定 copy 完每个 chunck 后,sleep 多久。当无法通过 –max-lag 和 –max-load 进行节流时,此选项非常有用。应该使用较小的,sub-second 值,例如 0.1,否则工具将会花费较长的时间来拷贝大表。
⑤ 配置类
–charset “string”, -A
- 指定默认字符集,连接到 MySQL 后执行 set names character。
–default-engine
- 使用系统默认的存储引擎创建新表。
- 默认情况下,创建的新表和原表 engine 相同。当指定该选项时,则去掉建表语句中的 engine 选项,使用系统默认的存储引擎创建新表。
–defaults-file, -F
- 指定配置文件,需指定绝对路径。
–data-dir
- 指定新表的数据文件所在目录。仅可在 5.6 及以上版本使用。如果与 –remove-data-dir 同时使用,则忽略该参数。
–remove-data-dir
- 如果原始表是使用 DATA DIRECTORY 指定了数据文件目录,删除它并在 MySQL 默认数据目录中创建新表,而不创建新的 isl 文件。
–set-vars
- 设置 MySQL 变量列表:variable=value,以逗号分隔。
- 默认情况下,该工具设置下面几个默认变量:
wait_timeout=10000
innodb_lock_wait_timeout=1
lock_wait_timeout=60
–config
- 指定配置文件列表,用逗号分隔,如果指定这个选项,必须是命令行的第一个选项。
–pause-file “string”
- 当此参数指定的文件存在时,将暂停执行 DDL。比如,当 DDL 影响业务时,可创建指定的文件,暂停 DDL。
Sleeping 60 seconds because /tmp/a.txt exists
⑥ 复制 chunk 类
–chunk-size
- 指定每个复制块的行数,默认值:1000。可指定单位:k,M,G。
- 默认复制块的行为是:动态地调整块大小,试图使块在 –chunk-time 秒内复制完成。当没有显式设置此选项时,将使用其默认值作为起点,之后将忽略此选项的值。当如果显示指定该选项时,将禁用动态调整复制块的行为。
–chunk-time
- 指定复制每个数据块所需要的时间。类型:float;默认值:0.5。
- 使用该选项可动态调整块大小,通过跟踪复制率(每秒的行数),并在复制每个数据块之后调整块大小,以使复制下一个数据块执行该选项指定的时间(以秒为单位)。
- 如果将此选项设置为零,则块大小不会自动调整;因此复制每个数据块时间将会变化,但复制块大小不会变化。
–chunk-size-limit
- 复制块的最大限制。类型:float;默认值:4.0。
- 当表没有唯一索引时,块大小可能不准确。此选项指定错误的最大可容忍限制。该工具使用 <EXPLAIN> 来估计块中有多少行。如果估计值超过了期望的块大小乘以限制,那么该工具将跳过该块。
- 这个选项的最小值是 1,这意味着任何块都不能大于 –chunk-size。可以通过指定值 0 来禁用过大块检查。
–chunk-index
- 指定对表进行分块的索引(FORCE index),如果指定索引不存在,那么工具将使用默认的方式选择索引。
–chunk-index-columns
- 指定只使用复合索引中最左边的这么多列。这在 MySQL 查询优化器中的一个 bug 导致它扫描大范围的行,而不是使用索引精确地定位起始点和结束点的情况下非常有用。
⑦ slave 相关
–slave-user
- 类型:字符串
- 指定连接从库的用户。这个用户可以有很少的权限,但是用户一定要是存在的。
–slave-password
- 类型:字符串
- 指定连接到从库的密码,可以和 –slave-user 一块使用,指定的用户和密码在所有从库上必须是一样的。
–channel
- 指定使用复制通道连接到服务器时使用的通道名称。
- 适用场景:多源复制情况下,show slave status 会返回两行,使用此选项指定复制通道。
–max-lag
- type: time; default: 1s
- 指定当从库复制延迟大于该值时,暂停 data copy,直到所有复制的延迟都小于这个值。
- 在复制完每个块后,该工具会连接到所有从库,查看其复制延迟(Seconds_Behind_Master)。如果任何从库的延迟时间超过此选项的值,则工具将休眠 –check-interval 指定的时间,然后再次检查所有从库。如果指定 –check-slave-lag,那么该工具只检查该服务器的延迟,而不是所有服务器。如果希望准确地控制该工具检测哪些服务器,可以使用 –recursion-method 指定 DSN 值。
- 该工具永远等待从实例停止延迟。如果任何从实例停止,该工具将永远等待,直到从实例启动。
–recurse
- type: int
- 发现从实例时在层次结构中要递归的级别数。默认是无限的。
–recursion-method
- type:array; 默认值:processlist,host
- 用于判断是否存在从库的方式,可以的方式有:processlist:show processlist;hosts:show slave hostsdsn=DSN:DSNs from a tablenone:不查找从库
⑧ check 类
–check-interval
- 指定检查 –max-lag 的时间间隔,默认值 1。如果任何从库的延迟时间超过 –max-lag 的值,将休眠 –check-interval 指定的时间,然后再次检查。
–check-slave-lag
- 指定检查延迟的从库,以DSN的方式指定。当延迟超过 –max-lag 时,将暂停 data copy。
–skip-check-slave-lag
- 指定 DSN,跳过检查指定从库延迟,可以指定多个, 例如:
–skip-check-slave-lag h=127.0.0.1,P=12345 –skip-check-slave-lag h=127.0.0.1,P=12346
–[no]check-replication-filters
- 检查从库是否设置 replication filter,如 binlog_ignore_db 和 replicate_do_db,默认值为 yes。如果设置了,则中止执行。因为如果更新的表 Master 上存在,而 Slave 上不存在,会导致复制失败。使用 –no-check-replication-filters 选项来禁用该检查。
–[no]check-alter
- 解析 –alter 指定的值,并警告可能的意外行为,默认值:yes。目前,它检查的有:列名:该工具的早期版本中,用 CHANGE COLUMN name new_name 重命名列会导致该列的数据丢失。现在会尝试解析 alter 语句并捕捉这些情况,因此重命名的列应该具有与原始列相同的数据。但是,执行此操作的代码并不是一个成熟的 SQL 解析器,因此应该首先使用 –dry-run 和 –print 运行该工具,并验证它是否正确地检测到重命名的列。drop primary key:如果 –alter 包含 DROP PRIMARY KEY(大小写和空格不敏感),则会打印警告并退出,除非指定 –dry-run。更改主键可能是危险的,但是工具可以处理它。工具触发器,特别是 DELETE 触发器,最容易受到主键更改的影响。因此应该首先使用 –dry—run 和 — print 运行该工具,并验证触发器是否正确。
–[no]check-plan
- 检查 SQL 执行计划。默认值 yes,则在执行 SQL 前执行 EXPLAIN,如果 MySQL 选择了一个糟糕的执行计划,会导致访问很多行,该工具将跳过表的 chunk。
- 该工具使用很多个方式来决定执行计划是否糟糕。
–[no]check-unique-key-change
- 默认值为 yes,如果 –alter 的指定语句试图添加唯一索引,将不会执行,并打印一个 select 语句用于检查列上是否有重复记录。
- 因为 pt-online-schema-change 使用 INSERT IGNORE 将行复制到新表,所以如果正在写入的行主键冲突,不会报错,数据将丢失。
–[no]version-check
- 默认值:yes
- 检查 Percona Toolkit、MySQL 和其他程序的最新版本。
猜你喜欢
- 2024-09-11 kubernetes基础知识之项目部署(k8s项目部署)
- 2024-09-11 聊聊kingbus的startMasterServer(聊聊日常电视剧全集免费)
- 2024-09-11 这篇Redis文章,图灵看了都说好(redis原理图)
- 2024-09-11 PT-KILL长尾慢SQL有时失灵?自写脚本更靠谱
- 2024-09-11 基于 Spring Boot 的电商秒杀系统 jseckill
- 2024-09-11 技术分享 | 从库 MTS 多线程并行回放(一)
- 2024-09-11 常用数据库的最大连接数的获取和修改
- 2024-09-11 MySQL 调试环境搭建:VSCode + Docker
- 2024-09-11 Linux服务器百万并发实现与问题排查
- 2024-09-11 Elasticsearch + Logstash + Kibana 安装(全)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)