运维管理23 分钟阅读
TDSQL MySQL 版 运维命令 100 条
TDSQL MySQL 版虽然兼容 MySQL 协议和大量 MySQL 语法,但它并不是在单机 MySQL 外面简单加一层代理。对于 InnoDB 引擎分布式实例来说,SQL 会先经过 Proxy 解析和路由,再发送到对应的 set 执行。
2026年7月30日阅读—点赞—收藏—
dba100mysql墨力计划tdsql
在知识库中专注阅读,并随时返回相关工具与课程
TDSQL MySQL 版虽然兼容 MySQL 协议和大量 MySQL 语法,但它并不是在单机 MySQL 外面简单加一层代理。对于 InnoDB 引擎分布式实例来说,SQL 会先经过 Proxy 解析和路由,再发送到对应的 set 执行。
TDSQL MySQL 版虽然兼容 MySQL 协议和大量 MySQL 语法,但它并不是在单机 MySQL 外面简单加一层代理。对于 InnoDB 引擎分布式实例来说,SQL 会先经过 Proxy 解析和路由,再发送到对应的 set 执行。
这意味着很多在单机 MySQL 中习以为常的操作,在 TDSQL 中需要重新理解:
shardkeyINSERT 必须包含分表键UPDATE 和 DELETE 必须带 WHERE 条件下面整理了 TDSQL MySQL 版 InnoDB 引擎常用的 100 条命令,覆盖连接、基础信息、对象检查、分表设计、数据操作、事务、读写分离、会话、锁、SQL 性能、空间、索引、Sequence、透传和导入导出等场景。
TDSQL MySQL 版存在不同内核和 SQL 引擎版本,部分语法与返回字段可能不同。本文不适用于 TDSQL Boundless、TDSQL PostgreSQL,也不能直接当作普通 MySQL 8.0 命令清单使用。执行前应通过控制台确认实例类型、内核版本和 SQL 引擎版本。
文中的数据库名、表名、账号、IP、端口、set 名称和分表键均为示例。涉及删除数据、终止连接、透传写操作、表结构变更和数据导入时,应先在测试环境验证。
1mysql -h 192.168.1.10 -P 3306 -u appuser -p密码由终端交互式输入,不建议直接写在命令行中。
1mysql -c -h 192.168.1.10 -P 3306 -u appuser -p-c 表示保留 SQL 注释。使用读写分离、透传 SQL 和 Proxy 管理注释时,应带上该参数,避免注释被客户端过滤。
1SELECT VERSION();结果反映当前兼容内核版本,但还应结合控制台确认 TDSQL 产品形态和 SQL 引擎版本。
1SELECT2 @@hostname AS hostname,3 @@port AS port,4 @@version AS version,5 CONNECTION_ID() AS connection_id;经过 Proxy 连接时,部分变量反映的是当前路由节点或平台提供的逻辑信息。
1SELECT DATABASE();1SELECT2 USER() AS login_user,3 CURRENT_USER() AS privilege_user;TDSQL MySQL 版的账号创建和权限配置通常需要通过控制台完成,不能照搬普通 MySQL 的用户管理流程。
1SELECT2 NOW() AS local_time,3 UTC_TIMESTAMP() AS utc_time;1SELECT2 @@session.time_zone AS session_time_zone,3 @@global.time_zone AS global_time_zone,4 @@system_time_zone AS system_time_zone;1SELECT2 @@character_set_server,3 @@character_set_database,4 @@character_set_connection,5 @@character_set_client,6 @@character_set_results;1SELECT2 @@global.sql_mode,3 @@session.sql_mode;SQL 模式会影响严格校验、分组查询和日期值处理。
1SHOW DATABASES;1CREATE DATABASE appdb2DEFAULT CHARACTER SET utf8mb4;1USE appdb;1SHOW CREATE DATABASE appdb;1SHOW FULL TABLES FROM appdb;1DESC appdb.orders;1SHOW CREATE TABLE appdb.orders\G这是检查 shardkey、主键、唯一索引、字符集和二级分区定义的重要入口。
1SHOW TABLE STATUS FROM appdb LIKE 'orders'\G返回的行数通常是估算值,分布式实例中的空间数据还应结合控制台监控判断。
1SELECT2 column_name,3 column_type,4 is_nullable,5 column_key,6 column_default,7 extra8FROM information_schema.columns9WHERE table_schema = 'appdb'10 AND table_name = 'orders'11ORDER BY ordinal_position;1SELECT2 constraint_name,3 constraint_type4FROM information_schema.table_constraints5WHERE table_schema = 'appdb'6 AND table_name = 'orders'7ORDER BY constraint_type, constraint_name;1CREATE TABLE appdb.orders (2 order_id BIGINT NOT NULL,3 customer_id BIGINT NOT NULL,4 order_time DATETIME NOT NULL,5 amount DECIMAL(18,2) NOT NULL,6 PRIMARY KEY (order_id, customer_id),7 KEY idx_orders_customer (customer_id)8) ENGINE = InnoDB9SHARDKEY = customer_id;SHARDKEY 必须放在建表语句末尾。分表键应选择分布较均匀、查询经常携带并且不会更新的字段。
1CREATE TABLE appdb.user_account (2 user_id BIGINT NOT NULL,3 account_no VARCHAR(64) NOT NULL,4 user_name VARCHAR(100),5 PRIMARY KEY (user_id),6 UNIQUE KEY uk_account_user (account_no, user_id)7) ENGINE = InnoDB8SHARDKEY = user_id;分表的主键和每个唯一索引都必须包含分表键,否则无法保证跨分片全局唯一。
1CREATE TABLE appdb.system_config (2 config_key VARCHAR(100) PRIMARY KEY,3 config_value VARCHAR(500)4) ENGINE = InnoDB;不指定 shardkey 时创建的是单表,数据存放在一个 set 中,适合数据量较小且不需要广播的对象。
1CREATE TABLE appdb.region_dict (2 region_id INT PRIMARY KEY,3 region_name VARCHAR(100)4) ENGINE = InnoDB5SHARDKEY = noshardkey_allset;广播表会在所有 set 中保存全量数据,适合较小、更新不频繁并且经常参与跨 set 关联的字典表。
1CREATE TABLE appdb.orders_range (2 order_id BIGINT NOT NULL,3 order_time DATE NOT NULL,4 amount DECIMAL(18,2),5 PRIMARY KEY (order_id, order_time)6)7TDSQL_DISTRIBUTED BY RANGE(order_id) (8 s1 VALUES LESS THAN (1000000),9 s2 VALUES LESS THAN (2000000)10);RANGE 和 LIST 一级分区语法需要相应 SQL 引擎版本支持,MySQL 5.7 兼容内核可能不支持。
1CREATE TABLE appdb.customer_list (2 customer_id BIGINT NOT NULL,3 customer_name VARCHAR(100),4 PRIMARY KEY (customer_id)5)6TDSQL_DISTRIBUTED BY LIST(customer_id) (7 s1 VALUES IN (1,3,5),8 s2 VALUES IN (2,4,6)9);s1、s2 是 set 别名,应根据实际 set 数量和官方规则配置,不能随意改成业务名称。
1CREATE TABLE appdb.order_history (2 customer_id BIGINT NOT NULL,3 order_id BIGINT NOT NULL,4 order_date DATE NOT NULL,5 amount DECIMAL(18,2),6 PRIMARY KEY (customer_id, order_id, order_date)7) ENGINE = InnoDB8SHARDKEY = customer_id9PARTITION BY RANGE COLUMNS(order_date) (10 PARTITION p202601 VALUES LESS THAN ('2026-02-01'),11 PARTITION p202602 VALUES LESS THAN ('2026-03-01'),12 PARTITION pmax VALUES LESS THAN (MAXVALUE)13);二级分区适合需要按时间裁剪和清理的表,不建议划分过细。
1SELECT2 table_schema,3 table_name,4 partition_name,5 partition_method,6 partition_expression,7 table_rows8FROM information_schema.partitions9WHERE table_schema = 'appdb'10 AND table_name = 'order_history'11ORDER BY partition_ordinal_position;1ALTER TABLE appdb.order_history2ADD PARTITION (3 PARTITION p202603 VALUES LESS THAN ('2026-04-01')4);执行前应检查现有 MAXVALUE 分区和当前内核支持情况。
1ALTER TABLE appdb.order_history2DROP PARTITION p202601;删除分区会同时删除其中数据,执行前必须确认数据保留策略和备份。
1INSERT INTO appdb.orders2 (order_id, customer_id, order_time, amount)3VALUES4 (10001, 2001, NOW(), 199.00);分表的 INSERT 必须包含分表键,否则 Proxy 无法判断数据应该写入哪个 set。
1INSERT INTO appdb.orders2 (order_id, customer_id, order_time, amount)3VALUES4 (10002, 2001, NOW(), 99.00),5 (10003, 2002, NOW(), 299.00);不同分表键的数据可能被路由到不同 set,应关注分布式事务和批量大小。
1SELECT *2FROM appdb.orders3WHERE customer_id = 20014 AND order_id = 10001;带等值分表键时,Proxy 可以直接路由到目标 set,通常是效率最高的访问方式。
1SELECT *2FROM appdb.orders3WHERE order_time >= '2026-07-01'4ORDER BY order_time DESC5LIMIT 100;不带分表键的查询可能下发到所有 set,再由 Proxy 聚合结果。数据量大时应重点评估扫描和网络开销。
1UPDATE appdb.orders2SET amount = 209.003WHERE customer_id = 20014 AND order_id = 10001;UPDATE 必须带 WHERE 条件,建议包含分表键。TDSQL 不允许直接更新 shardkey 的值。
1DELETE FROM appdb.orders2WHERE customer_id = 20013 AND order_id = 10001;DELETE 必须带 WHERE 条件,建议包含分表键,避免广播到全部 set。
1REPLACE INTO appdb.orders2 (order_id, customer_id, order_time, amount)3VALUES4 (10001, 2001, NOW(), 209.00);REPLACE 同样必须包含分表键,并可能先删除冲突行再插入,应评估触发的写放大。
1INSERT INTO appdb.orders2 (order_id, customer_id, order_time, amount)3VALUES4 (10001, 2001, NOW(), 209.00)5ON DUPLICATE KEY UPDATE6 amount = VALUES(amount),7 order_time = VALUES(order_time);唯一键必须符合分表规则,不能在更新部分修改分表键。
1SELECT2 order_id,3 customer_id,4 order_time,5 amount6FROM appdb.orders7WHERE customer_id = 20018ORDER BY order_time DESC, order_id DESC9LIMIT 20 OFFSET 0;分布式查询如果排序字段不唯一,不同 set 聚合后可能出现顺序不稳定,因此应增加唯一字段作为辅助排序。
1SELECT2 o.order_id,3 o.customer_id,4 d.product_id,5 d.quantity6FROM appdb.orders o7JOIN appdb.order_detail d8 ON d.customer_id = o.customer_id9 AND d.order_id = o.order_id10WHERE o.customer_id = 2001;关联表使用相同分表键并在条件中带上该键,更有机会在单个 set 内完成计算。
1START TRANSACTION;1COMMIT;1ROLLBACK;1SAVEPOINT sp_before_update;回滚到保存点:
1ROLLBACK TO SAVEPOINT sp_before_update;应先确认当前内核版本和分布式事务场景是否支持预期行为。
1SELECT @@session.autocommit;1SET SESSION autocommit = 0;使用完后恢复:
1SET SESSION autocommit = 1;长时间不提交的分布式事务会占用锁和资源。
1SELECT @@session.transaction_isolation;较老兼容版本可以查看:
1SELECT @@session.tx_isolation;1SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;1/*slave*/ SELECT *2FROM appdb.orders3WHERE customer_id = 20014ORDER BY order_time DESC5LIMIT 20;连接客户端时必须使用 -c 保留注释。备节点读取可能存在延迟,不适合强一致读场景。
1/*slave:slaveonly,20*/ SELECT COUNT(*)2FROM appdb.orders3WHERE customer_id = 2001;slaveonly 表示没有符合条件的备节点时不回退到主节点,20 表示允许的延迟阈值。具体单位和支持形式应以当前版本官方文档为准。
1SELECT CONNECTION_ID();1SHOW FULL PROCESSLIST;重点关注连接来源、状态、运行时间和 SQL 文本。
1SELECT2 id,3 user,4 host,5 db,6 command,7 time,8 state,9 info10FROM information_schema.processlist11ORDER BY time DESC;1SELECT2 id,3 user,4 host,5 db,6 time,7 state,8 info9FROM information_schema.processlist10WHERE command <> 'Sleep'11 AND time >= 6012ORDER BY time DESC;1SELECT2 user,3 COUNT(*) AS connections4FROM information_schema.processlist5GROUP BY user6ORDER BY connections DESC;1SELECT2 SUBSTRING_INDEX(host, ':', 1) AS client_host,3 COUNT(*) AS connections4FROM information_schema.processlist5GROUP BY SUBSTRING_INDEX(host, ':', 1)6ORDER BY connections DESC;1KILL QUERY 12345;该操作只终止当前语句,连接通常保留。
1KILL CONNECTION 12345;终止连接会回滚未提交事务,执行前必须核对连接 ID、用户、来源地址和业务影响。
1/*proxy*/ SHOW STATUS;连接时应使用 mysql -c。该命令可以作为查看 set 名称和 Proxy 路由信息的入口,具体输出以实例版本为准。
1SHOW GLOBAL STATUS;筛选连接相关指标:
1SHOW GLOBAL STATUS LIKE 'Threads%';在分布式实例中,指标可能来自逻辑实例、Proxy 或当前路由节点,应结合控制台实例级、分片级和节点级监控解释。
1EXPLAIN2SELECT *3FROM appdb.orders4WHERE customer_id = 20015 AND order_time >= '2026-07-01';1EXPLAIN FORMAT=JSON2SELECT *3FROM appdb.orders4WHERE customer_id = 2001;是否支持完整 JSON 字段与当前兼容内核版本有关。
1SHOW INDEX FROM appdb.orders;1SELECT2 index_name,3 seq_in_index,4 column_name,5 cardinality,6 non_unique7FROM information_schema.statistics8WHERE table_schema = 'appdb'9 AND table_name = 'orders'10ORDER BY index_name, seq_in_index;cardinality 是估算值,不能代替实际数据分布分析。
1ANALYZE TABLE appdb.orders;分表执行时可能涉及多个 set。应在低峰期执行,并确认当前版本对分表的支持方式。
1SHOW VARIABLES LIKE 'optimizer%';1SHOW VARIABLES LIKE 'max_execution_time';如果当前版本支持,可以在会话中设置:
1SET SESSION max_execution_time = 30000;单位通常为毫秒,应以实际变量说明为准。
1SHOW GLOBAL STATUS LIKE 'Created_tmp%';TDSQL MySQL 版分布式实例不支持用户创建 TEMPORARY TABLE,这里的指标主要用于观察执行过程中产生的内部临时对象。
1SHOW GLOBAL STATUS LIKE 'Sort%';1SHOW GLOBAL STATUS LIKE 'Select_scan';全局累计值需要结合采样时间差、QPS 和分片监控判断,单次查询结果不能直接说明当前存在性能故障。
1SELECT2 trx_id,3 trx_state,4 trx_started,5 trx_mysql_thread_id,6 trx_rows_locked,7 trx_rows_modified,8 trx_query9FROM information_schema.innodb_trx10ORDER BY trx_started;视图可见性与账号权限和内核版本有关。
1SELECT2 trx_id,3 trx_mysql_thread_id,4 TIMESTAMPDIFF(SECOND, trx_started, NOW()) AS trx_seconds,5 trx_rows_locked,6 trx_rows_modified,7 trx_query8FROM information_schema.innodb_trx9ORDER BY trx_seconds DESC;1SHOW ENGINE INNODB STATUS\G重点关注最近死锁、事务、信号量、Buffer Pool 和 I/O。通过 Proxy 执行时,输出范围可能只对应某个 set,需要结合透传或控制台诊断。
1SELECT *2FROM performance_schema.data_locks;该表适用于支持相应 Performance Schema 结构的版本。
1SELECT *2FROM performance_schema.data_lock_waits;1SELECT2 r.trx_mysql_thread_id AS waiting_thread,3 r.trx_started AS waiting_since,4 b.trx_mysql_thread_id AS blocking_thread,5 b.trx_started AS blocking_since,6 r.trx_query AS waiting_query,7 b.trx_query AS blocking_query8FROM performance_schema.data_lock_waits w9JOIN information_schema.innodb_trx r10 ON r.trx_id = w.requesting_engine_transaction_id11JOIN information_schema.innodb_trx b12 ON b.trx_id = w.blocking_engine_transaction_id;不同内核版本的锁表字段可能不同,执行前应先 DESC performance_schema.data_lock_waits。
1SHOW ENGINE INNODB STATUS\G在输出中查找:
1LATEST DETECTED DEADLOCK1SHOW VARIABLES LIKE 'innodb_deadlock_detect';托管实例参数是否允许修改,应以控制台参数模板为准。
1SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';1SET SESSION innodb_lock_wait_timeout = 30;这只影响当前会话,不能代替对阻塞源和长事务的排查。
1SELECT2 table_schema,3 ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS size_gb4FROM information_schema.tables5WHERE table_schema NOT IN (6 'information_schema',7 'mysql',8 'performance_schema',9 'sys'10)11GROUP BY table_schema12ORDER BY size_gb DESC;分布式环境中的逻辑统计与物理分片占用可能不同,应同时查看控制台容量监控。
1SELECT2 table_schema,3 table_name,4 table_rows,5 ROUND(data_length / 1024 / 1024, 2) AS data_mb,6 ROUND(index_length / 1024 / 1024, 2) AS index_mb,7 ROUND((data_length + index_length) / 1024 / 1024, 2) AS total_mb8FROM information_schema.tables9WHERE table_schema = 'appdb'10ORDER BY data_length + index_length DESC11LIMIT 20;table_rows 对 InnoDB 通常是估算值。
1SELECT2 t.table_schema,3 t.table_name4FROM information_schema.tables t5LEFT JOIN information_schema.table_constraints c6 ON c.table_schema = t.table_schema7 AND c.table_name = t.table_name8 AND c.constraint_type = 'PRIMARY KEY'9WHERE t.table_schema = 'appdb'10 AND t.table_type = 'BASE TABLE'11 AND c.constraint_name IS NULL12ORDER BY t.table_name;1SELECT2 table_schema,3 table_name,4 index_name,5 GROUP_CONCAT(column_name ORDER BY seq_in_index) AS index_columns6FROM information_schema.statistics7WHERE table_schema = 'appdb'8GROUP BY table_schema, table_name, index_name9ORDER BY table_name, index_columns;结果需要人工比较,不能仅根据字段相同就直接删除索引。
1CREATE INDEX idx_orders_time2ON appdb.orders(order_time);对于分表,大范围不带分表键的查询即使有二级索引,也可能仍然需要访问全部 set。
1CREATE UNIQUE INDEX uk_orders_no_customer2ON appdb.orders(order_no, customer_id);所有唯一索引都必须包含 shardkey。
1DROP INDEX idx_orders_time2ON appdb.orders;删除前应确认索引不是唯一约束依赖对象,并观察完整业务周期。
1ALTER TABLE appdb.orders2ADD COLUMN remark VARCHAR(500) NULL;分布式大表执行 DDL 可能耗时较长,应评估锁、空间和各 set 的执行情况。
1ALTER TABLE appdb.orders2MODIFY COLUMN remark VARCHAR(1000) NULL;TDSQL 不支持对分表键字段进行改名,也不能通过更新数据改变分表键值。
1TRUNCATE TABLE appdb.stage_orders;执行前应确认表类型、数据保留要求和当前版本支持情况。清空操作不可按普通 DELETE 方式回退。
1CREATE TDSQL_SEQUENCE appdb.order_seq2START WITH 13TDSQL_MINVALUE 14TDSQL_MAXVALUE 9999999999995TDSQL_INCREMENT BY 16TDSQL_NOCYCLE7TDSQL_CACHE 20;Sequence 需要相应 SQL 引擎版本和权限支持,主要用于并发不高且需要全局唯一编号的场景。
1SHOW CREATE TDSQL_SEQUENCE appdb.order_seq;1SELECT TDSQL_NEXTVAL(appdb.order_seq);也可以使用当前版本支持的标准兼容形式:
1SELECT NEXT VALUE FOR appdb.order_seq;1SELECT TDSQL_RESETVAL(appdb.order_seq, 100000);重设前必须确认不会与现有业务数据冲突。
1DROP TDSQL_SEQUENCE appdb.order_seq;1/*sets:set_1544429718_1*/ SELECT COUNT(*)2FROM appdb.orders;实际 set 名称可以通过 /*proxy*/ SHOW STATUS 查询。连接时必须使用 mysql -c。
1/*sets:allsets*/ SELECT COUNT(*)2FROM appdb.orders;结果通常会分别返回各 set 的执行结果,不能直接把单行结果误认为整个逻辑表总数。
1/*shardkey:2001*/ SELECT *2FROM appdb.orders3WHERE customer_id = 2001;Proxy 会根据给定分表键把 SQL 路由到对应 set。
透传写操作风险较高。一次向多个 set 透传写入时,Proxy 不会自动提供普通分布式事务保障,可能造成数据不一致。
1mysqldump -h 192.168.1.10 -P 3306 -u backup_user -p \2 --single-transaction \3 --set-gtid-purged=OFF \4 appdb orders > /backup/orders.sql具体参数应以腾讯云数据导出导入指南和当前内核兼容性为准。大规模备份恢复优先使用控制台提供的备份能力或官方迁移工具。
1mysql -h 192.168.1.10 -P 3306 -u restore_user -p \2 appdb < /backup/orders.sql从单机 MySQL 导入到 TDSQL 分布式实例前,必须先调整表结构:确定表类型,为分表增加合适的 shardkey,并确保主键和所有唯一索引包含分表键。建议先导入表结构,验证无误后再导入数据,最后校验表数量、行数、索引和业务查询结果。
TDSQL MySQL 版的日常使用看起来与 MySQL 相似,但 DBA 排查问题时必须多考虑两层:Proxy 如何解析和路由 SQL,以及数据实际分布在哪些 set。
一条 SQL 在单机 MySQL 中能够使用索引,并不代表它在 TDSQL 中就一定高效。如果查询没有携带分表键,即使每个 set 内部都走索引,也可能需要广播到全部 set,再由 Proxy 完成聚合、排序和返回。
因此,TDSQL 运维和优化最重要的几个检查点是:
账号权限、参数模板、备份恢复、扩缩容、主备切换和监控告警等操作,应以腾讯云控制台和对应版本官方文档为准,不能简单照搬普通 MySQL 的 Shell 管理命令。