TiDB 如何使用会话级与全局临时表缓存中间数据
TiDB 如何使用会话级与全局临时表缓存中间数据【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb当应用需要把一组由多步 DML 构造出来的结果集暂存下来比如批处理中间结果、每个会话各自的临时工作区又不想污染正式表时可以用 TiDB 的临时表。TiDB 提供两种会话级本地临时表行为与 MySQL 临时表基本兼容只在当前会话可见会话关闭时自动删除全局临时表表结构对所有会话可见但数据只在当前事务内可用事务提交后数据即被丢弃。本文基于仓库中的设计文档 docs/design/2021-04-20-temporary-table.md 和集成测试 tests/integrationtest/t/session/temporary_table.test对应预期结果 tests/integrationtest/r/session/temporary_table.result给出可用的 SQL 操作路径。前提是你已经有一个可连接的 TiDB 集群和 SQL 客户端。两类临时表的可见性与生命周期设计文档定义了两种临时表在定义可见性和数据可见性两个维度上的差异操作前先确认自己要哪一种对比项会话级本地临时表全局临时表表定义可见范围仅创建它的会话元数据只在当前 TiDB 实例内存中所有会话元数据持久化在 TiKV数据生命周期会话内跨事务保留会话结束自动删除定义ON COMMIT DELETE ROWS后事务提交即清空DDL 路径绕过 online DDLADMIN SHOW DDL JOBS中看不到与普通表一样走 DDL并触发隐式提交SHOW TABLES不出现出现information_schema.TABLES不出现出现TABLE_TYPE为GLOBAL TEMPORARY TABLE权限检查建表检查CREATE TEMPORARY TABLES权限drop 和写入不检查权限所有 DDL 及写入都按普通表检查权限设计文档说明的适用目的包括结果集缓冲temporarily persisted、免去频繁TRUNCATE、以内存存储提升性能以及为 CTE 等特性物化中间数据。创建会话级临时表并写入中间数据语法来自设计文档CREATE TEMPORARY TABLE tbl_name (create_definition) [ENGINEengine_name]; DROP [TEMPORARY] TABLE tbl_name;下面的命令取自集成测试用例可直接照抄验证DROP TABLE IF EXISTS tmp1; CREATE TEMPORARY TABLE tmp1 (id int primary key auto_increment, u int unique, v int); INSERT INTO tmp1 (u, v) VALUES (11, 101); INSERT INTO tmp1 (u, v) VALUES (12, 102); INSERT INTO tmp1 VALUES (3, 13, 102); SELECT * FROM tmp1 WHERE id 1;预期结果文件中对应的文档示例输出为id u v 1 11 101几个行为判断点主键/唯一键冲突重复写入会报Error 1062 (23000): Duplicate entry 1 for key tmp1.PRIMARY文档示例INSERT ... ON DUPLICATE KEY UPDATE和REPLACE均可用行为与普通表一致。事务语义BEGIN后写入的行在会话内可见ROLLBACK撤销后对应行消失COMMIT不会清空数据——会话级临时表的数据在会话内跨事务保留。测试用例中先INSERT INTO tmp1 VALUES (5, 15, 105)再ROLLBACK随后SELECT * FROM tmp1 WHERE id 5返回空结果集文档示例。同名遮蔽若本地临时表与已有表、视图、序列同名临时表优先级更高。测试用例先创建普通表t1再执行CREATE TEMPORARY TABLE t1 (ct1 int);此后SHOW CREATE TABLE t1返回的是临时表定义文档示例。建表不触发隐式提交与设计文档一致创建和删除本地临时表不引起隐式提交。删除数据库不影响它drop 掉临时表所属的库本地临时表仍留在同名虚拟库中不会自动删除。创建全局临时表提交事务即清空语法来自设计文档CREATE GLOBAL TEMPORARY TABLE tbl_name (create_definition) [ENGINEengine_name] ON COMMIT DELETE ROWS; DROP TABLE tbl_name;测试用例中的完整路径如下DROP TABLE IF EXISTS g_tmp; CREATE GLOBAL TEMPORARY TABLE g_tmp (a int primary key, b int, c int, INDEX i_b(b)) ON COMMIT DELETE ROWS; BEGIN; INSERT INTO g_tmp VALUES (3, 3, 3); INSERT INTO g_tmp VALUES (4, 7, 9); SELECT * FROM g_tmp; SELECT b FROM g_tmp WHERE b 3; COMMIT; SELECT * FROM g_tmp;预期结果文件给出的文档示例输出事务内SELECT * FROM g_tmp返回刚插入的两行(3,3,3)和(4,7,9)SELECT b FROM g_tmp WHERE b 3返回7COMMIT之后再次SELECT * FROM g_tmp返回空结果集——这正是ON COMMIT DELETE ROWS的语义也是把全局临时表用作事务内暂存区时的核对方式。补充边界表结构全局可见、每个会话都会看到表定义但各会话写入的数据互不可见事务提交后一律丢弃设计文档说明在新会话中查询全局临时表只会返回空结果。全局临时表的 DDL 会像普通 DDL 一样触发隐式提交且 DDL binlog 会导出会话级临时表不会。控制临时表内存占用临时表默认使用内存存储TempTable 引擎与 MySQL 的默认不同。单表内存上限由系统变量tidb_tmp_table_max_size控制。测试用例展示了检查与设置方式SELECT global.tidb_tmp_table_max_size; SET session.tidb_tmp_table_max_size 1048576; -- 恢复默认 SET session.tidb_tmp_table_max_size default;测试预期结果中的文档示例输出默认值为67108864设置明显偏小的值123时会收到警告Warning 1292 Truncated incorrect tidb_tmp_table_max_size value: 123值会被截断为合法值而不是报错。超限时的现象在测试用例中有完整验证会话级与全局临时表都适用先插入 512*1024 字符的大字段行在接近上限的第三次插入时报错文档示例输出Error 1114 (HY000): The table t is full也就是说The table ... is full是判断临时表超过大小上限的直接信号。设计文档另外提到临时表内存用量超过阈值后会溢出到 TiDB 本地磁盘以避免 OOM该阈值由系统变量temptable_max_ram定义默认 1G。验证表是否按预期创建不依赖SHOW TABLES它不列出会话级临时表用以下方式核对SHOW CREATE TABLE tmp1; -- 对两类临时表都有效 SELECT TABLE_TYPE FROM information_schema.TABLES WHERE TABLE_NAME g_tmp;SHOW CREATE TABLE是设计文档确认对两类临时表都有效的命令全局临时表会出现在information_schema.TABLES中TABLE_TYPE值为GLOBAL TEMPORARY TABLE而会话级临时表不在information_schema.TABLES/COLUMNS中。全局临时表还会出现在SHOW TABLES里会话级临时表不会。不支持的操作与限制以下限制来自设计文档的兼容性表在临时表上执行会报错或设置被忽略规划中间数据流程时需要避开CREATE TABLE选项AUTO_RANDOM、SHARD_ROW_ID_BITS、PRE_SPLIT_REGIONS、PARTITION BY、FOREIGN KEY不支持报错用CREATE TABLE LIKE从一个带这些选项的源表建临时表同样报错。会话级临时表不支持ALTER TABLE操作包括加索引TiDB 会报错。SPLIT TABLE、SHOW TABLE REGIONS、ALTER PLACEMENT POLICY不支持。ADMIN CHECK TABLE、ADMIN CHECKSUM TABLE不支持。依赖 MVCC 的功能FLASHBACK TABLE、RECOVER TABLE、stale read、历史读不支持会报错。FOR UPDATE、LOCK IN SHARE MODE子句被忽略临时表不存在锁冲突。会话级临时表上不允许全局 SQL binding报错也不允许基于它创建视图全局临时表可以建全局或会话 SQL binding也可以在其上建视图。baseline / SPM 对临时表不生效临时表只维护行数统计AUTO ANALYZE不覆盖后台会话访问不到临时数据。临时表的 DML 不写 binlogMPP 相关设置broadcast join、shuffle hash join、follower read、tidb_isolation_read_engines等对内存临时表被忽略因为数据不在 TiKV / TiFlash 上。收尾核对完成一轮临时表操作后的核对清单会话级临时表在COMMIT后数据仍可见、在断开会话后自动消失且SHOW TABLES中不会出现全局临时表在COMMIT后SELECT返回空结果但表结构仍在、SHOW CREATE TABLE可查。如果需要了解元数据管理、写路径UnionScan / membuffer等内部细节继续阅读 临时表设计文档完整的行为验证可以对照 集成测试用例 与 预期执行结果。【免费下载链接】tidbTiDB is built for agentic workloads that grow unpredictably, with ACID guarantees and native support for transactions, analytics, and vector search. No data silos. No noisy neighbors. No infrastructure ceiling.项目地址: https://gitcode.com/GitHub_Trending/ti/tidb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →