标签: alter-table

向表中添加可为空列的成本超过 10 分钟

我在表上添加新列时遇到问题。
我尝试运行了几次,但是运行了 10 多分钟后,由于锁定时间,我决定取消查询。

ALTER TABLE mytable ADD mycolumn VARCHAR(50);
Run Code Online (Sandbox Code Playgroud)

有用的信息:

  • PostgreSQL 版本:9.1
  • 行数:~ 250K
  • 列数:38
  • 可空列数:32
  • 约束数量:5(1 PK、3 FK、1 UNIQUE)
  • 索引数:1
  • 操作系统类型:Debian Squeeze 64

我发现了有关 PostgreSQL 管理可空列的方式的有趣信息(通过 HeapTupleHeader)。

我的第一个猜测是,因为这个表已经有 32 个 8 位的可空列MAXALIGN, HeapTupleHeader 是 4 字节长度(未验证,我不知道如何这样做)。

因此,添加新的可为空的列可能需要在每一行上更新 HeapTupleHeader 以添加新的 8-bits MAXALIGN,这可能会导致性能问题。

因此,我尝试更改可空列之一(实际上并不是真正可以为空的),以便将可空列的数量减少到 31,以检查我的猜测是否属实。

ALTER TABLE mytable ALTER myothercolumn SET NOT NULL;
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个改动也需要很长时间,超过5分钟,所以我也中止了。

您知道是什么导致了这种性能成本吗?

postgresql database-design alter-table postgresql-9.1

11
推荐指数
1
解决办法
4025
查看次数

ALTER TABLE ... DROP COLUMN 真的是元数据操作吗?

我发现了几个声明 ALTER TABLE ... DROP COLUMN 是仅元数据操作的来源。

来源

怎么会这样?DROP COLUMN 期间的数据是否不需要从底层非聚集索引和聚集索引/堆中清除?

此外,为什么Microsoft Docs暗示它是一个完整记录的操作?

对表所做的修改会被记录下来并且完全可以恢复。影响大表中所有行的更改(例如删除列或在某些版本的 SQL Server 上添加具有默认值的 NOT NULL 列)可能需要很长时间才能完成并生成许多日志记录。以与影响多行的任何 INSERT、UPDATE 或 DELETE 语句相同的方式运行这些 ALTER TABLE 语句。

作为次要问题:如果数据没有从底层页面中删除,引擎如何跟踪删除的列?

sql-server alter-table transaction-log

11
推荐指数
1
解决办法
2042
查看次数

改变列:null 到 not null

我不得不将 MYSQL 中的一列更改为 NULL 到 NOT NULL,但是我得到了语法错误。我只想更改最后一列,已经进行了一些研究,但还没有找到解决方案,这可能很简单,但我是数据库新手,直到现在才意识到这一点。有谁能够帮助我?

示例: 快速将 NULL 列更改为 NOT NULL

ALTER TABLE glpi_ticketsatisfactions ALTER COLUMN comment BIGINT NOT NULL;
Run Code Online (Sandbox Code Playgroud)

我的表: 我的桌子

错误:

[42000][1064] 你的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,在第 1 行的“BIGINT NOT NULL”附近使用正确的语法

CREATE TABLE

CREATE TABLE glpi_ticketsatisfactions 
( id int(11) NOT NULL AUTO_INCREMENT, 
  tickets_id int(11) NOT NULL DEFAULT '0', 
  type int(11) NOT NULL DEFAULT '1', 
  ate_begin datetime DEFAULT NULL, 
  date_answered datetime DEFAULT NULL,
  satisfaction int(11) DEFAULT NULL, 
  comment text COLLATE utf8_unicode_ci, 
  PRIMARY KEY (id), 
  UNIQUE KEY tickets_id …
Run Code Online (Sandbox Code Playgroud)

mysql alter-table

10
推荐指数
1
解决办法
6万
查看次数

更改列大小需要很长时间?

我有一个包含 45M 行(45 GB 数据空间和 2GB 索引空间)的表。我添加了一个新列,它立即完成。

alter table T add C char(25)
Run Code Online (Sandbox Code Playgroud)

然后我发现尺寸太小,所以我运行以下查询。

alter table T alter column C varchar(2500)
Run Code Online (Sandbox Code Playgroud)

它运行了一个小时,并且仍在运行。sp_whoisactive 显示(目前,仍在运行)

reads: 48,000,000
writes: 5,000,000
physical reads: 3,900,000
Run Code Online (Sandbox Code Playgroud)

不是应该很快吗?

sql-server alter-table sql-server-2014

9
推荐指数
2
解决办法
2万
查看次数

无需停机即可更改大表

我有一个非常大的表,让我们调用它example,然后我尝试在该表上执行一些更改命令:

ALTER TABLE `example` ADD `example_column` TINYINT(1) NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)

检查alter命令的进度:

mysql -e 'show engine innodb status \G' | grep 'undo \| log \| entries'
Run Code Online (Sandbox Code Playgroud)

给我很好的信息,关于时间 - 或多或少需要 17 天才能完成......

更改阻塞表,因此阻塞生产表 17 天不是一个好的选择。;)

我尝试在网上调查一些很棒的工具,例如:

  1. pt-online-schema-change - Percona
  2. gh-ost - GitHub 的 MySQL 在线架构迁移

我还阅读了文档和上述工具的限制部分:

鬼魂限制

  • 根本不支持触发器
  • 根本不支持外键

pt-online-schema-change 限制

  • 触发器的使用意味着如果表上已经定义了任何触发器,则该工具将无法工作。

  • 不提供任何改变包含外键的表的好方法

我的示例表有触发器和外键...

你能给我一些建议,如何处理这个改变?

我有 MySQL 5.6。我使用 GTID(基于行)复制。

我将非常感谢您的建议!

mysql alter-table mysql-5.6 percona-toolkit

9
推荐指数
1
解决办法
1万
查看次数

如何将 PostgreSQL 10 标识列添加到现有表中?

我正在阅读有关新的Postgres 10 标识列的信息,并了解了如何使用它SERIALCREATE TABLE.

是否也可以向现有表添加标识列?

例如,使用旧SERIAL列,我可以执行以下操作:

ALTER TABLE sourceTable ADD  COLUMN ogc_fid SERIAL;
Run Code Online (Sandbox Code Playgroud)

对于标识列,是否有与上述相同的内容?我试过:

ALTER TABLE sourceTable ADD  COLUMN ogc_fid GENERATED BY DEFAULT AS IDENTITY;
Run Code Online (Sandbox Code Playgroud)

但是得到了一个错误:

错误:“BY”第 1 行或附近的语法错误:...R TABLE sourceTable ADD COLUMN ogc_fid GENERATED BY DEFAULT

我正在考虑用我的脚本中的SERIAL列替换列IDENTITY,只是想检查这是否可行。

postgresql alter-table identity postgresql-10

8
推荐指数
1
解决办法
7449
查看次数

ALTER TABLE - ADD COLUMN 是否锁定表?

我有一个关于ALTER TABLE ... ADD COLUMNDDL 语句的问题。

在使用 MariaDB v10.2 的 Amazon RDS 实例上,我注意到INSERT语句完成并且行在表上完成SELECT之前正确插入表中(通过 验证)ALTER TABLE ... ADD COLUMN

ALTER TABLE操作完成之前,不应该将任何执行写入的 DML 语句排队吗?

我发布这个问题是因为我被要求执行一些测试来验证是否可以ALTER TABLE ... ADD COLUMN在工作时间内在实时生产数据库上运行,在频繁使用的数据库上,在有几百万行的表上运行——我觉得很不明智。即使ALTER TABLE没有在表上放置锁,它也必须等到任何连接不再使用该表(由于连接放置了元数据锁),这可能会在很久以后发生。
编辑:显然这个评估过于悲观。我一直在做几个测试,mysqlslap在表上执行繁重的操作 ( INSERT, UPDATE,DELETE语句和SELECT语句LIKE避免在ALTER TABLE ... ADD COLUMN运行时在 150 个模拟并发连接上使用索引;分析显示元数据锁定,但等待时间很短(每个 1 秒),表更改在大约 30 分钟内完成,而没有运行 SQL 语句时则需要 10 分钟。虽然这很令人满意,但另一方面,我想知道假设 DDL 语句是非阻塞的是否安全。

(可能值得注意的是InnoDB …

mariadb alter-table amazon-rds

8
推荐指数
1
解决办法
1万
查看次数

让 ALTER TABLE 等待锁而不阻塞其他任何事情

许多 PostgreSQLALTER TABLE命令(例如添加具有默认值的新列)在最新版本的 PostgreSQL 中进行了巧妙的优化,一旦 Postgres 短暂获取了表上的锁,即使在大型表上,它们也能基本上立即执行。

不幸的是,最后的警告很重要。链接博客文章中类似这样的命令

ALTER TABLE users ADD COLUMN credits bigint NOT NULL DEFAULT 0;
Run Code Online (Sandbox Code Playgroud)

仍然需要等待表上的独占锁users才能运行,尽管一旦获取锁就会立即执行。更糟糕的是,当它等待该锁时,它会阻止涉及该表的所有写入和读取。

重现此问题的一些简单步骤(在 Postgres 13.3 中测试):

  1. 在一个psqlshell 中,创建一个表,然后启动一个事务,从表中进行读取,但不提交:

    CREATE TABLE users (id SERIAL, name TEXT);
    INSERT INTO users (name) VALUES ('bob'), ('fred');
    START TRANSACTION;
    SELECT * FROM users WHERE id = 1;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 让第一个 shell 打开,然后打开第二个 shell 并尝试更改表:

    ALTER TABLE users ADD COLUMN credits bigint NOT NULL DEFAULT 0;
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,此查询挂起,等待第一个 shell …

postgresql alter-table locking

8
推荐指数
1
解决办法
8582
查看次数

删除表的多个 KEYS

在一个表中删除多个 KEYS 是首选还是一个一个的首选?

“按键A,按键B,按键C”

表中有 9 亿多条记录。

它在内部如何运作?

mysql innodb index alter-table

7
推荐指数
1
解决办法
2万
查看次数

如何将所有表从一个 Postgres 模式移动到另一个

我想将所有表从架构移动xyz到默认架构public

我可以移动单个表

ALTER TABLE table_name
    SET SCHEMA public;
Run Code Online (Sandbox Code Playgroud)

我可以得到所有的桌子

SELECT table_name FROM information_schema.tables WHERE table_schema='xyz'
Run Code Online (Sandbox Code Playgroud)

有没有办法将这两者结合在一起?

schema postgresql alter-table

7
推荐指数
2
解决办法
6864
查看次数